diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_atomic.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_atomic.cpp index fe2d64d2f..16270a090 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_atomic.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_atomic.cpp @@ -74,7 +74,7 @@ Id BufferAtomicU32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id if (const Id offset = buffer.Offset(PointerSize::B32); Sirit::ValidId(offset)) { address = ctx.OpIAdd(ctx.U32[1], address, offset); } - const auto [id, pointer_type] = buffer.Alias(PointerType::U32); + const auto [id, pointer_type] = buffer.Alias(is_float ? PointerType::F32 : PointerType::U32); const Id ptr = ctx.OpAccessChain(pointer_type, id, ctx.u32_zero_value, address); const auto [scope, semantics]{AtomicArgs(ctx)}; return AccessBoundsCheck<32, 1, is_float>(ctx, address, buffer.Size(PointerSize::B32), [&] { diff --git a/src/shader_recompiler/frontend/translate/vector_memory.cpp b/src/shader_recompiler/frontend/translate/vector_memory.cpp index ffb21a23b..668821201 100644 --- a/src/shader_recompiler/frontend/translate/vector_memory.cpp +++ b/src/shader_recompiler/frontend/translate/vector_memory.cpp @@ -113,9 +113,9 @@ void Translator::EmitVectorMemory(const GcnInst& inst) { case Opcode::BUFFER_ATOMIC_DEC: return BUFFER_ATOMIC(AtomicOp::Dec, inst); case Opcode::BUFFER_ATOMIC_FMIN: - return BUFFER_ATOMIC(AtomicOp::Fmin, inst); + return BUFFER_ATOMIC(AtomicOp::Fmin, inst); case Opcode::BUFFER_ATOMIC_FMAX: - return BUFFER_ATOMIC(AtomicOp::Fmax, inst); + return BUFFER_ATOMIC(AtomicOp::Fmax, inst); // MIMG // Image load operations @@ -399,6 +399,8 @@ void Translator::BUFFER_ATOMIC(AtomicOp op, const GcnInst& inst) { IR::Value vdata_val = [&] { if constexpr (std::is_same_v) { return ir.GetVectorReg(vdata); + } else if constexpr (std::is_same_v) { + return ir.GetVectorReg(vdata); } else if constexpr (std::is_same_v) { return ir.PackUint2x32( ir.CompositeConstruct(ir.GetVectorReg(vdata), @@ -449,7 +451,11 @@ void Translator::BUFFER_ATOMIC(AtomicOp op, const GcnInst& inst) { }(); if (mubuf.glc) { - ir.SetVectorReg(vdata, IR::U32{original_val}); + if constexpr (std::is_same_v) { + UNREACHABLE(); + } else { + ir.SetVectorReg(vdata, T{original_val}); + } } } diff --git a/src/shader_recompiler/ir/opcodes.inc b/src/shader_recompiler/ir/opcodes.inc index 34bddb015..3b907360c 100644 --- a/src/shader_recompiler/ir/opcodes.inc +++ b/src/shader_recompiler/ir/opcodes.inc @@ -137,12 +137,12 @@ OPCODE(BufferAtomicSMin32, U32, Opaq OPCODE(BufferAtomicSMin64, U64, Opaque, Opaque, U64 ) OPCODE(BufferAtomicUMin32, U32, Opaque, Opaque, U32 ) OPCODE(BufferAtomicUMin64, U64, Opaque, Opaque, U64 ) -OPCODE(BufferAtomicFMin32, U32, Opaque, Opaque, F32 ) +OPCODE(BufferAtomicFMin32, F32, Opaque, Opaque, F32 ) OPCODE(BufferAtomicSMax32, U32, Opaque, Opaque, U32 ) OPCODE(BufferAtomicSMax64, U64, Opaque, Opaque, U64 ) OPCODE(BufferAtomicUMax32, U32, Opaque, Opaque, U32 ) OPCODE(BufferAtomicUMax64, U64, Opaque, Opaque, U64 ) -OPCODE(BufferAtomicFMax32, U32, Opaque, Opaque, F32 ) +OPCODE(BufferAtomicFMax32, F32, Opaque, Opaque, F32 ) OPCODE(BufferAtomicInc32, U32, Opaque, Opaque, ) OPCODE(BufferAtomicDec32, U32, Opaque, Opaque, ) OPCODE(BufferAtomicAnd32, U32, Opaque, Opaque, U32, ) diff --git a/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp b/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp index 312f818ba..12d8d0e02 100644 --- a/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp +++ b/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp @@ -139,6 +139,9 @@ IR::Type BufferDataType(const IR::Inst& inst, AmdGpu::NumberFormat num_format) { case IR::Opcode::BufferAtomicUMax64: case IR::Opcode::BufferAtomicUMin64: return IR::Type::U64; + case IR::Opcode::BufferAtomicFMax32: + case IR::Opcode::BufferAtomicFMin32: + return IR::Type::F32; case IR::Opcode::LoadBufferFormatF32: case IR::Opcode::StoreBufferFormatF32: // Formatted buffer loads can use a variety of types.