From 412355aab4e1bb8e38842d29330f648648baf356 Mon Sep 17 00:00:00 2001 From: Stephen Miller <56742918+StevenMiller123@users.noreply.github.com> Date: Fri, 29 Aug 2025 18:06:40 -0500 Subject: [PATCH] shader_recompiler: Support multiple attributes using the same load in vertex fetch shaders (#3475) * Support multiple uses of the same load. Co-Authored-By: TheTurtle <47210458+raphaelthegreat@users.noreply.github.com> * Keep base_sgpr as a s32 Requires manually casting to s32 now. --------- Co-authored-by: TheTurtle <47210458+raphaelthegreat@users.noreply.github.com> --- src/shader_recompiler/frontend/fetch_shader.cpp | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/shader_recompiler/frontend/fetch_shader.cpp b/src/shader_recompiler/frontend/fetch_shader.cpp index 55508b0f2..9d1c8e60e 100644 --- a/src/shader_recompiler/frontend/fetch_shader.cpp +++ b/src/shader_recompiler/frontend/fetch_shader.cpp @@ -2,7 +2,6 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include -#include #include "common/assert.h" #include "shader_recompiler/frontend/decode.h" #include "shader_recompiler/frontend/fetch_shader.h" @@ -53,9 +52,8 @@ std::optional ParseFetchShader(const Shader::Info& info) { struct VsharpLoad { u32 dword_offset{}; s32 base_sgpr{}; - s32 dst_reg{-1}; }; - boost::container::static_vector loads; + std::array loads{}; u32 semantic_index = 0; while (!code_slice.atEnd()) { @@ -67,7 +65,8 @@ std::optional ParseFetchShader(const Shader::Info& info) { } if (inst.inst_class == InstClass::ScalarMemRd) { - loads.emplace_back(inst.control.smrd.offset, inst.src[0].code * 2, inst.dst[0].code); + loads[inst.dst[0].code] = + VsharpLoad{inst.control.smrd.offset, static_cast(inst.src[0].code) * 2}; continue; } @@ -92,21 +91,17 @@ std::optional ParseFetchShader(const Shader::Info& info) { // Find the load instruction that loaded the V# to the SPGR. // This is so we can determine its index in the vertex table. - const auto it = std::ranges::find_if( - loads, [&](VsharpLoad& load) { return load.dst_reg == base_sgpr; }); + const auto it = loads[base_sgpr]; auto& attrib = data.attributes.emplace_back(); attrib.semantic = semantic_index++; attrib.dest_vgpr = inst.src[1].code; attrib.num_elements = inst.control.mubuf.count; - attrib.sgpr_base = it->base_sgpr; - attrib.dword_offset = it->dword_offset; + attrib.sgpr_base = it.base_sgpr; + attrib.dword_offset = it.dword_offset; // Store instance id rate attrib.instance_data = inst.src[0].code; - - // Mark load as used. - it->dst_reg = -1; } }