Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions src/shader_recompiler/backend/spirv/emit_spirv_atomic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,21 @@ Id BufferAtomicU32CmpSwap(EmitContext& ctx, IR::Inst* inst, u32 handle, Id addre
});
}

Id BufferAtomicF32CmpSwap(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value,
Id cmp_value,
Id (Sirit::Module::*atomic_func)(Id, Id, Id, Id, Id, Id, Id)) {
const auto& buffer = ctx.buffers[handle];
if (const Id offset = buffer.Offset(PointerSize::B32); Sirit::ValidId(offset)) {
address = ctx.OpIAdd(ctx.F32[1], address, offset);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Address is not F32

}
const auto [id, pointer_type] = buffer.Alias(PointerType::U32);
const Id ptr = ctx.OpAccessChain(pointer_type, id, ctx.f32_zero_value, address);
const auto [scope, semantics]{AtomicArgs(ctx)};
return AccessBoundsCheck<32>(ctx, address, buffer.Size(PointerSize::B32), [&] {
return (ctx.*atomic_func)(ctx.F32[1], ptr, scope, semantics, semantics, value, cmp_value);
});
}

Id BufferAtomicU64(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value,
Id (Sirit::Module::*atomic_func)(Id, Id, Id, Id, Id)) {
const auto& buffer = ctx.buffers[handle];
Expand Down Expand Up @@ -342,6 +357,12 @@ Id EmitBufferAtomicCmpSwap32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id ad
&Sirit::Module::OpAtomicCompareExchange);
}

Id EmitBufferAtomicFCmpSwap32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value,
Id cmp_value) {
return BufferAtomicF32CmpSwap(ctx, inst, handle, address, value, cmp_value,
&Sirit::Module::OpAtomicCompareExchange);
}

Id EmitImageAtomicIAdd32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id value) {
return ImageAtomicU32(ctx, inst, handle, coords, value, &Sirit::Module::OpAtomicIAdd);
}
Expand Down
2 changes: 2 additions & 0 deletions src/shader_recompiler/backend/spirv/emit_spirv_instructions.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ Id EmitBufferAtomicXor32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id addres
Id EmitBufferAtomicSwap32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value);
Id EmitBufferAtomicCmpSwap32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value,
Id cmp_value);
Id EmitBufferAtomicFCmpSwap32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value,
Id cmp_value);
Id EmitGetAttribute(EmitContext& ctx, IR::Attribute attr, u32 comp, u32 index);
Id EmitGetAttributeU32(EmitContext& ctx, IR::Attribute attr, u32 comp);
void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, Id value, u32 comp);
Expand Down
6 changes: 6 additions & 0 deletions src/shader_recompiler/frontend/translate/vector_memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ void Translator::EmitVectorMemory(const GcnInst& inst) {
return BUFFER_ATOMIC(AtomicOp::Fmin, inst);
case Opcode::BUFFER_ATOMIC_FMAX:
return BUFFER_ATOMIC(AtomicOp::Fmax, inst);
case Opcode::BUFFER_ATOMIC_FCMPSWAP:
return BUFFER_ATOMIC(AtomicOp::FCmpSwap, inst);

// MIMG
// Image load operations
Expand Down Expand Up @@ -415,6 +417,10 @@ void Translator::BUFFER_ATOMIC(AtomicOp op, const GcnInst& inst) {
const IR::Value cmp_val = ir.GetVectorReg(vdata + 1);
return ir.BufferAtomicCmpSwap(handle, address, vdata_val, cmp_val, buffer_info);
}
case AtomicOp::FCmpSwap: {
const IR::Value cmp_val = ir.GetVectorReg(vdata + 1);
return ir.BufferAtomicFCmpSwap(handle, address, vdata_val, cmp_val, buffer_info);
}
case AtomicOp::Add:
return ir.BufferAtomicIAdd(handle, address, vdata_val, buffer_info);
case AtomicOp::Smin:
Expand Down
5 changes: 5 additions & 0 deletions src/shader_recompiler/ir/ir_emitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -628,6 +628,11 @@ Value IREmitter::BufferAtomicCmpSwap(const Value& handle, const Value& address,
return Inst(Opcode::BufferAtomicCmpSwap32, Flags{info}, handle, address, vdata, cmp_value);
}

Value IREmitter::BufferAtomicFCmpSwap(const Value& handle, const Value& address, const Value& vdata,
const Value& cmp_value, BufferInstInfo info) {
return Inst(Opcode::BufferAtomicFCmpSwap32, Flags{info}, handle, address, vdata, cmp_value);
}

U32 IREmitter::DataAppend(const U32& counter) {
return Inst<U32>(Opcode::DataAppend, counter, Imm32(0));
}
Expand Down
3 changes: 3 additions & 0 deletions src/shader_recompiler/ir/ir_emitter.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,9 @@ class IREmitter {
[[nodiscard]] Value BufferAtomicCmpSwap(const Value& handle, const Value& address,
const Value& value, const Value& cmp_value,
BufferInstInfo info);
[[nodiscard]] Value BufferAtomicFCmpSwap(const Value& handle, const Value& address,
const Value& value, const Value& cmp_value,
BufferInstInfo info);

[[nodiscard]] U32 DataAppend(const U32& counter);
[[nodiscard]] U32 DataConsume(const U32& counter);
Expand Down
1 change: 1 addition & 0 deletions src/shader_recompiler/ir/microinstruction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ bool Inst::MayHaveSideEffects() const noexcept {
case Opcode::BufferAtomicXor32:
case Opcode::BufferAtomicSwap32:
case Opcode::BufferAtomicCmpSwap32:
case Opcode::BufferAtomicFCmpSwap32:
case Opcode::DataAppend:
case Opcode::DataConsume:
case Opcode::WriteSharedU16:
Expand Down
1 change: 1 addition & 0 deletions src/shader_recompiler/ir/opcodes.inc
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ OPCODE(BufferAtomicOr32, U32, Opaq
OPCODE(BufferAtomicXor32, U32, Opaque, Opaque, U32, )
OPCODE(BufferAtomicSwap32, U32, Opaque, Opaque, U32, )
OPCODE(BufferAtomicCmpSwap32, U32, Opaque, Opaque, U32, U32, )
OPCODE(BufferAtomicFCmpSwap32, U32, Opaque, Opaque, F32, F32, )

// Vector utility
OPCODE(CompositeConstructU32x2, U32x2, U32, U32, )
Expand Down
1 change: 1 addition & 0 deletions src/shader_recompiler/ir/passes/resource_tracking_pass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ bool IsBufferAtomic(const IR::Inst& inst) {
case IR::Opcode::BufferAtomicXor32:
case IR::Opcode::BufferAtomicSwap32:
case IR::Opcode::BufferAtomicCmpSwap32:
case IR::Opcode::BufferAtomicFCmpSwap32:
return true;
default:
return false;
Expand Down