From 2bb396f58f0af114af16c1a28b73a41d78c978a8 Mon Sep 17 00:00:00 2001 From: nmzik Date: Sun, 16 Aug 2026 10:12:34 +0200 Subject: [PATCH] graphics: support SDWA arithmetic right shifts --- .../frontend/decode/VectorAluOps.cpp | 6 ++-- tests/ShaderRecompilerComputeTests.cpp | 32 +++++++++++++++++++ 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/graphics/shader/recompiler/frontend/decode/VectorAluOps.cpp b/src/graphics/shader/recompiler/frontend/decode/VectorAluOps.cpp index 0338cee2d..ab6a00e05 100644 --- a/src/graphics/shader/recompiler/frontend/decode/VectorAluOps.cpp +++ b/src/graphics/shader/recompiler/frontend/decode/VectorAluOps.cpp @@ -16,7 +16,7 @@ enum class Vop2SdwaProfile { Float16, IntegerFullDestination, IntegerPartialDestination, - ReverseLogicalRight, + ReverseRightShift, ReverseLogicalLeft, Bitwise, Count, @@ -44,9 +44,9 @@ constexpr Vop2OpcodeInfo VOP2_OPCODE_LIST[] = { {0x13u, Opcode::VMinU32, Vop2SdwaProfile::IntegerPartialDestination}, {0x14u, Opcode::VMaxU32, Vop2SdwaProfile::IntegerFullDestination}, {0x15u, Opcode::VLshrB32}, - {0x16u, Opcode::VLshrrevB32, Vop2SdwaProfile::ReverseLogicalRight}, + {0x16u, Opcode::VLshrrevB32, Vop2SdwaProfile::ReverseRightShift}, {0x17u, Opcode::VAshrI32}, - {0x18u, Opcode::VAshrrevI32}, + {0x18u, Opcode::VAshrrevI32, Vop2SdwaProfile::ReverseRightShift}, {0x19u, Opcode::VLshlB32}, {0x1au, Opcode::VLshlrevB32, Vop2SdwaProfile::ReverseLogicalLeft}, {0x1bu, Opcode::VAndB32, Vop2SdwaProfile::Bitwise}, diff --git a/tests/ShaderRecompilerComputeTests.cpp b/tests/ShaderRecompilerComputeTests.cpp index b3db18e0f..9476a9143 100644 --- a/tests/ShaderRecompilerComputeTests.cpp +++ b/tests/ShaderRecompilerComputeTests.cpp @@ -11759,6 +11759,32 @@ TestCase Vop2SdwaAddNcCapturedHighWordDestination() { return test; } +TestCase Vop2SdwaAshrrevCapturedWord0SignExtends() { + using O = ShaderOpcode; + + std::vector code; + AppendBufferLoadDword(&code, 1, 30); + code.push_back(0x303202f9u); + code.push_back( + 0x0c860686u); // v_ashrrev_i32 v25, 6, sign_extend(v1.word0) + AppendStoreVgpr(&code, 25, 1); + AppendEnd(&code); + + TestCase test; + test.name = "Vop2SdwaAshrrevCapturedWord0SignExtends"; + test.code = std::move(code); + test.initial = {0xabcd8000u, 0}; + test.expected = {0xabcd8000u, 0xfffffe00u}; + test.opcodes = {O::BufferLoadDword, O::VAshrrevI32, O::VMovB32, + O::BufferStoreDword, O::SEndpgm}; + test.decoded_counts = { + {"v_ashrrev_i32 v25, 6, v1.sdwa(sel=4,sext=1)", 1}}; + test.ir_counts = {{" = BitFieldSExtract ", 1}, + {" = ShiftRightArithmetic32 ", 1}}; + test.required_spirv = {"OpBitFieldSExtract", "OpShiftRightArithmetic"}; + return test; +} + TestCase Vop2SdwaSubNcPreservesByteAndWordDestinations() { using O = ShaderOpcode; @@ -17539,6 +17565,7 @@ std::vector MakeCases() { AddCase(VectorIntegerOps); AddCase(Vop2SdwaSubNcExactByte2Destination); AddCase(Vop2SdwaAddNcCapturedHighWordDestination); + AddCase(Vop2SdwaAshrrevCapturedWord0SignExtends); AddCase(Vop2SdwaSubNcPreservesByteAndWordDestinations); AddCase(Vop2SdwaMinU32PreservesWordDestination); AddCase(VectorShiftCountsMaskLowBits); @@ -20980,6 +21007,11 @@ int main(int argc, char **argv) { RunCase(&vulkan, VectorAlignByteUsesFiveBitByteOffset()); return 0; } + if (argc == 2 && std::strcmp(argv[1], "--sdwa-ashr-only") == 0) { + VulkanHarness vulkan; + RunCase(&vulkan, Vop2SdwaAshrrevCapturedWord0SignExtends()); + return 0; + } if (argc == 2 && std::strcmp(argv[1], "--sff1-b64-only") == 0) { VulkanHarness vulkan; RunCase(&vulkan, ScalarBitfieldPack());