diff --git a/src/graphics/shader/recompiler/decompiler/VectorAluOps.cpp b/src/graphics/shader/recompiler/decompiler/VectorAluOps.cpp index d00a81c43..78208d643 100644 --- a/src/graphics/shader/recompiler/decompiler/VectorAluOps.cpp +++ b/src/graphics/shader/recompiler/decompiler/VectorAluOps.cpp @@ -805,7 +805,7 @@ constexpr uint32_t SdwaSelAll() { } constexpr Vop2SdwaRule VOP2_SDWA_RULES[] = { - {Opcode::VCndmaskB32, SdwaSelWords(), SdwaSelWords() | SdwaSelFull(), + {Opcode::VCndmaskB32, SdwaSelWords() | SdwaSelFull(), SdwaSelWords() | SdwaSelFull(), SdwaSelWords() | SdwaSelFull(), true, false}, {Opcode::VAddF32, SdwaSelFull(), SdwaSelFull(), SdwaSelFull(), false, true}, {Opcode::VSubF32, SdwaSelFull(), SdwaSelFull(), SdwaSelFull(), false, true}, diff --git a/tests/ShaderRecompilerComputeTests.cpp b/tests/ShaderRecompilerComputeTests.cpp index 8f0fb494b..a220f6eaf 100644 --- a/tests/ShaderRecompilerComputeTests.cpp +++ b/tests/ShaderRecompilerComputeTests.cpp @@ -11783,6 +11783,32 @@ TestCase Vop2SdwaCndmaskSourceModifier() { {O::VMovB32, O::VCmpTU32, O::VCndmaskB32, O::BufferStoreDword, O::SEndpgm}}; } +TestCase Vop2SdwaCndmaskFullDestinationWithSubDwordSource() { + using O = ShaderOpcode; + + std::vector code; + AppendVMovLiteral(&code, 0, 0xabcd1234u); + AppendVMovLiteral(&code, 1, 0x55667788u); + code.push_back(EncodeVopc(0xc0, Vgpr(0), 0)); // v_cmp_f_u32 + code.push_back(0x020e02f9u); + code.push_back(0x06040600u); + AppendStoreVgpr(&code, 7, 0); + code.push_back(EncodeVopc(0xc7, Vgpr(0), 0)); // v_cmp_t_u32 + code.push_back(0x020e02f9u); + code.push_back(0x06040600u); + AppendStoreVgpr(&code, 7, 1); + AppendEnd(&code); + + TestCase test; + test.name = "Vop2SdwaCndmaskFullDestinationWithSubDwordSource"; + test.code = code; + test.expected = {0x00001234u, 0x55667788u}; + test.opcodes = {O::VMovB32, O::VCmpFU32, O::VCmpTU32, O::VCndmaskB32, + O::BufferStoreDword, O::SEndpgm}; + test.required_spirv = {"OpBitFieldUExtract", "OpSelect"}; + return test; +} + TestCase Vop3CndmaskUsesSgprMaskLaneBits() { using O = ShaderOpcode; @@ -15142,6 +15168,7 @@ std::vector MakeCases() { AddCase(VectorCompareClassF32); AddCase(VectorCompareF16Ops); AddCase(Vop2SdwaCndmaskSourceModifier); + AddCase(Vop2SdwaCndmaskFullDestinationWithSubDwordSource); AddCase(Vop3CndmaskUsesSgprMaskLaneBits); AddCase(Vop3CndmaskAllowsDataSourceModifier); AddCase(VectorCompareExecOps); diff --git a/tests/shaderCfgTests.cpp b/tests/shaderCfgTests.cpp index 15eb520e1..b48581025 100644 --- a/tests/shaderCfgTests.cpp +++ b/tests/shaderCfgTests.cpp @@ -1170,6 +1170,8 @@ void TestNewShaderRecompilerMoreAluFamilies() { EncodeVop2Sdwa(5, 6, 0, 4, 5), 0x025e6af9u, 0x16060635u, // v_cndmask_b32 v47, v53, -v53 + 0x020e02f9u, + 0x06040600u, // v_cndmask_b32 v7, v0.lo, v1; full-width destination 0x100490f9u, 0x86860600u, // v_mul_f32 v2, s0, s72 (SDWA full) EncodeVop2(0x35, 9, 249, 1), @@ -1396,6 +1398,9 @@ void TestNewShaderRecompilerMoreAluFamilies() { Check(Common::ContainsStr(result.decoded_dump, "v_cndmask_b32 v47, v53,") && Common::ContainsStr(result.decoded_dump, "v53.neg"), "new decoder did not decode V_CNDMASK_B32 SDWA source modifier"); + Check(Common::ContainsStr(result.decoded_dump, "v_cndmask_b32 v7, v0.sdwa(sel=4") && + Common::ContainsStr(result.decoded_dump, "v1"), + "new decoder did not decode full-destination V_CNDMASK_B32 with SDWA source"); Check(Common::ContainsStr(result.decoded_dump, "v_add_f32 v125, v5.dpp"), "new decoder did not decode VOP2 DPP source metadata"); Check(!Common::ContainsStr(result.decoded_dump, "VOP2 SDWA/DPP modifiers are not implemented"), @@ -1700,6 +1705,8 @@ void TestNewShaderRecompilerMoreAluFamilies() { Check(Common::ContainsStr(result.ir_dump, "SelectMaskF32Bits v47, vcc_lo, v53.neg, v53") && Common::ContainsStr(result.ir_dump, "v53.neg"), "V_CNDMASK_B32 SDWA source modifier did not lower to float-bit select IR"); + Check(Common::ContainsStr(result.ir_dump, "SelectMaskU32 v7, vcc_lo, v1, v0.sdwa(sel=4"), + "full-destination V_CNDMASK_B32 with SDWA source did not lower to integer select IR"); Check(Common::ContainsStr(result.ir_dump, "FAddF32 v125.dpp") && Common::ContainsStr(result.ir_dump, "v5.dpp"), "VOP2 DPP source/destination did not lower to IR metadata");