On Tue, Apr 3, 2018 at 2:32 PM, Jason Ekstrand <ja...@jlekstrand.net> wrote: > --- > src/compiler/nir/nir_builder.h | 106 > +++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 106 insertions(+) > > diff --git a/src/compiler/nir/nir_builder.h b/src/compiler/nir/nir_builder.h > index 8f7ddf1..69c7261 100644 > --- a/src/compiler/nir/nir_builder.h > +++ b/src/compiler/nir/nir_builder.h > @@ -525,6 +525,112 @@ nir_ssa_for_alu_src(nir_builder *build, nir_alu_instr > *instr, unsigned srcn) > return nir_imov_alu(build, *src, num_components); > } > > +static inline nir_deref_instr * > +nir_build_deref_var(nir_builder *build, nir_variable *var) > +{ > + nir_deref_instr *deref = > + nir_deref_instr_create(build->shader, nir_deref_type_var); > + > + deref->mode = var->data.mode; > + deref->type = var->type; > + deref->var = var; > + > + nir_ssa_dest_init(&deref->instr, &deref->dest, 1, 32, NULL); > + > + nir_builder_instr_insert(build, &deref->instr); > + > + return deref; > +} > + > +static inline nir_deref_instr * > +nir_build_deref_array(nir_builder *build, nir_deref_instr *parent, > + nir_ssa_def *index) > +{ > + assert(glsl_type_is_array(parent->type) || > + glsl_type_is_matrix(parent->type) || > + glsl_type_is_vector(parent->type)); > + > + nir_deref_instr *deref = > + nir_deref_instr_create(build->shader, nir_deref_type_array); > + > + deref->mode = parent->mode; > + deref->type = glsl_get_array_element(parent->type); > + deref->parent = nir_src_for_ssa(&parent->dest.ssa); > + deref->arr.index = nir_src_for_ssa(index); > + > + nir_ssa_dest_init(&deref->instr, &deref->dest, > + parent->dest.ssa.num_components, > + parent->dest.ssa.bit_size, NULL); > + > + nir_builder_instr_insert(build, &deref->instr); > + > + return deref; > +} > + > +static inline nir_deref_instr * > +nir_build_deref_array_wildcard(nir_builder *build, nir_deref_instr *parent) > +{ > + assert(glsl_type_is_array(parent->type) || > + glsl_type_is_matrix(parent->type)); > + > + nir_deref_instr *deref = > + nir_deref_instr_create(build->shader, nir_deref_type_array_wildcard); > + > + deref->mode = parent->mode; > + deref->type = glsl_get_array_element(parent->type); > + deref->parent = nir_src_for_ssa(&parent->dest.ssa); > + > + nir_ssa_dest_init(&deref->instr, &deref->dest, > + parent->dest.ssa.num_components, > + parent->dest.ssa.bit_size, NULL); > + > + nir_builder_instr_insert(build, &deref->instr); > + > + return deref; > +} > + > +static inline nir_deref_instr * > +nir_build_deref_struct(nir_builder *build, nir_deref_instr *parent, > + unsigned index) > +{ > + assert(glsl_type_is_struct(parent->type)); > + > + nir_deref_instr *deref = > + nir_deref_instr_create(build->shader, nir_deref_type_struct); > + > + deref->mode = parent->mode; > + deref->type = glsl_get_struct_field(parent->type, index); > + deref->parent = nir_src_for_ssa(&parent->dest.ssa); > + deref->strct.index = index; > + > + nir_ssa_dest_init(&deref->instr, &deref->dest, > + parent->dest.ssa.num_components, > + parent->dest.ssa.bit_size, NULL); > + > + nir_builder_instr_insert(build, &deref->instr); > + > + return deref; > +} > + > +static inline nir_deref_instr * > +nir_build_deref_cast(nir_builder *build, nir_ssa_def *parent, > + nir_variable_mode mode, const struct glsl_type *type)
so a couple small differences between deref_cast and what I had in mind for deref_ptr: 1) deref_ptr took two ssa src's, one is the input pointer (a vec2), and the 2nd an array idx (which can be zero), which matches the 'Element' parameter in the Op*PtrAccessChain instructions. Ie. a ptr is dereferenced as ptrval[Element].foo.bar (where ptr->foo.bar or (*ptr).foo.bar is just a nice way to write ptr[0].foo.bar) 2) not sure nir_variable_mode makes sense with pointers.. well maybe we need to add some nir_variable_mode values to differentiate between global/local/const memory spaces (I couldn't think of a good name for global since nir_var_global is already taken but has a different meaning). But in any case, the variable mode comes from the pointer value itself. Other random thought, I don't think we should allow a deref_cast (if that is what we use for pointers) to have a src instruction that is a deref instruction. We probably instead want an intrinsic that evaluates to the address of a deref chain. So something like: ptr2 = &ptr1->foo; ptr2++; result_val = ptr2->bar; becomes something like: vec1 64 ssa_0 = ... ptr1 address ... vec1 64 ssa_1 = ... ptr1 address space, ie. global/shared/const ... vec2 64 ssa_2 = vec2 ssa_0, ssa_1 vec1 32 ssa_3 = deref_cast (struct.SomeStruct *)&ssa_2[0] vec1 32 ssa_4 = deref_struct () &ssa_3->foo vec2 64 ssa_5 = intrinsic address_deref (ssa_4) () vec1 32 ssa_6 = deref_cast (struct.OtherStruct *)&ssa_5[1] vec2 64 ssa_7 = intrinsic address_deref (ssa_6) () vec1 32 ssa_8 = deref_cast (struct.OtherStruct *)&ssa_7[0] vec1 32 ssa_9 = deref_struct () &ssa_8->bar vec1 32 ssa_10 = intrinsic load_deref (ssa_9) () /* load 'result_val' */ BR, -R > +{ > + nir_deref_instr *deref = > + nir_deref_instr_create(build->shader, nir_deref_type_cast); > + > + deref->mode = mode; > + deref->type = type; > + deref->parent = nir_src_for_ssa(parent); > + > + nir_ssa_dest_init(&deref->instr, &deref->dest, > + parent->num_components, parent->bit_size, NULL); > + > + nir_builder_instr_insert(build, &deref->instr); > + > + return deref; > +} > + > static inline nir_ssa_def * > nir_load_var(nir_builder *build, nir_variable *var) > { > -- > 2.5.0.400.gff86faf > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev