<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Thu, Mar 15, 2018 at 8:22 AM, Bas Nieuwenhuizen <span dir="ltr"><<a href="mailto:bas@basnieuwenhuizen.nl" target="_blank">bas@basnieuwenhuizen.nl</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">On Thu, Mar 15, 2018 at 6:33 AM, Jason Ekstrand <<a href="mailto:jason@jlekstrand.net">jason@jlekstrand.net</a>> wrote:<br>
> This commit adds a new instruction type to NIR for handling derefs.<br>
> Nothing uses it yet but this adds the data structure as well as all of<br>
> the code to validate, print, clone, and [de]serialize them.<br>
><br>
> Cc: Rob Clark <<a href="mailto:robdclark@gmail.com">robdclark@gmail.com</a>><br>
> Cc: Connor Abbott <<a href="mailto:cwabbott0@gmail.com">cwabbott0@gmail.com</a>><br>
><br>
> ---<br>
><br>
> This is not tested beyond compile testing. I'm sending it out ahead so<br>
> that people can comment on the instruction data structure. I think this<br>
> should handle all the SPIR-V use-cases fairly nicely as well as the<br>
> use-cases we have today.<br>
><br>
> src/compiler/nir/nir.c | 49 +++++++++++++++++++++++<br>
> src/compiler/nir/nir.h | 47 +++++++++++++++++++++-<br>
> src/compiler/nir/nir_clone.c | 45 +++++++++++++++++++++<br>
> src/compiler/nir/nir_print.c | 46 ++++++++++++++++++++++<br>
> src/compiler/nir/nir_<wbr>serialize.c | 85 ++++++++++++++++++++++++++++++<wbr>++++++++++<br>
> src/compiler/nir/nir_validate.<wbr>c | 67 ++++++++++++++++++++++++++++++<wbr>+<br>
> 6 files changed, 338 insertions(+), 1 deletion(-)<br>
><br>
> diff --git a/src/compiler/nir/nir.c b/src/compiler/nir/nir.c<br>
> index a97b119..1023eb9 100644<br>
> --- a/src/compiler/nir/nir.c<br>
> +++ b/src/compiler/nir/nir.c<br>
> @@ -469,6 +469,26 @@ nir_alu_instr_create(nir_<wbr>shader *shader, nir_op op)<br>
> return instr;<br>
> }<br>
><br>
> +nir_deref_instr *<br>
> +nir_deref_instr_create(nir_<wbr>shader *shader, nir_deref_type deref_type)<br>
> +{<br>
> + nir_deref_instr *instr =<br>
> + rzalloc_size(shader, sizeof(nir_deref_instr));<br>
> +<br>
> + instr_init(&instr->instr, nir_instr_type_deref);<br>
> +<br>
> + instr->deref_type = deref_type;<br>
> + if (deref_type != nir_deref_type_var)<br>
> + src_init(&instr->parent);<br>
> +<br>
> + if (deref_type == nir_deref_type_array_indirect)<br>
> + src_init(&instr->arr.indirect)<wbr>;<br>
> +<br>
> + dest_init(&instr->dest);<br>
> +<br>
> + return instr;<br>
> +}<br>
> +<br>
> nir_jump_instr *<br>
> nir_jump_instr_create(nir_<wbr>shader *shader, nir_jump_type type)<br>
> {<br>
> @@ -1198,6 +1218,12 @@ visit_alu_dest(nir_alu_instr *instr, nir_foreach_dest_cb cb, void *state)<br>
> }<br>
><br>
> static bool<br>
> +visit_deref_dest(nir_deref_<wbr>instr *instr, nir_foreach_dest_cb cb, void *state)<br>
> +{<br>
> + return cb(&instr->dest, state);<br>
> +}<br>
> +<br>
> +static bool<br>
> visit_intrinsic_dest(nir_<wbr>intrinsic_instr *instr, nir_foreach_dest_cb cb,<br>
> void *state)<br>
> {<br>
> @@ -1238,6 +1264,8 @@ nir_foreach_dest(nir_instr *instr, nir_foreach_dest_cb cb, void *state)<br>
> switch (instr->type) {<br>
> case nir_instr_type_alu:<br>
> return visit_alu_dest(nir_instr_as_<wbr>alu(instr), cb, state);<br>
> + case nir_instr_type_deref:<br>
> + return visit_deref_dest(nir_instr_as_<wbr>deref(instr), cb, state);<br>
> case nir_instr_type_intrinsic:<br>
> return visit_intrinsic_dest(nir_<wbr>instr_as_intrinsic(instr), cb, state);<br>
> case nir_instr_type_tex:<br>
> @@ -1349,6 +1377,23 @@ visit_alu_src(nir_alu_instr *instr, nir_foreach_src_cb cb, void *state)<br>
> }<br>
><br>
> static bool<br>
> +visit_deref_instr_src(nir_<wbr>deref_instr *instr,<br>
> + nir_foreach_src_cb cb, void *state)<br>
> +{<br>
> + if (instr->deref_type != nir_deref_type_var) {<br>
> + if (!visit_src(&instr->parent, cb, state))<br>
> + return false;<br>
> + }<br>
> +<br>
> + if (instr->deref_type == nir_deref_type_array_indirect) {<br>
> + if (!visit_src(&instr->arr.<wbr>indirect, cb, state))<br>
> + return false;<br>
> + }<br>
> +<br>
> + return true;<br>
> +}<br>
> +<br>
> +static bool<br>
> visit_tex_src(nir_tex_instr *instr, nir_foreach_src_cb cb, void *state)<br>
> {<br>
> for (unsigned i = 0; i < instr->num_srcs; i++) {<br>
> @@ -1436,6 +1481,10 @@ nir_foreach_src(nir_instr *instr, nir_foreach_src_cb cb, void *state)<br>
> if (!visit_alu_src(nir_instr_as_<wbr>alu(instr), cb, state))<br>
> return false;<br>
> break;<br>
> + case nir_instr_type_deref:<br>
> + if (!visit_deref_instr_src(nir_<wbr>instr_as_deref(instr), cb, state))<br>
> + return false;<br>
> + break;<br>
> case nir_instr_type_intrinsic:<br>
> if (!visit_intrinsic_src(nir_<wbr>instr_as_intrinsic(instr), cb, state))<br>
> return false;<br>
> diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h<br>
> index 839d403..a40a3a0 100644<br>
> --- a/src/compiler/nir/nir.h<br>
> +++ b/src/compiler/nir/nir.h<br>
> @@ -421,6 +421,7 @@ typedef struct nir_register {<br>
><br>
> typedef enum {<br>
> nir_instr_type_alu,<br>
> + nir_instr_type_deref,<br>
> nir_instr_type_call,<br>
> nir_instr_type_tex,<br>
> nir_instr_type_intrinsic,<br>
> @@ -888,7 +889,10 @@ bool nir_alu_srcs_equal(const nir_alu_instr *alu1, const nir_alu_instr *alu2,<br>
> typedef enum {<br>
> nir_deref_type_var,<br>
> nir_deref_type_array,<br>
> - nir_deref_type_struct<br>
> + nir_deref_type_struct,<br>
> + nir_deref_type_array_direct,<br>
> + nir_deref_type_array_indirect,<br>
> + nir_deref_type_array_wildcard,<br>
> } nir_deref_type;<br>
><br>
> typedef struct nir_deref {<br>
> @@ -950,6 +954,42 @@ nir_deref_tail(nir_deref *deref)<br>
> typedef struct {<br>
> nir_instr instr;<br>
><br>
> + /** The type of this deref instruction */<br>
> + nir_deref_type deref_type;<br>
> +<br>
> + /** The mode of the underlying variable */<br>
> + nir_variable_mode mode;<br>
> +<br>
> + /** The dereferenced type of the resulting pointer value */<br>
> + const struct glsl_type *type;<br>
> +<br>
> + union {<br>
> + /** Variable being dereferenced if deref_type is a deref_var */<br>
> + nir_variable *var;<br>
> +<br>
> + /** Parent deref if deref_type is not deref_var */<br>
> + nir_src parent;<br>
> + };<br>
> +<br>
> + /** Additional deref parameters */<br>
> + union {<br>
> + struct {<br>
> + unsigned base_offset;<br>
> + nir_src indirect;<br>
> + } arr;<br>
> +<br>
> + struct {<br>
> + unsigned index;<br>
> + } strct;<br>
> + };<br>
> +<br>
> + /** Destination to store the resulting "pointer" */<br>
> + nir_dest dest;<br>
> +} nir_deref_instr;<br>
> +<br>
> +typedef struct {<br>
> + nir_instr instr;<br>
> +<br>
> unsigned num_params;<br>
> nir_deref_var **params;<br>
> nir_deref_var *return_deref;<br>
> @@ -1521,6 +1561,8 @@ typedef struct {<br>
><br>
> NIR_DEFINE_CAST(nir_instr_as_<wbr>alu, nir_instr, nir_alu_instr, instr,<br>
> type, nir_instr_type_alu)<br>
> +NIR_DEFINE_CAST(nir_instr_as_<wbr>deref, nir_instr, nir_deref_instr, instr,<br>
> + type, nir_instr_type_deref)<br>
> NIR_DEFINE_CAST(nir_instr_as_<wbr>call, nir_instr, nir_call_instr, instr,<br>
> type, nir_instr_type_call)<br>
> NIR_DEFINE_CAST(nir_instr_as_<wbr>jump, nir_instr, nir_jump_instr, instr,<br>
> @@ -2047,6 +2089,9 @@ void nir_metadata_preserve(nir_<wbr>function_impl *impl, nir_metadata preserved);<br>
> /** creates an instruction with default swizzle/writemask/etc. with NULL registers */<br>
> nir_alu_instr *nir_alu_instr_create(nir_<wbr>shader *shader, nir_op op);<br>
><br>
> +nir_deref_instr *nir_deref_instr_create(nir_<wbr>shader *shader,<br>
> + nir_deref_type deref_type);<br>
> +<br>
> nir_jump_instr *nir_jump_instr_create(nir_<wbr>shader *shader, nir_jump_type type);<br>
><br>
> nir_load_const_instr *nir_load_const_instr_create(<wbr>nir_shader *shader,<br>
> diff --git a/src/compiler/nir/nir_clone.c b/src/compiler/nir/nir_clone.c<br>
> index bcfdaa7..98b3f98 100644<br>
> --- a/src/compiler/nir/nir_clone.c<br>
> +++ b/src/compiler/nir/nir_clone.c<br>
> @@ -346,6 +346,49 @@ clone_alu(clone_state *state, const nir_alu_instr *alu)<br>
> return nalu;<br>
> }<br>
><br>
> +static nir_deref_instr *<br>
> +clone_deref_instr(clone_state *state, const nir_deref_instr *deref)<br>
> +{<br>
> + nir_deref_instr *nderef =<br>
> + nir_deref_instr_create(state-><wbr>ns, deref->deref_type);<br>
> +<br>
> + __clone_dst(state, &nderef->instr, &nderef->dest, &deref->dest);<br>
> +<br>
> + nderef->mode = deref->mode;<br>
> + nderef->type = deref->type;<br>
> +<br>
> + if (deref->deref_type == nir_deref_type_var) {<br>
> + nderef->var = remap_var(state, deref->var);<br>
> + } else {<br>
> + __clone_src(state, &nderef->instr, &nderef->parent, &deref->parent);<br>
> + }<br>
> +<br>
> + switch (deref->deref_type) {<br>
> + case nir_deref_type_struct:<br>
> + nderef->strct.index = deref->strct.index;<br>
> + break;<br>
> +<br>
> + case nir_deref_type_array_indirect:<br>
> + __clone_src(state, &nderef->instr,<br>
> + &nderef->arr.indirect, &deref->arr.indirect);<br>
> + /* fall through */<br>
> +<br>
> + case nir_deref_type_array_direct:<br>
> + nderef->arr.base_offset = deref->arr.base_offset;<br>
> + break;<br>
> +<br>
> + case nir_deref_type_var:<br>
> + case nir_deref_type_array_wildcard:<br>
> + /* Nothing to do */<br>
> + break;<br>
> +<br>
> + default:<br>
> + unreachable("Invalid instruction deref type");<br>
> + }<br>
> +<br>
> + return nderef;<br>
> +}<br>
> +<br>
> static nir_intrinsic_instr *<br>
> clone_intrinsic(clone_state *state, const nir_intrinsic_instr *itr)<br>
> {<br>
> @@ -502,6 +545,8 @@ clone_instr(clone_state *state, const nir_instr *instr)<br>
> switch (instr->type) {<br>
> case nir_instr_type_alu:<br>
> return &clone_alu(state, nir_instr_as_alu(instr))-><wbr>instr;<br>
> + case nir_instr_type_deref:<br>
> + return &clone_deref_instr(state, nir_instr_as_deref(instr))-><wbr>instr;<br>
> case nir_instr_type_intrinsic:<br>
> return &clone_intrinsic(state, nir_instr_as_intrinsic(instr))<wbr>->instr;<br>
> case nir_instr_type_load_const:<br>
> diff --git a/src/compiler/nir/nir_print.c b/src/compiler/nir/nir_print.c<br>
> index 7888dbd..32aa3fc 100644<br>
> --- a/src/compiler/nir/nir_print.c<br>
> +++ b/src/compiler/nir/nir_print.c<br>
> @@ -486,6 +486,48 @@ print_var_decl(nir_variable *var, print_state *state)<br>
> }<br>
><br>
> static void<br>
> +print_deref_instr(nir_deref_<wbr>instr *instr, print_state *state)<br>
> +{<br>
> + FILE *fp = state->fp;<br>
> +<br>
> + print_dest(&instr->dest, state);<br>
> +<br>
> + if (instr->deref_type == nir_deref_type_var) {<br>
> + fprintf(fp, " = %s", get_var_name(instr->var, state));<br>
> + return;<br>
> + }<br>
> +<br>
> + fprintf(fp, " = &");<br>
> + print_src(&instr->parent, state);<br>
> +<br>
> + assert(instr->parent.is_ssa);<br>
> + nir_deref_instr *parent =<br>
> + nir_instr_as_deref(instr-><wbr>parent.ssa->parent_instr);<br>
> +<br>
> + switch (instr->deref_type) {<br>
> + case nir_deref_type_struct:<br>
> + fprintf(fp, "->%s",<br>
> + glsl_get_struct_elem_name(<wbr>parent->type, instr->strct.index));<br>
> + break;<br>
> +<br>
> + case nir_deref_type_array_direct:<br>
> + fprintf(fp, "[%u]", instr->arr.base_offset);<br>
> + break;<br>
> +<br>
> + case nir_deref_type_array_indirect:<br>
> + fprintf(fp, "[");<br>
> + if (instr->arr.base_offset)<br>
> + fprintf(fp, "%u + ", instr->arr.base_offset);<br>
> + print_src(&instr->arr.<wbr>indirect, state);<br>
> + fprintf(fp, "]");<br>
> + break;<br>
> +<br>
> + default:<br>
> + unreachable("Invalid deref instruction type");<br>
> + }<br>
> +}<br>
> +<br>
> +static void<br>
> print_var(nir_variable *var, print_state *state)<br>
> {<br>
> FILE *fp = state->fp;<br>
> @@ -922,6 +964,10 @@ print_instr(const nir_instr *instr, print_state *state, unsigned tabs)<br>
> print_alu_instr(nir_instr_as_<wbr>alu(instr), state);<br>
> break;<br>
><br>
> + case nir_instr_type_deref:<br>
> + print_deref_instr(nir_instr_<wbr>as_deref(instr), state);<br>
> + break;<br>
> +<br>
> case nir_instr_type_call:<br>
> print_call_instr(nir_instr_as_<wbr>call(instr), state);<br>
> break;<br>
> diff --git a/src/compiler/nir/nir_<wbr>serialize.c b/src/compiler/nir/nir_<wbr>serialize.c<br>
> index 00df49c..87e40d9 100644<br>
> --- a/src/compiler/nir/nir_<wbr>serialize.c<br>
> +++ b/src/compiler/nir/nir_<wbr>serialize.c<br>
> @@ -479,6 +479,85 @@ read_alu(read_ctx *ctx)<br>
> }<br>
><br>
> static void<br>
> +write_deref(write_ctx *ctx, const nir_deref_instr *deref)<br>
> +{<br>
> + blob_write_uint32(ctx->blob, deref->deref_type);<br>
> +<br>
> + blob_write_uint32(ctx->blob, deref->mode);<br>
> + encode_type_to_blob(ctx->blob, deref->type);<br>
> +<br>
> + write_dest(ctx, &deref->dest);<br>
> +<br>
> + if (deref->deref_type == nir_deref_type_var) {<br>
> + write_object(ctx, deref->var);<br>
> + return;<br>
> + }<br>
> +<br>
> + write_src(ctx, &deref->parent);<br>
> +<br>
> + switch (deref->deref_type) {<br>
> + case nir_deref_type_struct:<br>
> + blob_write_uint32(ctx->blob, deref->strct.index);<br>
> + break;<br>
> +<br>
> + case nir_deref_type_array_indirect:<br>
> + write_src(ctx, &deref->arr.indirect);<br>
> + /* fall through */<br>
> + case nir_deref_type_array_direct:<br>
> + blob_write_uint32(ctx->blob, deref->arr.base_offset);<br>
> + break;<br>
> +<br>
> + case nir_deref_type_array_wildcard:<br>
> + /* Nothing to do */<br>
> + break;<br>
> +<br>
> + default:<br>
> + unreachable("Invalid deref type");<br>
> + }<br>
> +}<br>
> +<br>
> +static nir_deref_instr *<br>
> +read_deref(read_ctx *ctx)<br>
> +{<br>
> + nir_deref_type deref_type = blob_read_uint32(ctx->blob);<br>
> + nir_deref_instr *deref = nir_deref_instr_create(ctx-><wbr>nir, deref_type);<br>
> +<br>
> + deref->mode = blob_read_uint32(ctx->blob);<br>
> + deref->type = decode_type_from_blob(ctx-><wbr>blob);<br>
> +<br>
> + read_dest(ctx, &deref->dest, &deref->instr);<br>
> +<br>
> + if (deref_type == nir_deref_type_var) {<br>
> + deref->var = read_object(ctx);<br>
> + return deref;<br>
> + }<br>
> +<br>
> + read_src(ctx, &deref->parent, &deref->instr);<br>
> +<br>
> + switch (deref->deref_type) {<br>
> + case nir_deref_type_struct:<br>
> + deref->strct.index = blob_read_uint32(ctx->blob);<br>
> + break;<br>
> +<br>
> + case nir_deref_type_array_indirect:<br>
> + read_src(ctx, &deref->arr.indirect, &deref->instr);<br>
> + /* fall through */<br>
> + case nir_deref_type_array_direct:<br>
> + deref->arr.base_offset = blob_read_uint32(ctx->blob);<br>
> + break;<br>
> +<br>
> + case nir_deref_type_array_wildcard:<br>
> + /* Nothing to do */<br>
> + break;<br>
> +<br>
> + default:<br>
> + unreachable("Invalid deref type");<br>
> + }<br>
> +<br>
> + return deref;<br>
> +}<br>
> +<br>
> +static void<br>
> write_intrinsic(write_ctx *ctx, const nir_intrinsic_instr *intrin)<br>
> {<br>
> blob_write_uint32(ctx->blob, intrin->intrinsic);<br>
> @@ -803,6 +882,9 @@ write_instr(write_ctx *ctx, const nir_instr *instr)<br>
> case nir_instr_type_alu:<br>
> write_alu(ctx, nir_instr_as_alu(instr));<br>
> break;<br>
> + case nir_instr_type_deref:<br>
> + write_deref(ctx, nir_instr_as_deref(instr));<br>
> + break;<br>
> case nir_instr_type_intrinsic:<br>
> write_intrinsic(ctx, nir_instr_as_intrinsic(instr))<wbr>;<br>
> break;<br>
> @@ -840,6 +922,9 @@ read_instr(read_ctx *ctx, nir_block *block)<br>
> case nir_instr_type_alu:<br>
> instr = &read_alu(ctx)->instr;<br>
> break;<br>
> + case nir_instr_type_deref:<br>
> + instr = &read_deref(ctx)->instr;<br>
> + break;<br>
> case nir_instr_type_intrinsic:<br>
> instr = &read_intrinsic(ctx)->instr;<br>
> break;<br>
> diff --git a/src/compiler/nir/nir_<wbr>validate.c b/src/compiler/nir/nir_<wbr>validate.c<br>
> index a49948f..354b32b 100644<br>
> --- a/src/compiler/nir/nir_<wbr>validate.c<br>
> +++ b/src/compiler/nir/nir_<wbr>validate.c<br>
> @@ -397,6 +397,69 @@ validate_alu_instr(nir_alu_<wbr>instr *instr, validate_state *state)<br>
> }<br>
><br>
> static void<br>
> +validate_deref_instr(nir_<wbr>deref_instr *instr, validate_state *state)<br>
> +{<br>
> + if (instr->deref_type == nir_deref_type_var) {<br>
> + /* Variable dereferences are stupid simple. */<br>
> + validate_assert(state, instr->mode == instr->var->data.mode);<br>
> + validate_assert(state, instr->type == instr->var->type);<br>
> + } else {<br>
> + /* We require the parent to be SSA. This may be lifted in the future */<br>
> + validate_assert(state, instr->parent.is_ssa);<br>
> +<br>
> + /* The parent pointer value must have the same number of components<br>
> + * as the destination.<br>
> + */<br>
> + validate_src(&instr->parent, state, nir_dest_bit_size(instr->dest)<wbr>,<br>
> + nir_dest_num_components(instr-<wbr>>dest));<br>
> +<br>
> + nir_instr *parent_instr = instr->parent.ssa->parent_<wbr>instr;<br>
> +<br>
> + /* The parent must come from another deref instruction */<br>
> + validate_assert(state, parent_instr->type == nir_instr_type_deref);<br>
<br>
</div></div>I thought a lot of the value was that we could pipe this through<br>
things like phis eventually? I'm fine with not starting that way<br>
though.<br><div><div class="h5"></div></div></blockquote><div><br></div><div>Yeah, mostly just so that we start small.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="h5">
> +<br>
> + nir_deref_instr *parent = nir_instr_as_deref(parent_<wbr>instr);<br>
> +<br>
> + validate_assert(state, instr->mode == parent->mode);<br>
> +<br>
> + switch (instr->deref_type) {<br>
> + case nir_deref_type_struct:<br>
> + validate_assert(state, glsl_type_is_struct(parent-><wbr>type));<br>
> + validate_assert(state,<br>
> + instr->strct.index < glsl_get_length(parent->type))<wbr>;<br>
> + validate_assert(state, instr->type ==<br>
> + glsl_get_struct_field(parent-><wbr>type, instr->strct.index));<br>
> + break;<br>
> +<br>
> + case nir_deref_type_array_direct:<br>
> + case nir_deref_type_array_indirect:<br>
> + case nir_deref_type_array_wildcard:<br>
> + validate_assert(state, glsl_type_is_array(parent-><wbr>type));<br>
> + validate_assert(state,<br>
> + instr->type == glsl_get_array_element(parent-<wbr>>type));<br>
> +<br>
> + if (instr->deref_type != nir_deref_type_array_wildcard) {<br>
> + validate_assert(state,<br>
> + instr->arr.base_offset < glsl_get_length(parent->type))<wbr>;<br>
> + }<br>
> +<br>
> + if (instr->deref_type == nir_deref_type_array_indirect)<br>
> + validate_src(&instr->arr.<wbr>indirect, state, 32, 1);<br>
> + break;<br>
> +<br>
> + default:<br>
> + unreachable("Invalid deref instruction type");<br>
> + }<br>
> + }<br>
> +<br>
> + /* We intentionally don't validate the size of the destination because we<br>
> + * want to let other compiler components such as SPIR-V decide how big<br>
> + * pointers should be.<br>
> + */<br>
> + validate_dest(&instr->dest, state, 0, 0);<br>
> +}<br>
> +<br>
> +static void<br>
> validate_deref_chain(nir_deref *deref, nir_variable_mode mode,<br>
> validate_state *state)<br>
> {<br>
> @@ -622,6 +685,10 @@ validate_instr(nir_instr *instr, validate_state *state)<br>
> validate_alu_instr(nir_instr_<wbr>as_alu(instr), state);<br>
> break;<br>
><br>
> + case nir_instr_type_deref:<br>
> + validate_deref_instr(nir_<wbr>instr_as_deref(instr), state);<br>
> + break;<br>
> +<br>
> case nir_instr_type_call:<br>
> validate_call_instr(nir_instr_<wbr>as_call(instr), state);<br>
> break;<br>
> --<br>
> 2.5.0.400.gff86faf<br>
><br>
</div></div>> ______________________________<wbr>_________________<br>
> mesa-dev mailing list<br>
> <a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
> <a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/<wbr>mailman/listinfo/mesa-dev</a><br>
</blockquote></div><br></div></div>