shader: implement 32-bit RDNA2 IMAGE_ATOMIC_CMPSWAP (#952)

* shader: implement 32-bit RDNA2 image atomic compare-and-swap

* shader: share atomic emission and correct image barriers

---------

Co-authored-by: nmzik <Nmzik@mail.ru>
This commit is contained in:
Louis
2026-10-01 23:15:53 +02:00
committed by GitHub
parent 4428640b44
commit b3e419ff11
12 changed files with 163 additions and 102 deletions
@@ -192,6 +192,7 @@ constexpr MimgGatherInfo MIMG_GATHER_OPCODE_LIST[] = {
constexpr Detail::OpcodeMap MIMG_ATOMIC_OPCODE_LIST[] = {
{0x0fu, Opcode::IMAGE_ATOMIC_SWAP},
{0x10u, Opcode::IMAGE_ATOMIC_CMPSWAP},
{0x11u, Opcode::IMAGE_ATOMIC_ADD},
{0x14u, Opcode::IMAGE_ATOMIC_SMIN},
{0x15u, Opcode::IMAGE_ATOMIC_UMIN},
@@ -359,6 +360,10 @@ void DecodeMimg(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index
SetUnsupported(inst, Family::MIMG, opcode,
"MIMG image gather requires exactly one dmask bit");
}
if (inst.opcode == Opcode::IMAGE_ATOMIC_CMPSWAP && inst.dmask != 0x3u) {
SetUnsupported(inst, Family::MIMG, opcode,
"MIMG image compare-and-swap requires 32-bit DMASK 0x3");
}
const bool supports_d16 = sample != nullptr || gather != nullptr || opcode == 0x00u ||
opcode == 0x01u || opcode == 0x08u || opcode == 0x09u;
if (d16 && !supports_d16) {
@@ -574,6 +574,7 @@ std::string InstructionToString(const Instruction& inst) {
case Opcode::IMAGE_SAMPLE:
case Opcode::IMAGE_STORE:
case Opcode::IMAGE_STORE_MIP:
case Opcode::IMAGE_ATOMIC_CMPSWAP:
case Opcode::IMAGE_ATOMIC_SWAP:
case Opcode::IMAGE_ATOMIC_ADD:
case Opcode::IMAGE_ATOMIC_SMIN:
@@ -599,6 +599,7 @@ enum class Opcode {
IMAGE_STORE,
IMAGE_STORE_MIP,
IMAGE_ATOMIC_SWAP,
IMAGE_ATOMIC_CMPSWAP,
IMAGE_ATOMIC_ADD,
IMAGE_ATOMIC_SMIN,
IMAGE_ATOMIC_UMIN,