glsl: Check earlier for MaxTextureImageUnits and MaxImageUniforms
authorCaio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Sat, 9 Nov 2019 06:21:10 +0000 (22:21 -0800)
committerCaio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Mon, 11 Nov 2019 18:58:40 +0000 (10:58 -0800)
Currently the linker do all the work then check for the limits, which
means num_textures and num_images in shader_info may have to store more
than the limit.  This breaks down now since shader_info was packed and
doesn't expect to store larger invalid values.

To fix this, pull the check before we set the counts in shader_info.
Add necessary plumbing to make sure we bail once those errors are
found.

Fixes: 84a1a2578da ("compiler: pack shader_info from 160 bytes to 96 bytes")
Reviewed-by: Timothy Arceri <tarceri@itsqueeze.com>
src/compiler/glsl/link_uniforms.cpp
src/compiler/glsl/linker.cpp

index d588f3fc190fe55e9dfea4356951843b89e9a2e4..ceeb7f244356248d4c53c3d2975ec223d8940535 100644 (file)
@@ -1505,6 +1505,22 @@ link_assign_uniform_locations(struct gl_shader_program *prog,
          uniform_size.process(var);
       }
 
+      if (uniform_size.num_shader_samplers >
+          ctx->Const.Program[i].MaxTextureImageUnits) {
+         linker_error(prog, "Too many %s shader texture samplers\n",
+                      _mesa_shader_stage_to_string(i));
+         continue;
+      }
+
+      if (uniform_size.num_shader_images >
+          ctx->Const.Program[i].MaxImageUniforms) {
+         linker_error(prog, "Too many %s shader image uniforms (%u > %u)\n",
+                      _mesa_shader_stage_to_string(i),
+                      sh->Program->info.num_images,
+                      ctx->Const.Program[i].MaxImageUniforms);
+         continue;
+      }
+
       sh->Program->info.num_textures = uniform_size.num_shader_samplers;
       sh->Program->info.num_images = uniform_size.num_shader_images;
       sh->num_uniform_components = uniform_size.num_shader_uniform_components;
@@ -1516,6 +1532,11 @@ link_assign_uniform_locations(struct gl_shader_program *prog,
       }
    }
 
+   if (prog->data->LinkStatus == LINKING_FAILURE) {
+      delete hiddenUniforms;
+      return;
+   }
+
    prog->data->NumUniformStorage = uniform_size.num_active_uniforms;
    prog->data->NumHiddenUniforms = uniform_size.num_hidden_uniforms;
 
index d39c63ae7439d024a16d03f3a5ab1149204743c1..977d91f5118b129f31d04ba8574b42de4190acf2 100644 (file)
@@ -3336,12 +3336,6 @@ check_resources(struct gl_context *ctx, struct gl_shader_program *prog)
       if (sh == NULL)
          continue;
 
-      if (sh->Program->info.num_textures >
-          ctx->Const.Program[i].MaxTextureImageUnits) {
-         linker_error(prog, "Too many %s shader texture samplers\n",
-                      _mesa_shader_stage_to_string(i));
-      }
-
       if (sh->num_uniform_components >
           ctx->Const.Program[i].MaxUniformComponents) {
          if (ctx->Const.GLSLSkipStrictMaxUniformLimitCheck) {
@@ -3473,12 +3467,6 @@ check_image_resources(struct gl_context *ctx, struct gl_shader_program *prog)
       struct gl_linked_shader *sh = prog->_LinkedShaders[i];
 
       if (sh) {
-         if (sh->Program->info.num_images > ctx->Const.Program[i].MaxImageUniforms)
-            linker_error(prog, "Too many %s shader image uniforms (%u > %u)\n",
-                         _mesa_shader_stage_to_string(i),
-                         sh->Program->info.num_images,
-                         ctx->Const.Program[i].MaxImageUniforms);
-
          total_image_units += sh->Program->info.num_images;
          total_shader_storage_blocks += sh->Program->info.num_ssbos;
 
@@ -4765,6 +4753,9 @@ link_and_validate_uniforms(struct gl_context *ctx,
    update_array_sizes(prog);
    link_assign_uniform_locations(prog, ctx);
 
+   if (prog->data->LinkStatus == LINKING_FAILURE)
+      return;
+
    link_assign_atomic_counter_resources(ctx, prog);
    link_calculate_subroutine_compat(prog);
    check_resources(ctx, prog);