From 89e1c3ecfad772b3fbcf9745215aeb10567d57c9 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Mon, 18 Aug 2025 02:13:52 +0300 Subject: [PATCH] rsx/vk: Update shader interpreter to use new varying draw params model --- .../GLSLInterpreter/VertexInterpreter.glsl | 5 ++++ rpcs3/Emu/RSX/VK/VKFragmentProgram.cpp | 8 ++++-- rpcs3/Emu/RSX/VK/VKShaderInterpreter.cpp | 8 ++++++ rpcs3/Emu/RSX/VK/VKVertexProgram.cpp | 25 ++++++++++++++----- rpcs3/Emu/RSX/VK/VKVertexProgram.h | 2 ++ rpcs3/Emu/RSX/gcm_enums.h | 1 + 6 files changed, 41 insertions(+), 8 deletions(-) diff --git a/rpcs3/Emu/RSX/Program/GLSLInterpreter/VertexInterpreter.glsl b/rpcs3/Emu/RSX/Program/GLSLInterpreter/VertexInterpreter.glsl index 57d308f717..a8de503a41 100644 --- a/rpcs3/Emu/RSX/Program/GLSLInterpreter/VertexInterpreter.glsl +++ b/rpcs3/Emu/RSX/Program/GLSLInterpreter/VertexInterpreter.glsl @@ -545,6 +545,11 @@ void main() } } +#ifdef VULKAN + // Inject FS custom payload + write_fs_payload(); +#endif + // Unconditionally update COLOR0 and SPECULAR0 write_output(1, 0); write_output(2, 1); diff --git a/rpcs3/Emu/RSX/VK/VKFragmentProgram.cpp b/rpcs3/Emu/RSX/VK/VKFragmentProgram.cpp index f65d4a9c59..ea9d7cd0f1 100644 --- a/rpcs3/Emu/RSX/VK/VKFragmentProgram.cpp +++ b/rpcs3/Emu/RSX/VK/VKFragmentProgram.cpp @@ -227,9 +227,13 @@ void VKFragmentDecompilerThread::insertConstants(std::stringstream & OS) } // Draw params are always provided by vertex program. Instead of pointer chasing, they're provided as varyings. - OS << - "layout(location=" << vk::get_varying_register_location("usr") << ") in flat uvec4 draw_params_payload;\n\n" + if (!(m_prog.ctrl & RSX_SHADER_CONTROL_INTERPRETER_MODEL)) + { + OS << + "layout(location=" << vk::get_varying_register_location("usr") << ") in flat uvec4 draw_params_payload;\n\n"; + } + OS << "#define _fs_constants_offset draw_params_payload.x\n" "#define _fs_context_offset draw_params_payload.y\n" "#define _fs_texture_base_index draw_params_payload.z\n" diff --git a/rpcs3/Emu/RSX/VK/VKShaderInterpreter.cpp b/rpcs3/Emu/RSX/VK/VKShaderInterpreter.cpp index 2e28c2359e..907f5b2d9c 100644 --- a/rpcs3/Emu/RSX/VK/VKShaderInterpreter.cpp +++ b/rpcs3/Emu/RSX/VK/VKShaderInterpreter.cpp @@ -89,6 +89,9 @@ namespace vk comp.insertConstants(builder, { uniforms }); comp.insertInputs(builder, {}); + // Outputs + builder << "layout(location=16) out flat uvec4 draw_params_payload;\n\n"; + builder << "#define scale_offset_mat get_vertex_context().scale_offset_mat\n" "#define transform_branch_bits get_vertex_context().transform_branch_bits\n" @@ -125,6 +128,7 @@ namespace vk ::glsl::insert_glsl_legacy_function(builder, properties); ::glsl::insert_vertex_input_fetch(builder, ::glsl::glsl_rules::glsl_rules_vulkan); + comp.insertFSExport(builder); builder << program_common::interpreter::get_vertex_interpreter(); const std::string s = builder.str(); @@ -163,6 +167,8 @@ namespace vk std::string shader_str; RSXFragmentProgram frag; + frag.ctrl |= RSX_SHADER_CONTROL_INTERPRETER_MODEL; + auto vk_prog = std::make_unique(); m_fragment_instruction_start = init(vk_prog.get(), compiler_options); m_fragment_textures_start = m_fragment_instruction_start + 1; @@ -177,6 +183,8 @@ namespace vk ::glsl::insert_subheader_block(builder); comp.insertConstants(builder); + builder << "layout(location=16) in flat uvec4 draw_params_payload;\n\n"; + builder << "#define fog_param0 fs_contexts[_fs_context_offset].fog_param0\n" "#define fog_param1 fs_contexts[_fs_context_offset].fog_param1\n" diff --git a/rpcs3/Emu/RSX/VK/VKVertexProgram.cpp b/rpcs3/Emu/RSX/VK/VKVertexProgram.cpp index 95e448f45a..a9fb828c18 100644 --- a/rpcs3/Emu/RSX/VK/VKVertexProgram.cpp +++ b/rpcs3/Emu/RSX/VK/VKVertexProgram.cpp @@ -312,7 +312,22 @@ void VKVertexDecompilerThread::insertOutputs(std::stringstream& OS, const std::v } } - OS << "layout(location=" << vk::get_varying_register_location("usr") << ") out flat uvec4 draw_params_payload;\n"; + if (!(m_prog.ctrl & RSX_SHADER_CONTROL_INTERPRETER_MODEL)) + { + OS << "layout(location=" << vk::get_varying_register_location("usr") << ") out flat uvec4 draw_params_payload;\n"; + } +} + +void VKVertexDecompilerThread::insertFSExport(std::stringstream& OS) +{ + OS << + "void write_fs_payload()\n" + "{\n" + " draw_params_payload.x = get_draw_params().fs_constants_offset;\n" + " draw_params_payload.y = get_draw_params().fs_context_offset;\n" + " draw_params_payload.z = get_draw_params().fs_texture_base_index;\n" + " draw_params_payload.w = get_draw_params().fs_stipple_pattern_offset;\n" + "}\n\n"; } void VKVertexDecompilerThread::insertMainStart(std::stringstream & OS) @@ -330,6 +345,8 @@ void VKVertexDecompilerThread::insertMainStart(std::stringstream & OS) glsl::insert_glsl_legacy_function(OS, properties2); glsl::insert_vertex_input_fetch(OS, glsl::glsl_rules_vulkan); + insertFSExport(OS); + // Declare global registers with optional initialization std::string registers; if (ParamType *vec4Types = m_parr.SearchParam(PF_PARAM_OUT, "vec4")) @@ -414,11 +431,7 @@ void VKVertexDecompilerThread::insertMainEnd(std::stringstream & OS) OS << " vs_main();\n\n"; // FS payload - OS << - "draw_params_payload.x = get_draw_params().fs_constants_offset;\n" - "draw_params_payload.y = get_draw_params().fs_context_offset;\n" - "draw_params_payload.z = get_draw_params().fs_texture_base_index;\n" - "draw_params_payload.w = get_draw_params().fs_stipple_pattern_offset;\n\n"; + OS << "write_fs_payload();\n\n"; for (auto &i : reg_table) { diff --git a/rpcs3/Emu/RSX/VK/VKVertexProgram.h b/rpcs3/Emu/RSX/VK/VKVertexProgram.h index 3422333fc6..c36f089a2e 100644 --- a/rpcs3/Emu/RSX/VK/VKVertexProgram.h +++ b/rpcs3/Emu/RSX/VK/VKVertexProgram.h @@ -49,6 +49,8 @@ public: void Task(); const std::vector& get_inputs() { return inputs; } + + void insertFSExport(std::stringstream& OS); }; class VKVertexProgram : public rsx::VertexProgramBase diff --git a/rpcs3/Emu/RSX/gcm_enums.h b/rpcs3/Emu/RSX/gcm_enums.h index eaa182171e..61b51c3857 100644 --- a/rpcs3/Emu/RSX/gcm_enums.h +++ b/rpcs3/Emu/RSX/gcm_enums.h @@ -456,6 +456,7 @@ namespace gcm // Custom RSX_SHADER_CONTROL_ATTRIBUTE_INTERPOLATION = 0x10000, // Rasterizing triangles and not lines or points RSX_SHADER_CONTROL_INSTANCED_CONSTANTS = 0x20000, // Support instance ID offsets when loading constants + RSX_SHADER_CONTROL_INTERPRETER_MODEL = 0x40000, // Compile internals expecting interpreter }; // GCM Reports