diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index 71c8bad62b2..c29ddeb3697 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -128,6 +128,10 @@ typedef enum { 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 | diff --git a/src/compiler/nir/nir_print.c b/src/compiler/nir/nir_print.c index 44aa645b59d..98035c63be4 100644 --- a/src/compiler/nir/nir_print.c +++ b/src/compiler/nir/nir_print.c @@ -723,9 +723,14 @@ print_deref_instr(nir_deref_instr *instr, print_state *state) 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) { diff --git a/src/compiler/nir/nir_validate.c b/src/compiler/nir/nir_validate.c index ee1c5c13c9b..e6b4980f265 100644 --- a/src/compiler/nir/nir_validate.c +++ b/src/compiler/nir/nir_validate.c @@ -407,8 +407,6 @@ validate_var_use(nir_variable *var, validate_state *state) 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); @@ -420,8 +418,22 @@ validate_deref_instr(nir_deref_instr *instr, validate_state *state) */ 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));