mesa: only verify that enabled arrays have backing buffers
[mesa.git] / src / mesa / main / uniforms.c
index 47010badbc67670464deef9e553c198616a0aee7..f26fd784e71a979db2f55af85a7cd752dbc41d27 100644 (file)
 #include "main/shaderobj.h"
 #include "main/uniforms.h"
 #include "main/enums.h"
-#include "ir_uniform.h"
+#include "compiler/glsl/ir_uniform.h"
 #include "compiler/glsl_types.h"
 #include "program/program.h"
+#include "util/bitscan.h"
 
 /**
  * Update the vertex/fragment program's TexturesUsed array.
@@ -66,8 +67,8 @@ void
 _mesa_update_shader_textures_used(struct gl_shader_program *shProg,
                                  struct gl_program *prog)
 {
-   GLuint s;
-   struct gl_shader *shader =
+   GLbitfield mask = prog->SamplersUsed;
+   struct gl_linked_shader *shader =
       shProg->_LinkedShaders[_mesa_program_enum_to_shader_stage(prog->Target)];
 
    assert(shader);
@@ -77,26 +78,25 @@ _mesa_update_shader_textures_used(struct gl_shader_program *shProg,
 
    shProg->SamplersValidated = GL_TRUE;
 
-   for (s = 0; s < MAX_SAMPLERS; s++) {
-      if (prog->SamplersUsed & (1 << s)) {
-         GLuint unit = shader->SamplerUnits[s];
-         GLuint tgt = shader->SamplerTargets[s];
-         assert(unit < ARRAY_SIZE(prog->TexturesUsed));
-         assert(tgt < NUM_TEXTURE_TARGETS);
-
-         /* The types of the samplers associated with a particular texture
-          * unit must be an exact match.  Page 74 (page 89 of the PDF) of the
-          * OpenGL 3.3 core spec says:
-          *
-          *     "It is not allowed to have variables of different sampler
-          *     types pointing to the same texture image unit within a program
-          *     object."
-          */
-         if (prog->TexturesUsed[unit] & ~(1 << tgt))
-            shProg->SamplersValidated = GL_FALSE;
-
-         prog->TexturesUsed[unit] |= (1 << tgt);
-      }
+   while (mask) {
+      const int s = u_bit_scan(&mask);
+      GLuint unit = shader->SamplerUnits[s];
+      GLuint tgt = shader->SamplerTargets[s];
+      assert(unit < ARRAY_SIZE(prog->TexturesUsed));
+      assert(tgt < NUM_TEXTURE_TARGETS);
+
+      /* The types of the samplers associated with a particular texture
+       * unit must be an exact match.  Page 74 (page 89 of the PDF) of the
+       * OpenGL 3.3 core spec says:
+       *
+       *     "It is not allowed to have variables of different sampler
+       *     types pointing to the same texture image unit within a program
+       *     object."
+       */
+      if (prog->TexturesUsed[unit] & ~(1 << tgt))
+         shProg->SamplersValidated = GL_FALSE;
+
+      prog->TexturesUsed[unit] |= (1 << tgt);
    }
 }
 
@@ -915,7 +915,7 @@ _mesa_GetUniformLocation(GLuint programObj, const GLcharARB *name)
     *     "If program has not been successfully linked, the error
     *     INVALID_OPERATION is generated."
     */
-   if (shProg->LinkStatus == GL_FALSE) {
+   if (shProg->data->LinkStatus == GL_FALSE) {
       _mesa_error(ctx, GL_INVALID_OPERATION,
                  "glGetUniformLocation(program not linked)");
       return -1;
@@ -1002,10 +1002,10 @@ _mesa_UniformBlockBinding(GLuint program,
    if (!shProg)
       return;
 
-   if (uniformBlockIndex >= shProg->NumUniformBlocks) {
+   if (uniformBlockIndex >= shProg->data->NumUniformBlocks) {
       _mesa_error(ctx, GL_INVALID_VALUE,
                  "glUniformBlockBinding(block index %u >= %u)",
-                 uniformBlockIndex, shProg->NumUniformBlocks);
+                  uniformBlockIndex, shProg->data->NumUniformBlocks);
       return;
    }
 
@@ -1016,28 +1016,14 @@ _mesa_UniformBlockBinding(GLuint program,
       return;
    }
 
-   if (shProg->UniformBlocks[uniformBlockIndex]->Binding !=
+   if (shProg->data->UniformBlocks[uniformBlockIndex].Binding !=
        uniformBlockBinding) {
-      int i;
 
       FLUSH_VERTICES(ctx, 0);
       ctx->NewDriverState |= ctx->DriverFlags.NewUniformBuffer;
 
-      const int interface_block_index =
-         shProg->UboInterfaceBlockIndex[uniformBlockIndex];
-
-      shProg->BufferInterfaceBlocks[interface_block_index].Binding =
+      shProg->data->UniformBlocks[uniformBlockIndex].Binding =
          uniformBlockBinding;
-
-      for (i = 0; i < MESA_SHADER_STAGES; i++) {
-        int stage_index =
-            shProg->InterfaceBlockStageIndex[i][interface_block_index];
-
-        if (stage_index != -1) {
-           struct gl_shader *sh = shProg->_LinkedShaders[i];
-           sh->BufferInterfaceBlocks[stage_index].Binding = uniformBlockBinding;
-        }
-      }
    }
 }
 
@@ -1059,10 +1045,11 @@ _mesa_ShaderStorageBlockBinding(GLuint program,
    if (!shProg)
       return;
 
-   if (shaderStorageBlockIndex >= shProg->NumShaderStorageBlocks) {
+   if (shaderStorageBlockIndex >= shProg->data->NumShaderStorageBlocks) {
       _mesa_error(ctx, GL_INVALID_VALUE,
                  "glShaderStorageBlockBinding(block index %u >= %u)",
-                 shaderStorageBlockIndex, shProg->NumShaderStorageBlocks);
+                  shaderStorageBlockIndex,
+                  shProg->data->NumShaderStorageBlocks);
       return;
    }
 
@@ -1074,28 +1061,14 @@ _mesa_ShaderStorageBlockBinding(GLuint program,
       return;
    }
 
-   if (shProg->ShaderStorageBlocks[shaderStorageBlockIndex]->Binding !=
+   if (shProg->data->ShaderStorageBlocks[shaderStorageBlockIndex].Binding !=
        shaderStorageBlockBinding) {
-      int i;
 
       FLUSH_VERTICES(ctx, 0);
       ctx->NewDriverState |= ctx->DriverFlags.NewShaderStorageBuffer;
 
-      const int interface_block_index =
-         shProg->SsboInterfaceBlockIndex[shaderStorageBlockIndex];
-
-      shProg->BufferInterfaceBlocks[interface_block_index].Binding =
+      shProg->data->ShaderStorageBlocks[shaderStorageBlockIndex].Binding =
          shaderStorageBlockBinding;
-
-      for (i = 0; i < MESA_SHADER_STAGES; i++) {
-        int stage_index =
-            shProg->InterfaceBlockStageIndex[i][interface_block_index];
-
-        if (stage_index != -1) {
-           struct gl_shader *sh = shProg->_LinkedShaders[i];
-           sh->BufferInterfaceBlocks[stage_index].Binding = shaderStorageBlockBinding;
-        }
-      }
    }
 }
 
@@ -1173,6 +1146,12 @@ mesa_bufferiv(struct gl_shader_program *shProg, GLenum type,
                                   GL_REFERENCED_BY_FRAGMENT_SHADER, params,
                                   caller);
       return;
+   case GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER:
+   case GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER:
+      _mesa_program_resource_prop(shProg, res, index,
+                                  GL_REFERENCED_BY_COMPUTE_SHADER, params,
+                                  caller);
+      return;
    default:
       _mesa_error(ctx, GL_INVALID_ENUM,
                   "%s(pname 0x%x (%s))", caller, pname,