[Mesa-dev] [PATCH] glsl: join calculate_array_size() and calculate_array_stride()

Samuel Iglesias Gonsálvez siglesias at igalia.com
Tue Oct 27 06:08:22 PDT 2015


Reviewed-by: Samuel Iglesias Gonsálvez <siglesias at igalia.com>

On 27/10/15 12:55, Juha-Pekka Heikkila wrote:
> These helpers are ran for same case the same loop. Here joined
> their operation so the loop is ran just once. Also fixed
> out-of-memory condition here.
> 
> v2: Make the loop simpler to read as per Tapani's suggestion
> 
> Signed-off-by: Juha-Pekka Heikkila <juhapekka.heikkila at gmail.com>
> ---
>  src/glsl/linker.cpp | 190 ++++++++++++++++++++++------------------------------
>  1 file changed, 80 insertions(+), 110 deletions(-)
> 
> diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
> index cfd8f81..5404faf 100644
> --- a/src/glsl/linker.cpp
> +++ b/src/glsl/linker.cpp
> @@ -3504,80 +3504,78 @@ is_top_level_shader_storage_block_member(const char* name,
>     return result;
>  }
>  
> -static void
> -calculate_array_size(struct gl_shader_program *shProg,
> -                     struct gl_uniform_storage *uni)
> +static int
> +get_array_size(struct gl_uniform_storage *uni, const glsl_struct_field *field,
> +               char *interface_name, char *var_name)
>  {
> -   int block_index = uni->block_index;
> -   int array_size = -1;
> -   char *var_name = get_top_level_name(uni->name);
> -   char *interface_name =
> -      get_top_level_name(shProg->BufferInterfaceBlocks[block_index].Name);
> -
> -   if (strcmp(var_name, interface_name) == 0) {
> -      /* Deal with instanced array of SSBOs */
> -      char *temp_name = get_var_name(uni->name);
> -      free(var_name);
> -      var_name = get_top_level_name(temp_name);
> -      free(temp_name);
> -   }
> -
> -   for (unsigned i = 0; i < shProg->NumShaders; i++) {
> -      if (shProg->Shaders[i] == NULL)
> -         continue;
> -
> -      const gl_shader *stage = shProg->Shaders[i];
> -      foreach_in_list(ir_instruction, node, stage->ir) {
> -         ir_variable *var = node->as_variable();
> -         if (!var || !var->get_interface_type() ||
> -             var->data.mode != ir_var_shader_storage)
> -            continue;
> -
> -         const glsl_type *interface = var->get_interface_type();
> -
> -         if (strcmp(interface_name, interface->name) != 0)
> -            continue;
> -
> -         for (unsigned i = 0; i < interface->length; i++) {
> -            const glsl_struct_field *field = &interface->fields.structure[i];
> -            if (strcmp(field->name, var_name) != 0)
> -               continue;
> -            /* From GL_ARB_program_interface_query spec:
> -             *
> -             * "For the property TOP_LEVEL_ARRAY_SIZE, a single integer
> -             * identifying the number of active array elements of the top-level
> -             * shader storage block member containing to the active variable is
> -             * written to <params>.  If the top-level block member is not
> -             * declared as an array, the value one is written to <params>.  If
> -             * the top-level block member is an array with no declared size,
> -             * the value zero is written to <params>.
> -             */
> -            if (is_top_level_shader_storage_block_member(uni->name,
> -                                                         interface_name,
> -                                                         var_name))
> -               array_size = 1;
> -            else if (field->type->is_unsized_array())
> -               array_size = 0;
> -            else if (field->type->is_array())
> -               array_size = field->type->length;
> -            else
> -               array_size = 1;
> +   /* From GL_ARB_program_interface_query spec:
> +    *
> +    * "For the property TOP_LEVEL_ARRAY_SIZE, a single integer
> +    * identifying the number of active array elements of the top-level
> +    * shader storage block member containing to the active variable is
> +    * written to <params>.  If the top-level block member is not
> +    * declared as an array, the value one is written to <params>.  If
> +    * the top-level block member is an array with no declared size,
> +    * the value zero is written to <params>.
> +    */
> +   if (is_top_level_shader_storage_block_member(uni->name,
> +                                                interface_name,
> +                                                var_name))
> +      return  1;
> +   else if (field->type->is_unsized_array())
> +      return 0;
> +   else if (field->type->is_array())
> +      return field->type->length;
> +
> +   return 1;
> +}
>  
> -            goto found_top_level_array_size;
> -         }
> +static int
> +get_array_stride(struct gl_uniform_storage *uni, const glsl_type *interface,
> +                 const glsl_struct_field *field, char *interface_name,
> +                 char *var_name)
> +{
> +   /* From GL_ARB_program_interface_query:
> +    *
> +    * "For the property TOP_LEVEL_ARRAY_STRIDE, a single integer
> +    *  identifying the stride between array elements of the top-level
> +    *  shader storage block member containing the active variable is
> +    *  written to <params>.  For top-level block members declared as
> +    *  arrays, the value written is the difference, in basic machine
> +    *  units, between the offsets of the active variable for
> +    *  consecutive elements in the top-level array.  For top-level
> +    *  block members not declared as an array, zero is written to
> +    *  <params>."
> +    */
> +   if (field->type->is_array()) {
> +      const enum glsl_matrix_layout matrix_layout =
> +         glsl_matrix_layout(field->matrix_layout);
> +      bool row_major = matrix_layout == GLSL_MATRIX_LAYOUT_ROW_MAJOR;
> +      const glsl_type *array_type = field->type->fields.array;
> +
> +      if (is_top_level_shader_storage_block_member(uni->name,
> +                                                   interface_name,
> +                                                   var_name))
> +         return 0;
> +
> +      if (interface->interface_packing != GLSL_INTERFACE_PACKING_STD430) {
> +         if (array_type->is_record() || array_type->is_array())
> +            return glsl_align(array_type->std140_size(row_major), 16);
> +         else
> +            return MAX2(array_type->std140_base_alignment(row_major), 16);
> +      } else {
> +         return array_type->std430_array_stride(row_major);
>        }
>     }
> -found_top_level_array_size:
> -   free(interface_name);
> -   free(var_name);
> -   uni->top_level_array_size = array_size;
> +   return 0;
>  }
>  
>  static void
> -calculate_array_stride(struct gl_shader_program *shProg,
> -                       struct gl_uniform_storage *uni)
> +calculate_array_size_and_stride(struct gl_shader_program *shProg,
> +                                struct gl_uniform_storage *uni)
>  {
>     int block_index = uni->block_index;
> +   int array_size = -1;
>     int array_stride = -1;
>     char *var_name = get_top_level_name(uni->name);
>     char *interface_name =
> @@ -3586,9 +3584,17 @@ calculate_array_stride(struct gl_shader_program *shProg,
>     if (strcmp(var_name, interface_name) == 0) {
>        /* Deal with instanced array of SSBOs */
>        char *temp_name = get_var_name(uni->name);
> +      if (!temp_name) {
> +         linker_error(shProg, "Out of memory during linking.\n");
> +         goto write_top_level_array_size_and_stride;
> +      }
>        free(var_name);
>        var_name = get_top_level_name(temp_name);
>        free(temp_name);
> +      if (!var_name) {
> +         linker_error(shProg, "Out of memory during linking.\n");
> +         goto write_top_level_array_size_and_stride;
> +      }
>     }
>  
>     for (unsigned i = 0; i < shProg->NumShaders; i++) {
> @@ -3604,61 +3610,26 @@ calculate_array_stride(struct gl_shader_program *shProg,
>  
>           const glsl_type *interface = var->get_interface_type();
>  
> -         if (strcmp(interface_name, interface->name) != 0) {
> +         if (strcmp(interface_name, interface->name) != 0)
>              continue;
> -         }
>  
>           for (unsigned i = 0; i < interface->length; i++) {
>              const glsl_struct_field *field = &interface->fields.structure[i];
>              if (strcmp(field->name, var_name) != 0)
>                 continue;
> -            /* From GL_ARB_program_interface_query:
> -             *
> -             * "For the property TOP_LEVEL_ARRAY_STRIDE, a single integer
> -             *  identifying the stride between array elements of the top-level
> -             *  shader storage block member containing the active variable is
> -             *  written to <params>.  For top-level block members declared as
> -             *  arrays, the value written is the difference, in basic machine
> -             *  units, between the offsets of the active variable for
> -             *  consecutive elements in the top-level array.  For top-level
> -             *  block members not declared as an array, zero is written to
> -             *  <params>."
> -             */
> -            if (field->type->is_array()) {
> -               const enum glsl_matrix_layout matrix_layout =
> -                  glsl_matrix_layout(field->matrix_layout);
> -               bool row_major = matrix_layout == GLSL_MATRIX_LAYOUT_ROW_MAJOR;
> -               const glsl_type *array_type = field->type->fields.array;
> -
> -               if (is_top_level_shader_storage_block_member(uni->name,
> -                                                            interface_name,
> -                                                            var_name)) {
> -                  array_stride = 0;
> -                  goto found_top_level_array_stride;
> -               }
> -               if (interface->interface_packing != GLSL_INTERFACE_PACKING_STD430) {
> -                  if (array_type->is_record() || array_type->is_array()) {
> -                     array_stride = array_type->std140_size(row_major);
> -                     array_stride = glsl_align(array_stride, 16);
> -                  } else {
> -                     unsigned element_base_align = 0;
> -                     element_base_align = array_type->std140_base_alignment(row_major);
> -                     array_stride = MAX2(element_base_align, 16);
> -                  }
> -               } else {
> -                  array_stride = array_type->std430_array_stride(row_major);
> -               }
> -            } else {
> -               array_stride = 0;
> -            }
> -            goto found_top_level_array_stride;
> +
> +            array_stride = get_array_stride(uni, interface, field,
> +                                            interface_name, var_name);
> +            array_size = get_array_size(uni, field, interface_name, var_name);
> +            goto write_top_level_array_size_and_stride;
>           }
>        }
>     }
> -found_top_level_array_stride:
> +write_top_level_array_size_and_stride:
>     free(interface_name);
>     free(var_name);
>     uni->top_level_array_stride = array_stride;
> +   uni->top_level_array_size = array_size;
>  }
>  
>  /**
> @@ -3746,8 +3717,7 @@ build_program_resource_list(struct gl_shader_program *shProg)
>           continue;
>  
>        if (is_shader_storage) {
> -         calculate_array_size(shProg, &shProg->UniformStorage[i]);
> -         calculate_array_stride(shProg, &shProg->UniformStorage[i]);
> +         calculate_array_size_and_stride(shProg, &shProg->UniformStorage[i]);
>        }
>  
>        if (!add_program_resource(shProg, type,
> 


More information about the mesa-dev mailing list