[Mesa-dev] [PATCH 12/22] nir: add type alignment support to lower_io

Rob Clark robdclark at gmail.com
Thu Nov 22 18:31:46 UTC 2018


On Wed, Nov 21, 2018 at 4:53 PM Jason Ekstrand <jason at jlekstrand.net> wrote:
>
> On Tue, Nov 13, 2018 at 9:48 AM Karol Herbst <kherbst at redhat.com> wrote:
>>
>> From: Rob Clark <robdclark at gmail.com>
>>
>> For cl we can have structs with 8/16/32/64 bit scalar types (as well as,
>> ofc, arrays/structs/etc), which are padded according to 'C' rules.  So
>> for lowering struct deref's we need to not just consider a field's size,
>> but also it's alignment.
>>
>> Signed-off-by: Karol Herbst <kherbst at redhat.com>
>> ---
>>  src/compiler/nir/nir.h          | 10 +++++++
>>  src/compiler/nir/nir_lower_io.c | 52 ++++++++++++++++++++++++---------
>>  2 files changed, 49 insertions(+), 13 deletions(-)
>>
>> diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
>> index c469e111b2c..11e3d18320a 100644
>> --- a/src/compiler/nir/nir.h
>> +++ b/src/compiler/nir/nir.h
>> @@ -2825,10 +2825,20 @@ typedef enum {
>>      */
>>     nir_lower_io_force_sample_interpolation = (1 << 1),
>>  } nir_lower_io_options;
>> +typedef struct nir_memory_model {
>> +   int (*type_size)(const struct glsl_type *);
>> +   int (*type_align)(const struct glsl_type *);
>> +} nir_memory_model;
>
>
> I don't really like the name "memory model".  In my mind, that implies a lot more than just a scheme for laying out memory.  Maybe nir_io_layout_cb or nir_io_type_size_align_cb?
>

I guess it is the part of the memory-model that lower_io needs.. maybe
nir_io_memory_model?  But I guess I'd rather leave the name the same
and when we need to add other things memory model related we just add
to that same struct and pass it wherever else it is needed.  It seems
nice to only have one struct of call backs for all things memory model
related and re-use that everywhere that memory model needs to be
abstracted rather than a different one for each lowering pass that
needs to care.

failing that nir_io_layout_cb is fine.. nir_io_type_size_align_cb
seems a bit clunky.

(my $0.02)

BR,
-R


> I made this comment to Karol on IRC but I did something similar but with a different approach with glsl_get_natural_size_align.  I think I like this approach better.  It's potentially a bit less efficient but it's way simpler.  We should convert the constant lowering code over to it so we can be consistent.
>
>>
>>  bool nir_lower_io(nir_shader *shader,
>>                    nir_variable_mode modes,
>>                    int (*type_size)(const struct glsl_type *),
>>                    nir_lower_io_options);
>> +// TEMP use different name to avoid fixing all the callers yet:
>> +bool nir_lower_io2(nir_shader *shader,
>> +                  nir_variable_mode modes,
>> +                  const nir_memory_model *mm,
>> +                  nir_lower_io_options);
>> +
>>  nir_src *nir_get_io_offset_src(nir_intrinsic_instr *instr);
>>  nir_src *nir_get_io_vertex_index_src(nir_intrinsic_instr *instr);
>>
>> diff --git a/src/compiler/nir/nir_lower_io.c b/src/compiler/nir/nir_lower_io.c
>> index 2a6c284de2b..292baf9e4fc 100644
>> --- a/src/compiler/nir/nir_lower_io.c
>> +++ b/src/compiler/nir/nir_lower_io.c
>> @@ -38,7 +38,7 @@
>>  struct lower_io_state {
>>     void *dead_ctx;
>>     nir_builder builder;
>> -   int (*type_size)(const struct glsl_type *type);
>> +   const nir_memory_model *mm;
>>     nir_variable_mode modes;
>>     nir_lower_io_options options;
>>  };
>> @@ -86,12 +86,26 @@ nir_is_per_vertex_io(const nir_variable *var, gl_shader_stage stage)
>>     return false;
>>  }
>>
>> +static int
>> +default_type_align(const struct glsl_type *type)
>> +{
>> +   return 1;
>> +}
>> +
>> +static inline int
>> +align(int value, int alignment)
>> +{
>> +   return (value + alignment - 1) & ~(alignment - 1);
>> +}
>
>
> we have an ALIGN macro which should be accessible from here which does exactly that.
>
>>
>> +
>>  static nir_ssa_def *
>>  get_io_offset(nir_deref_instr *deref, nir_ssa_def **vertex_index,
>>                struct lower_io_state *state, unsigned *component)
>>  {
>>     nir_builder *b = &state->builder;
>> -   int (*type_size)(const struct glsl_type *) = state->type_size;
>> +   int (*type_size)(const struct glsl_type *) = state->mm->type_size;
>> +   int (*type_align)(const struct glsl_type *) = state->mm->type_align ?
>> +      state->mm->type_align : default_type_align;
>>     nir_deref_path path;
>>     nir_deref_path_init(&path, deref, NULL);
>>
>> @@ -137,7 +151,10 @@ get_io_offset(nir_deref_instr *deref, nir_ssa_def **vertex_index,
>>
>>           unsigned field_offset = 0;
>>           for (unsigned i = 0; i < (*p)->strct.index; i++) {
>> -            field_offset += type_size(glsl_get_struct_field(parent->type, i));
>> +            const struct glsl_type *field_type =
>> +               glsl_get_struct_field(parent->type, i);
>> +            field_offset = align(field_offset, type_align(field_type));
>> +            field_offset += type_size(field_type);
>>           }
>>           offset = nir_iadd(b, offset, nir_imm_int(b, field_offset));
>>        } else {
>> @@ -207,7 +224,7 @@ lower_load(nir_intrinsic_instr *intrin, struct lower_io_state *state,
>>        nir_intrinsic_set_component(load, component);
>>
>>     if (load->intrinsic == nir_intrinsic_load_uniform)
>> -      nir_intrinsic_set_range(load, state->type_size(var->type));
>> +      nir_intrinsic_set_range(load, state->mm->type_size(var->type));
>>
>>     if (vertex_index) {
>>        load->src[0] = nir_src_for_ssa(vertex_index);
>> @@ -488,10 +505,8 @@ nir_lower_io_block(nir_block *block,
>>  }
>>
>>  static bool
>> -nir_lower_io_impl(nir_function_impl *impl,
>> -                  nir_variable_mode modes,
>> -                  int (*type_size)(const struct glsl_type *),
>> -                  nir_lower_io_options options)
>> +nir_lower_io_impl(nir_function_impl *impl, nir_variable_mode modes,
>> +                  const nir_memory_model *mm, nir_lower_io_options options)
>>  {
>>     struct lower_io_state state;
>>     bool progress = false;
>> @@ -499,7 +514,7 @@ nir_lower_io_impl(nir_function_impl *impl,
>>     nir_builder_init(&state.builder, impl);
>>     state.dead_ctx = ralloc_context(NULL);
>>     state.modes = modes;
>> -   state.type_size = type_size;
>> +   state.mm = mm;
>>     state.options = options;
>>
>>     nir_foreach_block(block, impl) {
>> @@ -514,22 +529,33 @@ nir_lower_io_impl(nir_function_impl *impl,
>>  }
>>
>>  bool
>> -nir_lower_io(nir_shader *shader, nir_variable_mode modes,
>> -             int (*type_size)(const struct glsl_type *),
>> -             nir_lower_io_options options)
>> +nir_lower_io2(nir_shader *shader, nir_variable_mode modes,
>> +             const nir_memory_model *mm, nir_lower_io_options options)
>>  {
>>     bool progress = false;
>>
>>     nir_foreach_function(function, shader) {
>>        if (function->impl) {
>>           progress |= nir_lower_io_impl(function->impl, modes,
>> -                                       type_size, options);
>> +                                       mm, options);
>>        }
>>     }
>>
>>     return progress;
>>  }
>>
>> +
>> +bool
>> +nir_lower_io(nir_shader *shader, nir_variable_mode modes,
>> +             int (*type_size)(const struct glsl_type *),
>> +             nir_lower_io_options options)
>> +{
>> +   nir_memory_model mm = {
>> +         .type_size = type_size,
>> +   };
>> +   return nir_lower_io2(shader, modes, &mm, options);
>> +}
>> +
>>  /**
>>   * Return the offset source for a load/store intrinsic.
>>   */
>> --
>> 2.19.1
>>
>> _______________________________________________
>> mesa-dev mailing list
>> mesa-dev at lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list