diff --git a/src/shader_recompiler/frontend/translate/data_share.cpp b/src/shader_recompiler/frontend/translate/data_share.cpp index e9680bfe1..7b1c2a708 100644 --- a/src/shader_recompiler/frontend/translate/data_share.cpp +++ b/src/shader_recompiler/frontend/translate/data_share.cpp @@ -123,7 +123,6 @@ void Translator::DS_ADD_U32(const GcnInst& inst) { const IR::U32 addr_offset = ir.IAdd(addr, offset); const IR::U32 value = ir.SharedAtomicIAdd(addr_offset, data); - ir.WriteShared(32, value, addr_offset); SetDst(inst.dst[0], value); } @@ -134,8 +133,7 @@ void Translator::DS_MIN_U32(const GcnInst& inst) { const IR::U32 offset = ir.Imm32(u32(inst.control.ds.offset0)); const IR::U32 addr_offset = ir.IAdd(addr, offset); - const IR::U32 value = ir.SharedAtomicUMax(addr_offset, data); - ir.WriteShared(32, value, addr_offset); + const IR::U32 value = ir.SharedAtomicIMax(addr_offset, data, false); SetDst(inst.dst[0], value); } @@ -146,8 +144,7 @@ void Translator::DS_MAX_U32(const GcnInst& inst) { const IR::U32 offset = ir.Imm32(u32(inst.control.ds.offset0)); const IR::U32 addr_offset = ir.IAdd(addr, offset); - const IR::U32 value = ir.SharedAtomicUMax(addr_offset, data); - ir.WriteShared(32, value, addr_offset); + const IR::U32 value = ir.SharedAtomicIMax(addr_offset, data, false); SetDst(inst.dst[0], value); } diff --git a/src/shader_recompiler/frontend/translate/vector_memory.cpp b/src/shader_recompiler/frontend/translate/vector_memory.cpp index 7cca2d9e4..097f47a98 100644 --- a/src/shader_recompiler/frontend/translate/vector_memory.cpp +++ b/src/shader_recompiler/frontend/translate/vector_memory.cpp @@ -437,6 +437,7 @@ void Translator::BUFFER_STORE_FORMAT(u32 num_dwords, bool is_typed, bool is_form void Translator::BUFFER_ATOMIC(u32 num_dwords, AtomicOp op, const GcnInst& inst) { const auto& mtbuf = inst.control.mtbuf; const IR::VectorReg vaddr{inst.src[0].code}; + const IR::VectorReg vdata{inst.src[1].code}; const IR::ScalarReg sharp{inst.src[2].code * 4}; const IR::Value address = [&] -> IR::Value { if (mtbuf.idxen && mtbuf.offen) { @@ -459,7 +460,7 @@ void Translator::BUFFER_ATOMIC(u32 num_dwords, AtomicOp op, const GcnInst& inst) ir.CompositeConstruct(ir.GetScalarReg(sharp), ir.GetScalarReg(sharp + 1), ir.GetScalarReg(sharp + 2), ir.GetScalarReg(sharp + 3)); - const IR::Value value = ir.LoadBufferFormat(num_dwords, handle, address, info); + const IR::Value value = ir.GetVectorReg(vdata); const IR::Value result = [&] { switch (op) { @@ -470,11 +471,11 @@ void Translator::BUFFER_ATOMIC(u32 num_dwords, AtomicOp op, const GcnInst& inst) case AtomicOp::Smin: return ir.BufferAtomicIMin(handle, address, value, true, info); case AtomicOp::Umin: - return ir.BufferAtomicUMin(handle, address, value, info); + return ir.BufferAtomicIMin(handle, address, value, false, info); case AtomicOp::Smax: return ir.BufferAtomicIMax(handle, address, value, true, info); case AtomicOp::Umax: - return ir.BufferAtomicUMax(handle, address, value, info); + return ir.BufferAtomicIMax(handle, address, value, false, info); case AtomicOp::And: return ir.BufferAtomicAnd(handle, address, value, info); case AtomicOp::Or: @@ -490,9 +491,9 @@ void Translator::BUFFER_ATOMIC(u32 num_dwords, AtomicOp op, const GcnInst& inst) } }(); - // TODO: Check if unused - // const IR::VectorReg dst_reg{inst.src[1].code}; - ir.StoreBuffer(num_dwords, handle, address, value, info); + if (mtbuf.glc) { + ir.SetVectorReg(vdata, IR::U32{result}); + } } void Translator::IMAGE_GET_LOD(const GcnInst& inst) { diff --git a/src/shader_recompiler/ir/ir_emitter.cpp b/src/shader_recompiler/ir/ir_emitter.cpp index 1d9c53443..e13f0f439 100644 --- a/src/shader_recompiler/ir/ir_emitter.cpp +++ b/src/shader_recompiler/ir/ir_emitter.cpp @@ -298,28 +298,14 @@ U32U64 IREmitter::SharedAtomicIAdd(const U32U64& a, const U32U64& b) { } } -U32 IREmitter::SharedAtomicSMin(const U32& a, const U32& b) { - return Inst(Opcode::SharedAtomicSMin32, a, b); -} - -U32 IREmitter::SharedAtomicUMin(const U32& a, const U32& b) { - return Inst(Opcode::SharedAtomicUMin32, a, b); -} - U32 IREmitter::SharedAtomicIMin(const U32& a, const U32& b, bool is_signed) { - return is_signed ? SharedAtomicSMin(a, b) : SharedAtomicUMin(a, b); -} - -U32 IREmitter::SharedAtomicSMax(const U32& a, const U32& b) { - return Inst(Opcode::SharedAtomicSMax32, a, b); -} - -U32 IREmitter::SharedAtomicUMax(const U32& a, const U32& b) { - return Inst(Opcode::SharedAtomicUMax32, a, b); + return is_signed ? Inst(Opcode::SharedAtomicSMin32, a, b) + : Inst(Opcode::SharedAtomicUMin32, a, b); } U32 IREmitter::SharedAtomicIMax(const U32& a, const U32& b, bool is_signed) { - return is_signed ? SharedAtomicSMax(a, b) : SharedAtomicUMax(a, b); + return is_signed ? Inst(Opcode::SharedAtomicSMax32, a, b) + : Inst(Opcode::SharedAtomicUMax32, a, b); } U32 IREmitter::ReadConst(const Value& base, const U32& offset) { @@ -388,36 +374,16 @@ Value IREmitter::BufferAtomicIAdd(const Value& handle, const Value& address, con return Inst(Opcode::BufferAtomicIAdd32, Flags{info}, handle, address, value); } -Value IREmitter::BufferAtomicSMin(const Value& handle, const Value& address, const Value& value, - BufferInstInfo info) { - return Inst(Opcode::BufferAtomicSMin32, Flags{info}, handle, address, value); -} - -Value IREmitter::BufferAtomicUMin(const Value& handle, const Value& address, const Value& value, - BufferInstInfo info) { - return Inst(Opcode::BufferAtomicUMin32, Flags{info}, handle, address, value); -} - Value IREmitter::BufferAtomicIMin(const Value& handle, const Value& address, const Value& value, bool is_signed, BufferInstInfo info) { - return is_signed ? BufferAtomicSMin(handle, address, value, info) - : BufferAtomicUMin(handle, address, value, info); -} - -Value IREmitter::BufferAtomicSMax(const Value& handle, const Value& address, const Value& value, - BufferInstInfo info) { - return Inst(Opcode::BufferAtomicSMax32, Flags{info}, handle, address, value); -} - -Value IREmitter::BufferAtomicUMax(const Value& handle, const Value& address, const Value& value, - BufferInstInfo info) { - return Inst(Opcode::BufferAtomicUMax32, Flags{info}, handle, address, value); + return is_signed ? Inst(Opcode::BufferAtomicSMin32, Flags{info}, handle, address, value) + : Inst(Opcode::BufferAtomicUMin32, Flags{info}, handle, address, value); } Value IREmitter::BufferAtomicIMax(const Value& handle, const Value& address, const Value& value, bool is_signed, BufferInstInfo info) { - return is_signed ? BufferAtomicSMax(handle, address, value, info) - : BufferAtomicUMax(handle, address, value, info); + return is_signed ? Inst(Opcode::BufferAtomicSMax32, Flags{info}, handle, address, value) + : Inst(Opcode::BufferAtomicUMax32, Flags{info}, handle, address, value); } Value IREmitter::BufferAtomicInc(const Value& handle, const Value& address, const Value& value, diff --git a/src/shader_recompiler/ir/ir_emitter.h b/src/shader_recompiler/ir/ir_emitter.h index 6f9592b64..f2079fc82 100644 --- a/src/shader_recompiler/ir/ir_emitter.h +++ b/src/shader_recompiler/ir/ir_emitter.h @@ -85,11 +85,7 @@ public: void WriteShared(int bit_size, const Value& value, const U32& offset); [[nodiscard]] U32U64 SharedAtomicIAdd(const U32U64& a, const U32U64& b); - [[nodiscard]] U32 SharedAtomicSMin(const U32& a, const U32& b); - [[nodiscard]] U32 SharedAtomicUMin(const U32& a, const U32& b); [[nodiscard]] U32 SharedAtomicIMin(const U32& a, const U32& b, bool is_signed); - [[nodiscard]] U32 SharedAtomicSMax(const U32& a, const U32& b); - [[nodiscard]] U32 SharedAtomicUMax(const U32& a, const U32& b); [[nodiscard]] U32 SharedAtomicIMax(const U32& a, const U32& b, bool is_signed); [[nodiscard]] U32 ReadConst(const Value& base, const U32& offset); @@ -106,16 +102,8 @@ public: [[nodiscard]] Value BufferAtomicIAdd(const Value& handle, const Value& a, const Value& b, BufferInstInfo info); - [[nodiscard]] Value BufferAtomicSMin(const Value& handle, const Value& a, const Value& b, - BufferInstInfo info); - [[nodiscard]] Value BufferAtomicUMin(const Value& handle, const Value& a, const Value& b, - BufferInstInfo info); [[nodiscard]] Value BufferAtomicIMin(const Value& handle, const Value& a, const Value& b, bool is_signed, BufferInstInfo info); - [[nodiscard]] Value BufferAtomicSMax(const Value& handle, const Value& a, const Value& b, - BufferInstInfo info); - [[nodiscard]] Value BufferAtomicUMax(const Value& handle, const Value& a, const Value& b, - BufferInstInfo info); [[nodiscard]] Value BufferAtomicIMax(const Value& handle, const Value& a, const Value& b, bool is_signed, BufferInstInfo info); [[nodiscard]] Value BufferAtomicInc(const Value& handle, const Value& address,