From cda236dbb34bd37b473c60d700884d75bd100471 Mon Sep 17 00:00:00 2001 From: Hamza Shakir <60213466+hamzashakir99@users.noreply.github.com> Date: Sat, 26 Sep 2026 01:57:12 +0400 Subject: [PATCH] Shader recompiler: accept V_NOT_B32 SDWA partial dst with any source; allow 64 buffers SDWA source extraction and destination insertion are independent. Cover the reported word1-to-word0 preserve form and byte-source partial destinations in compute tests. Verify 64 distinct compute buffers survive resource tracking and binding layout, and remove the obsolete CFG rejection. (cherry picked from commit 9e74df7dc0b116fb0adfb9e179255c7c4c78f0f4) --- .../frontend/decode/VectorAluOps.cpp | 4 ++- src/graphics/shader/recompiler/ir/ShaderIR.h | 2 +- tests/ResourceTrackingTests.cpp | 25 ++++++++++++++ tests/ShaderRecompilerComputeTests.cpp | 33 +++++++++++++++++++ tests/shaderCfgTests.cpp | 2 -- 5 files changed, 62 insertions(+), 4 deletions(-) diff --git a/src/graphics/shader/recompiler/frontend/decode/VectorAluOps.cpp b/src/graphics/shader/recompiler/frontend/decode/VectorAluOps.cpp index 55f608eca..26eda2f0f 100644 --- a/src/graphics/shader/recompiler/frontend/decode/VectorAluOps.cpp +++ b/src/graphics/shader/recompiler/frontend/decode/VectorAluOps.cpp @@ -522,8 +522,10 @@ constexpr Vop1SdwaRule VOP1_SDWA_RULES[] = { {Opcode::V_CVT_F32_U32, SdwaSelBytes() | SdwaSelWords() | SdwaSelFull(), 0, 0, false}, {Opcode::V_CVT_F32_I32, SdwaSelBytes() | SdwaSelWords() | SdwaSelFull(), 0, 0, false}, {Opcode::V_CVT_F32_UBYTE0, SdwaSelBytes() | SdwaSelWords() | SdwaSelFull(), 0, 0, false}, + // The source field extract and the destination insert are independent (Translate.cpp), so a + // partial destination may combine with any source selector. {Opcode::V_NOT_B32, SdwaSelBytes() | SdwaSelWords() | SdwaSelFull(), SdwaSelBytes() | SdwaSelWords(), - SdwaSelFull(), false}, + SdwaSelBytes() | SdwaSelWords() | SdwaSelFull(), false}, {Opcode::V_FFBL_B32, SdwaSelBytes() | SdwaSelWords() | SdwaSelFull(), 0, 0, false}, {Opcode::V_CVT_F32_F16, SdwaSelWords() | SdwaSelFull(), 0, 0, true}, {Opcode::V_CVT_F16_F32, SdwaSelBytes() | SdwaSelWords() | SdwaSelFull(), SdwaSelWords(), diff --git a/src/graphics/shader/recompiler/ir/ShaderIR.h b/src/graphics/shader/recompiler/ir/ShaderIR.h index 2359479f4..e9827605b 100644 --- a/src/graphics/shader/recompiler/ir/ShaderIR.h +++ b/src/graphics/shader/recompiler/ir/ShaderIR.h @@ -435,7 +435,7 @@ struct BindingLayout { }; struct ShaderInfo { - static constexpr uint32_t MaxBuffers = 32; + static constexpr uint32_t MaxBuffers = 64; static constexpr uint32_t MaxImages = 64; static constexpr uint32_t MaxSamplers = 32; static constexpr uint32_t MaxSampledPairs = 64; diff --git a/tests/ResourceTrackingTests.cpp b/tests/ResourceTrackingTests.cpp index 128e688e2..4dd4d8af3 100644 --- a/tests/ResourceTrackingTests.cpp +++ b/tests/ResourceTrackingTests.cpp @@ -2815,6 +2815,31 @@ void TestGraphicsPushConstantLayout() { } void TestResourceLimitIsTransactional() { + Fixture accepted; + MemoryInfo accepted_memory; + accepted_memory.kind = ResourceKind::Buffer; + for (uint32_t index = 0; index < ShaderInfo::MaxBuffers; index++) { + const auto handle = accepted.Buffer( + {Value(index), Value(index + 1u), Value(index + 2u), Value(index + 3u)}, + index * 4u); + accepted.Emit(ValueOpcode::LoadBufferU32, + {handle, Value(0u), Value(0u), Value(0u), Value(true)}, + accepted.AddMemory(accepted_memory, index * 4u)); + } + accepted.PlanAndTrack(); + Check(accepted.program.info.buffers.size() == 64u && + accepted.program.descriptor_sources.size() == 64u && + accepted.program.memory_info.back().resource == 63u, + "compute shader did not retain all 64 distinct buffers"); + ShaderComputeInputInfo compute{}; + CollectShaderInfo(accepted.program, {.compute = &compute}); + AllocateBindings(accepted.program); + const auto *binding = FindBinding(accepted.program.bindings, + DescriptorBindingKind::Buffers); + Check(binding != nullptr && binding->resources.size() == 64u && + accepted.program.bindings.memory_offset_count == 64u, + "compute shader binding layout truncated the 64 buffers"); + Fixture fixture; MemoryInfo memory; memory.kind = ResourceKind::Buffer; diff --git a/tests/ShaderRecompilerComputeTests.cpp b/tests/ShaderRecompilerComputeTests.cpp index 8e5a0377f..2ce1d0521 100644 --- a/tests/ShaderRecompilerComputeTests.cpp +++ b/tests/ShaderRecompilerComputeTests.cpp @@ -18937,6 +18937,38 @@ TestCase Vop1SdwaNotPreservesHighWordDestination() { return test; } +TestCase Vop1SdwaNotPartialSourcesAndDestinations() { + using O = ShaderOpcode; + + std::vector code; + AppendBufferLoadDword(&code, 8, 30); + AppendVMovLiteral(&code, 28, 0xabcd5555u); + code.push_back(EncodeVop1(0x37, 28, 249)); + code.push_back(EncodeVop1Sdwa(8, 4, 2, 5)); // v28.word0 = ~v8.word1, preserve word1 + AppendStoreVgpr(&code, 28, 0); + + AppendVMovLiteral(&code, 3, 0xa1b2c3d4u); + code.push_back(EncodeVop1(0x37, 3, 249)); + code.push_back(EncodeVop1Sdwa(8, 2, 2, 0)); // v3.byte2 = ~v8.byte0, preserve others + AppendStoreVgpr(&code, 3, 1); + + code.push_back(EncodeVop1(0x37, 4, 249)); + code.push_back(EncodeVop1Sdwa(8, 0, 0, 0)); // v4.byte0 = ~v8.byte0, zero others + AppendStoreVgpr(&code, 4, 2); + AppendEnd(&code); + + TestCase test; + test.name = "Vop1SdwaNotPartialSourcesAndDestinations"; + test.code = std::move(code); + test.initial = {0x12345678u, 0u, 0u}; + test.expected = {0xabcdedcbu, 0xa187c3d4u, 0x00000087u}; + test.opcodes = {O::BUFFER_LOAD_DWORD, O::V_MOV_B32, O::V_NOT_B32, + O::BUFFER_STORE_DWORD, O::S_ENDPGM}; + test.decoded_counts = {{"V_NOT_B32", 3u}}; + test.required_spirv = {"OpBitFieldUExtract", "OpNot"}; + return test; +} + TestCase Vop1SdwaMovByteDestinations() { using O = ShaderOpcode; @@ -28641,6 +28673,7 @@ std::vector MakeCases() { AddCase(Vop1SdwaFfblCapturedHighWordSource); AddCase(Vop1SdwaNotCapturedByte0Source); AddCase(Vop1SdwaNotPreservesHighWordDestination); + AddCase(Vop1SdwaNotPartialSourcesAndDestinations); AddCase(Vop1SdwaMovByteDestinations); AddCase(Vop2SdwaSubNcExactByte2Destination); AddCase(Vop2SdwaAddNcCapturedHighWordDestination); diff --git a/tests/shaderCfgTests.cpp b/tests/shaderCfgTests.cpp index 42ba3d5ac..eebdb9181 100644 --- a/tests/shaderCfgTests.cpp +++ b/tests/shaderCfgTests.cpp @@ -3523,8 +3523,6 @@ void TestNewShaderRecompilerVop1SdwaNotDestination() { check_rejected(0x00260400u, "V_NOT_B32 SDWA accepted source absolute"); check_rejected(0x00062400u, "V_NOT_B32 SDWA accepted clamp"); check_rejected(0x00064400u, "V_NOT_B32 SDWA accepted output modifier"); - check_rejected(0x00000400u, - "V_NOT_B32 SDWA partial destination accepted a byte source"); } void TestNewShaderRecompilerBootB16PackedAndSdwaOpcodes() {