diff --git a/src/graphics/shader/recompiler/decompiler/MemoryOps.cpp b/src/graphics/shader/recompiler/decompiler/MemoryOps.cpp index e09174081..083172897 100644 --- a/src/graphics/shader/recompiler/decompiler/MemoryOps.cpp +++ b/src/graphics/shader/recompiler/decompiler/MemoryOps.cpp @@ -421,13 +421,13 @@ bool DecodeDs(uint32_t pc, std::span code, uint32_t word_index, const uint32_t data0 = (word1 >> 8u) & 0xffu; const uint32_t addr = word1 & 0xffu; - inst.pc = pc; - inst.word = word0; - inst.word_count = 2; - inst.offset = offset0 | (offset1 << 8u); - inst.gds = ((word0 >> 17u) & 1u) != 0u; - inst.family = Family::DS; - inst.opcode_id = opcode; + inst.pc = pc; + inst.word = word0; + inst.word_count = 2; + inst.offset = offset0 | (offset1 << 8u); + inst.gds = ((word0 >> 17u) & 1u) != 0u; + inst.family = Family::DS; + inst.opcode_id = opcode; const auto* info = LookupMemoryOpcode(DS_OPS, static_cast(std::size(DS_OPS)), opcode); ApplyMemoryInfo(inst, info); SetRawWords(inst, code, word_index, 2); @@ -442,11 +442,6 @@ bool DecodeDs(uint32_t pc, std::span code, uint32_t word_index, inst.opcode == Opcode::DsReadAddtidB32)) { SetUnsupported(inst, Family::DS, opcode, "DS swizzle/addtid is available only for LDS"); } - if (inst.gds && (inst.opcode == Opcode::DsAppend || inst.opcode == Opcode::DsConsume) && - inst.offset != 0u) { - SetUnsupported(inst, Family::DS, opcode, - "GDS append/consume requires a zero instruction offset"); - } if (inst.opcode == Opcode::DsWriteAddtidB32 && data1 != 0u) { SetUnsupported(inst, Family::DS, opcode, "DS write addtid data1 operand is not implemented"); diff --git a/src/graphics/shader/recompiler/emitter/SpirvEmitter.cpp b/src/graphics/shader/recompiler/emitter/SpirvEmitter.cpp index 82868950e..e47b662d4 100644 --- a/src/graphics/shader/recompiler/emitter/SpirvEmitter.cpp +++ b/src/graphics/shader/recompiler/emitter/SpirvEmitter.cpp @@ -1,7 +1,7 @@ #include "graphics/shader/recompiler/emitter/SpirvEmitter.h" -#include "graphics/shader/recompiler/ir/SrtWalker.h" #include "graphics/shader/recompiler/emitter/spirvEmitterInternal.h" +#include "graphics/shader/recompiler/ir/SrtWalker.h" #include #include @@ -160,8 +160,7 @@ bool ValidateInstructionContract(const IR::Instruction& inst, std::string* error inst.dst.kind != IR::OperandKind::Null)) || ((inst.op == IR::Opcode::DsAppend || inst.op == IR::Opcode::DsConsume) && (!ds_kind || !ds_resource || inst.src_count != 1 || - inst.dst.kind != IR::OperandKind::Register || - (kind == IR::ResourceKind::Gds && inst.memory.offset != 0))) || + inst.dst.kind != IR::OperandKind::Register)) || ((inst.op == IR::Opcode::DsMinF32 || inst.op == IR::Opcode::DsMaxF32) && (!ds_kind || !ds_resource || inst.src_count != 3 || inst.dst.kind != IR::OperandKind::Null)) || diff --git a/tests/ShaderRecompilerComputeTests.cpp b/tests/ShaderRecompilerComputeTests.cpp index 182c9128b..1e22110b0 100644 --- a/tests/ShaderRecompilerComputeTests.cpp +++ b/tests/ShaderRecompilerComputeTests.cpp @@ -13593,23 +13593,36 @@ TestCase DsAppendUsesEncodedGdsSelector() { using O = ShaderOpcode; std::vector code; - AppendSMovLiteral(&code, 124, 0x00000001u); + AppendSMovLiteral(&code, 124, 0x00000008u); code.push_back(EncodeDs0(0x3e, 0, true)); code.push_back(EncodeDs1(0, 0, 0)); code.push_back(EncodeDs0(0x3d, 0, true)); code.push_back(EncodeDs1(1, 0, 0)); + code.push_back(EncodeDs0(0x3e, 4, true)); + code.push_back(EncodeDs1(2, 0, 0)); + code.push_back(EncodeDs0(0x3d, 4, true)); + code.push_back(EncodeDs1(3, 0, 0)); + AppendSMovLiteral(&code, 124, 0x00080008u); + code.push_back(EncodeDs0(0x3e, 4, true)); + code.push_back(EncodeDs1(4, 0, 0)); + code.push_back(EncodeDs0(0x3d, 4, true)); + code.push_back(EncodeDs1(5, 0, 0)); AppendStoreVgpr(&code, 0, 0); AppendStoreVgpr(&code, 1, 1); + AppendStoreVgpr(&code, 2, 2); + AppendStoreVgpr(&code, 3, 3); + AppendStoreVgpr(&code, 4, 4); + AppendStoreVgpr(&code, 5, 5); AppendEnd(&code); TestCase test{ "DsAppendGdsSelector", code, {}, - {10, 74}, + {10, 74, 20, 84, 40, 104}, {O::SMovB32, O::DsAppend, O::DsConsume, O::BufferStoreDword, O::SEndpgm}}; - test.gds_initial = {10}; - test.expected_gds = {10}; + test.gds_initial = {10, 20, 30, 40}; + test.expected_gds = {10, 20, 30, 40}; return test; }