diff options
Diffstat (limited to 'src/glsl/linker.cpp')
-rw-r--r-- | src/glsl/linker.cpp | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp index 576b72a65fe..d7638facce6 100644 --- a/src/glsl/linker.cpp +++ b/src/glsl/linker.cpp @@ -360,8 +360,12 @@ cross_validate_globals(struct gl_shader_program *prog, && (var->type->fields.array == existing->type->fields.array) && ((var->type->length == 0) || (existing->type->length == 0))) { - if (existing->type->length == 0) + if (existing->type->length == 0) { existing->type = var->type; + existing->max_array_access = + MAX2(existing->max_array_access, + var->max_array_access); + } } else { linker_error_printf(prog, "%s `%s' declared as type " "`%s' and type `%s'\n", @@ -863,6 +867,28 @@ link_intrastage_shaders(void *mem_ctx, free(linking_shaders); + /* Make a pass over all global variables to ensure that arrays with + * unspecified sizes have a size specified. The size is inferred from the + * max_array_access field. + */ + foreach_list(node, linked->ir) { + ir_variable *const var = ((ir_instruction *) node)->as_variable(); + + if (var == NULL) + continue; + + if (!var->type->is_array() || (var->type->length != 0)) + continue; + + const glsl_type *type = + glsl_type::get_array_instance(var->type->fields.array, + var->max_array_access); + + assert(type != NULL); + var->type = type; + } + + return linked; } |