mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-07-22 10:04:39 +00:00
buffer_atomic_imax_x2
This commit is contained in:
parent
7f727340aa
commit
3c13ad8bc4
@ -226,10 +226,18 @@ Id EmitBufferAtomicSMax32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id addre
|
||||
return BufferAtomicU32(ctx, inst, handle, address, value, &Sirit::Module::OpAtomicSMax);
|
||||
}
|
||||
|
||||
Id EmitBufferAtomicSMax64(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) {
|
||||
return BufferAtomicU64(ctx, inst, handle, address, value, &Sirit::Module::OpAtomicSMax);
|
||||
}
|
||||
|
||||
Id EmitBufferAtomicUMax32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) {
|
||||
return BufferAtomicU32(ctx, inst, handle, address, value, &Sirit::Module::OpAtomicUMax);
|
||||
}
|
||||
|
||||
Id EmitBufferAtomicUMax64(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) {
|
||||
return BufferAtomicU64(ctx, inst, handle, address, value, &Sirit::Module::OpAtomicUMax);
|
||||
}
|
||||
|
||||
Id EmitBufferAtomicFMax32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) {
|
||||
if (ctx.profile.supports_buffer_fp32_atomic_min_max) {
|
||||
return BufferAtomicU32<true>(ctx, inst, handle, address, value,
|
||||
|
@ -94,7 +94,9 @@ Id EmitBufferAtomicSMin32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id addre
|
||||
Id EmitBufferAtomicUMin32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value);
|
||||
Id EmitBufferAtomicFMin32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value);
|
||||
Id EmitBufferAtomicSMax32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value);
|
||||
Id EmitBufferAtomicSMax64(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value);
|
||||
Id EmitBufferAtomicUMax32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value);
|
||||
Id EmitBufferAtomicUMax64(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value);
|
||||
Id EmitBufferAtomicFMax32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value);
|
||||
Id EmitBufferAtomicInc32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address);
|
||||
Id EmitBufferAtomicDec32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address);
|
||||
|
@ -291,6 +291,7 @@ public:
|
||||
void BUFFER_LOAD(u32 num_dwords, bool is_inst_typed, bool is_buffer_typed, const GcnInst& inst);
|
||||
void BUFFER_STORE(u32 num_dwords, bool is_inst_typed, bool is_buffer_typed,
|
||||
const GcnInst& inst);
|
||||
template <typename T = IR::U32>
|
||||
void BUFFER_ATOMIC(AtomicOp op, const GcnInst& inst);
|
||||
|
||||
// Image Memory
|
||||
|
@ -78,8 +78,12 @@ void Translator::EmitVectorMemory(const GcnInst& inst) {
|
||||
return BUFFER_ATOMIC(AtomicOp::Umin, inst);
|
||||
case Opcode::BUFFER_ATOMIC_SMAX:
|
||||
return BUFFER_ATOMIC(AtomicOp::Smax, inst);
|
||||
case Opcode::BUFFER_ATOMIC_SMAX_X2:
|
||||
return BUFFER_ATOMIC<IR::U64>(AtomicOp::Smax, inst);
|
||||
case Opcode::BUFFER_ATOMIC_UMAX:
|
||||
return BUFFER_ATOMIC(AtomicOp::Umax, inst);
|
||||
case Opcode::BUFFER_ATOMIC_UMAX_X2:
|
||||
return BUFFER_ATOMIC<IR::U64>(AtomicOp::Umax, inst);
|
||||
case Opcode::BUFFER_ATOMIC_AND:
|
||||
return BUFFER_ATOMIC(AtomicOp::And, inst);
|
||||
case Opcode::BUFFER_ATOMIC_OR:
|
||||
@ -304,6 +308,7 @@ void Translator::BUFFER_STORE(u32 num_dwords, bool is_inst_typed, bool is_buffer
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Translator::BUFFER_ATOMIC(AtomicOp op, const GcnInst& inst) {
|
||||
const auto& mubuf = inst.control.mubuf;
|
||||
const IR::VectorReg vaddr{inst.src[0].code};
|
||||
@ -328,7 +333,17 @@ void Translator::BUFFER_ATOMIC(AtomicOp op, const GcnInst& inst) {
|
||||
buffer_info.globally_coherent.Assign(mubuf.glc);
|
||||
buffer_info.system_coherent.Assign(mubuf.slc);
|
||||
|
||||
IR::Value vdata_val = ir.GetVectorReg<Shader::IR::U32>(vdata);
|
||||
IR::Value vdata_val = [&] {
|
||||
if constexpr (std::is_same_v<T, IR::U32>) {
|
||||
return ir.GetVectorReg<Shader::IR::U32>(vdata);
|
||||
} else if constexpr (std::is_same_v<T, IR::U64>) {
|
||||
return ir.PackUint2x32(
|
||||
ir.CompositeConstruct(ir.GetVectorReg<Shader::IR::U32>(vdata),
|
||||
ir.GetVectorReg<Shader::IR::U32>(vdata + 1)));
|
||||
} else {
|
||||
static_assert(false, "buffer_atomic: type not supported");
|
||||
}
|
||||
}();
|
||||
const IR::Value handle =
|
||||
ir.CompositeConstruct(ir.GetScalarReg(srsrc), ir.GetScalarReg(srsrc + 1),
|
||||
ir.GetScalarReg(srsrc + 2), ir.GetScalarReg(srsrc + 3));
|
||||
|
@ -511,8 +511,16 @@ Value IREmitter::BufferAtomicFMin(const Value& handle, const Value& address, con
|
||||
|
||||
Value IREmitter::BufferAtomicIMax(const Value& handle, const Value& address, const Value& value,
|
||||
bool is_signed, BufferInstInfo info) {
|
||||
return is_signed ? Inst(Opcode::BufferAtomicSMax32, Flags{info}, handle, address, value)
|
||||
: Inst(Opcode::BufferAtomicUMax32, Flags{info}, handle, address, value);
|
||||
switch (value.Type()) {
|
||||
case Type::U32:
|
||||
return is_signed ? Inst(Opcode::BufferAtomicSMax32, Flags{info}, handle, address, value)
|
||||
: Inst(Opcode::BufferAtomicUMax32, Flags{info}, handle, address, value);
|
||||
case Type::U64:
|
||||
return is_signed ? Inst(Opcode::BufferAtomicSMax64, Flags{info}, handle, address, value)
|
||||
: Inst(Opcode::BufferAtomicUMax64, Flags{info}, handle, address, value);
|
||||
default:
|
||||
ThrowInvalidType(value.Type());
|
||||
}
|
||||
}
|
||||
|
||||
Value IREmitter::BufferAtomicFMax(const Value& handle, const Value& address, const Value& value,
|
||||
|
@ -73,7 +73,9 @@ bool Inst::MayHaveSideEffects() const noexcept {
|
||||
case Opcode::BufferAtomicUMin32:
|
||||
case Opcode::BufferAtomicFMin32:
|
||||
case Opcode::BufferAtomicSMax32:
|
||||
case Opcode::BufferAtomicSMax64:
|
||||
case Opcode::BufferAtomicUMax32:
|
||||
case Opcode::BufferAtomicUMax64:
|
||||
case Opcode::BufferAtomicFMax32:
|
||||
case Opcode::BufferAtomicInc32:
|
||||
case Opcode::BufferAtomicDec32:
|
||||
|
@ -127,7 +127,9 @@ OPCODE(BufferAtomicSMin32, U32, Opaq
|
||||
OPCODE(BufferAtomicUMin32, U32, Opaque, Opaque, U32 )
|
||||
OPCODE(BufferAtomicFMin32, U32, 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(BufferAtomicInc32, U32, Opaque, Opaque, )
|
||||
OPCODE(BufferAtomicDec32, U32, Opaque, Opaque, )
|
||||
|
@ -23,7 +23,9 @@ bool IsBufferAtomic(const IR::Inst& inst) {
|
||||
case IR::Opcode::BufferAtomicUMin32:
|
||||
case IR::Opcode::BufferAtomicFMin32:
|
||||
case IR::Opcode::BufferAtomicSMax32:
|
||||
case IR::Opcode::BufferAtomicSMax64:
|
||||
case IR::Opcode::BufferAtomicUMax32:
|
||||
case IR::Opcode::BufferAtomicUMax64:
|
||||
case IR::Opcode::BufferAtomicFMax32:
|
||||
case IR::Opcode::BufferAtomicInc32:
|
||||
case IR::Opcode::BufferAtomicDec32:
|
||||
|
Loading…
Reference in New Issue
Block a user