[Mesa-dev] [PATCH 1/8] nir: add varying array splitting pass

Timothy Arceri tarceri at itsqueeze.com
Wed Nov 29 21:59:23 UTC 2017


On 29/11/17 21:47, Nicolai Hähnle wrote:
> On 21.11.2017 04:28, Timothy Arceri wrote:
>> V2: fix matrix support, non-array matrices were being skipped in v1
>> ---
>>   src/compiler/Makefile.sources                      |   1 +
>>   src/compiler/nir/meson.build                       |   1 +
>>   src/compiler/nir/nir.h                             |   1 +
>>   src/compiler/nir/nir_lower_io_arrays_to_elements.c | 373 
>> +++++++++++++++++++++
>>   4 files changed, 376 insertions(+)
>>   create mode 100644 src/compiler/nir/nir_lower_io_arrays_to_elements.c
>>
>> diff --git a/src/compiler/Makefile.sources 
>> b/src/compiler/Makefile.sources
>> index 2ab8e163a2..c5094b7f19 100644
>> --- a/src/compiler/Makefile.sources
>> +++ b/src/compiler/Makefile.sources
>> @@ -219,20 +219,21 @@ NIR_FILES = \
>>       nir/nir_lower_double_ops.c \
>>       nir/nir_lower_drawpixels.c \
>>       nir/nir_lower_global_vars_to_local.c \
>>       nir/nir_lower_gs_intrinsics.c \
>>       nir/nir_lower_load_const_to_scalar.c \
>>       nir/nir_lower_locals_to_regs.c \
>>       nir/nir_lower_idiv.c \
>>       nir/nir_lower_indirect_derefs.c \
>>       nir/nir_lower_int64.c \
>>       nir/nir_lower_io.c \
>> +    nir/nir_lower_io_arrays_to_elements.c \
>>       nir/nir_lower_io_to_temporaries.c \
>>       nir/nir_lower_io_to_scalar.c \
>>       nir/nir_lower_io_types.c \
>>       nir/nir_lower_passthrough_edgeflags.c \
>>       nir/nir_lower_patch_vertices.c \
>>       nir/nir_lower_phis_to_scalar.c \
>>       nir/nir_lower_regs_to_ssa.c \
>>       nir/nir_lower_returns.c \
>>       nir/nir_lower_samplers.c \
>>       nir/nir_lower_samplers_as_deref.c \
>> diff --git a/src/compiler/nir/meson.build b/src/compiler/nir/meson.build
>> index e5c8326aa0..b61a07773d 100644
>> --- a/src/compiler/nir/meson.build
>> +++ b/src/compiler/nir/meson.build
>> @@ -107,20 +107,21 @@ files_libnir = files(
>>     'nir_lower_double_ops.c',
>>     'nir_lower_drawpixels.c',
>>     'nir_lower_global_vars_to_local.c',
>>     'nir_lower_gs_intrinsics.c',
>>     'nir_lower_load_const_to_scalar.c',
>>     'nir_lower_locals_to_regs.c',
>>     'nir_lower_idiv.c',
>>     'nir_lower_indirect_derefs.c',
>>     'nir_lower_int64.c',
>>     'nir_lower_io.c',
>> +  'nir_lower_io_arrays_to_elements.c',
>>     'nir_lower_io_to_temporaries.c',
>>     'nir_lower_io_to_scalar.c',
>>     'nir_lower_io_types.c',
>>     'nir_lower_passthrough_edgeflags.c',
>>     'nir_lower_patch_vertices.c',
>>     'nir_lower_phis_to_scalar.c',
>>     'nir_lower_regs_to_ssa.c',
>>     'nir_lower_returns.c',
>>     'nir_lower_samplers.c',
>>     'nir_lower_samplers_as_deref.c',
>> diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
>> index f46f614711..c62af4afb9 100644
>> --- a/src/compiler/nir/nir.h
>> +++ b/src/compiler/nir/nir.h
>> @@ -2475,20 +2475,21 @@ bool 
>> nir_lower_constant_initializers(nir_shader *shader,
>>                                        nir_variable_mode modes);
>>   bool nir_move_vec_src_uses_to_dest(nir_shader *shader);
>>   bool nir_lower_vec_to_movs(nir_shader *shader);
>>   void nir_lower_alpha_test(nir_shader *shader, enum compare_func func,
>>                             bool alpha_to_one);
>>   bool nir_lower_alu_to_scalar(nir_shader *shader);
>>   bool nir_lower_load_const_to_scalar(nir_shader *shader);
>>   bool nir_lower_read_invocation_to_scalar(nir_shader *shader);
>>   bool nir_lower_phis_to_scalar(nir_shader *shader);
>> +void nir_lower_io_arrays_to_elements(nir_shader *producer, nir_shader 
>> *consumer);
>>   void nir_lower_io_to_scalar(nir_shader *shader, nir_variable_mode 
>> mask);
>>   void nir_lower_io_to_scalar_early(nir_shader *shader, 
>> nir_variable_mode mask);
>>   bool nir_lower_samplers(nir_shader *shader,
>>                           const struct gl_shader_program 
>> *shader_program);
>>   bool nir_lower_samplers_as_deref(nir_shader *shader,
>>                                    const struct gl_shader_program 
>> *shader_program);
>>   typedef struct nir_lower_subgroups_options {
>>      uint8_t subgroup_size;
>> diff --git a/src/compiler/nir/nir_lower_io_arrays_to_elements.c 
>> b/src/compiler/nir/nir_lower_io_arrays_to_elements.c
>> new file mode 100644
>> index 0000000000..c41f300edb
>> --- /dev/null
>> +++ b/src/compiler/nir/nir_lower_io_arrays_to_elements.c
>> @@ -0,0 +1,373 @@
>> +/*
>> + * Copyright © 2017 Timothy Arceri
>> + *
>> + * Permission is hereby granted, free of charge, to any person 
>> obtaining a
>> + * copy of this software and associated documentation files (the 
>> "Software"),
>> + * to deal in the Software without restriction, including without 
>> limitation
>> + * the rights to use, copy, modify, merge, publish, distribute, 
>> sublicense,
>> + * and/or sell copies of the Software, and to permit persons to whom the
>> + * Software is furnished to do so, subject to the following conditions:
>> + *
>> + * The above copyright notice and this permission notice (including 
>> the next
>> + * paragraph) shall be included in all copies or substantial portions 
>> of the
>> + * Software.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
>> EXPRESS OR
>> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
>> MERCHANTABILITY,
>> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT 
>> SHALL
>> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES 
>> OR OTHER
>> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
>> ARISING
>> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 
>> OTHER DEALINGS
>> + * IN THE SOFTWARE.
>> + */
>> +
>> +#include "nir.h"
>> +#include "nir_builder.h"
>> +
>> +/** @file nir_lower_io_arrays_to_elements.c
>> + *
>> + * Split arrays/matrices with direct indexing into individual 
>> elements. This
>> + * will allow optimisation passes to better clean up unused elements.
>> + *
>> + */
>> +
>> +static unsigned
>> +get_io_offset(nir_builder *b, nir_deref_var *deref, nir_variable *var,
>> +              unsigned *element_index)
>> +{
>> +   nir_deref *tail = &deref->deref;
>> +
>> +   /* For per-vertex input arrays (i.e. geometry shader inputs), skip 
>> the
>> +    * outermost array index.  Process the rest normally.
>> +    */
>> +   if (nir_is_per_vertex_io(var, b->shader->info.stage)) {
>> +      tail = tail->child;
>> +   }
>> +
>> +   unsigned offset = 0;
>> +   while (tail->child != NULL) {
>> +      tail = tail->child;
>> +
>> +      if (tail->deref_type == nir_deref_type_array) {
>> +         nir_deref_array *deref_array = nir_deref_as_array(tail);
>> +         assert(deref_array->deref_array_type != 
>> nir_deref_array_type_indirect);
>> +
>> +         unsigned size = glsl_count_attribute_slots(tail->type, false);
>> +         offset += size * deref_array->base_offset;
>> +
>> +         unsigned num_elements = glsl_type_is_array(tail->type) ?
>> +            glsl_get_aoa_size(tail->type) : 1;
>> +
>> +         num_elements *= 
>> glsl_type_is_matrix(glsl_without_array(tail->type)) ?
>> +            glsl_get_matrix_columns(glsl_without_array(tail->type)) : 1;
>> +
>> +         *element_index += num_elements * deref_array->base_offset;
>> +      } else if (tail->deref_type == nir_deref_type_struct) {
>> +         /* TODO: we could also add struct splitting support to this 
>> pass */
>> +         break;
> 
> Maybe make this an assert to emphasize the point?


Looking at this with fresh eyes this morning. An assert is not needed 
here, we can split and array of structs we just can't go any further 
than that.


More information about the mesa-dev mailing list