[Mesa-dev] [WIP 06/13] glsl: change do_dead_code signature, store uniform locations

Tapani Pälli tapani.palli at intel.com
Thu Mar 27 23:45:29 PDT 2014


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.palli at 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



More information about the mesa-dev mailing list