From a57b3f3b74e25191413b841b83a147014fda1e65 Mon Sep 17 00:00:00 2001 From: squidbus <175574877+squidbus@users.noreply.github.com> Date: Mon, 25 May 2026 06:55:20 -0700 Subject: [PATCH] Revert quad/rect list parameter forwarding changes (#4476) * Revert "shader_recompiler: Pad number of TES passthrough outputs to fragment inputs if needed" This reverts commit 64360630255eb0d2c0c23eac90efb64df989cb7b. * Revert "shader_recompiler: Only forward declared number of vertex inputs. (#4293)" This reverts commit 47f5cc14376c9d7694fc5728ed4ea98609ffe119. --- .../backend/spirv/emit_spirv_quad_rect.cpp | 39 +++++-------------- .../backend/spirv/emit_spirv_quad_rect.h | 4 +- .../inject_clip_distance_attributes.cpp | 11 +----- src/shader_recompiler/ir/passes/ir_passes.h | 3 +- src/shader_recompiler/recompiler.cpp | 2 +- src/shader_recompiler/runtime_info.h | 1 - .../renderer_vulkan/vk_graphics_pipeline.cpp | 6 +-- .../renderer_vulkan/vk_pipeline_cache.cpp | 1 - 8 files changed, 16 insertions(+), 51 deletions(-) diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_quad_rect.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_quad_rect.cpp index eb9f20e79..48aa9f870 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_quad_rect.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_quad_rect.cpp @@ -12,9 +12,8 @@ using Sirit::Id; constexpr u32 SPIRV_VERSION_1_5 = 0x00010500; struct QuadRectListEmitter : public Sirit::Module { - explicit QuadRectListEmitter(const VertexRuntimeInfo& vs_info_, - const FragmentRuntimeInfo& fs_info_) - : Sirit::Module{SPIRV_VERSION_1_5}, vs_info{vs_info_}, fs_info{fs_info_} { + explicit QuadRectListEmitter(const FragmentRuntimeInfo& fs_info_) + : Sirit::Module{SPIRV_VERSION_1_5}, fs_info{fs_info_} { void_id = TypeVoid(); bool_id = TypeBool(); float_id = TypeFloat(32); @@ -25,11 +24,9 @@ struct QuadRectListEmitter : public Sirit::Module { vec3_id = TypeVector(float_id, 3); vec4_id = TypeVector(float_id, 4); - float_zero = Constant(float_id, 0.0f); float_one = Constant(float_id, 1.0f); float_min_one = Constant(float_id, -1.0f); int_zero = Constant(int_id, 0); - vec4_zero = ConstantComposite(vec4_id, float_zero, float_zero, float_zero, float_zero); const Id float_arr{TypeArray(float_id, Constant(uint_id, 1U))}; gl_per_vertex_type = TypeStruct(vec4_id, float_id, float_arr, float_arr); @@ -192,14 +189,8 @@ struct QuadRectListEmitter : public Sirit::Module { OpStore(OpAccessChain(output_vec4, gl_per_vertex, Int(0)), position); // out_paramN = in_paramN[index]; - for (int i = 0; i < outputs.size(); i++) { - Id param; - if (i < inputs.size()) { - param = OpLoad(vec4_id, OpAccessChain(input_vec4, inputs[i], index)); - } else { - // Not enough inputs to forward, use dummy value. - param = vec4_zero; - } + for (int i = 0; i < inputs.size(); i++) { + const Id param{OpLoad(vec4_id, OpAccessChain(input_vec4, inputs[i], index))}; OpStore(outputs[i], param); } @@ -245,7 +236,6 @@ private: } void DefineOutputs(spv::ExecutionModel model) { - auto num_forwards = vs_info.num_exports; if (model == spv::ExecutionModel::TessellationControl) { const Id gl_per_vertex_array{TypeArray(gl_per_vertex_type, Constant(uint_id, 4U))}; gl_out = AddOutput(gl_per_vertex_array); @@ -261,12 +251,9 @@ private: Decorate(gl_tess_level_outer, spv::Decoration::Patch); } else { gl_per_vertex = AddOutput(gl_per_vertex_type); - // Tessellation eval stage comes before fragment, output number of forwards it will - // actually accept. - num_forwards = fs_info.num_inputs; } - outputs.reserve(num_forwards); - for (int i = 0; i < num_forwards; i++) { + outputs.reserve(fs_info.num_inputs); + for (int i = 0; i < fs_info.num_inputs; i++) { const auto& input = fs_info.inputs[i]; if (input.IsDefault()) { continue; @@ -289,10 +276,8 @@ private: const Id gl_per_vertex_array{TypeArray(gl_per_vertex_type, Constant(uint_id, 32U))}; gl_in = AddInput(gl_per_vertex_array); const Id float_arr{TypeArray(vec4_id, Int(32))}; - - const auto num_forwards = vs_info.num_exports; - inputs.reserve(num_forwards); - for (int i = 0; i < num_forwards; i++) { + inputs.reserve(fs_info.num_inputs); + for (int i = 0; i < fs_info.num_inputs; i++) { const auto& input = fs_info.inputs[i]; if (input.IsDefault()) { continue; @@ -303,7 +288,6 @@ private: } private: - VertexRuntimeInfo vs_info; FragmentRuntimeInfo fs_info; Id main; Id void_id; @@ -315,11 +299,9 @@ private: Id vec2_id; Id vec3_id; Id vec4_id; - Id float_zero; Id float_one; Id float_min_one; Id int_zero; - Id vec4_zero; Id gl_per_vertex_type; Id gl_in; union { @@ -337,9 +319,8 @@ private: std::vector interfaces; }; -std::vector EmitAuxilaryTessShader(AuxShaderType type, const VertexRuntimeInfo& vs_info, - const FragmentRuntimeInfo& fs_info) { - QuadRectListEmitter ctx{vs_info, fs_info}; +std::vector EmitAuxilaryTessShader(AuxShaderType type, const FragmentRuntimeInfo& fs_info) { + QuadRectListEmitter ctx{fs_info}; switch (type) { case AuxShaderType::RectListTCS: ctx.EmitRectListTCS(); diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_quad_rect.h b/src/shader_recompiler/backend/spirv/emit_spirv_quad_rect.h index 889e3ada8..c6c970ec3 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_quad_rect.h +++ b/src/shader_recompiler/backend/spirv/emit_spirv_quad_rect.h @@ -8,8 +8,7 @@ namespace Shader { struct FragmentRuntimeInfo; -struct VertexRuntimeInfo; -} // namespace Shader +} namespace Shader::Backend::SPIRV { @@ -20,7 +19,6 @@ enum class AuxShaderType : u32 { }; [[nodiscard]] std::vector EmitAuxilaryTessShader(AuxShaderType type, - const VertexRuntimeInfo& vs_info, const FragmentRuntimeInfo& fs_info); } // namespace Shader::Backend::SPIRV diff --git a/src/shader_recompiler/ir/passes/inject_clip_distance_attributes.cpp b/src/shader_recompiler/ir/passes/inject_clip_distance_attributes.cpp index 173dfac06..cf93142a1 100644 --- a/src/shader_recompiler/ir/passes/inject_clip_distance_attributes.cpp +++ b/src/shader_recompiler/ir/passes/inject_clip_distance_attributes.cpp @@ -5,19 +5,10 @@ #include "shader_recompiler/ir/basic_block.h" #include "shader_recompiler/ir/ir_emitter.h" #include "shader_recompiler/ir/program.h" -#include "shader_recompiler/profile.h" namespace Shader { -void InjectClipDistanceAttributes(IR::Program& program, RuntimeInfo& runtime_info, - const Profile& profile) { - if (program.info.stage == Stage::Vertex && profile.needs_clip_distance_emulation && - program.info.stores.GetAny(IR::Attribute::ClipDistance)) { - // Increment to include the added clip distance export. - ++runtime_info.vs_info.num_exports; - return; - } - +void InjectClipDistanceAttributes(IR::Program& program, RuntimeInfo& runtime_info) { auto& info = runtime_info.fs_info; if (!info.clip_distance_emulation || program.info.l_stage != LogicalStage::Fragment) { diff --git a/src/shader_recompiler/ir/passes/ir_passes.h b/src/shader_recompiler/ir/passes/ir_passes.h index 523184b0b..1b14a1c6b 100644 --- a/src/shader_recompiler/ir/passes/ir_passes.h +++ b/src/shader_recompiler/ir/passes/ir_passes.h @@ -8,8 +8,7 @@ namespace Shader { struct Profile; -void InjectClipDistanceAttributes(IR::Program& program, RuntimeInfo& runtime_info, - const Profile& profile); +void InjectClipDistanceAttributes(IR::Program& program, RuntimeInfo& runtime_info); } // namespace Shader namespace Shader::Optimization { diff --git a/src/shader_recompiler/recompiler.cpp b/src/shader_recompiler/recompiler.cpp index f8c71759e..d6efa2890 100644 --- a/src/shader_recompiler/recompiler.cpp +++ b/src/shader_recompiler/recompiler.cpp @@ -61,7 +61,7 @@ IR::Program TranslateProgram(const std::span& code, Pools& pools, Inf // On NVIDIA GPUs HW interpolation of clip distance values seems broken, and we need to emulate // it with expensive discard in PS. - Shader::InjectClipDistanceAttributes(program, runtime_info, profile); + Shader::InjectClipDistanceAttributes(program, runtime_info); // Run optimization passes if (!profile.support_float64) { diff --git a/src/shader_recompiler/runtime_info.h b/src/shader_recompiler/runtime_info.h index f1607c137..b5110a354 100644 --- a/src/shader_recompiler/runtime_info.h +++ b/src/shader_recompiler/runtime_info.h @@ -95,7 +95,6 @@ using OutputMap = std::array; struct VertexRuntimeInfo : protected CommonEsVsRuntimeInfo { u32 num_outputs; - u32 num_exports; std::array outputs; bool tess_emulated_primitive{}; bool emulate_depth_negative_one_to_one{}; diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index 3a91fd09c..7058796cb 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp @@ -193,9 +193,8 @@ GraphicsPipeline::GraphicsPipeline( } else if (is_rect_list || is_quad_list) { const auto type = is_quad_list ? AuxShaderType::QuadListTCS : AuxShaderType::RectListTCS; if (!preloading) { - const auto& vs_info = runtime_infos[u32(Shader::LogicalStage::Vertex)].vs_info; const auto& fs_info = runtime_infos[u32(Shader::LogicalStage::Fragment)].fs_info; - sdata.tcs = Shader::Backend::SPIRV::EmitAuxilaryTessShader(type, vs_info, fs_info); + sdata.tcs = Shader::Backend::SPIRV::EmitAuxilaryTessShader(type, fs_info); } shader_stages.emplace_back(vk::PipelineShaderStageCreateInfo{ .stage = vk::ShaderStageFlagBits::eTessellationControl, @@ -212,10 +211,9 @@ GraphicsPipeline::GraphicsPipeline( }); } else if (is_rect_list || is_quad_list) { if (!preloading) { - const auto& vs_info = runtime_infos[u32(Shader::LogicalStage::Vertex)].vs_info; const auto& fs_info = runtime_infos[u32(Shader::LogicalStage::Fragment)].fs_info; sdata.tes = Shader::Backend::SPIRV::EmitAuxilaryTessShader( - AuxShaderType::PassthroughTES, vs_info, fs_info); + AuxShaderType::PassthroughTES, fs_info); } shader_stages.emplace_back(vk::PipelineShaderStageCreateInfo{ .stage = vk::ShaderStageFlagBits::eTessellationEvaluation, diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 38923b3df..18beb001c 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -134,7 +134,6 @@ const Shader::RuntimeInfo& PipelineCache::BuildRuntimeInfo(Stage stage, LogicalS info.vs_info.step_rate_0 = regs.vgt_instance_step_rate_0; info.vs_info.step_rate_1 = regs.vgt_instance_step_rate_1; info.vs_info.num_outputs = MapOutputs(info.vs_info.outputs, regs.vs_output_control); - info.vs_info.num_exports = regs.vs_output_config.NumExports(); info.vs_info.emulate_depth_negative_one_to_one = !instance.IsDepthClipControlSupported() && regs.clipper_control.clip_space == AmdGpu::ClipSpace::MinusWToW;