On Sun, Apr 8, 2018 at 7:21 AM, Rob Clark <robdcl...@gmail.com> wrote: > 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) ()
or maybe "address_from_deref" would be a better name for this intrinsic.. > 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