diff --git a/src/graphics/shader/recompiler/frontend/decode/VectorAluOps.cpp b/src/graphics/shader/recompiler/frontend/decode/VectorAluOps.cpp index 55f608eca..26eda2f0f 100644 --- a/src/graphics/shader/recompiler/frontend/decode/VectorAluOps.cpp +++ b/src/graphics/shader/recompiler/frontend/decode/VectorAluOps.cpp @@ -522,8 +522,10 @@ constexpr Vop1SdwaRule VOP1_SDWA_RULES[] = { {Opcode::V_CVT_F32_U32, SdwaSelBytes() | SdwaSelWords() | SdwaSelFull(), 0, 0, false}, {Opcode::V_CVT_F32_I32, SdwaSelBytes() | SdwaSelWords() | SdwaSelFull(), 0, 0, false}, {Opcode::V_CVT_F32_UBYTE0, SdwaSelBytes() | SdwaSelWords() | SdwaSelFull(), 0, 0, false}, + // The source field extract and the destination insert are independent (Translate.cpp), so a + // partial destination may combine with any source selector. {Opcode::V_NOT_B32, SdwaSelBytes() | SdwaSelWords() | SdwaSelFull(), SdwaSelBytes() | SdwaSelWords(), - SdwaSelFull(), false}, + SdwaSelBytes() | SdwaSelWords() | SdwaSelFull(), false}, {Opcode::V_FFBL_B32, SdwaSelBytes() | SdwaSelWords() | SdwaSelFull(), 0, 0, false}, {Opcode::V_CVT_F32_F16, SdwaSelWords() | SdwaSelFull(), 0, 0, true}, {Opcode::V_CVT_F16_F32, SdwaSelBytes() | SdwaSelWords() | SdwaSelFull(), SdwaSelWords(), diff --git a/src/graphics/shader/recompiler/ir/ShaderIR.h b/src/graphics/shader/recompiler/ir/ShaderIR.h index 2359479f4..e9827605b 100644 --- a/src/graphics/shader/recompiler/ir/ShaderIR.h +++ b/src/graphics/shader/recompiler/ir/ShaderIR.h @@ -435,7 +435,7 @@ struct BindingLayout { }; struct ShaderInfo { - static constexpr uint32_t MaxBuffers = 32; + static constexpr uint32_t MaxBuffers = 64; static constexpr uint32_t MaxImages = 64; static constexpr uint32_t MaxSamplers = 32; static constexpr uint32_t MaxSampledPairs = 64; diff --git a/tests/shaderCfgTests.cpp b/tests/shaderCfgTests.cpp index 42ba3d5ac..eaa6908c9 100644 --- a/tests/shaderCfgTests.cpp +++ b/tests/shaderCfgTests.cpp @@ -3475,7 +3475,7 @@ void TestNewShaderRecompilerVop1SdwaNotDestination() { auto options = MakeCompileOptions(ShaderType::Pixel); const auto check_destination = [&](uint32_t modifier, uint32_t dst_sel, - uint32_t dst_unused) { + uint32_t dst_unused, uint32_t src_sel = 6u) { const uint32_t shader[] = { 0x7e066ef9u, modifier, EncodeExp0(0x00, 0x1), EncodeExp1(3, 0, 0, 0), EncodeSopp(0x01), @@ -3493,7 +3493,7 @@ void TestNewShaderRecompilerVop1SdwaNotDestination() { decoded.dst.explicit_sdwa_dst, "V_NOT_B32 SDWA destination metadata is incorrect"); Check(decoded.src0.kind == ShaderRecompiler::Decoder::OperandKind::Vgpr && - decoded.src0.reg == 0u && decoded.src0.sdwa_sel == 6u && + decoded.src0.reg == 0u && decoded.src0.sdwa_sel == src_sel && !decoded.src0.negate && !decoded.src0.absolute, "V_NOT_B32 SDWA source metadata is incorrect"); @@ -3504,6 +3504,10 @@ void TestNewShaderRecompilerVop1SdwaNotDestination() { check_destination(0x00061400u, 4u, 2u); check_destination(0x00060500u, 5u, 0u); check_destination(0x00060000u, 0u, 0u); + // Partial destinations combine with partial sources, e.g. PPSA10595's + // v_not_b32 v28.word0, v8.word1 with UNUSED_PRESERVE. + check_destination(0x00051400u, 4u, 2u, 5u); + check_destination(0x00000400u, 4u, 0u, 0u); const auto check_rejected = [&](uint32_t modifier, const char *message) { const uint32_t instruction[] = {0x7e066ef9u, modifier}; @@ -3523,8 +3527,6 @@ void TestNewShaderRecompilerVop1SdwaNotDestination() { check_rejected(0x00260400u, "V_NOT_B32 SDWA accepted source absolute"); check_rejected(0x00062400u, "V_NOT_B32 SDWA accepted clamp"); check_rejected(0x00064400u, "V_NOT_B32 SDWA accepted output modifier"); - check_rejected(0x00000400u, - "V_NOT_B32 SDWA partial destination accepted a byte source"); } void TestNewShaderRecompilerBootB16PackedAndSdwaOpcodes() {