From 1ff580498c4f2251bacbc0fa52970ab1765e9c4b Mon Sep 17 00:00:00 2001 From: nmzik Date: Thu, 27 Aug 2026 04:25:11 +0200 Subject: [PATCH] shader: support V_CMPX_NGT_F16 SDWA --- .../frontend/decode/ShaderDecoder.h | 1 + .../frontend/decode/VectorAluOps.cpp | 5 +++- .../recompiler/frontend/translate/Vector.cpp | 3 +++ tests/ShaderRecompilerComputeTests.cpp | 27 +++++++++++++++++++ 4 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/graphics/shader/recompiler/frontend/decode/ShaderDecoder.h b/src/graphics/shader/recompiler/frontend/decode/ShaderDecoder.h index 5b7c5a741..4a843db41 100644 --- a/src/graphics/shader/recompiler/frontend/decode/ShaderDecoder.h +++ b/src/graphics/shader/recompiler/frontend/decode/ShaderDecoder.h @@ -366,6 +366,7 @@ enum class Opcode { V_CMPX_LE_F16, V_CMPX_GT_F16, V_CMPX_GE_F16, + V_CMPX_NGT_F16, V_CMPX_NEQ_F16, V_CMPX_NLT_F16, V_CMPX_LT_I32, diff --git a/src/graphics/shader/recompiler/frontend/decode/VectorAluOps.cpp b/src/graphics/shader/recompiler/frontend/decode/VectorAluOps.cpp index 4b429d11d..eff3d10d9 100644 --- a/src/graphics/shader/recompiler/frontend/decode/VectorAluOps.cpp +++ b/src/graphics/shader/recompiler/frontend/decode/VectorAluOps.cpp @@ -242,7 +242,8 @@ constexpr VopcOpcodeInfo VOPC_OPCODE_LIST[] = { {0xedu, Opcode::V_CMP_NEQ_F16}, {0xd9u, Opcode::V_CMPX_LT_F16}, {0xdau, Opcode::V_CMPX_EQ_F16}, {0xdbu, Opcode::V_CMPX_LE_F16}, {0xdcu, Opcode::V_CMPX_GT_F16}, {0xdeu, Opcode::V_CMPX_GE_F16}, - {0xfdu, Opcode::V_CMPX_NEQ_F16}, {0xfeu, Opcode::V_CMPX_NLT_F16}, + {0xfbu, Opcode::V_CMPX_NGT_F16}, {0xfdu, Opcode::V_CMPX_NEQ_F16}, + {0xfeu, Opcode::V_CMPX_NLT_F16}, }; constexpr auto VOPC_OPS = Detail::MakeOpcodeTable<0x100>(VOPC_OPCODE_LIST); @@ -874,6 +875,7 @@ bool IsVopcFloatCompareOpcode(Opcode opcode) { case Opcode::V_CMPX_LE_F16: case Opcode::V_CMPX_GT_F16: case Opcode::V_CMPX_GE_F16: + case Opcode::V_CMPX_NGT_F16: case Opcode::V_CMPX_NEQ_F16: case Opcode::V_CMPX_NLT_F16: case Opcode::V_CMP_CLASS_F32: return true; @@ -1513,6 +1515,7 @@ bool IsVopcCompareExec(Opcode opcode) { case Opcode::V_CMPX_LE_F16: case Opcode::V_CMPX_GT_F16: case Opcode::V_CMPX_GE_F16: + case Opcode::V_CMPX_NGT_F16: case Opcode::V_CMPX_NEQ_F16: case Opcode::V_CMPX_NLT_F16: return true; default: return false; diff --git a/src/graphics/shader/recompiler/frontend/translate/Vector.cpp b/src/graphics/shader/recompiler/frontend/translate/Vector.cpp index cf0da25ac..6a5bbc0c5 100644 --- a/src/graphics/shader/recompiler/frontend/translate/Vector.cpp +++ b/src/graphics/shader/recompiler/frontend/translate/Vector.cpp @@ -256,6 +256,9 @@ bool Translator::EmitVector(const Decoder::Instruction& inst, std::string* error case O::V_CMPX_LE_F16: EmitFloatCompare(inst, IR::ValueOpcode::FPOrdLessThanEqual32, true, true); return true; + case O::V_CMPX_NGT_F16: + EmitFloatCompare(inst, IR::ValueOpcode::FPUnordLessThanEqual32, true, true); + return true; case O::V_CMP_NEQ_F16: EmitFloatCompare(inst, IR::ValueOpcode::FPUnordNotEqual32, true, false); return true; diff --git a/tests/ShaderRecompilerComputeTests.cpp b/tests/ShaderRecompilerComputeTests.cpp index 94a53c1e8..5d95231aa 100644 --- a/tests/ShaderRecompilerComputeTests.cpp +++ b/tests/ShaderRecompilerComputeTests.cpp @@ -15772,6 +15772,32 @@ TestCase VectorVopcCmpxGtU16CapturedSdwaExecMask() { return test; } +TestCase VectorVopcCmpxNgtF16CapturedSdwaExecMask() { + using O = ShaderOpcode; + + std::vector code; + AppendVMovLiteral(&code, 31, 0x7e003c00u); + AppendVMovU32(&code, 3, 7); + AppendVMovU32(&code, 30, 0); + code.insert(code.end(), {0x7df700f9u, 0x8605001fu}); + AppendBufferStoreDword(&code, 3, 30); + AppendVMovLiteral(&code, 31, 0x3c007e00u); + AppendVMovU32(&code, 3, 9); + AppendVMovU32(&code, 30, 4); + code.insert(code.end(), {0x7df700f9u, 0x8605001fu}); + AppendBufferStoreDword(&code, 3, 30); + AppendEnd(&code); + + TestCase test{"VectorVopcCmpxNgtF16CapturedSdwaExecMask", + code, + {0x11111111u, 0x22222222u}, + {7, 0x22222222u}, + {O::V_MOV_B32, O::V_CMPX_NGT_F16, O::BUFFER_STORE_DWORD, + O::S_ENDPGM}}; + test.decoded_counts = {{"V_CMPX_NGT_F16", 2}}; + return test; +} + TestCase VectorCompareInvertedMaskSelect() { using O = ShaderOpcode; @@ -20297,6 +20323,7 @@ std::vector MakeCases() { AddCase(VectorVop3CmpxWritesExecMask); AddCase(VectorVopcSdwaCmpxWritesExecMask); AddCase(VectorVopcCmpxGtU16CapturedSdwaExecMask); + AddCase(VectorVopcCmpxNgtF16CapturedSdwaExecMask); AddCase(VectorCompareInvertedMaskSelect); AddCase(BranchSelect); AddCase(SimpleLoop);