diff --git a/src/asahi/compiler/agx_opcodes.py b/src/asahi/compiler/agx_opcodes.py index f22611addfc..77f2be718bc 100644 --- a/src/asahi/compiler/agx_opcodes.py +++ b/src/asahi/compiler/agx_opcodes.py @@ -207,6 +207,8 @@ op("wait", (0x38, 0xFF, 2, _), dests = 0, op("get_sr", (0x72, 0x7F | L, 4, _), dests = 1, imms = [SR]) +op("sample_mask", (0x7fc1, 0xffff, 6, _), dests = 0, srcs = 1, can_eliminate = False) + # Essentially same encoding op("ld_tile", (0x49, 0x7F, 8, _), dests = 1, srcs = 0, can_eliminate = False, imms = [FORMAT]) diff --git a/src/asahi/compiler/agx_pack.c b/src/asahi/compiler/agx_pack.c index cb462f94daf..93c07ebf3a5 100644 --- a/src/asahi/compiler/agx_pack.c +++ b/src/asahi/compiler/agx_pack.c @@ -235,6 +235,25 @@ agx_pack_cmpsel_src(agx_index src, enum agx_size dest_size) } } +static unsigned +agx_pack_sample_mask_src(agx_index src) +{ + unsigned value = src.value; + unsigned packed_value = + (value & BITFIELD_MASK(6)) | + (((value >> 6) & BITFIELD_MASK(2)) << 10); + + if (src.type == AGX_INDEX_IMMEDIATE) { + assert(value < 0x100); + return packed_value | (1 << 7); + } else { + assert(src.type == AGX_INDEX_REGISTER); + assert(!(src.cache && src.discard)); + + return packed_value; + } +} + static unsigned agx_pack_float_mod(agx_index src) { @@ -412,6 +431,21 @@ agx_pack_instr(struct util_dynarray *emission, struct util_dynarray *fixups, agx break; } + case AGX_OPCODE_SAMPLE_MASK: + { + unsigned S = agx_pack_sample_mask_src(I->src[0]); + uint64_t raw = + 0x7fc1 | + ((S & 0xff) << 16) | + (0x3 << 24) | + ((S >> 8) << 26) | + (0x158ull << 32); + + unsigned size = 8; + memcpy(util_dynarray_grow_bytes(emission, 1, size), &raw, size); + break; + } + case AGX_OPCODE_LD_VARY: case AGX_OPCODE_LD_VARY_FLAT: {