glsl: track total amount of uniform locations used
authorTapani Pälli <tapani.palli@intel.com>
Fri, 8 Jan 2016 06:20:25 +0000 (08:20 +0200)
committerTapani Pälli <tapani.palli@intel.com>
Tue, 12 Jan 2016 05:52:44 +0000 (07:52 +0200)
Linker missed a check for situation where we exceed max amount of
uniform locations with explicit + implicit locations. Patch adds this
check to already existing iteration over uniforms in linker.

Fixes following CTS test:
   ES31-CTS.explicit_uniform_location.uniform-loc-negative-link-max-num-of-locations

v2: use var->type->uniform_locations() (Timothy)

Signed-off-by: Tapani Pälli <tapani.palli@intel.com>
Reviewed-by: Timothy Arceri <timothy.arceri@collabora.com>
src/glsl/linker.cpp

index 418bd09e49e1640cdab4846862740c9221613586..d76cd9068c2175405e7caf40f9b1b1a880ed0bc2 100644 (file)
@@ -3130,6 +3130,7 @@ check_explicit_uniform_locations(struct gl_context *ctx,
       return;
    }
 
+   unsigned entries_total = 0;
    for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
       struct gl_shader *sh = prog->_LinkedShaders[i];
 
@@ -3138,8 +3139,12 @@ check_explicit_uniform_locations(struct gl_context *ctx,
 
       foreach_in_list(ir_instruction, node, sh->ir) {
          ir_variable *var = node->as_variable();
-         if (var && (var->data.mode == ir_var_uniform &&
-                     var->data.explicit_location)) {
+         if (!var || var->data.mode != ir_var_uniform)
+            continue;
+
+         entries_total += var->type->uniform_locations();
+
+         if (var->data.explicit_location) {
             bool ret;
             if (var->type->is_subroutine())
                ret = reserve_subroutine_explicit_locations(prog, sh, var);
@@ -3153,6 +3158,14 @@ check_explicit_uniform_locations(struct gl_context *ctx,
       }
    }
 
+   /* Verify that total amount of entries for explicit and implicit locations
+    * is less than MAX_UNIFORM_LOCATIONS.
+    */
+   if (entries_total >= ctx->Const.MaxUserAssignableUniformLocations) {
+      linker_error(prog, "count of uniform locations >= MAX_UNIFORM_LOCATIONS"
+                   "(%u >= %u)", entries_total,
+                   ctx->Const.MaxUserAssignableUniformLocations);
+   }
    delete uniform_map;
 }