mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-06-25 20:06:17 +00:00
BUFFER_ATOMIC_CMPSWAP (#3045)
This commit is contained in:
parent
952cef5a15
commit
ce84e80f65
6 changed files with 37 additions and 0 deletions
|
@ -68,6 +68,22 @@ Id BufferAtomicU32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Id BufferAtomicU32CmpSwap(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 (Sirit::ValidId(buffer.offset)) {
|
||||||
|
address = ctx.OpIAdd(ctx.U32[1], address, buffer.offset);
|
||||||
|
}
|
||||||
|
const Id index = ctx.OpShiftRightLogical(ctx.U32[1], address, ctx.ConstU32(2u));
|
||||||
|
const auto [id, pointer_type] = buffer[EmitContext::PointerType::U32];
|
||||||
|
const Id ptr = ctx.OpAccessChain(pointer_type, id, ctx.u32_zero_value, index);
|
||||||
|
const auto [scope, semantics]{AtomicArgs(ctx)};
|
||||||
|
return BufferAtomicU32BoundsCheck(ctx, index, buffer.size_dwords, [&] {
|
||||||
|
return (ctx.*atomic_func)(ctx.U32[1], ptr, scope, semantics, semantics, value, cmp_value);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Id ImageAtomicU32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id value,
|
Id ImageAtomicU32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id value,
|
||||||
Id (Sirit::Module::*atomic_func)(Id, Id, Id, Id, Id)) {
|
Id (Sirit::Module::*atomic_func)(Id, Id, Id, Id, Id)) {
|
||||||
const auto& texture = ctx.images[handle & 0xFFFF];
|
const auto& texture = ctx.images[handle & 0xFFFF];
|
||||||
|
@ -175,6 +191,12 @@ Id EmitBufferAtomicSwap32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id addre
|
||||||
return BufferAtomicU32(ctx, inst, handle, address, value, &Sirit::Module::OpAtomicExchange);
|
return BufferAtomicU32(ctx, inst, handle, address, value, &Sirit::Module::OpAtomicExchange);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Id EmitBufferAtomicCmpSwap32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value,
|
||||||
|
Id cmp_value) {
|
||||||
|
return BufferAtomicU32CmpSwap(ctx, inst, handle, address, value, cmp_value,
|
||||||
|
&Sirit::Module::OpAtomicCompareExchange);
|
||||||
|
}
|
||||||
|
|
||||||
Id EmitImageAtomicIAdd32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id value) {
|
Id EmitImageAtomicIAdd32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id value) {
|
||||||
return ImageAtomicU32(ctx, inst, handle, coords, value, &Sirit::Module::OpAtomicIAdd);
|
return ImageAtomicU32(ctx, inst, handle, coords, value, &Sirit::Module::OpAtomicIAdd);
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,6 +96,8 @@ Id EmitBufferAtomicAnd32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id addres
|
||||||
Id EmitBufferAtomicOr32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value);
|
Id EmitBufferAtomicOr32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value);
|
||||||
Id EmitBufferAtomicXor32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value);
|
Id EmitBufferAtomicXor32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value);
|
||||||
Id EmitBufferAtomicSwap32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value);
|
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 EmitGetAttribute(EmitContext& ctx, IR::Attribute attr, u32 comp, Id index);
|
Id EmitGetAttribute(EmitContext& ctx, IR::Attribute attr, u32 comp, Id index);
|
||||||
Id EmitGetAttributeU32(EmitContext& ctx, IR::Attribute attr, u32 comp);
|
Id EmitGetAttributeU32(EmitContext& ctx, IR::Attribute attr, u32 comp);
|
||||||
void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, Id value, u32 comp);
|
void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, Id value, u32 comp);
|
||||||
|
|
|
@ -331,6 +331,10 @@ void Translator::BUFFER_ATOMIC(AtomicOp op, const GcnInst& inst) {
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case AtomicOp::Swap:
|
case AtomicOp::Swap:
|
||||||
return ir.BufferAtomicSwap(handle, address, vdata_val, buffer_info);
|
return ir.BufferAtomicSwap(handle, address, vdata_val, buffer_info);
|
||||||
|
case AtomicOp::CmpSwap: {
|
||||||
|
IR::Value cmp_val = ir.GetVectorReg(vdata + 1);
|
||||||
|
return ir.BufferAtomicCmpSwap(handle, address, vdata_val, cmp_val, buffer_info);
|
||||||
|
}
|
||||||
case AtomicOp::Add:
|
case AtomicOp::Add:
|
||||||
return ir.BufferAtomicIAdd(handle, address, vdata_val, buffer_info);
|
return ir.BufferAtomicIAdd(handle, address, vdata_val, buffer_info);
|
||||||
case AtomicOp::Smin:
|
case AtomicOp::Smin:
|
||||||
|
|
|
@ -513,6 +513,11 @@ Value IREmitter::BufferAtomicSwap(const Value& handle, const Value& address, con
|
||||||
return Inst(Opcode::BufferAtomicSwap32, Flags{info}, handle, address, value);
|
return Inst(Opcode::BufferAtomicSwap32, Flags{info}, handle, address, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Value IREmitter::BufferAtomicCmpSwap(const Value& handle, const Value& address, const Value& vdata,
|
||||||
|
const Value& cmp_value, BufferInstInfo info) {
|
||||||
|
return Inst(Opcode::BufferAtomicCmpSwap32, Flags{info}, handle, address, vdata, cmp_value);
|
||||||
|
}
|
||||||
|
|
||||||
U32 IREmitter::DataAppend(const U32& counter) {
|
U32 IREmitter::DataAppend(const U32& counter) {
|
||||||
return Inst<U32>(Opcode::DataAppend, counter, Imm32(0));
|
return Inst<U32>(Opcode::DataAppend, counter, Imm32(0));
|
||||||
}
|
}
|
||||||
|
|
|
@ -150,6 +150,9 @@ public:
|
||||||
const Value& value, BufferInstInfo info);
|
const Value& value, BufferInstInfo info);
|
||||||
[[nodiscard]] Value BufferAtomicSwap(const Value& handle, const Value& address,
|
[[nodiscard]] Value BufferAtomicSwap(const Value& handle, const Value& address,
|
||||||
const Value& value, BufferInstInfo info);
|
const Value& value, BufferInstInfo info);
|
||||||
|
[[nodiscard]] Value BufferAtomicCmpSwap(const Value& handle, const Value& address,
|
||||||
|
const Value& value, const Value& cmp_value,
|
||||||
|
BufferInstInfo info);
|
||||||
|
|
||||||
[[nodiscard]] U32 DataAppend(const U32& counter);
|
[[nodiscard]] U32 DataAppend(const U32& counter);
|
||||||
[[nodiscard]] U32 DataConsume(const U32& counter);
|
[[nodiscard]] U32 DataConsume(const U32& counter);
|
||||||
|
|
|
@ -126,6 +126,7 @@ OPCODE(BufferAtomicAnd32, U32, Opaq
|
||||||
OPCODE(BufferAtomicOr32, U32, Opaque, Opaque, U32, )
|
OPCODE(BufferAtomicOr32, U32, Opaque, Opaque, U32, )
|
||||||
OPCODE(BufferAtomicXor32, U32, Opaque, Opaque, U32, )
|
OPCODE(BufferAtomicXor32, U32, Opaque, Opaque, U32, )
|
||||||
OPCODE(BufferAtomicSwap32, U32, Opaque, Opaque, U32, )
|
OPCODE(BufferAtomicSwap32, U32, Opaque, Opaque, U32, )
|
||||||
|
OPCODE(BufferAtomicCmpSwap32, U32, Opaque, Opaque, U32, U32, )
|
||||||
|
|
||||||
// Vector utility
|
// Vector utility
|
||||||
OPCODE(CompositeConstructU32x2, U32x2, U32, U32, )
|
OPCODE(CompositeConstructU32x2, U32x2, U32, U32, )
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue