Patch adds gl_shader_program structure as additional parameter to do_dead_code optimization pass. This pass is modified to check if any removed uniform has explicit location set and in this case add this location to a list of reserved locations in the program structure. This information will be utilized when assigning uniform locations.
Signed-off-by: Tapani Pälli <tapani.pa...@intel.com> --- src/glsl/glsl_parser_extras.cpp | 2 +- src/glsl/ir_optimization.h | 3 ++- src/glsl/opt_dead_code.cpp | 40 ++++++++++++++++++++++++++++++++++++++-- 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/glsl/glsl_parser_extras.cpp b/src/glsl/glsl_parser_extras.cpp index e5fcd91..4e35bc0 100644 --- a/src/glsl/glsl_parser_extras.cpp +++ b/src/glsl/glsl_parser_extras.cpp @@ -1532,7 +1532,7 @@ do_common_optimization(exec_list *ir, bool linked, } if (linked) - progress = do_dead_code(ir, uniform_locations_assigned) || progress; + progress = do_dead_code(ir, uniform_locations_assigned, prog) || progress; else progress = do_dead_code_unlinked(ir) || progress; progress = do_dead_code_local(ir) || progress; diff --git a/src/glsl/ir_optimization.h b/src/glsl/ir_optimization.h index 8db6e2e..3dde51e 100644 --- a/src/glsl/ir_optimization.h +++ b/src/glsl/ir_optimization.h @@ -82,7 +82,8 @@ void do_dead_builtin_varyings(struct gl_context *ctx, gl_shader *producer, gl_shader *consumer, unsigned num_tfeedback_decls, class tfeedback_decl *tfeedback_decls); -bool do_dead_code(exec_list *instructions, bool uniform_locations_assigned); +bool do_dead_code(exec_list *instructions, bool uniform_locations_assigned, + struct gl_shader_program *prog = NULL); bool do_dead_code_local(exec_list *instructions); bool do_dead_code_unlinked(exec_list *instructions); bool do_dead_functions(exec_list *instructions); diff --git a/src/glsl/opt_dead_code.cpp b/src/glsl/opt_dead_code.cpp index af53d94..3e33d8e 100644 --- a/src/glsl/opt_dead_code.cpp +++ b/src/glsl/opt_dead_code.cpp @@ -29,6 +29,7 @@ #include "ir.h" #include "ir_visitor.h" +#include "ir_uniform.h" #include "ir_variable_refcount.h" #include "glsl_types.h" #include "main/hash_table.h" @@ -43,7 +44,8 @@ static bool debug = false; * for usage on an unlinked instruction stream. */ bool -do_dead_code(exec_list *instructions, bool uniform_locations_assigned) +do_dead_code(exec_list *instructions, bool uniform_locations_assigned, + struct gl_shader_program *prog) { ir_variable_refcount_visitor v; bool progress = false; @@ -104,6 +106,40 @@ do_dead_code(exec_list *instructions, bool uniform_locations_assigned) entry->var->constant_value)) continue; + /* Build a list of explicit locations of the removed uniforms, we + * need this because even though such uniform is inactive, it's + * location must be reserved. + * + * The GL_ARB_explicit_uniform_location spec says: + * "No two default-block uniform variables in the program can have + * the same location, even if they are unused, otherwise a compiler + * or linker error will be generated." + * + * "When the linker generates locations for uniforms without an + * explicit location, it assumes for all uniforms with an explicit + * location all their array elements and structure members are + * used and the linker will not generate a conflicting location, + * even if that element of member is deemed unused." + */ + if ((entry->var->data.mode == ir_var_uniform && + entry->var->data.explicit_location) && + strncmp(entry->var->name, "gl_", 3) != 0) { + + prog->ReservedUniformLocations = + reralloc(prog, + prog->ReservedUniformLocations, + unsigned, + prog->NumReservedLocations + 2); + + /* Store location and component slot count. */ + prog->ReservedUniformLocations[prog->NumReservedLocations] = + entry->var->data.location; + prog->ReservedUniformLocations[prog->NumReservedLocations + 1] = + entry->var->type->component_slots(); + + prog->NumReservedLocations += 2; + } + entry->var->remove(); progress = true; @@ -140,7 +176,7 @@ do_dead_code_unlinked(exec_list *instructions) * inside the body of the function, something has already gone * terribly, terribly wrong. */ - if (do_dead_code(&sig->body, false)) + if (do_dead_code(&sig->body, false, NULL)) progress = true; } } -- 1.8.3.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev