graphics: implement RDNA2 buffer atomic OR x2

This commit is contained in:
nmzik
2026-09-03 05:39:05 +02:00
parent cd74809086
commit 858c18468b
14 changed files with 195 additions and 26 deletions
@@ -58,6 +58,7 @@ constexpr MemoryOpcodeInfo MUBUF_OPCODE_LIST[] = {
{0x3bu, Opcode::BUFFER_ATOMIC_XOR, 1, 32},
{0x3fu, Opcode::BUFFER_ATOMIC_FMIN, 1, 32},
{0x40u, Opcode::BUFFER_ATOMIC_FMAX, 1, 32},
{0x5au, Opcode::BUFFER_ATOMIC_OR_X2, 2, 32},
};
constexpr MemoryOpcodeInfo MTBUF_OPCODE_LIST[] = {
@@ -600,6 +600,7 @@ std::string InstructionToString(const Instruction& inst) {
case Opcode::BUFFER_ATOMIC_UMAX:
case Opcode::BUFFER_ATOMIC_AND:
case Opcode::BUFFER_ATOMIC_OR:
case Opcode::BUFFER_ATOMIC_OR_X2:
case Opcode::BUFFER_ATOMIC_XOR:
case Opcode::BUFFER_ATOMIC_FMIN:
case Opcode::BUFFER_ATOMIC_FMAX:
@@ -463,6 +463,7 @@ enum class Opcode {
BUFFER_ATOMIC_UMAX,
BUFFER_ATOMIC_AND,
BUFFER_ATOMIC_OR,
BUFFER_ATOMIC_OR_X2,
BUFFER_ATOMIC_XOR,
BUFFER_ATOMIC_FMIN,
BUFFER_ATOMIC_FMAX,
@@ -522,12 +522,21 @@ bool Translator::BUFFER_ATOMIC(const Decoder::Instruction& inst, IR::ValueOpcode
const auto memory = MemoryInfoFromDecoded(inst);
const auto resource = GetBufferResource(memory);
const auto address = ReadBufferAddress(inst, 1);
const auto result = ir.Emit(opcode,
{resource, address.index, address.offset, address.soffset,
ReadU32(MemorySourceAt(inst, 0)), ir.GetExec()},
AddMemoryInfo(memory, inst.pc));
const auto data_src = MemorySourceAt(inst, 0);
IR::Value data = ReadU32(data_src);
if (memory.data_dwords == 2u) {
data = ir.ConstructU64(ReadU32(data_src), ReadU32(OffsetOperand(data_src, 1u)));
}
const auto result = ir.Emit(opcode,
{resource, address.index, address.offset, address.soffset, data,
ir.GetExec()},
AddMemoryInfo(memory, inst.pc));
if (inst.glc) {
WriteOperand(inst.dst, result);
WriteOperand(inst.dst,
memory.data_dwords == 1u ? result : ir.CompositeExtract(result, 0u));
if (memory.data_dwords == 2u) {
WriteOperand(OffsetOperand(inst.dst, 1u), ir.CompositeExtract(result, 1u));
}
}
return true;
}
@@ -935,6 +944,8 @@ bool Translator::EmitMemory(const Decoder::Instruction& inst) {
return BUFFER_ATOMIC(inst, IR::ValueOpcode::BufferAtomicAnd32);
case Decoder::Opcode::BUFFER_ATOMIC_OR:
return BUFFER_ATOMIC(inst, IR::ValueOpcode::BufferAtomicOr32);
case Decoder::Opcode::BUFFER_ATOMIC_OR_X2:
return BUFFER_ATOMIC(inst, IR::ValueOpcode::BufferAtomicOr64);
case Decoder::Opcode::BUFFER_ATOMIC_XOR:
return BUFFER_ATOMIC(inst, IR::ValueOpcode::BufferAtomicXor32);
case Decoder::Opcode::BUFFER_ATOMIC_FMIN: