mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-04-30 23:28:06 +02:00
nir/serialize: Pack deref modes better
With nir_var_image, we've now run out of bits in our packed blob for deref instructions. We could revert to an unpacked blob or we could be a bit more clever about how we encode deref modes and pack them into 5 bits. Reviewed-by: Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13386>
This commit is contained in:
parent
9272a952c9
commit
d343aef942
2 changed files with 48 additions and 5 deletions
|
|
@ -136,7 +136,9 @@ typedef enum {
|
|||
nir_var_mem_ssbo = (1 << 9),
|
||||
nir_var_mem_constant = (1 << 10),
|
||||
|
||||
/* Generic modes intentionally come last. */
|
||||
/* Generic modes intentionally come last. See encode_dref_modes() in
|
||||
* nir_serialize.c for more details.
|
||||
*/
|
||||
nir_var_shader_temp = (1 << 11),
|
||||
nir_var_function_temp = (1 << 12),
|
||||
nir_var_mem_shared = (1 << 13),
|
||||
|
|
|
|||
|
|
@ -627,7 +627,8 @@ union packed_instr {
|
|||
unsigned instr_type:4;
|
||||
unsigned deref_type:3;
|
||||
unsigned cast_type_same_as_last:1;
|
||||
unsigned modes:15; /* deref_var redefines this */
|
||||
unsigned modes:5; /* See (de|en)code_deref_modes() */
|
||||
unsigned _pad:10;
|
||||
unsigned packed_src_ssa_16bit:1; /* deref_var redefines this */
|
||||
unsigned dest:8;
|
||||
} deref;
|
||||
|
|
@ -965,11 +966,51 @@ read_alu(read_ctx *ctx, union packed_instr header)
|
|||
return alu;
|
||||
}
|
||||
|
||||
#define MODE_ENC_GENERIC_BIT (1 << 4)
|
||||
|
||||
static nir_variable_mode
|
||||
decode_deref_modes(unsigned modes)
|
||||
{
|
||||
if (modes & MODE_ENC_GENERIC_BIT) {
|
||||
modes &= ~MODE_ENC_GENERIC_BIT;
|
||||
return modes << (ffs(nir_var_mem_generic) - 1);
|
||||
} else {
|
||||
return 1 << modes;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned
|
||||
encode_deref_modes(nir_variable_mode modes)
|
||||
{
|
||||
/* Mode sets on derefs generally come in two forms. For certain OpenCL
|
||||
* cases, we can have more than one of the generic modes set. In this
|
||||
* case, we need the full bitfield. Fortunately, there are only 4 of
|
||||
* these. For all other modes, we can only have one mode at a time so we
|
||||
* can compress them by only storing the bit position. This, plus one bit
|
||||
* to select encoding, lets us pack the entire bitfield in 5 bits.
|
||||
*/
|
||||
STATIC_ASSERT((nir_var_all & ~nir_var_mem_generic) <
|
||||
(1 << MODE_ENC_GENERIC_BIT));
|
||||
|
||||
unsigned enc;
|
||||
if (modes == 0 || (modes & nir_var_mem_generic)) {
|
||||
assert(!(modes & ~nir_var_mem_generic));
|
||||
enc = modes >> (ffs(nir_var_mem_generic) - 1);
|
||||
assert(enc < MODE_ENC_GENERIC_BIT);
|
||||
enc |= MODE_ENC_GENERIC_BIT;
|
||||
} else {
|
||||
assert(util_is_power_of_two_nonzero(modes));
|
||||
enc = ffs(modes) - 1;
|
||||
assert(enc < MODE_ENC_GENERIC_BIT);
|
||||
}
|
||||
assert(modes == decode_deref_modes(enc));
|
||||
return enc;
|
||||
}
|
||||
|
||||
static void
|
||||
write_deref(write_ctx *ctx, const nir_deref_instr *deref)
|
||||
{
|
||||
assert(deref->deref_type < 8);
|
||||
assert(deref->modes < (1 << 15));
|
||||
|
||||
union packed_instr header;
|
||||
header.u32 = 0;
|
||||
|
|
@ -978,7 +1019,7 @@ write_deref(write_ctx *ctx, const nir_deref_instr *deref)
|
|||
header.deref.deref_type = deref->deref_type;
|
||||
|
||||
if (deref->deref_type == nir_deref_type_cast) {
|
||||
header.deref.modes = deref->modes;
|
||||
header.deref.modes = encode_deref_modes(deref->modes);
|
||||
header.deref.cast_type_same_as_last = deref->type == ctx->last_type;
|
||||
}
|
||||
|
||||
|
|
@ -1114,7 +1155,7 @@ read_deref(read_ctx *ctx, union packed_instr header)
|
|||
if (deref_type == nir_deref_type_var) {
|
||||
deref->modes = deref->var->data.mode;
|
||||
} else if (deref->deref_type == nir_deref_type_cast) {
|
||||
deref->modes = header.deref.modes;
|
||||
deref->modes = decode_deref_modes(header.deref.modes);
|
||||
} else {
|
||||
assert(deref->parent.is_ssa);
|
||||
deref->modes = nir_instr_as_deref(deref->parent.ssa->parent_instr)->modes;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue