mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2026-03-27 13:50:06 -06:00
Recompiler: Implement IMAGE_ATOMIC_CMPSWAP (#4109)
* To implement ImageAtomicCmpSwap ...but it doesn't work, so here it shall stay. * a fix * Clang * Add to MayHaveSideEffects I missed this while digging through IR code.
This commit is contained in:
parent
df6bb8562e
commit
85476e55ea
@ -140,6 +140,15 @@ Id ImageAtomicF32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id va
|
||||
const auto [scope, semantics]{AtomicArgs(ctx)};
|
||||
return (ctx.*atomic_func)(ctx.F32[1], pointer, scope, semantics, value);
|
||||
}
|
||||
|
||||
Id ImageAtomicU32CmpSwap(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id value,
|
||||
Id cmp_value,
|
||||
Id (Sirit::Module::*atomic_func)(Id, Id, Id, Id, Id, Id, Id)) {
|
||||
const auto& texture = ctx.images[handle & 0xFFFF];
|
||||
const Id pointer{ctx.OpImageTexelPointer(ctx.image_u32, texture.id, coords, ctx.ConstU32(0U))};
|
||||
const auto [scope, semantics]{AtomicArgs(ctx)};
|
||||
return (ctx.*atomic_func)(ctx.F32[1], pointer, scope, semantics, semantics, value, cmp_value);
|
||||
}
|
||||
} // Anonymous namespace
|
||||
|
||||
Id EmitSharedAtomicIAdd32(EmitContext& ctx, Id offset, Id value) {
|
||||
@ -420,6 +429,12 @@ Id EmitImageAtomicExchange32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id co
|
||||
return ImageAtomicU32(ctx, inst, handle, coords, value, &Sirit::Module::OpAtomicExchange);
|
||||
}
|
||||
|
||||
Id EmitImageAtomicCmpSwap32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id value,
|
||||
Id cmp_value) {
|
||||
return ImageAtomicU32CmpSwap(ctx, inst, handle, coords, value, cmp_value,
|
||||
&Sirit::Module::OpAtomicCompareExchange);
|
||||
}
|
||||
|
||||
Id EmitDataAppend(EmitContext& ctx, u32 gds_addr, u32 binding) {
|
||||
const auto& buffer = ctx.buffers[binding];
|
||||
const auto [id, pointer_type] = buffer.Alias(PointerType::U32);
|
||||
|
||||
@ -456,6 +456,8 @@ Id EmitImageAtomicAnd32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords,
|
||||
Id EmitImageAtomicOr32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id value);
|
||||
Id EmitImageAtomicXor32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id value);
|
||||
Id EmitImageAtomicExchange32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id value);
|
||||
Id EmitImageAtomicCmpSwap32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value,
|
||||
Id cmp_value);
|
||||
Id EmitCubeFaceIndex(EmitContext& ctx, IR::Inst* inst, Id cube_coords);
|
||||
Id EmitLaneId(EmitContext& ctx);
|
||||
Id EmitWarpId(EmitContext& ctx);
|
||||
|
||||
@ -3430,8 +3430,8 @@ constexpr std::array<InstFormat, 112> InstructionFormatMIMG = {{
|
||||
{InstClass::VectorMemImgNoSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32,
|
||||
ScalarType::Uint32},
|
||||
// 16 = IMAGE_ATOMIC_CMPSWAP
|
||||
{InstClass::VectorMemImgNoSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Undefined,
|
||||
ScalarType::Undefined},
|
||||
{InstClass::VectorMemImgNoSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32,
|
||||
ScalarType::Uint32},
|
||||
// 17 = IMAGE_ATOMIC_ADD
|
||||
{InstClass::VectorMemImgNoSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32,
|
||||
ScalarType::Uint32},
|
||||
|
||||
@ -137,6 +137,8 @@ void Translator::EmitVectorMemory(const GcnInst& inst) {
|
||||
// Image atomic operations
|
||||
case Opcode::IMAGE_ATOMIC_SWAP:
|
||||
return IMAGE_ATOMIC(AtomicOp::Swap, inst);
|
||||
case Opcode::IMAGE_ATOMIC_CMPSWAP:
|
||||
return IMAGE_ATOMIC(AtomicOp::CmpSwap, inst);
|
||||
case Opcode::IMAGE_ATOMIC_ADD:
|
||||
return IMAGE_ATOMIC(AtomicOp::Add, inst);
|
||||
case Opcode::IMAGE_ATOMIC_SMIN:
|
||||
@ -520,6 +522,10 @@ void Translator::IMAGE_ATOMIC(AtomicOp op, const GcnInst& inst) {
|
||||
switch (op) {
|
||||
case AtomicOp::Swap:
|
||||
return ir.ImageAtomicExchange(handle, body, value, {});
|
||||
case AtomicOp::CmpSwap: {
|
||||
const IR::Value cmp_val = ir.GetVectorReg(val_reg + 1);
|
||||
return ir.ImageAtomicCmpSwap(handle, body, value, cmp_val, info);
|
||||
}
|
||||
case AtomicOp::Add:
|
||||
return ir.ImageAtomicIAdd(handle, body, value, info);
|
||||
case AtomicOp::Smin:
|
||||
|
||||
@ -2055,6 +2055,11 @@ Value IREmitter::ImageAtomicExchange(const Value& handle, const Value& coords, c
|
||||
return Inst(Opcode::ImageAtomicExchange32, Flags{info}, handle, coords, value);
|
||||
}
|
||||
|
||||
Value IREmitter::ImageAtomicCmpSwap(const Value& handle, const Value& coords, const Value& value,
|
||||
const Value& cmp_value, TextureInstInfo info) {
|
||||
return Inst(Opcode::ImageAtomicCmpSwap32, Flags{info}, handle, coords, value, cmp_value);
|
||||
}
|
||||
|
||||
Value IREmitter::ImageSampleRaw(const Value& image_handle, const Value& sampler_handle,
|
||||
const Value& address1, const Value& address2, const Value& address3,
|
||||
const Value& address4, TextureInstInfo info) {
|
||||
|
||||
@ -360,6 +360,9 @@ public:
|
||||
TextureInstInfo info);
|
||||
[[nodiscard]] Value ImageAtomicExchange(const Value& handle, const Value& coords,
|
||||
const Value& value, TextureInstInfo info);
|
||||
[[nodiscard]] Value ImageAtomicCmpSwap(const Value& handle, const Value& coords,
|
||||
const Value& value, const Value& cmp_value,
|
||||
TextureInstInfo info);
|
||||
|
||||
[[nodiscard]] Value ImageSampleRaw(const Value& image_handle, const Value& sampler_handle,
|
||||
const Value& address1, const Value& address2,
|
||||
|
||||
@ -123,6 +123,7 @@ bool Inst::MayHaveSideEffects() const noexcept {
|
||||
case Opcode::ImageAtomicOr32:
|
||||
case Opcode::ImageAtomicXor32:
|
||||
case Opcode::ImageAtomicExchange32:
|
||||
case Opcode::ImageAtomicCmpSwap32:
|
||||
case Opcode::DebugPrint:
|
||||
case Opcode::EmitVertex:
|
||||
case Opcode::EmitPrimitive:
|
||||
|
||||
@ -436,6 +436,7 @@ OPCODE(ImageAtomicAnd32, U32, Opaq
|
||||
OPCODE(ImageAtomicOr32, U32, Opaque, Opaque, U32, )
|
||||
OPCODE(ImageAtomicXor32, U32, Opaque, Opaque, U32, )
|
||||
OPCODE(ImageAtomicExchange32, U32, Opaque, Opaque, U32, )
|
||||
OPCODE(ImageAtomicCmpSwap32, U32, Opaque, Opaque, U32, U32, )
|
||||
|
||||
// Cube operations - optional, usable if profile.supports_native_cube_calc
|
||||
OPCODE(CubeFaceIndex, F32, F32x3, )
|
||||
|
||||
@ -214,6 +214,7 @@ bool IsImageAtomicInstruction(const IR::Inst& inst) {
|
||||
case IR::Opcode::ImageAtomicOr32:
|
||||
case IR::Opcode::ImageAtomicXor32:
|
||||
case IR::Opcode::ImageAtomicExchange32:
|
||||
case IR::Opcode::ImageAtomicCmpSwap32:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user