mesa: validate sampler type across the whole program
authorTimothy Arceri <tarceri@itsqueeze.com>
Fri, 21 Apr 2017 07:04:10 +0000 (17:04 +1000)
committerTimothy Arceri <tarceri@itsqueeze.com>
Sat, 22 Apr 2017 00:01:15 +0000 (10:01 +1000)
Currently we were only making sure types were the same within a
single stage. This looks to have regressed with 953a0af8e3f73.

Fixes: 953a0af8e3f73 ("mesa: validate sampler uniforms during gluniform calls")
Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
Reviewed-by: Tapani Pälli <tapani.palli@intel.com>
https://bugs.freedesktop.org/show_bug.cgi?id=97524

src/mesa/main/uniform_query.cpp
src/mesa/main/uniforms.c
src/mesa/program/ir_to_mesa.cpp

index c6488325a84b1939dbaf17d1d2f331b354ca0f81..e400d0eb00fb175a857c7499b71c92a05e76f644 100644 (file)
@@ -972,6 +972,8 @@ _mesa_uniform(GLint location, GLsizei count, const GLvoid *values,
     */
    if (uni->type->is_sampler()) {
       bool flushed = false;
+      shProg->SamplersValidated = GL_TRUE;
+
       for (int i = 0; i < MESA_SHADER_STAGES; i++) {
         struct gl_linked_shader *const sh = shProg->_LinkedShaders[i];
 
index 59ae4c5dce233ff998b9ff85172e61e6a9471cc6..8869b6eb22d6bf3165f066e0a840c44f3ef6fbaf 100644 (file)
@@ -67,11 +67,15 @@ void
 _mesa_update_shader_textures_used(struct gl_shader_program *shProg,
                                   struct gl_program *prog)
 {
-   memset(prog->TexturesUsed, 0, sizeof(prog->TexturesUsed));
+   GLbitfield mask = prog->SamplersUsed;
+   gl_shader_stage prog_stage =
+      _mesa_program_enum_to_shader_stage(prog->Target);
+   struct gl_linked_shader *shader = shProg->_LinkedShaders[prog_stage];
 
-   shProg->SamplersValidated = GL_TRUE;
+   assert(shader);
+
+   memset(prog->TexturesUsed, 0, sizeof(prog->TexturesUsed));
 
-   GLbitfield mask = prog->SamplersUsed;
    while (mask) {
       const int s = u_bit_scan(&mask);
       GLuint unit = prog->SamplerUnits[s];
@@ -87,8 +91,20 @@ _mesa_update_shader_textures_used(struct gl_shader_program *shProg,
        *     types pointing to the same texture image unit within a program
        *     object."
        */
-      if (prog->TexturesUsed[unit] & ~(1 << tgt))
-         shProg->SamplersValidated = GL_FALSE;
+      unsigned stages_mask = shProg->data->linked_stages;
+      while (stages_mask) {
+         const int stage = u_bit_scan(&stages_mask);
+
+         /* Skip validation if we are yet to update textures used in this
+          * stage.
+          */
+         if (prog_stage < stage)
+            break;
+
+         struct gl_program *glprog = shProg->_LinkedShaders[stage]->Program;
+         if (glprog->TexturesUsed[unit] & ~(1 << tgt))
+            shProg->SamplersValidated = GL_FALSE;
+      }
 
       prog->TexturesUsed[unit] |= (1 << tgt);
    }
index b0fecde11ca82733ee794c8728618c748909920d..39cde15e507c5652402351d6eb5b1202d1e4a816 100644 (file)
@@ -3117,6 +3117,11 @@ _mesa_glsl_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
    }
 
    if (prog->data->LinkStatus) {
+      /* Reset sampler validated to true, validation happens via the
+       * LinkShader call below.
+       */
+      prog->SamplersValidated = GL_TRUE;
+
       if (!ctx->Driver.LinkShader(ctx, prog)) {
          prog->data->LinkStatus = linking_failure;
       }