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

Juha-Pekka Heikkila juhapekka.heikkila at gmail.com
Wed Oct 21 06:12:46 PDT 2015


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.

Signed-off-by: Juha-Pekka Heikkila <juhapekka.heikkila at gmail.com>
---
 src/glsl/linker.cpp | 112 +++++++++++++++++-----------------------------------
 1 file changed, 37 insertions(+), 75 deletions(-)

diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
index 25ca928..175d90b 100644
--- a/src/glsl/linker.cpp
+++ b/src/glsl/linker.cpp
@@ -3471,11 +3471,12 @@ is_top_level_shader_storage_block_member(const char* name,
 }
 
 static void
-calculate_array_size(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 =
       get_top_level_name(shProg->BufferInterfaceBlocks[block_index].Name);
@@ -3483,9 +3484,17 @@ calculate_array_size(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++) {
@@ -3508,76 +3517,7 @@ calculate_array_size(struct gl_shader_program *shProg,
             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;
 
-            goto found_top_level_array_size;
-         }
-      }
-   }
-found_top_level_array_size:
-   free(interface_name);
-   free(var_name);
-   uni->top_level_array_size = array_size;
-}
-
-static void
-calculate_array_stride(struct gl_shader_program *shProg,
-                       struct gl_uniform_storage *uni)
-{
-   int block_index = uni->block_index;
-   int array_stride = -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:
              *
              * "For the property TOP_LEVEL_ARRAY_STRIDE, a single integer
@@ -3617,14 +3557,37 @@ calculate_array_stride(struct gl_shader_program *shProg,
             } else {
                array_stride = 0;
             }
-            goto found_top_level_array_stride;
+found_top_level_array_stride:
+            /* 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;
+
+            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;
 }
 
 /**
@@ -3712,8 +3675,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,
-- 
1.9.1



More information about the mesa-dev mailing list