diff --git a/rpcs3/Emu/RSX/Program/GLSLSnippets/RSXProg/RSXDefines2.glsl b/rpcs3/Emu/RSX/Program/GLSLSnippets/RSXProg/RSXDefines2.glsl index 67e9e0b2c6..df3add46e5 100644 --- a/rpcs3/Emu/RSX/Program/GLSLSnippets/RSXProg/RSXDefines2.glsl +++ b/rpcs3/Emu/RSX/Program/GLSLSnippets/RSXProg/RSXDefines2.glsl @@ -22,12 +22,16 @@ struct vertex_context_t float reserved[3]; }; -struct vertex_layout_t +struct draw_parameters_t { uint vertex_base_index; uint vertex_index_offset; uint draw_id; - uint reserved; + uint xform_constants_offset; + uint vs_context_offset; + uint fs_constants_offset; + uint fs_context_offset; + uint fs_texture_base_index; uvec2 attrib_data[16]; }; diff --git a/rpcs3/Emu/RSX/Program/GLSLSnippets/RSXProg/RSXVertexFetch.glsl b/rpcs3/Emu/RSX/Program/GLSLSnippets/RSXProg/RSXVertexFetch.glsl index 152fb01c43..06e10590ce 100644 --- a/rpcs3/Emu/RSX/Program/GLSLSnippets/RSXProg/RSXVertexFetch.glsl +++ b/rpcs3/Emu/RSX/Program/GLSLSnippets/RSXProg/RSXVertexFetch.glsl @@ -156,7 +156,7 @@ attribute_desc fetch_desc(const in int location) #ifdef VULKAN // Fetch parameters streamed separately from draw parameters - uvec2 attrib = vertex_layouts[vs_attrib_layout_offset].attrib_data[location]; + uvec2 attrib = get_draw_params().attrib_data[location]; #else // Data is packed into a ubo const int block = (location >> 1); @@ -179,8 +179,8 @@ attribute_desc fetch_desc(const in int location) } #ifdef VULKAN -#define vertex_index_offset vertex_layouts[vs_attrib_layout_offset].vertex_index_offset -#define vertex_base_index vertex_layouts[vs_attrib_layout_offset].vertex_base_index +#define vertex_index_offset get_draw_params().vertex_index_offset +#define vertex_base_index get_draw_params().vertex_base_index #endif vec4 read_location(const in int location) diff --git a/rpcs3/Emu/RSX/VK/VKDraw.cpp b/rpcs3/Emu/RSX/VK/VKDraw.cpp index ee7448bc22..62863c6194 100644 --- a/rpcs3/Emu/RSX/VK/VKDraw.cpp +++ b/rpcs3/Emu/RSX/VK/VKDraw.cpp @@ -820,7 +820,7 @@ void VKGSRender::emit_geometry(u32 sub_index) update_descriptors = true; // Allocate stream layout memory for this batch - const u64 alloc_size = rsx::method_registers.current_draw_clause.pass_count() * 144; + const u64 alloc_size = rsx::method_registers.current_draw_clause.pass_count() * 160; m_vertex_layout_dynamic_offset = m_vertex_layout_ring_info.alloc<16>(alloc_size); } diff --git a/rpcs3/Emu/RSX/VK/VKFragmentProgram.cpp b/rpcs3/Emu/RSX/VK/VKFragmentProgram.cpp index f071d5ddfa..bdc6b60687 100644 --- a/rpcs3/Emu/RSX/VK/VKFragmentProgram.cpp +++ b/rpcs3/Emu/RSX/VK/VKFragmentProgram.cpp @@ -225,6 +225,18 @@ void VKFragmentDecompilerThread::insertConstants(std::stringstream & OS) } } + // Always provided by vertex program, not part of local bindings + OS << + "layout(std430, set=0, binding=2) readonly buffer DrawParametersBuffer\n" + "{\n" + " draw_parameters_t draw_parameters[];\n" + "};\n\n" + + "#define get_draw_params() draw_parameters[draw_parameters_offset]\n" + "#define fs_constants_offset get_draw_params().fs_constants_offset\n" + "#define fs_context_offset get_draw_params().fs_context_offset\n" + "#define fs_texture_base_index get_draw_params().fs_texture_base_index\n\n"; + if (!properties.constant_offsets.empty()) { OS << "layout(std430, set=1, binding=" << vk_prog->binding_table.cbuf_location << ") readonly buffer FragmentConstantsBuffer\n"; @@ -282,16 +294,14 @@ void VKFragmentDecompilerThread::insertConstants(std::stringstream & OS) OS << "layout(push_constant) uniform push_constants_block\n" "{\n" - " layout(offset=12) uint fs_constants_offset;\n" - " uint fs_context_offset;\n" - " uint fs_texture_base_index;\n" + " uint draw_parameters_offset;\n" "};\n\n"; const vk::glsl::program_input push_constants { .domain = glsl::glsl_fragment_program, .type = vk::glsl::input_type_push_constant, - .bound_data = vk::glsl::push_constant_ref{.offset = 12, .size = 12 }, + .bound_data = vk::glsl::push_constant_ref{.offset = 0, .size = 4 }, .set = vk::glsl::binding_set_index_vertex, .location = umax, .name = "fs_push_constants_block" diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index 6657867e49..cd9d591b5e 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -2184,26 +2184,16 @@ void VKGSRender::upload_transform_constants(const rsx::io_buffer& buffer) void VKGSRender::update_vertex_env(u32 id, const vk::vertex_upload_info& vertex_info) { #pragma pack(push, 1) - struct rsx_vs_prog_push_constants_block_t - { - u32 xform_constants_offset; - u32 vs_context_offset; - u32 vs_attrib_layout_offset; - }; - - struct rsx_fs_prog_push_constants_block_t - { - u32 fs_constants_offset; - u32 fs_context_offset; - u32 fs_texture_base_index; - }; - struct rsx_prog_vertex_layout_entry_t { u32 vertex_base_index; u32 vertex_index_offset; u32 draw_id; - u32 reserved; + u32 xform_constants_offset; + u32 vs_context_offset; + u32 fs_constants_offset; + u32 fs_context_offset; + u32 fs_texture_base_index; s32 attrib_data[1]; }; #pragma pack(pop) @@ -2211,46 +2201,36 @@ void VKGSRender::update_vertex_env(u32 id, const vk::vertex_upload_info& vertex_ // Actual allocation must have been done previously const u32 vs_constant_id_offset = static_cast(m_xform_constants_dynamic_offset) / 16u; const u32 vertex_context_offset = static_cast(m_vertex_env_dynamic_offset) / 96u; - const u32 vertex_layout_offset = static_cast(m_vertex_layout_dynamic_offset) / 144u; + const u32 vertex_layout_offset = static_cast(m_vertex_layout_dynamic_offset) / 160u; const u32 fs_constant_id_offset = static_cast(m_fragment_constants_dynamic_offset) / 16u; const u32 fs_context_offset = static_cast(m_fragment_env_dynamic_offset) / 32u; const u32 fs_texture_base_index = static_cast(m_texture_parameters_dynamic_offset) / 48u; - // Pack - rsx_vs_prog_push_constants_block_t vs_push_constants; - vs_push_constants.xform_constants_offset = vs_constant_id_offset; - vs_push_constants.vs_context_offset = vertex_context_offset; - vs_push_constants.vs_attrib_layout_offset = vertex_layout_offset + id; - - rsx_fs_prog_push_constants_block_t fs_push_constants; - fs_push_constants.fs_constants_offset = fs_constant_id_offset; - fs_push_constants.fs_context_offset = fs_context_offset; - fs_push_constants.fs_texture_base_index = fs_texture_base_index; - - vkCmdPushConstants( - *m_current_command_buffer, - m_program->layout(), - VK_SHADER_STAGE_VERTEX_BIT, - 0, - sizeof(vs_push_constants), - &vs_push_constants); - - vkCmdPushConstants( - *m_current_command_buffer, - m_program->layout(), - VK_SHADER_STAGE_FRAGMENT_BIT, - sizeof(vs_push_constants), - sizeof(fs_push_constants), - &fs_push_constants); - - // Now actually fill in the data - auto buf = m_vertex_layout_ring_info.map(m_vertex_layout_dynamic_offset + (144u * id), 144); + auto buf = m_vertex_layout_ring_info.map(m_vertex_layout_dynamic_offset + (160u * id), 160u); auto dst = reinterpret_cast(buf); + + // Pack dst->vertex_base_index = vertex_info.vertex_index_base; dst->vertex_index_offset = vertex_info.vertex_index_offset; dst->draw_id = id; - dst->reserved = 0; + dst->xform_constants_offset = vs_constant_id_offset; + dst->vs_context_offset = vertex_context_offset; + + dst->fs_constants_offset = fs_constant_id_offset; + dst->fs_context_offset = fs_context_offset; + dst->fs_texture_base_index = fs_texture_base_index; + + const u32 push_val = vertex_layout_offset + id; + vkCmdPushConstants( + *m_current_command_buffer, + m_program->layout(), + VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, + 0, + 4, + &push_val); + + // Now actually fill in the data m_draw_processor.fill_vertex_layout_state( m_vertex_layout, current_vp_metadata, diff --git a/rpcs3/Emu/RSX/VK/VKProgramPipeline.cpp b/rpcs3/Emu/RSX/VK/VKProgramPipeline.cpp index 78c598bc03..d54fa8f2c1 100644 --- a/rpcs3/Emu/RSX/VK/VKProgramPipeline.cpp +++ b/rpcs3/Emu/RSX/VK/VKProgramPipeline.cpp @@ -651,7 +651,7 @@ namespace vk .binding = input.location, .descriptorType = type, .descriptorCount = descriptor_count(input.name), - .stageFlags = to_shader_stage_flags(input.domain) + .stageFlags = to_shader_stage_flags(input.domain) | input.ex_stages }; bindings.push_back(binding); diff --git a/rpcs3/Emu/RSX/VK/VKProgramPipeline.h b/rpcs3/Emu/RSX/VK/VKProgramPipeline.h index 39dd4923e0..3555abadf1 100644 --- a/rpcs3/Emu/RSX/VK/VKProgramPipeline.h +++ b/rpcs3/Emu/RSX/VK/VKProgramPipeline.h @@ -60,6 +60,8 @@ namespace vk u32 location = umax; std::string name = "undefined"; + VkFlags ex_stages = 0; + inline bound_buffer& as_buffer() { return *std::get_if(&bound_data); } inline bound_sampler& as_sampler() { return *std::get_if(&bound_data); } inline push_constant_ref& as_push_constant() { return *std::get_if(&bound_data); } diff --git a/rpcs3/Emu/RSX/VK/VKVertexProgram.cpp b/rpcs3/Emu/RSX/VK/VKVertexProgram.cpp index fd6e73b69e..486c19dc47 100644 --- a/rpcs3/Emu/RSX/VK/VKVertexProgram.cpp +++ b/rpcs3/Emu/RSX/VK/VKVertexProgram.cpp @@ -79,14 +79,20 @@ void VKVertexDecompilerThread::insertHeader(std::stringstream &OS) glsl::insert_subheader_block(OS); + OS << + // Variable redirection + "#define get_draw_params() draw_parameters[draw_parameters_offset]\n" + "#define vs_context_offset get_draw_params().vs_context_offset\n" + "#define xform_constants_offset get_draw_params().xform_constants_offset\n\n" + // Helpers + "#define get_vertex_context() vertex_contexts[vs_context_offset]\n" + "#define get_user_clip_config() get_vertex_context().user_clip_configuration_bits\n\n"; + OS << "layout(std430, set=0, binding=" << vk_prog->binding_table.context_buffer_location << ") readonly buffer VertexContextBuffer\n" "{\n" " vertex_context_t vertex_contexts[];\n" - "};\n\n" - "" - "#define get_vertex_context() vertex_contexts[vs_context_offset]\n" - "#define get_user_clip_config() get_vertex_context().user_clip_configuration_bits\n\n"; + "};\n\n"; const vk::glsl::program_input context_input { @@ -118,9 +124,9 @@ void VKVertexDecompilerThread::insertHeader(std::stringstream &OS) } OS << - "layout(std430, set=0, binding=" << vk_prog->binding_table.vertex_buffers_location + 2 << ") readonly buffer VertexLayoutBuffer\n" + "layout(std430, set=0, binding=" << vk_prog->binding_table.vertex_buffers_location + 2 << ") readonly buffer DrawParametersBuffer\n" "{\n" - " vertex_layout_t vertex_layouts[];\n" + " draw_parameters_t draw_parameters[];\n" "};\n\n"; const vk::glsl::program_input layouts_input @@ -129,23 +135,22 @@ void VKVertexDecompilerThread::insertHeader(std::stringstream &OS) .type = vk::glsl::input_type_storage_buffer, .set = vk::glsl::binding_set_index_vertex, .location = vk_prog->binding_table.vertex_buffers_location + 2, - .name = "VertexLayoutBuffer" + .name = "DrawParametersBuffer", + .ex_stages = VK_SHADER_STAGE_FRAGMENT_BIT // Shared with fragment shader }; inputs.push_back(layouts_input); OS << "layout(push_constant) uniform push_constants_block\n" "{\n" - " uint xform_constants_offset;\n" - " uint vs_context_offset;\n" - " uint vs_attrib_layout_offset;\n" + " uint draw_parameters_offset;\n" "};\n\n"; const vk::glsl::program_input push_constants { .domain = glsl::glsl_vertex_program, .type = vk::glsl::input_type_push_constant, - .bound_data = vk::glsl::push_constant_ref{ .offset = 0, .size = 12 }, + .bound_data = vk::glsl::push_constant_ref{ .offset = 0, .size = 4 }, .set = vk::glsl::binding_set_index_vertex, .location = umax, .name = "push_constants_block"