From 025d1f7edfa6170607c6948467c7c7b867440636 Mon Sep 17 00:00:00 2001 From: nmzik Date: Mon, 26 Oct 2026 06:35:17 +0100 Subject: [PATCH] shader: decode the SHARED_LIMIT and PRIVATE_LIMIT inline constants Co-authored-by: Senaxx --- .../frontend/decode/ShaderDecoder.cpp | 4 ++++ .../frontend/decode/ShaderDecoder.h | 2 ++ .../frontend/translate/Translate.cpp | 24 ++++++++++--------- tests/ShaderRecompilerComputeTests.cpp | 18 ++++++++++++++ 4 files changed, 37 insertions(+), 11 deletions(-) diff --git a/src/graphics/shader/recompiler/frontend/decode/ShaderDecoder.cpp b/src/graphics/shader/recompiler/frontend/decode/ShaderDecoder.cpp index 2974f389b..2b01fbb60 100644 --- a/src/graphics/shader/recompiler/frontend/decode/ShaderDecoder.cpp +++ b/src/graphics/shader/recompiler/frontend/decode/ShaderDecoder.cpp @@ -258,7 +258,9 @@ void DecodeScalarSource(uint32_t code, uint32_t pc, Operand& operand) { case 126u: operand.kind = OperandKind::ExecLo; return; case 127u: operand.kind = OperandKind::ExecHi; return; case 235u: operand.kind = OperandKind::SharedBase; return; + case 236u: operand.kind = OperandKind::SharedLimit; return; case 237u: operand.kind = OperandKind::PrivateBase; return; + case 238u: operand.kind = OperandKind::PrivateLimit; return; case 239u: operand.kind = OperandKind::PopsExitingWaveId; return; case 248u: operand.kind = OperandKind::FloatInlineConstant; @@ -459,7 +461,9 @@ std::string OperandToString(const Operand& operand) { case OperandKind::M0: text = "m0"; break; case OperandKind::PopsExitingWaveId: text = "pops_exiting_wave_id"; break; case OperandKind::SharedBase: text = "shared_base"; break; + case OperandKind::SharedLimit: text = "shared_limit"; break; case OperandKind::PrivateBase: text = "private_base"; break; + case OperandKind::PrivateLimit: text = "private_limit"; break; case OperandKind::Null: text = "null"; break; default: text = "unknown"; break; } diff --git a/src/graphics/shader/recompiler/frontend/decode/ShaderDecoder.h b/src/graphics/shader/recompiler/frontend/decode/ShaderDecoder.h index e6109136f..bb6083be0 100644 --- a/src/graphics/shader/recompiler/frontend/decode/ShaderDecoder.h +++ b/src/graphics/shader/recompiler/frontend/decode/ShaderDecoder.h @@ -766,7 +766,9 @@ enum class OperandKind { M0, PopsExitingWaveId, SharedBase, + SharedLimit, PrivateBase, + PrivateLimit, Null, Vgpr, }; diff --git a/src/graphics/shader/recompiler/frontend/translate/Translate.cpp b/src/graphics/shader/recompiler/frontend/translate/Translate.cpp index 2020ec64a..6a387a82a 100644 --- a/src/graphics/shader/recompiler/frontend/translate/Translate.cpp +++ b/src/graphics/shader/recompiler/frontend/translate/Translate.cpp @@ -138,6 +138,8 @@ IR::U32 Translator::ReadRawU32(const Decoder::Operand& operand) { case Decoder::OperandKind::SharedBase: case Decoder::OperandKind::PrivateBase: case Decoder::OperandKind::PopsExitingWaveId: return IR::U32(IR::Value(0u)); + case Decoder::OperandKind::SharedLimit: + case Decoder::OperandKind::PrivateLimit: return IR::U32(IR::Value(0xffffffffu)); case Decoder::OperandKind::Sgpr: return ir.GetScalarReg(static_cast(operand.reg)); case Decoder::OperandKind::Vgpr: @@ -471,17 +473,17 @@ IR::U32 Translator::ReadU32(const Decoder::Operand& operand) { } std::array Translator::ReadU32Pair(const Decoder::Operand& operand) { - if (operand.kind == Decoder::OperandKind::PrivateBase || - operand.kind == Decoder::OperandKind::SharedBase) { - return {IR::U32(IR::Value(0u)), IR::U32(IR::Value( - operand.kind == Decoder::OperandKind::PrivateBase ? Decoder::PrivateApertureHigh - : Decoder::SharedApertureHigh))}; - } - if (operand.kind == Decoder::OperandKind::ExecLo) { - return {ir.GetExecLo(), ir.GetExecHi()}; - } - if (operand.kind == Decoder::OperandKind::VccLo) { - return {ir.GetVccLo(), ir.GetVccHi()}; + // Each aperture limit is its base plus 0xffffffff. + switch (operand.kind) { + case Decoder::OperandKind::SharedBase: + case Decoder::OperandKind::SharedLimit: + return {ReadRawU32(operand), IR::U32(IR::Value(Decoder::SharedApertureHigh))}; + case Decoder::OperandKind::PrivateBase: + case Decoder::OperandKind::PrivateLimit: + return {ReadRawU32(operand), IR::U32(IR::Value(Decoder::PrivateApertureHigh))}; + case Decoder::OperandKind::ExecLo: return {ir.GetExecLo(), ir.GetExecHi()}; + case Decoder::OperandKind::VccLo: return {ir.GetVccLo(), ir.GetVccHi()}; + default: break; } if (operand.kind == Decoder::OperandKind::FloatInlineConstant) { const auto bits = diff --git a/tests/ShaderRecompilerComputeTests.cpp b/tests/ShaderRecompilerComputeTests.cpp index 208e785c1..ecea4d833 100644 --- a/tests/ShaderRecompilerComputeTests.cpp +++ b/tests/ShaderRecompilerComputeTests.cpp @@ -22872,6 +22872,23 @@ TestCase Rdna2ScalarOpcodes() { O::S_SLEEP, O::V_MOV_B32, O::BUFFER_STORE_DWORD, O::S_ENDPGM}}; } +TestCase ScalarApertureLimits() { + using O = ShaderOpcode; + + std::vector code; + code.push_back(EncodeSop1(0x04, 20, 236)); + AppendStoreSgprPair(&code, 20, 0); + code.push_back(EncodeSop1(0x04, 20, 238)); + AppendStoreSgprPair(&code, 20, 2); + AppendEnd(&code); + + return {"ScalarApertureLimits", + code, + {}, + {0xffffffffu, 0x80000000u, 0xffffffffu, 0x70000000u}, + {O::S_MOV_B64, O::V_MOV_B32, O::BUFFER_STORE_DWORD, O::S_ENDPGM}}; +} + TestCase ScalarTrapDisabledFallsThroughExactRaw() { using O = ShaderOpcode; @@ -44346,6 +44363,7 @@ std::vector MakeCases() { AddCase(ExactPushConstantExtent); AddCase(ScalarShiftCountsMaskLowBits); AddCase(Rdna2ScalarOpcodes); + AddCase(ScalarApertureLimits); AddCase(ScalarTrapDisabledFallsThroughExactRaw); AddCase(ScalarWaitcntDepctrCapturedVmVsrc); AddCase(ScalarExtendedArithmetic);