From ae896d0bf680b275bf7ae9edc273a80256945ded Mon Sep 17 00:00:00 2001 From: nmzik Date: Thu, 27 Aug 2026 04:13:12 +0200 Subject: [PATCH] shader: support V_CMPX_GT_U16 SDWA --- .../frontend/decode/ShaderDecoder.h | 1 + .../frontend/decode/VectorAluOps.cpp | 4 ++- .../recompiler/frontend/translate/Vector.cpp | 3 +++ tests/ShaderRecompilerComputeTests.cpp | 27 +++++++++++++++++++ 4 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/graphics/shader/recompiler/frontend/decode/ShaderDecoder.h b/src/graphics/shader/recompiler/frontend/decode/ShaderDecoder.h index cf2b6462b..5b7c5a741 100644 --- a/src/graphics/shader/recompiler/frontend/decode/ShaderDecoder.h +++ b/src/graphics/shader/recompiler/frontend/decode/ShaderDecoder.h @@ -378,6 +378,7 @@ enum class Opcode { V_CMP_EQ_U16, V_CMP_LE_U16, V_CMP_GT_U16, + V_CMPX_GT_U16, V_CMP_NE_U16, V_CMP_GE_U16, V_CMP_F_U32, diff --git a/src/graphics/shader/recompiler/frontend/decode/VectorAluOps.cpp b/src/graphics/shader/recompiler/frontend/decode/VectorAluOps.cpp index 8101894ce..4b429d11d 100644 --- a/src/graphics/shader/recompiler/frontend/decode/VectorAluOps.cpp +++ b/src/graphics/shader/recompiler/frontend/decode/VectorAluOps.cpp @@ -224,7 +224,8 @@ constexpr VopcOpcodeInfo VOPC_OPCODE_LIST[] = { {0x96u, Opcode::V_CMPX_GE_I32}, {0xa9u, Opcode::V_CMP_LT_U16}, {0xaau, Opcode::V_CMP_EQ_U16}, {0xabu, Opcode::V_CMP_LE_U16}, {0xacu, Opcode::V_CMP_GT_U16}, {0xadu, Opcode::V_CMP_NE_U16}, - {0xaeu, Opcode::V_CMP_GE_U16}, {0xc0u, Opcode::V_CMP_F_U32}, + {0xaeu, Opcode::V_CMP_GE_U16}, {0xbcu, Opcode::V_CMPX_GT_U16}, + {0xc0u, Opcode::V_CMP_F_U32}, {0xc1u, Opcode::V_CMP_LT_U32}, {0xc2u, Opcode::V_CMP_EQ_U32}, {0xc3u, Opcode::V_CMP_LE_U32}, {0xc4u, Opcode::V_CMP_GT_U32}, {0xc5u, Opcode::V_CMP_NE_U32}, {0xc6u, Opcode::V_CMP_GE_U32}, @@ -1506,6 +1507,7 @@ bool IsVopcCompareExec(Opcode opcode) { case Opcode::V_CMPX_GE_U32: case Opcode::V_CMPX_NE_I64: case Opcode::V_CMPX_NE_U64: + case Opcode::V_CMPX_GT_U16: case Opcode::V_CMPX_LT_F16: case Opcode::V_CMPX_EQ_F16: case Opcode::V_CMPX_LE_F16: diff --git a/src/graphics/shader/recompiler/frontend/translate/Vector.cpp b/src/graphics/shader/recompiler/frontend/translate/Vector.cpp index c0100cf3f..cf0da25ac 100644 --- a/src/graphics/shader/recompiler/frontend/translate/Vector.cpp +++ b/src/graphics/shader/recompiler/frontend/translate/Vector.cpp @@ -124,6 +124,9 @@ bool Translator::EmitVector(const Decoder::Instruction& inst, std::string* error case O::V_CMP_GT_U16: EmitInteger16Compare(inst, IR::ValueOpcode::UGreaterThan32, false, false); return true; + case O::V_CMPX_GT_U16: + EmitInteger16Compare(inst, IR::ValueOpcode::UGreaterThan32, false, true); + return true; case O::V_CMP_GE_U16: EmitInteger16Compare(inst, IR::ValueOpcode::UGreaterThanEqual32, false, false); return true; diff --git a/tests/ShaderRecompilerComputeTests.cpp b/tests/ShaderRecompilerComputeTests.cpp index fcb473d9a..94a53c1e8 100644 --- a/tests/ShaderRecompilerComputeTests.cpp +++ b/tests/ShaderRecompilerComputeTests.cpp @@ -15746,6 +15746,32 @@ TestCase VectorVopcSdwaCmpxWritesExecMask() { {O::V_MOV_B32, O::V_CMPX_LT_U32, O::BUFFER_STORE_DWORD, O::S_ENDPGM}}; } +TestCase VectorVopcCmpxGtU16CapturedSdwaExecMask() { + using O = ShaderOpcode; + + std::vector code; + AppendVMovU32(&code, 2, 0x00008000u); + AppendVMovU32(&code, 3, 7); + AppendVMovU32(&code, 31, 0); + code.insert(code.end(), {0x7d7900f9u, 0x86060002u}); + AppendBufferStoreDword(&code, 3, 31); + AppendVMovU32(&code, 2, 0x00010000u); + AppendVMovU32(&code, 3, 9); + AppendVMovU32(&code, 31, 4); + code.insert(code.end(), {0x7d7900f9u, 0x86060002u}); + AppendBufferStoreDword(&code, 3, 31); + AppendEnd(&code); + + TestCase test{"VectorVopcCmpxGtU16CapturedSdwaExecMask", + code, + {0x11111111u, 0x22222222u}, + {7, 0x22222222u}, + {O::V_MOV_B32, O::V_CMPX_GT_U16, O::BUFFER_STORE_DWORD, + O::S_ENDPGM}}; + test.decoded_counts = {{"V_CMPX_GT_U16", 2}}; + return test; +} + TestCase VectorCompareInvertedMaskSelect() { using O = ShaderOpcode; @@ -20270,6 +20296,7 @@ std::vector MakeCases() { AddCase(VectorVop3FloatCompareNegSourceModifier); AddCase(VectorVop3CmpxWritesExecMask); AddCase(VectorVopcSdwaCmpxWritesExecMask); + AddCase(VectorVopcCmpxGtU16CapturedSdwaExecMask); AddCase(VectorCompareInvertedMaskSelect); AddCase(BranchSelect); AddCase(SimpleLoop);