glsl: error check max user assignable uniform locations
authorTimothy Arceri <tarceri@itsqueeze.com>
Thu, 5 Mar 2020 23:27:44 +0000 (10:27 +1100)
committerMarge Bot <eric+marge@anholt.net>
Sat, 18 Apr 2020 11:50:44 +0000 (11:50 +0000)
This adds the error check to the NIR uniform linker.

Reviewed-by: Alejandro PiƱeiro <apinheiro@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4623>

src/compiler/glsl/gl_nir_link_uniforms.c

index 69d7aa57022971d44266c1e0d28598775a1d6c38..de168eb1a3a0fa5c4fe4703a5ca7a3a4951f3f1f 100644 (file)
@@ -48,6 +48,8 @@ static void
 nir_setup_uniform_remap_tables(struct gl_context *ctx,
                                struct gl_shader_program *prog)
 {
+   unsigned total_entries = prog->NumExplicitUniformLocations;
+
    /* For glsl this may have been allocated by reserve_explicit_locations() so
     * that we can keep track of unused uniforms with explicit locations.
     */
@@ -122,6 +124,13 @@ nir_setup_uniform_remap_tables(struct gl_context *ctx,
       /* How many entries for this uniform? */
       const unsigned entries = MAX2(1, uniform->array_elements);
 
+      /* Add new entries to the total amount for checking against MAX_UNIFORM-
+       * _LOCATIONS. This only applies to the default uniform block (-1),
+       * because locations of uniform block entries are not assignable.
+       */
+      if (prog->data->UniformStorage[i].block_index == -1)
+         total_entries += entries;
+
       unsigned location =
          link_util_find_empty_block(prog, &prog->data->UniformStorage[i]);
 
@@ -155,6 +164,15 @@ nir_setup_uniform_remap_tables(struct gl_context *ctx,
       }
    }
 
+   /* Verify that total amount of entries for explicit and implicit locations
+    * is less than MAX_UNIFORM_LOCATIONS.
+    */
+   if (total_entries > ctx->Const.MaxUserAssignableUniformLocations) {
+      linker_error(prog, "count of uniform locations > MAX_UNIFORM_LOCATIONS"
+                   "(%u > %u)", total_entries,
+                   ctx->Const.MaxUserAssignableUniformLocations);
+   }
+
    /* Reserve all the explicit locations of the active subroutine uniforms. */
    for (unsigned i = 0; i < prog->data->NumUniformStorage; i++) {
       struct gl_uniform_storage *uniform = &prog->data->UniformStorage[i];