mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-07 23:41:26 +12:00
rsx: Reimplement vertex layout streaming
- Remove string comparisons from the hot-path! - Use attribute streaming and push constants to avoid forcing a descriptor block copy every other draw call/pass. While this isn't so bad on nvidia cards, it makes AMD cards a slideshow.
This commit is contained in:
parent
59ee74a275
commit
6a32f716db
7 changed files with 140 additions and 96 deletions
|
@ -366,20 +366,36 @@ namespace glsl
|
||||||
" // [32-60] starting offset\n"
|
" // [32-60] starting offset\n"
|
||||||
" // [60-61] swap bytes flag\n"
|
" // [60-61] swap bytes flag\n"
|
||||||
" // [61-62] volatile flag\n"
|
" // [61-62] volatile flag\n"
|
||||||
" // [62-63] modulo enable flag\n"
|
" // [62-63] modulo enable flag\n";
|
||||||
" int block = (location >> 1);\n"
|
|
||||||
" int sub_block = (location & 1) << 1;\n"
|
if (rules == glsl_rules_opengl4)
|
||||||
" uint attrib0 = ref(input_attributes_blob[block], sub_block + 0);\n"
|
{
|
||||||
" uint attrib1 = ref(input_attributes_blob[block], sub_block + 1);\n"
|
// Data is packed into a ubo
|
||||||
|
OS <<
|
||||||
|
" int block = (location >> 1);\n"
|
||||||
|
" int sub_block = (location & 1) << 1;\n"
|
||||||
|
" uvec2 attrib = uvec2(\n"
|
||||||
|
" ref(input_attributes_blob[block], sub_block + 0),\n"
|
||||||
|
" ref(input_attributes_blob[block], sub_block + 1));\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Fetch parameters streamed separately from draw parameters
|
||||||
|
OS <<
|
||||||
|
" location += int(layout_ptr_offset);\n"
|
||||||
|
" uvec2 attrib = texelFetch(vertex_layout_stream, location).xy;\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
OS <<
|
||||||
" attribute_desc result;\n"
|
" attribute_desc result;\n"
|
||||||
" result.stride = attrib0 & 0xFF;\n"
|
" result.stride = attrib.x & 0xFF;\n"
|
||||||
" result.frequency = (attrib0 >> 8) & 0xFFFF;\n"
|
" result.frequency = (attrib.x >> 8) & 0xFFFF;\n"
|
||||||
" result.type = (attrib0 >> 24) & 0x7;\n"
|
" result.type = (attrib.x >> 24) & 0x7;\n"
|
||||||
" result.attribute_size = (attrib0 >> 27) & 0x7;\n"
|
" result.attribute_size = (attrib.x >> 27) & 0x7;\n"
|
||||||
" result.starting_offset = (attrib1 & 0x1FFFFFFF);\n"
|
" result.starting_offset = (attrib.y & 0x1FFFFFFF);\n"
|
||||||
" result.swap_bytes = ((attrib1 >> 29) & 0x1) != 0;\n"
|
" result.swap_bytes = ((attrib.y >> 29) & 0x1) != 0;\n"
|
||||||
" result.is_volatile = ((attrib1 >> 30) & 0x1) != 0;\n"
|
" result.is_volatile = ((attrib.y >> 30) & 0x1) != 0;\n"
|
||||||
" result.modulo = ((attrib1 >> 31) & 0x1) != 0;\n"
|
" result.modulo = ((attrib.y >> 31) & 0x1) != 0;\n"
|
||||||
" return result;\n"
|
" return result;\n"
|
||||||
"}\n\n"
|
"}\n\n"
|
||||||
|
|
||||||
|
|
|
@ -185,13 +185,13 @@ void VKFragmentDecompilerThread::insertConstants(std::stringstream & OS)
|
||||||
|
|
||||||
if (!constants_block.empty())
|
if (!constants_block.empty())
|
||||||
{
|
{
|
||||||
OS << "layout(std140, set = 0, binding = 3) uniform FragmentConstantsBuffer\n";
|
OS << "layout(std140, set = 0, binding = 2) uniform FragmentConstantsBuffer\n";
|
||||||
OS << "{\n";
|
OS << "{\n";
|
||||||
OS << constants_block;
|
OS << constants_block;
|
||||||
OS << "};\n\n";
|
OS << "};\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
OS << "layout(std140, set = 0, binding = 4) uniform FragmentStateBuffer\n";
|
OS << "layout(std140, set = 0, binding = 3) uniform FragmentStateBuffer\n";
|
||||||
OS << "{\n";
|
OS << "{\n";
|
||||||
OS << " float fog_param0;\n";
|
OS << " float fog_param0;\n";
|
||||||
OS << " float fog_param1;\n";
|
OS << " float fog_param1;\n";
|
||||||
|
@ -203,7 +203,7 @@ void VKFragmentDecompilerThread::insertConstants(std::stringstream & OS)
|
||||||
OS << " float wpos_bias;\n";
|
OS << " float wpos_bias;\n";
|
||||||
OS << "};\n\n";
|
OS << "};\n\n";
|
||||||
|
|
||||||
OS << "layout(std140, set = 0, binding = 5) uniform TextureParametersBuffer\n";
|
OS << "layout(std140, set = 0, binding = 4) uniform TextureParametersBuffer\n";
|
||||||
OS << "{\n";
|
OS << "{\n";
|
||||||
OS << " vec4 texture_parameters[16];\n";
|
OS << " vec4 texture_parameters[16];\n";
|
||||||
OS << "};\n\n";
|
OS << "};\n\n";
|
||||||
|
|
|
@ -279,7 +279,7 @@ namespace
|
||||||
size_t idx = 0;
|
size_t idx = 0;
|
||||||
|
|
||||||
// Vertex stream, one stream for cacheable data, one stream for transient data
|
// Vertex stream, one stream for cacheable data, one stream for transient data
|
||||||
for (int i = 0; i < 2; i++)
|
for (int i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
bindings[idx].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
|
bindings[idx].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
|
||||||
bindings[idx].descriptorCount = 1;
|
bindings[idx].descriptorCount = 1;
|
||||||
|
@ -316,13 +316,6 @@ namespace
|
||||||
|
|
||||||
idx++;
|
idx++;
|
||||||
|
|
||||||
bindings[idx].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
|
||||||
bindings[idx].descriptorCount = 1;
|
|
||||||
bindings[idx].stageFlags = VK_SHADER_STAGE_ALL_GRAPHICS;
|
|
||||||
bindings[idx].binding = VERTEX_LAYOUT_BIND_SLOT;
|
|
||||||
|
|
||||||
idx++;
|
|
||||||
|
|
||||||
bindings[idx].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
bindings[idx].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||||
bindings[idx].descriptorCount = 1;
|
bindings[idx].descriptorCount = 1;
|
||||||
bindings[idx].stageFlags = VK_SHADER_STAGE_ALL_GRAPHICS;
|
bindings[idx].stageFlags = VK_SHADER_STAGE_ALL_GRAPHICS;
|
||||||
|
@ -350,6 +343,11 @@ namespace
|
||||||
|
|
||||||
verify(HERE), idx == VK_NUM_DESCRIPTOR_BINDINGS;
|
verify(HERE), idx == VK_NUM_DESCRIPTOR_BINDINGS;
|
||||||
|
|
||||||
|
std::array<VkPushConstantRange, 1> push_constants;
|
||||||
|
push_constants[0].offset = 0;
|
||||||
|
push_constants[0].size = 16;
|
||||||
|
push_constants[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
|
||||||
|
|
||||||
VkDescriptorSetLayoutCreateInfo infos = {};
|
VkDescriptorSetLayoutCreateInfo infos = {};
|
||||||
infos.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
infos.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
||||||
infos.pBindings = bindings.data();
|
infos.pBindings = bindings.data();
|
||||||
|
@ -362,6 +360,8 @@ namespace
|
||||||
layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
||||||
layout_info.setLayoutCount = 1;
|
layout_info.setLayoutCount = 1;
|
||||||
layout_info.pSetLayouts = &set_layout;
|
layout_info.pSetLayouts = &set_layout;
|
||||||
|
layout_info.pushConstantRangeCount = 1;
|
||||||
|
layout_info.pPushConstantRanges = push_constants.data();
|
||||||
|
|
||||||
VkPipelineLayout result;
|
VkPipelineLayout result;
|
||||||
CHECK_RESULT(vkCreatePipelineLayout(dev, &layout_info, nullptr, &result));
|
CHECK_RESULT(vkCreatePipelineLayout(dev, &layout_info, nullptr, &result));
|
||||||
|
@ -491,7 +491,7 @@ VKGSRender::VKGSRender() : GSRender()
|
||||||
m_fragment_env_ring_info.create(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_UBO_RING_BUFFER_SIZE_M * 0x100000, "fragment env buffer");
|
m_fragment_env_ring_info.create(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_UBO_RING_BUFFER_SIZE_M * 0x100000, "fragment env buffer");
|
||||||
m_vertex_env_ring_info.create(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_UBO_RING_BUFFER_SIZE_M * 0x100000, "vertex env buffer");
|
m_vertex_env_ring_info.create(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_UBO_RING_BUFFER_SIZE_M * 0x100000, "vertex env buffer");
|
||||||
m_fragment_texture_params_ring_info.create(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_UBO_RING_BUFFER_SIZE_M * 0x100000, "fragment texture params buffer");
|
m_fragment_texture_params_ring_info.create(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_UBO_RING_BUFFER_SIZE_M * 0x100000, "fragment texture params buffer");
|
||||||
m_vertex_layout_ring_info.create(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_UBO_RING_BUFFER_SIZE_M * 0x100000, "vertex layout buffer");
|
m_vertex_layout_ring_info.create(VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, VK_UBO_RING_BUFFER_SIZE_M * 0x100000, "vertex layout buffer");
|
||||||
m_fragment_constants_ring_info.create(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_UBO_RING_BUFFER_SIZE_M * 0x100000, "fragment constants buffer");
|
m_fragment_constants_ring_info.create(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_UBO_RING_BUFFER_SIZE_M * 0x100000, "fragment constants buffer");
|
||||||
m_transform_constants_ring_info.create(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_TRANSFORM_CONSTANTS_BUFFER_SIZE_M * 0x100000, "transform constants buffer");
|
m_transform_constants_ring_info.create(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_TRANSFORM_CONSTANTS_BUFFER_SIZE_M * 0x100000, "transform constants buffer");
|
||||||
m_index_buffer_ring_info.create(VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_INDEX_RING_BUFFER_SIZE_M * 0x100000, "index buffer");
|
m_index_buffer_ring_info.create(VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_INDEX_RING_BUFFER_SIZE_M * 0x100000, "index buffer");
|
||||||
|
@ -588,6 +588,7 @@ VKGSRender::~VKGSRender()
|
||||||
|
|
||||||
m_persistent_attribute_storage.reset();
|
m_persistent_attribute_storage.reset();
|
||||||
m_volatile_attribute_storage.reset();
|
m_volatile_attribute_storage.reset();
|
||||||
|
m_vertex_layout_storage.reset();
|
||||||
|
|
||||||
//Global resources
|
//Global resources
|
||||||
vk::destroy_global_resources();
|
vk::destroy_global_resources();
|
||||||
|
@ -1050,23 +1051,22 @@ void VKGSRender::emit_geometry(u32 sub_index)
|
||||||
if (sub_index == 0)
|
if (sub_index == 0)
|
||||||
{
|
{
|
||||||
analyse_inputs_interleaved(m_vertex_layout);
|
analyse_inputs_interleaved(m_vertex_layout);
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_vertex_layout.validate())
|
if (!m_vertex_layout.validate())
|
||||||
{
|
|
||||||
// No vertex inputs enabled
|
|
||||||
// Execute remainining pipeline barriers with NOP draw
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
draw_call.execute_pipeline_dependencies();
|
// No vertex inputs enabled
|
||||||
|
// Execute remainining pipeline barriers with NOP draw
|
||||||
|
do
|
||||||
|
{
|
||||||
|
draw_call.execute_pipeline_dependencies();
|
||||||
|
}
|
||||||
|
while (draw_call.next());
|
||||||
|
|
||||||
|
draw_call.end();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
while (draw_call.next());
|
|
||||||
|
|
||||||
draw_call.end();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
else if (draw_call.execute_pipeline_dependencies() & rsx::vertex_base_changed)
|
||||||
if (sub_index > 0 && draw_call.execute_pipeline_dependencies() & rsx::vertex_base_changed)
|
|
||||||
{
|
{
|
||||||
// Rebase vertex bases instead of
|
// Rebase vertex bases instead of
|
||||||
for (auto &info : m_vertex_layout.interleaved_blocks)
|
for (auto &info : m_vertex_layout.interleaved_blocks)
|
||||||
|
@ -1092,18 +1092,21 @@ void VKGSRender::emit_geometry(u32 sub_index)
|
||||||
|
|
||||||
auto persistent_buffer = m_persistent_attribute_storage ? m_persistent_attribute_storage->value : null_buffer_view->value;
|
auto persistent_buffer = m_persistent_attribute_storage ? m_persistent_attribute_storage->value : null_buffer_view->value;
|
||||||
auto volatile_buffer = m_volatile_attribute_storage ? m_volatile_attribute_storage->value : null_buffer_view->value;
|
auto volatile_buffer = m_volatile_attribute_storage ? m_volatile_attribute_storage->value : null_buffer_view->value;
|
||||||
|
auto layout_stream = m_vertex_layout_storage ? m_vertex_layout_storage->value : null_buffer_view->value;
|
||||||
bool update_descriptors = false;
|
bool update_descriptors = false;
|
||||||
|
|
||||||
if (sub_index == 0)
|
if (sub_index == 0)
|
||||||
{
|
{
|
||||||
update_descriptors = true;
|
update_descriptors = true;
|
||||||
|
|
||||||
|
// Allocate stream layout memory for this batch
|
||||||
|
m_vertex_layout_stream_info.range = rsx::method_registers.current_draw_clause.pass_count() * 128;
|
||||||
|
m_vertex_layout_stream_info.offset = m_vertex_layout_ring_info.alloc<256>(m_vertex_layout_stream_info.range);
|
||||||
|
// m_vertex_layout_stream_info.buffer = m_vertex_layout_ring_info.heap->value;
|
||||||
}
|
}
|
||||||
else
|
else if (persistent_buffer != old_persistent_buffer || volatile_buffer != old_volatile_buffer)
|
||||||
{
|
{
|
||||||
// Vertex env update will change information in the descriptor set
|
// Need to update descriptors; make a copy for the next draw
|
||||||
// Make a copy for the next draw call
|
|
||||||
// TODO: Restructure program to allow use of push constants when possible
|
|
||||||
// NOTE: AMD has insuffecient push constants buffer memory which is unfortunate
|
|
||||||
VkDescriptorSet new_descriptor_set = allocate_descriptor_set();
|
VkDescriptorSet new_descriptor_set = allocate_descriptor_set();
|
||||||
std::array<VkCopyDescriptorSet, VK_NUM_DESCRIPTOR_BINDINGS> copy_set;
|
std::array<VkCopyDescriptorSet, VK_NUM_DESCRIPTOR_BINDINGS> copy_set;
|
||||||
|
|
||||||
|
@ -1126,20 +1129,17 @@ void VKGSRender::emit_geometry(u32 sub_index)
|
||||||
vkUpdateDescriptorSets(*m_device, 0, 0, VK_NUM_DESCRIPTOR_BINDINGS, copy_set.data());
|
vkUpdateDescriptorSets(*m_device, 0, 0, VK_NUM_DESCRIPTOR_BINDINGS, copy_set.data());
|
||||||
m_current_frame->descriptor_set = new_descriptor_set;
|
m_current_frame->descriptor_set = new_descriptor_set;
|
||||||
|
|
||||||
if (persistent_buffer != old_persistent_buffer || volatile_buffer != old_volatile_buffer)
|
update_descriptors = true;
|
||||||
{
|
|
||||||
// Rare event, we need to actually change the descriptors
|
|
||||||
update_descriptors = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update vertex fetch parameters
|
// Update vertex fetch parameters
|
||||||
update_vertex_env(upload_info);
|
update_vertex_env(sub_index, upload_info);
|
||||||
|
|
||||||
if (update_descriptors)
|
if (update_descriptors)
|
||||||
{
|
{
|
||||||
m_program->bind_uniform(persistent_buffer, vk::glsl::program_input_type::input_type_texel_buffer, "persistent_input_stream", m_current_frame->descriptor_set);
|
m_program->bind_uniform(persistent_buffer, VERTEX_BUFFERS_FIRST_BIND_SLOT, m_current_frame->descriptor_set);
|
||||||
m_program->bind_uniform(volatile_buffer, vk::glsl::program_input_type::input_type_texel_buffer, "volatile_input_stream", m_current_frame->descriptor_set);
|
m_program->bind_uniform(volatile_buffer, VERTEX_BUFFERS_FIRST_BIND_SLOT + 1, m_current_frame->descriptor_set);
|
||||||
|
m_program->bind_uniform(layout_stream, VERTEX_BUFFERS_FIRST_BIND_SLOT + 2, m_current_frame->descriptor_set);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bind the new set of descriptors for use with this draw call
|
// Bind the new set of descriptors for use with this draw call
|
||||||
|
@ -2736,22 +2736,40 @@ void VKGSRender::load_program_env()
|
||||||
m_graphics_state &= ~handled_flags;
|
m_graphics_state &= ~handled_flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VKGSRender::update_vertex_env(const vk::vertex_upload_info& vertex_info)
|
void VKGSRender::update_vertex_env(u32 id, const vk::vertex_upload_info& vertex_info)
|
||||||
{
|
{
|
||||||
auto mem = m_vertex_layout_ring_info.alloc<256>(256);
|
// Actual allocation must have been done previously
|
||||||
auto buf = (u32*)m_vertex_layout_ring_info.map(mem, 128 + 16);
|
u32 base_offset;
|
||||||
|
|
||||||
buf[0] = vertex_info.vertex_index_base;
|
if (!m_vertex_layout_storage ||
|
||||||
buf[1] = vertex_info.vertex_index_offset;
|
!m_vertex_layout_storage->in_range(m_vertex_layout_stream_info.offset, m_vertex_layout_stream_info.range, base_offset))
|
||||||
buf += 4;
|
{
|
||||||
|
verify("Incompatible driver (MacOS?)" HERE), m_texbuffer_view_size >= m_vertex_layout_stream_info.range;
|
||||||
|
|
||||||
fill_vertex_layout_state(m_vertex_layout, vertex_info.first_vertex, vertex_info.allocated_vertex_count, (s32*)buf,
|
if (m_vertex_layout_storage)
|
||||||
|
m_current_frame->buffer_views_to_clean.push_back(std::move(m_vertex_layout_storage));
|
||||||
|
|
||||||
|
// View 64M blocks at a time (different drivers will only allow a fixed viewable heap size, 64M should be safe)
|
||||||
|
const size_t view_size = (base_offset + m_texbuffer_view_size) > m_vertex_layout_ring_info.size() ? m_vertex_layout_ring_info.size() - base_offset : m_texbuffer_view_size;
|
||||||
|
m_vertex_layout_storage = std::make_unique<vk::buffer_view>(*m_device, m_vertex_layout_ring_info.heap->value, VK_FORMAT_R32G32_UINT, base_offset, view_size);
|
||||||
|
base_offset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 draw_info[4];
|
||||||
|
draw_info[0] = vertex_info.vertex_index_base;
|
||||||
|
draw_info[1] = vertex_info.vertex_index_offset;
|
||||||
|
draw_info[2] = id;
|
||||||
|
draw_info[3] = (id * 16) + (base_offset / 8);
|
||||||
|
|
||||||
|
vkCmdPushConstants(*m_current_command_buffer, pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT, 0, 16, draw_info);
|
||||||
|
|
||||||
|
const size_t data_offset = (id * 128) + m_vertex_layout_stream_info.offset;
|
||||||
|
auto dst = m_vertex_layout_ring_info.map(data_offset, 128);
|
||||||
|
|
||||||
|
fill_vertex_layout_state(m_vertex_layout, vertex_info.first_vertex, vertex_info.allocated_vertex_count, (s32*)dst,
|
||||||
vertex_info.persistent_window_offset, vertex_info.volatile_window_offset);
|
vertex_info.persistent_window_offset, vertex_info.volatile_window_offset);
|
||||||
|
|
||||||
m_vertex_layout_ring_info.unmap();
|
m_vertex_layout_ring_info.unmap();
|
||||||
m_vertex_layout_buffer_info = { m_vertex_layout_ring_info.heap->value, mem, 128 + 16 };
|
|
||||||
|
|
||||||
m_program->bind_uniform(m_vertex_layout_buffer_info, VERTEX_LAYOUT_BIND_SLOT, m_current_frame->descriptor_set);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VKGSRender::init_buffers(rsx::framebuffer_creation_context context, bool skip_reading)
|
void VKGSRender::init_buffers(rsx::framebuffer_creation_context context, bool skip_reading)
|
||||||
|
|
|
@ -379,6 +379,7 @@ private:
|
||||||
|
|
||||||
std::unique_ptr<vk::buffer_view> m_persistent_attribute_storage;
|
std::unique_ptr<vk::buffer_view> m_persistent_attribute_storage;
|
||||||
std::unique_ptr<vk::buffer_view> m_volatile_attribute_storage;
|
std::unique_ptr<vk::buffer_view> m_volatile_attribute_storage;
|
||||||
|
std::unique_ptr<vk::buffer_view> m_vertex_layout_storage;
|
||||||
|
|
||||||
resource_manager m_resource_manager;
|
resource_manager m_resource_manager;
|
||||||
|
|
||||||
|
@ -432,9 +433,9 @@ private:
|
||||||
|
|
||||||
VkDescriptorBufferInfo m_vertex_env_buffer_info;
|
VkDescriptorBufferInfo m_vertex_env_buffer_info;
|
||||||
VkDescriptorBufferInfo m_fragment_env_buffer_info;
|
VkDescriptorBufferInfo m_fragment_env_buffer_info;
|
||||||
|
VkDescriptorBufferInfo m_vertex_layout_stream_info;
|
||||||
VkDescriptorBufferInfo m_vertex_constants_buffer_info;
|
VkDescriptorBufferInfo m_vertex_constants_buffer_info;
|
||||||
VkDescriptorBufferInfo m_fragment_constants_buffer_info;
|
VkDescriptorBufferInfo m_fragment_constants_buffer_info;
|
||||||
VkDescriptorBufferInfo m_vertex_layout_buffer_info;
|
|
||||||
VkDescriptorBufferInfo m_fragment_texture_params_buffer_info;
|
VkDescriptorBufferInfo m_fragment_texture_params_buffer_info;
|
||||||
|
|
||||||
std::array<frame_context_t, VK_MAX_ASYNC_FRAMES> frame_context_storage;
|
std::array<frame_context_t, VK_MAX_ASYNC_FRAMES> frame_context_storage;
|
||||||
|
@ -512,7 +513,7 @@ private:
|
||||||
|
|
||||||
bool load_program();
|
bool load_program();
|
||||||
void load_program_env();
|
void load_program_env();
|
||||||
void update_vertex_env(const vk::vertex_upload_info& vertex_info);
|
void update_vertex_env(u32 id, const vk::vertex_upload_info& vertex_info);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void init_buffers(rsx::framebuffer_creation_context context, bool skip_reading = false);
|
void init_buffers(rsx::framebuffer_creation_context context, bool skip_reading = false);
|
||||||
|
|
|
@ -34,12 +34,11 @@
|
||||||
#define OCCLUSION_MAX_POOL_SIZE DESCRIPTOR_MAX_DRAW_CALLS
|
#define OCCLUSION_MAX_POOL_SIZE DESCRIPTOR_MAX_DRAW_CALLS
|
||||||
|
|
||||||
#define VERTEX_PARAMS_BIND_SLOT 0
|
#define VERTEX_PARAMS_BIND_SLOT 0
|
||||||
#define VERTEX_LAYOUT_BIND_SLOT 1
|
#define VERTEX_CONSTANT_BUFFERS_BIND_SLOT 1
|
||||||
#define VERTEX_CONSTANT_BUFFERS_BIND_SLOT 2
|
#define FRAGMENT_CONSTANT_BUFFERS_BIND_SLOT 2
|
||||||
#define FRAGMENT_CONSTANT_BUFFERS_BIND_SLOT 3
|
#define FRAGMENT_STATE_BIND_SLOT 3
|
||||||
#define FRAGMENT_STATE_BIND_SLOT 4
|
#define FRAGMENT_TEXTURE_PARAMS_BIND_SLOT 4
|
||||||
#define FRAGMENT_TEXTURE_PARAMS_BIND_SLOT 5
|
#define VERTEX_BUFFERS_FIRST_BIND_SLOT 5
|
||||||
#define VERTEX_BUFFERS_FIRST_BIND_SLOT 6
|
|
||||||
#define TEXTURES_FIRST_BIND_SLOT 8
|
#define TEXTURES_FIRST_BIND_SLOT 8
|
||||||
#define VERTEX_TEXTURES_FIRST_BIND_SLOT 24 //8+16
|
#define VERTEX_TEXTURES_FIRST_BIND_SLOT 24 //8+16
|
||||||
|
|
||||||
|
@ -3199,6 +3198,7 @@ public:
|
||||||
void bind_uniform(const VkDescriptorImageInfo &image_descriptor, const std::string &uniform_name, VkDescriptorType type, VkDescriptorSet &descriptor_set);
|
void bind_uniform(const VkDescriptorImageInfo &image_descriptor, const std::string &uniform_name, VkDescriptorType type, VkDescriptorSet &descriptor_set);
|
||||||
void bind_uniform(const VkDescriptorImageInfo &image_descriptor, int texture_unit, ::glsl::program_domain domain, VkDescriptorSet &descriptor_set, bool is_stencil_mirror = false);
|
void bind_uniform(const VkDescriptorImageInfo &image_descriptor, int texture_unit, ::glsl::program_domain domain, VkDescriptorSet &descriptor_set, bool is_stencil_mirror = false);
|
||||||
void bind_uniform(const VkDescriptorBufferInfo &buffer_descriptor, uint32_t binding_point, VkDescriptorSet &descriptor_set);
|
void bind_uniform(const VkDescriptorBufferInfo &buffer_descriptor, uint32_t binding_point, VkDescriptorSet &descriptor_set);
|
||||||
|
void bind_uniform(const VkBufferView &buffer_view, uint32_t binding_point, VkDescriptorSet &descriptor_set);
|
||||||
void bind_uniform(const VkBufferView &buffer_view, program_input_type type, const std::string &binding_name, VkDescriptorSet &descriptor_set);
|
void bind_uniform(const VkBufferView &buffer_view, program_input_type type, const std::string &binding_name, VkDescriptorSet &descriptor_set);
|
||||||
|
|
||||||
void bind_buffer(const VkDescriptorBufferInfo &buffer_descriptor, uint32_t binding_point, VkDescriptorType type, VkDescriptorSet &descriptor_set);
|
void bind_buffer(const VkDescriptorBufferInfo &buffer_descriptor, uint32_t binding_point, VkDescriptorType type, VkDescriptorSet &descriptor_set);
|
||||||
|
|
|
@ -174,28 +174,33 @@ namespace vk
|
||||||
bind_buffer(buffer_descriptor, binding_point, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, descriptor_set);
|
bind_buffer(buffer_descriptor, binding_point, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, descriptor_set);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void program::bind_uniform(const VkBufferView &buffer_view, uint32_t binding_point, VkDescriptorSet &descriptor_set)
|
||||||
|
{
|
||||||
|
const VkWriteDescriptorSet descriptor_writer =
|
||||||
|
{
|
||||||
|
VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType
|
||||||
|
nullptr, // pNext
|
||||||
|
descriptor_set, // dstSet
|
||||||
|
binding_point, // dstBinding
|
||||||
|
0, // dstArrayElement
|
||||||
|
1, // descriptorCount
|
||||||
|
VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,// descriptorType
|
||||||
|
nullptr, // pImageInfo
|
||||||
|
nullptr, // pBufferInfo
|
||||||
|
&buffer_view // pTexelBufferView
|
||||||
|
};
|
||||||
|
|
||||||
|
vkUpdateDescriptorSets(m_device, 1, &descriptor_writer, 0, nullptr);
|
||||||
|
attribute_location_mask |= (1ull << binding_point);
|
||||||
|
}
|
||||||
|
|
||||||
void program::bind_uniform(const VkBufferView &buffer_view, program_input_type type, const std::string &binding_name, VkDescriptorSet &descriptor_set)
|
void program::bind_uniform(const VkBufferView &buffer_view, program_input_type type, const std::string &binding_name, VkDescriptorSet &descriptor_set)
|
||||||
{
|
{
|
||||||
for (const auto &uniform : uniforms[type])
|
for (const auto &uniform : uniforms[type])
|
||||||
{
|
{
|
||||||
if (uniform.name == binding_name)
|
if (uniform.name == binding_name)
|
||||||
{
|
{
|
||||||
const VkWriteDescriptorSet descriptor_writer =
|
bind_uniform(buffer_view, uniform.location, descriptor_set);
|
||||||
{
|
|
||||||
VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType
|
|
||||||
nullptr, // pNext
|
|
||||||
descriptor_set, // dstSet
|
|
||||||
uniform.location, // dstBinding
|
|
||||||
0, // dstArrayElement
|
|
||||||
1, // descriptorCount
|
|
||||||
VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,// descriptorType
|
|
||||||
nullptr, // pImageInfo
|
|
||||||
nullptr, // pBufferInfo
|
|
||||||
&buffer_view // pTexelBufferView
|
|
||||||
};
|
|
||||||
|
|
||||||
vkUpdateDescriptorSets(m_device, 1, &descriptor_writer, 0, nullptr);
|
|
||||||
attribute_location_mask |= (1ull << uniform.location);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,11 +42,12 @@ void VKVertexDecompilerThread::insertHeader(std::stringstream &OS)
|
||||||
OS << " float z_far;\n";
|
OS << " float z_far;\n";
|
||||||
OS << "};\n\n";
|
OS << "};\n\n";
|
||||||
|
|
||||||
OS << "layout(std140, set = 0, binding = 1) uniform VertexLayoutBuffer\n";
|
OS << "layout(push_constant) uniform VertexLayoutBuffer\n";
|
||||||
OS << "{\n";
|
OS << "{\n";
|
||||||
OS << " uint vertex_base_index;\n";
|
OS << " uint vertex_base_index;\n";
|
||||||
OS << " uint vertex_index_offset;\n";
|
OS << " uint vertex_index_offset;\n";
|
||||||
OS << " uvec4 input_attributes_blob[16 / 2];\n";
|
OS << " uint draw_id;\n";
|
||||||
|
OS << " uint layout_ptr_offset;\n";
|
||||||
OS << "};\n\n";
|
OS << "};\n\n";
|
||||||
|
|
||||||
vk::glsl::program_input in;
|
vk::glsl::program_input in;
|
||||||
|
@ -55,16 +56,13 @@ void VKVertexDecompilerThread::insertHeader(std::stringstream &OS)
|
||||||
in.name = "VertexContextBuffer";
|
in.name = "VertexContextBuffer";
|
||||||
in.type = vk::glsl::input_type_uniform_buffer;
|
in.type = vk::glsl::input_type_uniform_buffer;
|
||||||
inputs.push_back(in);
|
inputs.push_back(in);
|
||||||
|
|
||||||
in.location = VERTEX_LAYOUT_BIND_SLOT;
|
|
||||||
in.name = "VertexLayoutBuffer";
|
|
||||||
inputs.push_back(in);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VKVertexDecompilerThread::insertInputs(std::stringstream & OS, const std::vector<ParamType>& inputs)
|
void VKVertexDecompilerThread::insertInputs(std::stringstream & OS, const std::vector<ParamType>& inputs)
|
||||||
{
|
{
|
||||||
OS << "layout(set=0, binding=6) uniform usamplerBuffer persistent_input_stream;\n"; //Data stream with persistent vertex data (cacheable)
|
OS << "layout(set=0, binding=5) uniform usamplerBuffer persistent_input_stream;\n"; // Data stream with persistent vertex data (cacheable)
|
||||||
OS << "layout(set=0, binding=7) uniform usamplerBuffer volatile_input_stream;\n"; //Data stream with per-draw data (registers and immediate draw data)
|
OS << "layout(set=0, binding=6) uniform usamplerBuffer volatile_input_stream;\n"; // Data stream with per-draw data (registers and immediate draw data)
|
||||||
|
OS << "layout(set=0, binding=7) uniform usamplerBuffer vertex_layout_stream;\n"; // Data stream defining vertex data layout
|
||||||
|
|
||||||
vk::glsl::program_input in;
|
vk::glsl::program_input in;
|
||||||
in.location = VERTEX_BUFFERS_FIRST_BIND_SLOT;
|
in.location = VERTEX_BUFFERS_FIRST_BIND_SLOT;
|
||||||
|
@ -78,11 +76,17 @@ void VKVertexDecompilerThread::insertInputs(std::stringstream & OS, const std::v
|
||||||
in.name = "volatile_input_stream";
|
in.name = "volatile_input_stream";
|
||||||
in.type = vk::glsl::input_type_texel_buffer;
|
in.type = vk::glsl::input_type_texel_buffer;
|
||||||
this->inputs.push_back(in);
|
this->inputs.push_back(in);
|
||||||
|
|
||||||
|
in.location = VERTEX_BUFFERS_FIRST_BIND_SLOT + 2;
|
||||||
|
in.domain = glsl::glsl_vertex_program;
|
||||||
|
in.name = "vertex_layout_stream";
|
||||||
|
in.type = vk::glsl::input_type_texel_buffer;
|
||||||
|
this->inputs.push_back(in);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VKVertexDecompilerThread::insertConstants(std::stringstream & OS, const std::vector<ParamType> & constants)
|
void VKVertexDecompilerThread::insertConstants(std::stringstream & OS, const std::vector<ParamType> & constants)
|
||||||
{
|
{
|
||||||
OS << "layout(std140, set=0, binding = 2) uniform VertexConstantsBuffer\n";
|
OS << "layout(std140, set=0, binding = 1) uniform VertexConstantsBuffer\n";
|
||||||
OS << "{\n";
|
OS << "{\n";
|
||||||
OS << " vec4 vc[468];\n";
|
OS << " vec4 vc[468];\n";
|
||||||
OS << "};\n\n";
|
OS << "};\n\n";
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue