mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-04-21 03:54:45 +00:00
Update vector_memory.cpp
This commit is contained in:
parent
5f93037aeb
commit
8c3eb0f4f7
1 changed files with 59 additions and 0 deletions
|
@ -381,4 +381,63 @@ void Translator::IMAGE_ATOMIC(AtomicOp op, const GcnInst& inst) {
|
|||
}
|
||||
}
|
||||
|
||||
void Translator::BUFFER_ATOMIC(AtomicOp op, const GcnInst& inst) {
|
||||
const auto& mtbuf = inst.control.mtbuf;
|
||||
IR::VectorReg val_reg{inst.dst[0].code};
|
||||
IR::VectorReg addr_reg{inst.src[0].code};
|
||||
const IR::ScalarReg sharp_reg{inst.src[2].code * 4};
|
||||
|
||||
// Load the value to be used in the atomic operation
|
||||
const IR::Value value = ir.GetVectorReg(val_reg);
|
||||
|
||||
// Construct the address value
|
||||
const IR::Value address = [&] -> IR::Value {
|
||||
if (mtbuf.idxen && mtbuf.offen) {
|
||||
return ir.CompositeConstruct(ir.GetVectorReg(addr_reg), ir.GetVectorReg(addr_reg + 1));
|
||||
}
|
||||
if (mtbuf.idxen || mtbuf.offen) {
|
||||
return ir.GetVectorReg(addr_reg);
|
||||
}
|
||||
return {};
|
||||
}();
|
||||
|
||||
// Construct the handle
|
||||
const IR::Value handle = ir.GetScalarReg(sharp_reg);
|
||||
|
||||
// Perform the atomic operation
|
||||
const IR::Value prev = [&] {
|
||||
switch (op) {
|
||||
case AtomicOp::Swap:
|
||||
return ir.ImageAtomicExchange(handle, address, value, {});
|
||||
case AtomicOp::Add:
|
||||
return ir.ImageAtomicIAdd(handle, address, value, {});
|
||||
case AtomicOp::Smin:
|
||||
return ir.ImageAtomicIMin(handle, address, value, true, {});
|
||||
case AtomicOp::Umin:
|
||||
return ir.ImageAtomicUMin(handle, address, value, {});
|
||||
case AtomicOp::Smax:
|
||||
return ir.ImageAtomicIMax(handle, address, value, true, {});
|
||||
case AtomicOp::Umax:
|
||||
return ir.ImageAtomicUMax(handle, address, value, {});
|
||||
case AtomicOp::And:
|
||||
return ir.ImageAtomicAnd(handle, address, value, {});
|
||||
case AtomicOp::Or:
|
||||
return ir.ImageAtomicOr(handle, address, value, {});
|
||||
case AtomicOp::Xor:
|
||||
return ir.ImageAtomicXor(handle, address, value, {});
|
||||
case AtomicOp::Inc:
|
||||
return ir.ImageAtomicInc(handle, address, value, {});
|
||||
case AtomicOp::Dec:
|
||||
return ir.ImageAtomicDec(handle, address, value, {});
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}();
|
||||
|
||||
// Store the result if Global L2 Cache (GLC) is enabled
|
||||
if (mtbuf.glc) {
|
||||
ir.SetVectorReg(val_reg, IR::U32{prev});
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Shader::Gcn
|
||||
|
|
Loading…
Add table
Reference in a new issue