diff --git a/src/graphics/shader/recompiler/frontend/decode/MemoryOps.cpp b/src/graphics/shader/recompiler/frontend/decode/MemoryOps.cpp index fadfef652..28ce76c5a 100644 --- a/src/graphics/shader/recompiler/frontend/decode/MemoryOps.cpp +++ b/src/graphics/shader/recompiler/frontend/decode/MemoryOps.cpp @@ -86,6 +86,7 @@ constexpr MemoryOpcodeInfo FLAT_OPCODE_LIST[] = { constexpr MemoryOpcodeInfo DS_OPCODE_LIST[] = { {0x00u, Opcode::DS_ADD_U32, 1, 32}, {0x01u, Opcode::DS_SUB_U32, 1, 32}, + {0x03u, Opcode::DS_INC_U32, 1, 32}, {0x04u, Opcode::DS_DEC_U32, 1, 32}, {0x05u, Opcode::DS_MIN_I32, 1, 32}, {0x06u, Opcode::DS_MAX_I32, 1, 32}, {0x07u, Opcode::DS_MIN_U32, 1, 32}, {0x08u, Opcode::DS_MAX_U32, 1, 32}, {0x09u, Opcode::DS_AND_B32, 1, 32}, {0x0au, Opcode::DS_OR_B32, 1, 32}, @@ -168,7 +169,9 @@ bool IsDsAtomicOpcode(Opcode opcode) { case Opcode::DS_ADD_RTN_U32: case Opcode::DS_SUB_U32: case Opcode::DS_SUB_RTN_U32: + case Opcode::DS_INC_U32: case Opcode::DS_INC_RTN_U32: + case Opcode::DS_DEC_U32: case Opcode::DS_DEC_RTN_U32: case Opcode::DS_MIN_I32: case Opcode::DS_MIN_RTN_I32: diff --git a/src/graphics/shader/recompiler/frontend/decode/ShaderDecoder.cpp b/src/graphics/shader/recompiler/frontend/decode/ShaderDecoder.cpp index 69183a0d1..40220e48f 100644 --- a/src/graphics/shader/recompiler/frontend/decode/ShaderDecoder.cpp +++ b/src/graphics/shader/recompiler/frontend/decode/ShaderDecoder.cpp @@ -659,7 +659,9 @@ std::string InstructionToString(const Instruction& inst) { case Opcode::DS_ADD_RTN_U32: case Opcode::DS_SUB_U32: case Opcode::DS_SUB_RTN_U32: + case Opcode::DS_INC_U32: case Opcode::DS_INC_RTN_U32: + case Opcode::DS_DEC_U32: case Opcode::DS_DEC_RTN_U32: case Opcode::DS_MIN_I32: case Opcode::DS_MIN_RTN_I32: diff --git a/src/graphics/shader/recompiler/frontend/decode/ShaderDecoder.h b/src/graphics/shader/recompiler/frontend/decode/ShaderDecoder.h index efa174d40..0d01f6a18 100644 --- a/src/graphics/shader/recompiler/frontend/decode/ShaderDecoder.h +++ b/src/graphics/shader/recompiler/frontend/decode/ShaderDecoder.h @@ -502,7 +502,9 @@ enum class Opcode { DS_ADD_RTN_U32, DS_SUB_U32, DS_SUB_RTN_U32, + DS_INC_U32, DS_INC_RTN_U32, + DS_DEC_U32, DS_DEC_RTN_U32, DS_MIN_I32, DS_MIN_RTN_I32, diff --git a/src/graphics/shader/recompiler/frontend/translate/Memory.cpp b/src/graphics/shader/recompiler/frontend/translate/Memory.cpp index 4877062da..bec08ef4c 100644 --- a/src/graphics/shader/recompiler/frontend/translate/Memory.cpp +++ b/src/graphics/shader/recompiler/frontend/translate/Memory.cpp @@ -963,8 +963,12 @@ bool Translator::EmitMemory(const Decoder::Instruction& inst) { return DS_ATOMIC(inst, IR::ValueOpcode::SharedAtomicISub32, false); case Decoder::Opcode::DS_SUB_RTN_U32: return DS_ATOMIC(inst, IR::ValueOpcode::SharedAtomicISub32, true); + case Decoder::Opcode::DS_INC_U32: + return DS_ATOMIC(inst, IR::ValueOpcode::SharedAtomicInc32, false); case Decoder::Opcode::DS_INC_RTN_U32: return DS_ATOMIC(inst, IR::ValueOpcode::SharedAtomicInc32, true); + case Decoder::Opcode::DS_DEC_U32: + return DS_ATOMIC(inst, IR::ValueOpcode::SharedAtomicDec32, false); case Decoder::Opcode::DS_DEC_RTN_U32: return DS_ATOMIC(inst, IR::ValueOpcode::SharedAtomicDec32, true); case Decoder::Opcode::DS_MIN_I32: diff --git a/tests/ShaderRecompilerComputeTests.cpp b/tests/ShaderRecompilerComputeTests.cpp index 80a30cf08..0fc8c8a3c 100644 --- a/tests/ShaderRecompilerComputeTests.cpp +++ b/tests/ShaderRecompilerComputeTests.cpp @@ -24935,10 +24935,12 @@ TestCase DsAtomicNoReturnVariants() { std::vector code; AppendVMovU32(&code, 1, 0); - const u32 initial[] = {10, 10, 0xfffffff0u, 0xfffffff0u, 10, - 10, 0xf0f0u, 0xf000u, 0xf00fu}; - const u32 values[] = {5, 3, 5, 5, 5, 20, 0x0ff0u, 0x0f00u, 0x00ffu}; - const u32 ops[] = {0x00, 0x01, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b}; + const u32 initial[] = {10, 10, 2, 1, 0, 3, 9, 0xfffffff0u, 0xfffffff0u, + 10, 10, 0xf0f0u, 0xf000u, 0xf00fu}; + const u32 values[] = {5, 3, 2, 5, 2, 5, 5, 5, 5, + 5, 20, 0x0ff0u, 0x0f00u, 0x00ffu}; + const u32 ops[] = {0x00, 0x01, 0x03, 0x03, 0x04, 0x04, 0x04, + 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b}; for (u32 i = 0; i < static_cast(std::size(values)); i++) { AppendVMovLiteral(&code, 2, initial[i]); code.push_back(EncodeDs0(0x0d, i * 4u)); @@ -24956,12 +24958,14 @@ TestCase DsAtomicNoReturnVariants() { return {"DsAtomicNoReturnVariants", code, - std::vector(9, 0), - {15, 7, 0xfffffff0u, 5, 5, 20, 0x00f0u, 0xff00u, 0xf0f0u}, + std::vector(14, 0), + {15, 7, 0, 2, 2, 2, 5, 0xfffffff0u, 5, 5, 20, 0x00f0u, 0xff00u, + 0xf0f0u}, {O::V_MOV_B32, O::DS_WRITE_B32, O::DS_ADD_U32, O::DS_SUB_U32, - O::DS_MIN_I32, O::DS_MAX_I32, O::DS_MIN_U32, O::DS_MAX_U32, - O::DS_AND_B32, O::DS_OR_B32, O::DS_XOR_B32, O::DS_READ_B32, - O::BUFFER_STORE_DWORD, O::S_ENDPGM}}; + O::DS_INC_U32, O::DS_DEC_U32, O::DS_MIN_I32, O::DS_MAX_I32, + O::DS_MIN_U32, O::DS_MAX_U32, O::DS_AND_B32, O::DS_OR_B32, + O::DS_XOR_B32, O::DS_READ_B32, O::BUFFER_STORE_DWORD, + O::S_ENDPGM}}; } TestCase DsAtomicReturnVariants() {