From ef639610e70b935af2de4aee5d2652d4a7d3374b Mon Sep 17 00:00:00 2001 From: nmzik Date: Sat, 29 Aug 2026 15:26:13 +0400 Subject: [PATCH] shader: allow SDWA add-with-carry --- .../frontend/decode/VectorAluOps.cpp | 2 +- tests/ShaderRecompilerComputeTests.cpp | 35 ++++++++++--------- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/src/graphics/shader/recompiler/frontend/decode/VectorAluOps.cpp b/src/graphics/shader/recompiler/frontend/decode/VectorAluOps.cpp index c2a26bc44..8328c2136 100644 --- a/src/graphics/shader/recompiler/frontend/decode/VectorAluOps.cpp +++ b/src/graphics/shader/recompiler/frontend/decode/VectorAluOps.cpp @@ -59,7 +59,7 @@ constexpr Vop2OpcodeInfo VOP2_OPCODE_LIST[] = { {0x23u, Opcode::V_MBCNT_LO_U32_B32}, {0x24u, Opcode::V_MBCNT_HI_U32_B32}, {0x25u, Opcode::V_ADD_NC_U32, Vop2SdwaProfile::IntegerPartialDestination}, - {0x28u, Opcode::V_ADDC_U32}, + {0x28u, Opcode::V_ADDC_U32, Vop2SdwaProfile::IntegerFullDestination}, {0x2au, Opcode::V_SUBREV_CO_CI_U32}, {0x26u, Opcode::V_SUB_NC_U32, Vop2SdwaProfile::IntegerPartialDestination}, {0x27u, Opcode::V_SUBREV_NC_U32, Vop2SdwaProfile::IntegerFullDestination}, diff --git a/tests/ShaderRecompilerComputeTests.cpp b/tests/ShaderRecompilerComputeTests.cpp index c06286739..f5172058a 100644 --- a/tests/ShaderRecompilerComputeTests.cpp +++ b/tests/ShaderRecompilerComputeTests.cpp @@ -13957,37 +13957,35 @@ TestCase VectorAddcUsesPerLaneCarryIn() { TestCase VectorAddcWritesPerLaneCarryOut() { using O = ShaderOpcode; - std::vector code = { - EncodeVop1(0x01, 1, 0), - EncodeVop2(0x1a, 1, InlineU32(2), 1), - EncodeVop2(0x25, 1, Vgpr(0), 1), - EncodeVopc(0xc0, Vgpr(0), 0), - }; - AppendVMovLiteral(&code, 2, 0xffffffffu); - code.push_back(EncodeVop1(0x01, 3, InlineU32(1))); - code.push_back(EncodeVop2(0x28, 5, Vgpr(2), 3)); + std::vector code = {EncodeVop1(0x01, 1, Vgpr(0)), + EncodeVop2(0x1a, 4, InlineU32(2), 1), + EncodeVopc(0xc7, Vgpr(0), 0)}; + AppendBufferLoadDword(&code, 26, 4); + code.push_back(0x500434f9u); + code.push_back(0x0c860680u); code.push_back(EncodeVop1(0x01, 6, 106)); - code.push_back(EncodeVop2(0x1a, 4, InlineU32(2), 1)); AppendBufferStoreDword(&code, 6, 4); AppendEnd(&code); TestCase test; test.name = "VectorAddcWritesPerLaneCarryOut"; test.code = code; + test.initial = {0x0000ffffu, 0u, 0x0000ffffu, 0u}; // VCC is represented as the current invocation's carry bit, not a shared // four-lane ballot word. - test.expected = std::vector(8, 1u); - test.opcodes = {O::V_MOV_B32, O::V_LSHLREV_B32, O::V_ADD_NC_U32, - O::V_CMP_F_U32, O::V_ADDC_U32, O::BUFFER_STORE_DWORD, + test.expected = {1u, 0u, 1u, 0u}; + test.opcodes = {O::V_MOV_B32, O::V_LSHLREV_B32, O::V_CMP_T_U32, + O::BUFFER_LOAD_DWORD, O::V_ADDC_U32, O::BUFFER_STORE_DWORD, O::S_ENDPGM}; + test.decoded_counts = { + {"V_ADDC_U32 v2, vcc_lo, 0, v26.sdwa(sel=4,sext=1), vcc_lo", 1}}; + test.ir_counts = {{" = BitFieldSExtract ", 1}, {" = IAddCarry32 ", 2}}; + test.required_spirv = {"OpBitFieldSExtract"}; test.compute_info.threads_num[0] = 4; test.compute_info.threads_num[1] = 1; test.compute_info.threads_num[2] = 1; - test.compute_info.group_id[0] = true; test.compute_info.thread_ids_num = 1; - test.compute_info.workgroup_register = 0; test.has_compute_info = true; - test.dispatch_x = 2; return test; } @@ -24518,6 +24516,11 @@ int main(int argc, char **argv) { RunCase(&vulkan, Vop2SdwaAshrrevCapturedWord0SignExtends()); return 0; } + if (argc == 2 && std::strcmp(argv[1], "--sdwa-addc-only") == 0) { + VulkanHarness vulkan; + RunCase(&vulkan, VectorAddcWritesPerLaneCarryOut()); + return 0; + } if (argc == 2 && std::strcmp(argv[1], "--cvt-pk-i16-only") == 0) { VulkanHarness vulkan; RunCase(&vulkan, Vop3CvtPkI16I32Captured());