nir: add new variable modes for the resource/sampler heap pointers

These two new variable modes are used to relax restrictions on deref
casts through because it's possible to cast different modes from the
heap pointers.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40768>
This commit is contained in:
Samuel Pitoiset 2026-04-03 13:08:36 +02:00 committed by Marge Bot
parent e5144bcd6a
commit 457eac7d66
6 changed files with 42 additions and 11 deletions

View file

@ -259,6 +259,8 @@ nir_shader_add_variable(nir_shader *shader, nir_variable *var)
case nir_var_mem_pixel_local_in:
case nir_var_mem_pixel_local_out:
case nir_var_mem_pixel_local_inout:
case nir_var_resource_heap:
case nir_var_sampler_heap:
break;
default:

View file

@ -484,7 +484,7 @@ typedef struct nir_variable {
*
* :c:struct:`nir_variable_mode`
*/
unsigned mode : 24;
unsigned mode : 26;
/**
* Is the variable read-only?

View file

@ -84,13 +84,16 @@ typedef enum {
nir_var_function_out = (1 << 18),
nir_var_function_inout = (1 << 19),
nir_var_resource_heap = (1 << 20),
nir_var_sampler_heap = (1 << 21),
/* Generic modes intentionally come last. See encode_dref_modes() in
* nir_serialize.c for more details.
*/
nir_var_shader_temp = (1 << 20),
nir_var_function_temp = (1 << 21),
nir_var_mem_shared = (1 << 22),
nir_var_mem_global = (1 << 23),
nir_var_shader_temp = (1 << 22),
nir_var_function_temp = (1 << 23),
nir_var_mem_shared = (1 << 24),
nir_var_mem_global = (1 << 25),
nir_var_mem_generic = (nir_var_shader_temp |
nir_var_function_temp |
@ -114,7 +117,7 @@ typedef enum {
nir_var_mem_pixel_local_out |
nir_var_mem_pixel_local_inout,
nir_num_variable_modes = 24,
nir_num_variable_modes = 26,
nir_var_all = (1 << nir_num_variable_modes) - 1,
} nir_variable_mode;
MESA_DEFINE_CPP_ENUM_BITFIELD_OPERATORS(nir_variable_mode)

View file

@ -1086,6 +1086,13 @@ opt_restrict_deref_modes(nir_deref_instr *deref)
if (parent == NULL || parent->modes == deref->modes)
return false;
/* Casts from the heap pointers shouldn't be restricted because it's allowed
* to cast to some variable modes.
*/
if (parent->modes & (nir_var_resource_heap |
nir_var_sampler_heap))
return false;
assert(parent->modes & deref->modes);
deref->modes &= parent->modes;
return true;

View file

@ -813,6 +813,10 @@ get_variable_mode_str(nir_variable_mode mode, bool want_local_global_mode)
return "node_payload";
case nir_var_mem_node_payload_in:
return "node_payload_in";
case nir_var_resource_heap:
return "resource_heap";
case nir_var_sampler_heap:
return "sampler_heap";
default:
if (mode && (mode & nir_var_mem_generic) == mode)
return "generic";

View file

@ -330,10 +330,23 @@ validate_deref_instr(nir_deref_instr *instr, validate_state *state)
nir_deref_instr *parent = nir_src_as_deref(instr->parent);
if (parent) {
/* Casts can change the mode but it can't change completely. The new
* mode must have some bits in common with the old.
*/
validate_assert(state, instr->modes & parent->modes);
if (parent->modes & nir_var_resource_heap) {
/* Some casts from the resource heap pointer are allowed. */
validate_assert(state, instr->modes & (nir_var_resource_heap |
nir_var_image |
nir_var_uniform |
nir_var_mem_ubo |
nir_var_mem_ssbo));
} else if (parent->modes & nir_var_sampler_heap) {
/* Some casts from the sampler heap pointer are allowed. */
validate_assert(state, instr->modes & (nir_var_sampler_heap |
nir_var_uniform));
} else {
/* Casts can change the mode but it can't change completely. The
* new mode must have some bits in common with the old.
*/
validate_assert(state, instr->modes & parent->modes);
}
} else {
/* If our parent isn't a deref, just assert the mode is there */
validate_assert(state, instr->modes != 0);
@ -2353,7 +2366,9 @@ nir_validate_shader(nir_shader *shader, const char *when)
nir_var_mem_pixel_local_in |
nir_var_mem_pixel_local_out |
nir_var_mem_pixel_local_inout |
nir_var_image;
nir_var_image |
nir_var_resource_heap |
nir_var_sampler_heap;
if (mesa_shader_stage_is_callable(shader->info.stage))
valid_modes |= nir_var_shader_call_data;