nir_var_mem_ssbo = (1 << 7),
nir_var_mem_shared = (1 << 8),
nir_var_mem_global = (1 << 9),
+ nir_var_mem_generic = (nir_var_shader_temp |
+ nir_var_function_temp |
+ nir_var_mem_shared |
+ nir_var_mem_global),
nir_var_mem_push_const = (1 << 10), /* not actually used for variables */
nir_var_mem_constant = (1 << 11),
nir_var_read_only_modes = nir_var_shader_in | nir_var_uniform |
print_deref_link(instr, false, state);
- fprintf(fp, " (%s %s) ",
- get_variable_mode_str(instr->modes, true),
- glsl_get_type_name(instr->type));
+ fprintf(fp, " (");
+ unsigned modes = instr->modes;
+ while (modes) {
+ int m = u_bit_scan(&modes);
+ fprintf(fp, "%s%s", get_variable_mode_str(1 << m, true),
+ modes ? "|" : "");
+ }
+ fprintf(fp, " %s) ", glsl_get_type_name(instr->type));
if (instr->deref_type != nir_deref_type_var &&
instr->deref_type != nir_deref_type_cast) {
static void
validate_deref_instr(nir_deref_instr *instr, validate_state *state)
{
- validate_assert(state, util_bitcount(instr->modes) == 1);
-
if (instr->deref_type == nir_deref_type_var) {
/* Variable dereferences are stupid simple. */
validate_assert(state, instr->modes == instr->var->data.mode);
*/
validate_src(&instr->parent, state, 0, 0);
- /* We just validate that the type and mode are there */
- validate_assert(state, instr->modes);
+ /* Most variable modes in NIR can only exist by themselves. */
+ if (instr->modes & ~nir_var_mem_generic)
+ validate_assert(state, util_bitcount(instr->modes) == 1);
+
+ 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);
+ } else {
+ /* If our parent isn't a deref, just assert the mode is there */
+ validate_assert(state, instr->modes != 0);
+ }
+
+ /* We just validate that the type is there */
validate_assert(state, instr->type);
if (instr->cast.align_mul > 0) {
validate_assert(state, util_is_power_of_two_nonzero(instr->cast.align_mul));