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.heikk...@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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev