[Mesa-dev] [RFC v1 07/38] nir: Add a deref instruction type
Jason Ekstrand
jason at jlekstrand.net
Wed Mar 21 05:54:41 UTC 2018
This commit adds a new instruction type to NIR for handling derefs.
Nothing uses it yet but this adds the data structure as well as all of
the code to validate, print, clone, and [de]serialize them.
---
src/compiler/nir/nir.c | 50 +++++++++++++++++++
src/compiler/nir/nir.h | 44 ++++++++++++++++-
src/compiler/nir/nir_clone.c | 41 ++++++++++++++++
src/compiler/nir/nir_instr_set.c | 76 +++++++++++++++++++++++++++++
src/compiler/nir/nir_opt_copy_propagate.c | 18 +++++++
src/compiler/nir/nir_opt_dce.c | 7 +++
src/compiler/nir/nir_print.c | 46 ++++++++++++++++++
src/compiler/nir/nir_serialize.c | 79 +++++++++++++++++++++++++++++++
src/compiler/nir/nir_validate.c | 74 +++++++++++++++++++++++++++++
9 files changed, 434 insertions(+), 1 deletion(-)
diff --git a/src/compiler/nir/nir.c b/src/compiler/nir/nir.c
index b16d6fa..2ed96a1 100644
--- a/src/compiler/nir/nir.c
+++ b/src/compiler/nir/nir.c
@@ -469,6 +469,26 @@ nir_alu_instr_create(nir_shader *shader, nir_op op)
return instr;
}
+nir_deref_instr *
+nir_deref_instr_create(nir_shader *shader, nir_deref_type deref_type)
+{
+ nir_deref_instr *instr =
+ rzalloc_size(shader, sizeof(nir_deref_instr));
+
+ instr_init(&instr->instr, nir_instr_type_deref);
+
+ instr->deref_type = deref_type;
+ if (deref_type != nir_deref_type_var)
+ src_init(&instr->parent);
+
+ if (deref_type == nir_deref_type_array)
+ src_init(&instr->arr.index);
+
+ dest_init(&instr->dest);
+
+ return instr;
+}
+
nir_jump_instr *
nir_jump_instr_create(nir_shader *shader, nir_jump_type type)
{
@@ -1198,6 +1218,12 @@ visit_alu_dest(nir_alu_instr *instr, nir_foreach_dest_cb cb, void *state)
}
static bool
+visit_deref_dest(nir_deref_instr *instr, nir_foreach_dest_cb cb, void *state)
+{
+ return cb(&instr->dest, state);
+}
+
+static bool
visit_intrinsic_dest(nir_intrinsic_instr *instr, nir_foreach_dest_cb cb,
void *state)
{
@@ -1238,6 +1264,8 @@ nir_foreach_dest(nir_instr *instr, nir_foreach_dest_cb cb, void *state)
switch (instr->type) {
case nir_instr_type_alu:
return visit_alu_dest(nir_instr_as_alu(instr), cb, state);
+ case nir_instr_type_deref:
+ return visit_deref_dest(nir_instr_as_deref(instr), cb, state);
case nir_instr_type_intrinsic:
return visit_intrinsic_dest(nir_instr_as_intrinsic(instr), cb, state);
case nir_instr_type_tex:
@@ -1283,6 +1311,7 @@ nir_foreach_ssa_def(nir_instr *instr, nir_foreach_ssa_def_cb cb, void *state)
{
switch (instr->type) {
case nir_instr_type_alu:
+ case nir_instr_type_deref:
case nir_instr_type_tex:
case nir_instr_type_intrinsic:
case nir_instr_type_phi:
@@ -1349,6 +1378,23 @@ visit_alu_src(nir_alu_instr *instr, nir_foreach_src_cb cb, void *state)
}
static bool
+visit_deref_instr_src(nir_deref_instr *instr,
+ nir_foreach_src_cb cb, void *state)
+{
+ if (instr->deref_type != nir_deref_type_var) {
+ if (!visit_src(&instr->parent, cb, state))
+ return false;
+ }
+
+ if (instr->deref_type == nir_deref_type_array) {
+ if (!visit_src(&instr->arr.index, cb, state))
+ return false;
+ }
+
+ return true;
+}
+
+static bool
visit_tex_src(nir_tex_instr *instr, nir_foreach_src_cb cb, void *state)
{
for (unsigned i = 0; i < instr->num_srcs; i++) {
@@ -1436,6 +1482,10 @@ nir_foreach_src(nir_instr *instr, nir_foreach_src_cb cb, void *state)
if (!visit_alu_src(nir_instr_as_alu(instr), cb, state))
return false;
break;
+ case nir_instr_type_deref:
+ if (!visit_deref_instr_src(nir_instr_as_deref(instr), cb, state))
+ return false;
+ break;
case nir_instr_type_intrinsic:
if (!visit_intrinsic_src(nir_instr_as_intrinsic(instr), cb, state))
return false;
diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
index cc0b171..0e69a85 100644
--- a/src/compiler/nir/nir.h
+++ b/src/compiler/nir/nir.h
@@ -421,6 +421,7 @@ typedef struct nir_register {
typedef enum {
nir_instr_type_alu,
+ nir_instr_type_deref,
nir_instr_type_call,
nir_instr_type_tex,
nir_instr_type_intrinsic,
@@ -888,7 +889,8 @@ bool nir_alu_srcs_equal(const nir_alu_instr *alu1, const nir_alu_instr *alu2,
typedef enum {
nir_deref_type_var,
nir_deref_type_array,
- nir_deref_type_struct
+ nir_deref_type_array_wildcard,
+ nir_deref_type_struct,
} nir_deref_type;
typedef struct nir_deref {
@@ -950,6 +952,41 @@ nir_deref_tail(nir_deref *deref)
typedef struct {
nir_instr instr;
+ /** The type of this deref instruction */
+ nir_deref_type deref_type;
+
+ /** The mode of the underlying variable */
+ nir_variable_mode mode;
+
+ /** The dereferenced type of the resulting pointer value */
+ const struct glsl_type *type;
+
+ union {
+ /** Variable being dereferenced if deref_type is a deref_var */
+ nir_variable *var;
+
+ /** Parent deref if deref_type is not deref_var */
+ nir_src parent;
+ };
+
+ /** Additional deref parameters */
+ union {
+ struct {
+ nir_src index;
+ } arr;
+
+ struct {
+ unsigned index;
+ } strct;
+ };
+
+ /** Destination to store the resulting "pointer" */
+ nir_dest dest;
+} nir_deref_instr;
+
+typedef struct {
+ nir_instr instr;
+
unsigned num_params;
nir_deref_var **params;
nir_deref_var *return_deref;
@@ -1521,6 +1558,8 @@ typedef struct {
NIR_DEFINE_CAST(nir_instr_as_alu, nir_instr, nir_alu_instr, instr,
type, nir_instr_type_alu)
+NIR_DEFINE_CAST(nir_instr_as_deref, nir_instr, nir_deref_instr, instr,
+ type, nir_instr_type_deref)
NIR_DEFINE_CAST(nir_instr_as_call, nir_instr, nir_call_instr, instr,
type, nir_instr_type_call)
NIR_DEFINE_CAST(nir_instr_as_jump, nir_instr, nir_jump_instr, instr,
@@ -2047,6 +2086,9 @@ void nir_metadata_preserve(nir_function_impl *impl, nir_metadata preserved);
/** creates an instruction with default swizzle/writemask/etc. with NULL registers */
nir_alu_instr *nir_alu_instr_create(nir_shader *shader, nir_op op);
+nir_deref_instr *nir_deref_instr_create(nir_shader *shader,
+ nir_deref_type deref_type);
+
nir_jump_instr *nir_jump_instr_create(nir_shader *shader, nir_jump_type type);
nir_load_const_instr *nir_load_const_instr_create(nir_shader *shader,
diff --git a/src/compiler/nir/nir_clone.c b/src/compiler/nir/nir_clone.c
index bcfdaa7..5b9f81b 100644
--- a/src/compiler/nir/nir_clone.c
+++ b/src/compiler/nir/nir_clone.c
@@ -346,6 +346,45 @@ clone_alu(clone_state *state, const nir_alu_instr *alu)
return nalu;
}
+static nir_deref_instr *
+clone_deref_instr(clone_state *state, const nir_deref_instr *deref)
+{
+ nir_deref_instr *nderef =
+ nir_deref_instr_create(state->ns, deref->deref_type);
+
+ __clone_dst(state, &nderef->instr, &nderef->dest, &deref->dest);
+
+ nderef->mode = deref->mode;
+ nderef->type = deref->type;
+
+ if (deref->deref_type == nir_deref_type_var) {
+ nderef->var = remap_var(state, deref->var);
+ return nderef;
+ }
+
+ __clone_src(state, &nderef->instr, &nderef->parent, &deref->parent);
+
+ switch (deref->deref_type) {
+ case nir_deref_type_struct:
+ nderef->strct.index = deref->strct.index;
+ break;
+
+ case nir_deref_type_array:
+ __clone_src(state, &nderef->instr,
+ &nderef->arr.index, &deref->arr.index);
+ break;
+
+ case nir_deref_type_array_wildcard:
+ /* Nothing to do */
+ break;
+
+ default:
+ unreachable("Invalid instruction deref type");
+ }
+
+ return nderef;
+}
+
static nir_intrinsic_instr *
clone_intrinsic(clone_state *state, const nir_intrinsic_instr *itr)
{
@@ -502,6 +541,8 @@ clone_instr(clone_state *state, const nir_instr *instr)
switch (instr->type) {
case nir_instr_type_alu:
return &clone_alu(state, nir_instr_as_alu(instr))->instr;
+ case nir_instr_type_deref:
+ return &clone_deref_instr(state, nir_instr_as_deref(instr))->instr;
case nir_instr_type_intrinsic:
return &clone_intrinsic(state, nir_instr_as_intrinsic(instr))->instr;
case nir_instr_type_load_const:
diff --git a/src/compiler/nir/nir_instr_set.c b/src/compiler/nir/nir_instr_set.c
index 9cb9ed4..a2533f0 100644
--- a/src/compiler/nir/nir_instr_set.c
+++ b/src/compiler/nir/nir_instr_set.c
@@ -79,6 +79,39 @@ hash_alu(uint32_t hash, const nir_alu_instr *instr)
}
static uint32_t
+hash_deref(uint32_t hash, const nir_deref_instr *instr)
+{
+ hash = HASH(hash, instr->deref_type);
+ hash = HASH(hash, instr->mode);
+ hash = HASH(hash, instr->type);
+
+ if (instr->deref_type == nir_deref_type_var)
+ return HASH(hash, instr->var);
+
+ hash = hash_src(hash, &instr->parent);
+
+ switch (instr->deref_type) {
+ case nir_deref_type_struct:
+ hash = HASH(hash, instr->strct.index);
+ break;
+
+ case nir_deref_type_array:
+ hash = hash_src(hash, &instr->arr.index);
+ break;
+
+ case nir_deref_type_var:
+ case nir_deref_type_array_wildcard:
+ /* Nothing to do */
+ break;
+
+ default:
+ unreachable("Invalid instruction deref type");
+ }
+
+ return hash;
+}
+
+static uint32_t
hash_load_const(uint32_t hash, const nir_load_const_instr *instr)
{
hash = HASH(hash, instr->def.num_components);
@@ -182,6 +215,9 @@ hash_instr(const void *data)
case nir_instr_type_alu:
hash = hash_alu(hash, nir_instr_as_alu(instr));
break;
+ case nir_instr_type_deref:
+ hash = hash_deref(hash, nir_instr_as_deref(instr));
+ break;
case nir_instr_type_load_const:
hash = hash_load_const(hash, nir_instr_as_load_const(instr));
break;
@@ -289,6 +325,42 @@ nir_instrs_equal(const nir_instr *instr1, const nir_instr *instr2)
}
return true;
}
+ case nir_instr_type_deref: {
+ nir_deref_instr *deref1 = nir_instr_as_deref(instr1);
+ nir_deref_instr *deref2 = nir_instr_as_deref(instr2);
+
+ if (deref1->deref_type != deref2->deref_type ||
+ deref1->mode != deref2->mode ||
+ deref1->type != deref2->type)
+ return false;
+
+ if (deref1->deref_type == nir_deref_type_var)
+ return deref1->var == deref2->var;
+
+ if (!nir_srcs_equal(deref1->parent, deref2->parent))
+ return false;
+
+ switch (deref1->deref_type) {
+ case nir_deref_type_struct:
+ if (deref1->strct.index != deref2->strct.index)
+ return false;
+ break;
+
+ case nir_deref_type_array:
+ if (!nir_srcs_equal(deref1->arr.index, deref2->arr.index))
+ return false;
+ break;
+
+ case nir_deref_type_var:
+ case nir_deref_type_array_wildcard:
+ /* Nothing to do */
+ break;
+
+ default:
+ unreachable("Invalid instruction deref type");
+ }
+ break;
+ }
case nir_instr_type_tex: {
nir_tex_instr *tex1 = nir_instr_as_tex(instr1);
nir_tex_instr *tex2 = nir_instr_as_tex(instr2);
@@ -430,6 +502,7 @@ instr_can_rewrite(nir_instr *instr)
switch (instr->type) {
case nir_instr_type_alu:
+ case nir_instr_type_deref:
case nir_instr_type_load_const:
case nir_instr_type_phi:
return true;
@@ -468,6 +541,9 @@ nir_instr_get_dest_ssa_def(nir_instr *instr)
case nir_instr_type_alu:
assert(nir_instr_as_alu(instr)->dest.dest.is_ssa);
return &nir_instr_as_alu(instr)->dest.dest.ssa;
+ case nir_instr_type_deref:
+ assert(nir_instr_as_deref(instr)->dest.is_ssa);
+ return &nir_instr_as_deref(instr)->dest.ssa;
case nir_instr_type_load_const:
return &nir_instr_as_load_const(instr)->def;
case nir_instr_type_phi:
diff --git a/src/compiler/nir/nir_opt_copy_propagate.c b/src/compiler/nir/nir_opt_copy_propagate.c
index c4001fa..988c7f4 100644
--- a/src/compiler/nir/nir_opt_copy_propagate.c
+++ b/src/compiler/nir/nir_opt_copy_propagate.c
@@ -234,6 +234,24 @@ copy_prop_instr(nir_instr *instr)
return progress;
}
+ case nir_instr_type_deref: {
+ nir_deref_instr *deref = nir_instr_as_deref(instr);
+
+ if (deref->deref_type != nir_deref_type_var) {
+ assert(deref->dest.is_ssa);
+ const unsigned comps = deref->dest.ssa.num_components;
+ while (copy_prop_src(&deref->parent, instr, NULL, comps))
+ progress = true;
+ }
+
+ if (deref->deref_type == nir_deref_type_array) {
+ while (copy_prop_src(&deref->arr.index, instr, NULL, 1))
+ progress = true;
+ }
+
+ return progress;
+ }
+
case nir_instr_type_tex: {
nir_tex_instr *tex = nir_instr_as_tex(instr);
for (unsigned i = 0; i < tex->num_srcs; i++) {
diff --git a/src/compiler/nir/nir_opt_dce.c b/src/compiler/nir/nir_opt_dce.c
index 5cefba3..33c0d0c 100644
--- a/src/compiler/nir/nir_opt_dce.c
+++ b/src/compiler/nir/nir_opt_dce.c
@@ -67,6 +67,7 @@ static void
init_instr(nir_instr *instr, struct exec_list *worklist)
{
nir_alu_instr *alu_instr;
+ nir_deref_instr *deref_instr;
nir_intrinsic_instr *intrin_instr;
nir_tex_instr *tex_instr;
@@ -88,6 +89,12 @@ init_instr(nir_instr *instr, struct exec_list *worklist)
worklist_push(worklist, instr);
break;
+ case nir_instr_type_deref:
+ deref_instr = nir_instr_as_deref(instr);
+ if (!deref_instr->dest.is_ssa)
+ worklist_push(worklist, instr);
+ break;
+
case nir_instr_type_intrinsic:
intrin_instr = nir_instr_as_intrinsic(instr);
if (nir_intrinsic_infos[intrin_instr->intrinsic].flags &
diff --git a/src/compiler/nir/nir_print.c b/src/compiler/nir/nir_print.c
index 7888dbd..081ef72 100644
--- a/src/compiler/nir/nir_print.c
+++ b/src/compiler/nir/nir_print.c
@@ -486,6 +486,48 @@ print_var_decl(nir_variable *var, print_state *state)
}
static void
+print_deref_instr(nir_deref_instr *instr, print_state *state)
+{
+ FILE *fp = state->fp;
+
+ print_dest(&instr->dest, state);
+
+ if (instr->deref_type == nir_deref_type_var) {
+ fprintf(fp, " = deref %s", get_var_name(instr->var, state));
+ return;
+ }
+
+ fprintf(fp, " = deref (%s) &", get_variable_mode_str(instr->mode));
+ print_src(&instr->parent, state);
+
+ assert(instr->parent.is_ssa);
+ nir_deref_instr *parent =
+ nir_instr_as_deref(instr->parent.ssa->parent_instr);
+
+ switch (instr->deref_type) {
+ case nir_deref_type_struct:
+ fprintf(fp, "->%s",
+ glsl_get_struct_elem_name(parent->type, instr->strct.index));
+ break;
+
+ case nir_deref_type_array: {
+ nir_const_value *const_index = nir_src_as_const_value(instr->arr.index);
+ if (const_index) {
+ fprintf(fp, "[%u]", const_index->u32[0]);
+ } else {
+ fprintf(fp, "[");
+ print_src(&instr->arr.index, state);
+ fprintf(fp, "]");
+ }
+ break;
+ }
+
+ default:
+ unreachable("Invalid deref instruction type");
+ }
+}
+
+static void
print_var(nir_variable *var, print_state *state)
{
FILE *fp = state->fp;
@@ -922,6 +964,10 @@ print_instr(const nir_instr *instr, print_state *state, unsigned tabs)
print_alu_instr(nir_instr_as_alu(instr), state);
break;
+ case nir_instr_type_deref:
+ print_deref_instr(nir_instr_as_deref(instr), state);
+ break;
+
case nir_instr_type_call:
print_call_instr(nir_instr_as_call(instr), state);
break;
diff --git a/src/compiler/nir/nir_serialize.c b/src/compiler/nir/nir_serialize.c
index 00df49c..5a6edc2 100644
--- a/src/compiler/nir/nir_serialize.c
+++ b/src/compiler/nir/nir_serialize.c
@@ -479,6 +479,79 @@ read_alu(read_ctx *ctx)
}
static void
+write_deref(write_ctx *ctx, const nir_deref_instr *deref)
+{
+ blob_write_uint32(ctx->blob, deref->deref_type);
+
+ blob_write_uint32(ctx->blob, deref->mode);
+ encode_type_to_blob(ctx->blob, deref->type);
+
+ write_dest(ctx, &deref->dest);
+
+ if (deref->deref_type == nir_deref_type_var) {
+ write_object(ctx, deref->var);
+ return;
+ }
+
+ write_src(ctx, &deref->parent);
+
+ switch (deref->deref_type) {
+ case nir_deref_type_struct:
+ blob_write_uint32(ctx->blob, deref->strct.index);
+ break;
+
+ case nir_deref_type_array:
+ write_src(ctx, &deref->arr.index);
+ break;
+
+ case nir_deref_type_array_wildcard:
+ /* Nothing to do */
+ break;
+
+ default:
+ unreachable("Invalid deref type");
+ }
+}
+
+static nir_deref_instr *
+read_deref(read_ctx *ctx)
+{
+ nir_deref_type deref_type = blob_read_uint32(ctx->blob);
+ nir_deref_instr *deref = nir_deref_instr_create(ctx->nir, deref_type);
+
+ deref->mode = blob_read_uint32(ctx->blob);
+ deref->type = decode_type_from_blob(ctx->blob);
+
+ read_dest(ctx, &deref->dest, &deref->instr);
+
+ if (deref_type == nir_deref_type_var) {
+ deref->var = read_object(ctx);
+ return deref;
+ }
+
+ read_src(ctx, &deref->parent, &deref->instr);
+
+ switch (deref->deref_type) {
+ case nir_deref_type_struct:
+ deref->strct.index = blob_read_uint32(ctx->blob);
+ break;
+
+ case nir_deref_type_array:
+ read_src(ctx, &deref->arr.index, &deref->instr);
+ break;
+
+ case nir_deref_type_array_wildcard:
+ /* Nothing to do */
+ break;
+
+ default:
+ unreachable("Invalid deref type");
+ }
+
+ return deref;
+}
+
+static void
write_intrinsic(write_ctx *ctx, const nir_intrinsic_instr *intrin)
{
blob_write_uint32(ctx->blob, intrin->intrinsic);
@@ -803,6 +876,9 @@ write_instr(write_ctx *ctx, const nir_instr *instr)
case nir_instr_type_alu:
write_alu(ctx, nir_instr_as_alu(instr));
break;
+ case nir_instr_type_deref:
+ write_deref(ctx, nir_instr_as_deref(instr));
+ break;
case nir_instr_type_intrinsic:
write_intrinsic(ctx, nir_instr_as_intrinsic(instr));
break;
@@ -840,6 +916,9 @@ read_instr(read_ctx *ctx, nir_block *block)
case nir_instr_type_alu:
instr = &read_alu(ctx)->instr;
break;
+ case nir_instr_type_deref:
+ instr = &read_deref(ctx)->instr;
+ break;
case nir_instr_type_intrinsic:
instr = &read_intrinsic(ctx)->instr;
break;
diff --git a/src/compiler/nir/nir_validate.c b/src/compiler/nir/nir_validate.c
index e9d6bd5..27bbe3c 100644
--- a/src/compiler/nir/nir_validate.c
+++ b/src/compiler/nir/nir_validate.c
@@ -469,6 +469,76 @@ validate_deref_var(void *parent_mem_ctx, nir_deref_var *deref, validate_state *s
}
static void
+validate_deref_instr(nir_deref_instr *instr, validate_state *state)
+{
+ if (instr->deref_type == nir_deref_type_var) {
+ /* Variable dereferences are stupid simple. */
+ validate_assert(state, instr->mode == instr->var->data.mode);
+ validate_assert(state, instr->type == instr->var->type);
+ validate_var_use(instr->var, state);
+ } else {
+ /* We require the parent to be SSA. This may be lifted in the future */
+ validate_assert(state, instr->parent.is_ssa);
+
+ /* The parent pointer value must have the same number of components
+ * as the destination.
+ */
+ validate_src(&instr->parent, state, nir_dest_bit_size(instr->dest),
+ nir_dest_num_components(instr->dest));
+
+ nir_instr *parent_instr = instr->parent.ssa->parent_instr;
+
+ /* The parent must come from another deref instruction */
+ validate_assert(state, parent_instr->type == nir_instr_type_deref);
+
+ nir_deref_instr *parent = nir_instr_as_deref(parent_instr);
+
+ validate_assert(state, instr->mode == parent->mode);
+
+ switch (instr->deref_type) {
+ case nir_deref_type_struct:
+ validate_assert(state, glsl_type_is_struct(parent->type));
+ validate_assert(state,
+ instr->strct.index < glsl_get_length(parent->type));
+ validate_assert(state, instr->type ==
+ glsl_get_struct_field(parent->type, instr->strct.index));
+ break;
+
+ case nir_deref_type_array:
+ case nir_deref_type_array_wildcard:
+ if (instr->mode == nir_var_shared) {
+ /* Shared variables have a bit more relaxed rules because we need
+ * to be able to handle array derefs on vectors. Fortunately,
+ * nir_lower_io handles these just fine.
+ */
+ validate_assert(state, glsl_type_is_array(parent->type) ||
+ glsl_type_is_matrix(parent->type) ||
+ glsl_type_is_vector(parent->type));
+ } else {
+ /* Most of NIR cannot handle array derefs on vectors */
+ validate_assert(state, glsl_type_is_array(parent->type) ||
+ glsl_type_is_matrix(parent->type));
+ }
+ validate_assert(state,
+ instr->type == glsl_get_array_element(parent->type));
+
+ if (instr->deref_type == nir_deref_type_array)
+ validate_src(&instr->arr.index, state, 32, 1);
+ break;
+
+ default:
+ unreachable("Invalid deref instruction type");
+ }
+ }
+
+ /* We intentionally don't validate the size of the destination because we
+ * want to let other compiler components such as SPIR-V decide how big
+ * pointers should be.
+ */
+ validate_dest(&instr->dest, state, 0, 0);
+}
+
+static void
validate_intrinsic_instr(nir_intrinsic_instr *instr, validate_state *state)
{
unsigned bit_size = 0;
@@ -622,6 +692,10 @@ validate_instr(nir_instr *instr, validate_state *state)
validate_alu_instr(nir_instr_as_alu(instr), state);
break;
+ case nir_instr_type_deref:
+ validate_deref_instr(nir_instr_as_deref(instr), state);
+ break;
+
case nir_instr_type_call:
validate_call_instr(nir_instr_as_call(instr), state);
break;
--
2.5.0.400.gff86faf
More information about the mesa-dev
mailing list