agx: Add sample_mask instruction

Sets the output sample mask to a given 8-bit immediate or 16-bit
register. Also used to implement discards, which is my ES2 interest.

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14219>
This commit is contained in:
Alyssa Rosenzweig 2021-12-15 20:59:58 -05:00 committed by Marge Bot
parent dcc12656e3
commit f248f6623c
2 changed files with 36 additions and 0 deletions

View file

@ -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])

View file

@ -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:
{