mesa: remove array size so the static assert can work
[mesa.git] / src / mesa / main / shaderapi.c
index f2b8aa449ef7008b78523dfb48fba54d3fd69940..d40a35376701a04caccba8860f70f29cbe030cf3 100644 (file)
 #include "main/mtypes.h"
 #include "main/shaderapi.h"
 #include "main/shaderobj.h"
+#include "main/uniforms.h"
 #include "program/program.h"
 #include "program/prog_parameter.h"
-#include "program/prog_uniform.h"
 #include "ralloc.h"
 #include <stdbool.h>
 #include "../glsl/glsl_parser_extras.h"
+#include "../glsl/ir_uniform.h"
 
 /** Define this to enable shader substitution (see below) */
 #define SHADER_SUBST 0
@@ -82,6 +83,8 @@ get_shader_flags(void)
          flags |= GLSL_UNIFORMS;
       if (strstr(env, "useprog"))
          flags |= GLSL_USE_PROG;
+      if (strstr(env, "errors"))
+         flags |= GLSL_REPORT_ERRORS;
    }
 
    return flags;
@@ -102,6 +105,7 @@ _mesa_init_shader_state(struct gl_context *ctx)
 
    memset(&options, 0, sizeof(options));
    options.MaxUnrollIterations = 32;
+   options.MaxIfDepth = UINT_MAX;
 
    /* Default pragma settings */
    options.DefaultPragmas.Optimize = GL_TRUE;
@@ -124,68 +128,12 @@ _mesa_free_shader_state(struct gl_context *ctx)
                                  NULL);
    _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentFragmentProgram,
                                  NULL);
+   _mesa_reference_shader_program(ctx, &ctx->Shader._CurrentFragmentProgram,
+                                 NULL);
    _mesa_reference_shader_program(ctx, &ctx->Shader.ActiveProgram, NULL);
 }
 
 
-/**
- * Return the size of the given GLSL datatype, in floats (components).
- */
-GLint
-_mesa_sizeof_glsl_type(GLenum type)
-{
-   switch (type) {
-   case GL_FLOAT:
-   case GL_INT:
-   case GL_BOOL:
-   case GL_SAMPLER_1D:
-   case GL_SAMPLER_2D:
-   case GL_SAMPLER_3D:
-   case GL_SAMPLER_CUBE:
-   case GL_SAMPLER_1D_SHADOW:
-   case GL_SAMPLER_2D_SHADOW:
-   case GL_SAMPLER_2D_RECT_ARB:
-   case GL_SAMPLER_2D_RECT_SHADOW_ARB:
-   case GL_SAMPLER_1D_ARRAY_EXT:
-   case GL_SAMPLER_2D_ARRAY_EXT:
-   case GL_SAMPLER_1D_ARRAY_SHADOW_EXT:
-   case GL_SAMPLER_2D_ARRAY_SHADOW_EXT:
-   case GL_SAMPLER_CUBE_SHADOW_EXT:
-      return 1;
-   case GL_FLOAT_VEC2:
-   case GL_INT_VEC2:
-   case GL_UNSIGNED_INT_VEC2:
-   case GL_BOOL_VEC2:
-      return 2;
-   case GL_FLOAT_VEC3:
-   case GL_INT_VEC3:
-   case GL_UNSIGNED_INT_VEC3:
-   case GL_BOOL_VEC3:
-      return 3;
-   case GL_FLOAT_VEC4:
-   case GL_INT_VEC4:
-   case GL_UNSIGNED_INT_VEC4:
-   case GL_BOOL_VEC4:
-      return 4;
-   case GL_FLOAT_MAT2:
-   case GL_FLOAT_MAT2x3:
-   case GL_FLOAT_MAT2x4:
-      return 8; /* two float[4] vectors */
-   case GL_FLOAT_MAT3:
-   case GL_FLOAT_MAT3x2:
-   case GL_FLOAT_MAT3x4:
-      return 12; /* three float[4] vectors */
-   case GL_FLOAT_MAT4:
-   case GL_FLOAT_MAT4x2:
-   case GL_FLOAT_MAT4x3:
-      return 16;  /* four float[4] vectors */
-   default:
-      _mesa_problem(NULL, "Invalid type in _mesa_sizeof_glsl_type()");
-      return 1;
-   }
-}
-
-
 /**
  * Copy string from <src> to <dst>, up to maxLength characters, returning
  * length of <dst> in <length>.
@@ -220,18 +168,12 @@ static bool
 validate_shader_target(const struct gl_context *ctx, GLenum type)
 {
    switch (type) {
-#if FEATURE_ARB_fragment_shader
    case GL_FRAGMENT_SHADER:
       return ctx->Extensions.ARB_fragment_shader;
-#endif
-#if FEATURE_ARB_vertex_shader
    case GL_VERTEX_SHADER:
       return ctx->Extensions.ARB_vertex_shader;
-#endif
-#if FEATURE_ARB_geometry_shader4
    case GL_GEOMETRY_SHADER_ARB:
-      return ctx->Extensions.ARB_geometry_shader4;
-#endif
+      return _mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_geometry_shader4;
    default:
       return false;
    }
@@ -323,98 +265,6 @@ attach_shader(struct gl_context *ctx, GLuint program, GLuint shader)
 }
 
 
-static GLint
-get_attrib_location(struct gl_context *ctx, GLuint program, const GLchar *name)
-{
-   struct gl_shader_program *shProg
-      = _mesa_lookup_shader_program_err(ctx, program, "glGetAttribLocation");
-
-   if (!shProg) {
-      return -1;
-   }
-
-   if (!shProg->LinkStatus) {
-      _mesa_error(ctx, GL_INVALID_OPERATION,
-                  "glGetAttribLocation(program not linked)");
-      return -1;
-   }
-
-   if (!name)
-      return -1;
-
-   if (shProg->VertexProgram) {
-      const struct gl_program_parameter_list *attribs =
-         shProg->VertexProgram->Base.Attributes;
-      if (attribs) {
-         GLint i = _mesa_lookup_parameter_index(attribs, -1, name);
-         if (i >= 0) {
-            return attribs->Parameters[i].StateIndexes[0];
-         }
-      }
-   }
-   return -1;
-}
-
-
-static void
-bind_attrib_location(struct gl_context *ctx, GLuint program, GLuint index,
-                     const GLchar *name)
-{
-   struct gl_shader_program *shProg;
-   const GLint size = -1; /* unknown size */
-   GLint i, oldIndex;
-   GLenum datatype = GL_FLOAT_VEC4;
-
-   shProg = _mesa_lookup_shader_program_err(ctx, program,
-                                            "glBindAttribLocation");
-   if (!shProg) {
-      return;
-   }
-
-   if (!name)
-      return;
-
-   if (strncmp(name, "gl_", 3) == 0) {
-      _mesa_error(ctx, GL_INVALID_OPERATION,
-                  "glBindAttribLocation(illegal name)");
-      return;
-   }
-
-   if (index >= ctx->Const.VertexProgram.MaxAttribs) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glBindAttribLocation(index)");
-      return;
-   }
-
-   if (shProg->LinkStatus) {
-      /* get current index/location for the attribute */
-      oldIndex = get_attrib_location(ctx, program, name);
-   }
-   else {
-      oldIndex = -1;
-   }
-
-   /* this will replace the current value if it's already in the list */
-   i = _mesa_add_attribute(shProg->Attributes, name, size, datatype, index);
-   if (i < 0) {
-      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindAttribLocation");
-      return;
-   }
-
-   /*
-    * Note that this attribute binding won't go into effect until
-    * glLinkProgram is called again.
-    */
-}
-
-
-static void
-bind_frag_data_location(struct gl_context *ctx, GLuint program,
-                        GLuint colorNumber, const GLchar *name)
-{
-   _mesa_problem(ctx, "bind_frag_data_location() not implemented yet");
-}
-
-
 static GLuint
 create_shader(struct gl_context *ctx, GLenum type)
 {
@@ -473,10 +323,12 @@ delete_shader_program(struct gl_context *ctx, GLuint name)
    if (!shProg)
       return;
 
-   shProg->DeletePending = GL_TRUE;
+   if (!shProg->DeletePending) {
+      shProg->DeletePending = GL_TRUE;
 
-   /* effectively, decr shProg's refcount */
-   _mesa_reference_shader_program(ctx, &shProg, NULL);
+      /* effectively, decr shProg's refcount */
+      _mesa_reference_shader_program(ctx, &shProg, NULL);
+   }
 }
 
 
@@ -489,10 +341,12 @@ delete_shader(struct gl_context *ctx, GLuint shader)
    if (!sh)
       return;
 
-   sh->DeletePending = GL_TRUE;
+   if (!sh->DeletePending) {
+      sh->DeletePending = GL_TRUE;
 
-   /* effectively, decr sh's refcount */
-   _mesa_reference_shader(ctx, &sh, NULL);
+      /* effectively, decr sh's refcount */
+      _mesa_reference_shader(ctx, &sh, NULL);
+   }
 }
 
 
@@ -518,7 +372,7 @@ detach_shader(struct gl_context *ctx, GLuint program, GLuint shader)
          _mesa_reference_shader(ctx, &shProg->Shaders[i], NULL);
 
          /* alloc new, smaller array */
-         newList = (struct gl_shader **)
+         newList =
             malloc((n - 1) * sizeof(struct gl_shader *));
          if (!newList) {
             _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDetachShader");
@@ -564,38 +418,6 @@ detach_shader(struct gl_context *ctx, GLuint program, GLuint shader)
 }
 
 
-static void
-get_active_attrib(struct gl_context *ctx, GLuint program, GLuint index,
-                  GLsizei maxLength, GLsizei *length, GLint *size,
-                  GLenum *type, GLchar *nameOut)
-{
-   const struct gl_program_parameter_list *attribs = NULL;
-   struct gl_shader_program *shProg;
-
-   shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveAttrib");
-   if (!shProg)
-      return;
-
-   if (shProg->VertexProgram)
-      attribs = shProg->VertexProgram->Base.Attributes;
-
-   if (!attribs || index >= attribs->NumParameters) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(index)");
-      return;
-   }
-
-   _mesa_copy_string(nameOut, maxLength, length,
-                     attribs->Parameters[index].Name);
-
-   if (size)
-      *size = attribs->Parameters[index].Size
-         / _mesa_sizeof_glsl_type(attribs->Parameters[index].DataType);
-
-   if (type)
-      *type = attribs->Parameters[index].DataType;
-}
-
-
 /**
  * Return list of shaders attached to shader program.
  */
@@ -616,16 +438,6 @@ get_attached_shaders(struct gl_context *ctx, GLuint program, GLsizei maxCount,
 }
 
 
-static GLint
-get_frag_data_location(struct gl_context *ctx, GLuint program,
-                       const GLchar *name)
-{
-   _mesa_problem(ctx, "get_frag_data_location() not implemented yet");
-   return -1;
-}
-
-
-
 /**
  * glGetHandleARB() - return ID/name of currently bound shader program.
  */
@@ -653,79 +465,135 @@ get_handle(struct gl_context *ctx, GLenum pname)
 static void
 get_programiv(struct gl_context *ctx, GLuint program, GLenum pname, GLint *params)
 {
-   const struct gl_program_parameter_list *attribs;
    struct gl_shader_program *shProg
       = _mesa_lookup_shader_program(ctx, program);
 
+   /* Is transform feedback available in this context?
+    */
+   const bool has_xfb =
+      (ctx->API == API_OPENGL && ctx->Extensions.EXT_transform_feedback)
+      || ctx->API == API_OPENGL_CORE
+      || _mesa_is_gles3(ctx);
+
+   /* Are geometry shaders available in this context?
+    */
+   const bool has_gs =
+      _mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_geometry_shader4;
+
+   /* Are uniform buffer objects available in this context?
+    */
+   const bool has_ubo =
+      (ctx->API == API_OPENGL && ctx->Extensions.ARB_uniform_buffer_object)
+      || ctx->API == API_OPENGL_CORE
+      || _mesa_is_gles3(ctx);
+
    if (!shProg) {
       _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramiv(program)");
       return;
    }
 
-   if (shProg->VertexProgram)
-      attribs = shProg->VertexProgram->Base.Attributes;
-   else
-      attribs = NULL;
-
    switch (pname) {
    case GL_DELETE_STATUS:
       *params = shProg->DeletePending;
-      break; 
+      return;
    case GL_LINK_STATUS:
       *params = shProg->LinkStatus;
-      break;
+      return;
    case GL_VALIDATE_STATUS:
       *params = shProg->Validated;
-      break;
+      return;
    case GL_INFO_LOG_LENGTH:
       *params = shProg->InfoLog ? strlen(shProg->InfoLog) + 1 : 0;
-      break;
+      return;
    case GL_ATTACHED_SHADERS:
       *params = shProg->NumShaders;
-      break;
+      return;
    case GL_ACTIVE_ATTRIBUTES:
-      *params = attribs ? attribs->NumParameters : 0;
-      break;
+      *params = _mesa_count_active_attribs(shProg);
+      return;
    case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
-      *params = _mesa_longest_parameter_name(attribs, PROGRAM_INPUT) + 1;
-      break;
+      *params = _mesa_longest_attribute_name_length(shProg);
+      return;
    case GL_ACTIVE_UNIFORMS:
-      *params = shProg->Uniforms ? shProg->Uniforms->NumUniforms : 0;
-      break;
-   case GL_ACTIVE_UNIFORM_MAX_LENGTH:
-      *params = _mesa_longest_uniform_name(shProg->Uniforms);
-      if (*params > 0)
-         (*params)++;  /* add one for terminating zero */
-      break;
-   case GL_PROGRAM_BINARY_LENGTH_OES:
-      *params = 0;
-      break;
-#if FEATURE_EXT_transform_feedback
+      *params = shProg->NumUserUniformStorage;
+      return;
+   case GL_ACTIVE_UNIFORM_MAX_LENGTH: {
+      unsigned i;
+      GLint max_len = 0;
+
+      for (i = 0; i < shProg->NumUserUniformStorage; i++) {
+        /* Add one for the terminating NUL character.
+         */
+        const GLint len = strlen(shProg->UniformStorage[i].name) + 1;
+
+        if (len > max_len)
+           max_len = len;
+      }
+
+      *params = max_len;
+      return;
+   }
    case GL_TRANSFORM_FEEDBACK_VARYINGS:
+      if (!has_xfb)
+         break;
       *params = shProg->TransformFeedback.NumVarying;
-      break;
+      return;
    case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
+      if (!has_xfb)
+         break;
       *params = longest_feedback_varying_name(shProg) + 1;
-      break;
+      return;
    case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
+      if (!has_xfb)
+         break;
       *params = shProg->TransformFeedback.BufferMode;
-      break;
-#endif
-#if FEATURE_ARB_geometry_shader4
+      return;
    case GL_GEOMETRY_VERTICES_OUT_ARB:
+      if (!has_gs)
+         break;
       *params = shProg->Geom.VerticesOut;
-      break;
+      return;
    case GL_GEOMETRY_INPUT_TYPE_ARB:
+      if (!has_gs)
+         break;
       *params = shProg->Geom.InputType;
-      break;
+      return;
    case GL_GEOMETRY_OUTPUT_TYPE_ARB:
+      if (!has_gs)
+         break;
       *params = shProg->Geom.OutputType;
-      break;
-#endif
-   default:
-      _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramiv(pname)");
       return;
+   case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: {
+      unsigned i;
+      GLint max_len = 0;
+
+      if (!has_ubo)
+         break;
+
+      for (i = 0; i < shProg->NumUniformBlocks; i++) {
+        /* Add one for the terminating NUL character.
+         */
+        const GLint len = strlen(shProg->UniformBlocks[i].Name) + 1;
+
+        if (len > max_len)
+           max_len = len;
+      }
+
+      *params = max_len;
+      return;
+   }
+   case GL_ACTIVE_UNIFORM_BLOCKS:
+      if (!has_ubo)
+         break;
+
+      *params = shProg->NumUniformBlocks;
+      return;
+   default:
+      break;
    }
+
+   _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramiv(pname=%s)",
+               _mesa_lookup_enum_by_nr(pname));
 }
 
 
@@ -809,7 +677,8 @@ get_shader_source(struct gl_context *ctx, GLuint shader, GLsizei maxLength,
 
 
 /**
- * Set/replace shader source code.
+ * Set/replace shader source code.  A helper function used by
+ * glShaderSource[ARB] and glCreateShaderProgramEXT.
  */
 static void
 shader_source(struct gl_context *ctx, GLuint shader, const GLchar *source)
@@ -821,9 +690,7 @@ shader_source(struct gl_context *ctx, GLuint shader, const GLchar *source)
       return;
 
    /* free old shader source string and install new one */
-   if (sh->Source) {
-      free((void *) sh->Source);
-   }
+   free((void *)sh->Source);
    sh->Source = source;
    sh->CompileStatus = GL_FALSE;
 #ifdef DEBUG
@@ -854,6 +721,12 @@ compile_shader(struct gl_context *ctx, GLuint shaderObj)
     * compilation was successful.
     */
    _mesa_glsl_compile_shader(ctx, sh);
+
+   if (sh->CompileStatus == GL_FALSE && 
+       (ctx->Shader.Flags & GLSL_REPORT_ERRORS)) {
+      _mesa_debug(ctx, "Error compiling shader %u:\n%s\n",
+                  sh->Name, sh->InfoLog);
+   }
 }
 
 
@@ -876,7 +749,7 @@ link_program(struct gl_context *ctx, GLuint program)
           || shProg == ctx->Shader.CurrentGeometryProgram
           || shProg == ctx->Shader.CurrentFragmentProgram)) {
       _mesa_error(ctx, GL_INVALID_OPERATION,
-                  "glLinkProgram(transform feedback active");
+                  "glLinkProgram(transform feedback active)");
       return;
    }
 
@@ -884,6 +757,12 @@ link_program(struct gl_context *ctx, GLuint program)
 
    _mesa_glsl_link_shader(ctx, shProg);
 
+   if (shProg->LinkStatus == GL_FALSE && 
+       (ctx->Shader.Flags & GLSL_REPORT_ERRORS)) {
+      _mesa_debug(ctx, "Error linking program %u:\n%s\n",
+                  shProg->Name, shProg->InfoLog);
+   }
+
    /* debug code */
    if (0) {
       GLuint i;
@@ -929,10 +808,15 @@ print_shader_info(const struct gl_shader_program *shProg)
             shProg->Shaders[i]->Name,
             shProg->Shaders[i]->SourceChecksum);
    }
-   if (shProg->VertexProgram)
-      printf("  vert prog %u\n", shProg->VertexProgram->Base.Id);
-   if (shProg->FragmentProgram)
-      printf("  frag prog %u\n", shProg->FragmentProgram->Base.Id);
+   if (shProg->_LinkedShaders[MESA_SHADER_VERTEX])
+      printf("  vert prog %u\n",
+            shProg->_LinkedShaders[MESA_SHADER_VERTEX]->Program->Id);
+   if (shProg->_LinkedShaders[MESA_SHADER_FRAGMENT])
+      printf("  frag prog %u\n",
+            shProg->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program->Id);
+   if (shProg->_LinkedShaders[MESA_SHADER_GEOMETRY])
+      printf("  geom prog %u\n",
+            shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]->Program->Id);
 }
 
 
@@ -963,7 +847,6 @@ use_shader_program(struct gl_context *ctx, GLenum type,
    struct gl_shader_program **target;
 
    switch (type) {
-#if FEATURE_ARB_vertex_shader
    case GL_VERTEX_SHADER:
       target = &ctx->Shader.CurrentVertexProgram;
       if ((shProg == NULL)
@@ -971,8 +854,6 @@ use_shader_program(struct gl_context *ctx, GLenum type,
         shProg = NULL;
       }
       break;
-#endif
-#if FEATURE_ARB_geometry_shader4
    case GL_GEOMETRY_SHADER_ARB:
       target = &ctx->Shader.CurrentGeometryProgram;
       if ((shProg == NULL)
@@ -980,8 +861,6 @@ use_shader_program(struct gl_context *ctx, GLenum type,
         shProg = NULL;
       }
       break;
-#endif
-#if FEATURE_ARB_fragment_shader
    case GL_FRAGMENT_SHADER:
       target = &ctx->Shader.CurrentFragmentProgram;
       if ((shProg == NULL)
@@ -989,13 +868,33 @@ use_shader_program(struct gl_context *ctx, GLenum type,
         shProg = NULL;
       }
       break;
-#endif
    default:
       return false;
    }
 
    if (*target != shProg) {
       FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
+
+      /* If the shader is also bound as the current rendering shader, unbind
+       * it from that binding point as well.  This ensures that the correct
+       * semantics of glDeleteProgram are maintained.
+       */
+      switch (type) {
+      case GL_VERTEX_SHADER:
+        /* Empty for now. */
+        break;
+      case GL_GEOMETRY_SHADER_ARB:
+        /* Empty for now. */
+        break;
+      case GL_FRAGMENT_SHADER:
+        if (*target == ctx->Shader._CurrentFragmentProgram) {
+           _mesa_reference_shader_program(ctx,
+                                          &ctx->Shader._CurrentFragmentProgram,
+                                          NULL);
+        }
+        break;
+      }
+
       _mesa_reference_shader_program(ctx, target, shProg);
       return true;
    }
@@ -1019,59 +918,6 @@ _mesa_use_program(struct gl_context *ctx, struct gl_shader_program *shProg)
 }
 
 
-/**
- * Validate a program's samplers.
- * Specifically, check that there aren't two samplers of different types
- * pointing to the same texture unit.
- * \return GL_TRUE if valid, GL_FALSE if invalid
- */
-static GLboolean
-validate_samplers(const struct gl_program *prog, char *errMsg)
-{
-   static const char *targetName[] = {
-      "TEXTURE_2D_ARRAY",
-      "TEXTURE_1D_ARRAY",
-      "TEXTURE_CUBE",
-      "TEXTURE_3D",
-      "TEXTURE_RECT",
-      "TEXTURE_2D",
-      "TEXTURE_1D",
-   };
-   GLint targetUsed[MAX_TEXTURE_IMAGE_UNITS];
-   GLbitfield samplersUsed = prog->SamplersUsed;
-   GLuint i;
-
-   assert(Elements(targetName) == NUM_TEXTURE_TARGETS);
-
-   if (samplersUsed == 0x0)
-      return GL_TRUE;
-
-   for (i = 0; i < Elements(targetUsed); i++)
-      targetUsed[i] = -1;
-
-   /* walk over bits which are set in 'samplers' */
-   while (samplersUsed) {
-      GLuint unit;
-      gl_texture_index target;
-      GLint sampler = _mesa_ffs(samplersUsed) - 1;
-      assert(sampler >= 0);
-      assert(sampler < MAX_TEXTURE_IMAGE_UNITS);
-      unit = prog->SamplerUnits[sampler];
-      target = prog->SamplerTargets[sampler];
-      if (targetUsed[unit] != -1 && targetUsed[unit] != (int) target) {
-         _mesa_snprintf(errMsg, 100,
-                 "Texture unit %d is accessed both as %s and %s",
-                 unit, targetName[targetUsed[unit]], targetName[target]);
-         return GL_FALSE;
-      }
-      targetUsed[unit] = target;
-      samplersUsed ^= (1 << sampler);
-   }
-
-   return GL_TRUE;
-}
-
-
 /**
  * Do validation of the given shader program.
  * \param errMsg  returns error message if validation fails.
@@ -1081,9 +927,6 @@ static GLboolean
 validate_shader_program(const struct gl_shader_program *shProg,
                         char *errMsg)
 {
-   const struct gl_vertex_program *vp = shProg->VertexProgram;
-   const struct gl_fragment_program *fp = shProg->FragmentProgram;
-
    if (!shProg->LinkStatus) {
       return GL_FALSE;
    }
@@ -1108,12 +951,8 @@ validate_shader_program(const struct gl_shader_program *shProg,
     * Check: any two active samplers in the current program object are of
     * different types, but refer to the same texture image unit,
     */
-   if (vp && !validate_samplers(&vp->Base, errMsg)) {
+   if (!_mesa_sampler_uniforms_are_valid(shProg, errMsg, 100))
       return GL_FALSE;
-   }
-   if (fp && !validate_samplers(&fp->Base, errMsg)) {
-      return GL_FALSE;
-   }
 
    return GL_TRUE;
 }
@@ -1126,7 +965,7 @@ static void
 validate_program(struct gl_context *ctx, GLuint program)
 {
    struct gl_shader_program *shProg;
-   char errMsg[100];
+   char errMsg[100] = "";
 
    shProg = _mesa_lookup_shader_program_err(ctx, program, "glValidateProgram");
    if (!shProg) {
@@ -1161,29 +1000,12 @@ _mesa_AttachShader(GLuint program, GLuint shader)
 }
 
 
-void GLAPIENTRY
-_mesa_BindAttribLocationARB(GLhandleARB program, GLuint index,
-                            const GLcharARB *name)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   bind_attrib_location(ctx, program, index, name);
-}
-
-
-/* GL_EXT_gpu_shader4, GL3 */
-void GLAPIENTRY
-_mesa_BindFragDataLocation(GLuint program, GLuint colorNumber,
-                           const GLchar *name)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   bind_frag_data_location(ctx, program, colorNumber, name);
-}
-
-
 void GLAPIENTRY
 _mesa_CompileShaderARB(GLhandleARB shaderObj)
 {
    GET_CURRENT_CONTEXT(ctx);
+   if (MESA_VERBOSE & VERBOSE_API)
+      _mesa_debug(ctx, "glCompileShader %u\n", shaderObj);
    compile_shader(ctx, shaderObj);
 }
 
@@ -1192,6 +1014,8 @@ GLuint GLAPIENTRY
 _mesa_CreateShader(GLenum type)
 {
    GET_CURRENT_CONTEXT(ctx);
+   if (MESA_VERBOSE & VERBOSE_API)
+      _mesa_debug(ctx, "glCreateShader %s\n", _mesa_lookup_enum_by_nr(type));
    return create_shader(ctx, type);
 }
 
@@ -1208,6 +1032,8 @@ GLuint GLAPIENTRY
 _mesa_CreateProgram(void)
 {
    GET_CURRENT_CONTEXT(ctx);
+   if (MESA_VERBOSE & VERBOSE_API)
+      _mesa_debug(ctx, "glCreateProgram\n");
    return create_shader_program(ctx);
 }
 
@@ -1223,8 +1049,14 @@ _mesa_CreateProgramObjectARB(void)
 void GLAPIENTRY
 _mesa_DeleteObjectARB(GLhandleARB obj)
 {
+   if (MESA_VERBOSE & VERBOSE_API) {
+      GET_CURRENT_CONTEXT(ctx);
+      _mesa_debug(ctx, "glDeleteObjectARB(%u)\n", obj);
+   }
+
    if (obj) {
       GET_CURRENT_CONTEXT(ctx);
+      FLUSH_VERTICES(ctx, 0);
       if (is_program(ctx, obj)) {
          delete_shader_program(ctx, obj);
       }
@@ -1243,6 +1075,7 @@ _mesa_DeleteProgram(GLuint name)
 {
    if (name) {
       GET_CURRENT_CONTEXT(ctx);
+      FLUSH_VERTICES(ctx, 0);
       delete_shader_program(ctx, name);
    }
 }
@@ -1253,6 +1086,7 @@ _mesa_DeleteShader(GLuint name)
 {
    if (name) {
       GET_CURRENT_CONTEXT(ctx);
+      FLUSH_VERTICES(ctx, 0);
       delete_shader(ctx, name);
    }
 }
@@ -1274,16 +1108,6 @@ _mesa_DetachShader(GLuint program, GLuint shader)
 }
 
 
-void GLAPIENTRY
-_mesa_GetActiveAttribARB(GLhandleARB program, GLuint index,
-                         GLsizei maxLength, GLsizei * length, GLint * size,
-                         GLenum * type, GLcharARB * name)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   get_active_attrib(ctx, program, index, maxLength, length, size, type, name);
-}
-
-
 void GLAPIENTRY
 _mesa_GetAttachedObjectsARB(GLhandleARB container, GLsizei maxCount,
                             GLsizei * count, GLhandleARB * obj)
@@ -1302,24 +1126,6 @@ _mesa_GetAttachedShaders(GLuint program, GLsizei maxCount,
 }
 
 
-GLint GLAPIENTRY
-_mesa_GetAttribLocationARB(GLhandleARB program, const GLcharARB * name)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   return get_attrib_location(ctx, program, name);
-}
-
-
-/* GL_EXT_gpu_shader4, GL3 */
-GLint GLAPIENTRY
-_mesa_GetFragDataLocation(GLuint program, const GLchar *name)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   return get_frag_data_location(ctx, program, name);
-}
-
-
-
 void GLAPIENTRY
 _mesa_GetInfoLogARB(GLhandleARB object, GLsizei maxLength, GLsizei * length,
                     GLcharARB * infoLog)
@@ -1466,7 +1272,7 @@ read_shader(const char *fname)
       return NULL;
    }
 
-   buffer = (char *) malloc(max);
+   buffer = malloc(max);
    len = fread(buffer, 1, max, f);
    buffer[len] = 0;
 
@@ -1503,7 +1309,7 @@ _mesa_ShaderSourceARB(GLhandleARB shaderObj, GLsizei count,
     * This array holds offsets of where the appropriate string ends, thus the
     * last element will be set to the total length of the source code.
     */
-   offsets = (GLint *) malloc(count * sizeof(GLint));
+   offsets = malloc(count * sizeof(GLint));
    if (offsets == NULL) {
       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB");
       return;
@@ -1512,7 +1318,8 @@ _mesa_ShaderSourceARB(GLhandleARB shaderObj, GLsizei count,
    for (i = 0; i < count; i++) {
       if (string[i] == NULL) {
          free((GLvoid *) offsets);
-         _mesa_error(ctx, GL_INVALID_OPERATION, "glShaderSourceARB(null string)");
+         _mesa_error(ctx, GL_INVALID_OPERATION,
+                     "glShaderSourceARB(null string)");
          return;
       }
       if (length == NULL || length[i] < 0)
@@ -1529,7 +1336,7 @@ _mesa_ShaderSourceARB(GLhandleARB shaderObj, GLsizei count,
     * valgrind warnings in the parser/grammer code.
     */
    totalLength = offsets[count - 1] + 2;
-   source = (GLcharARB *) malloc(totalLength * sizeof(GLcharARB));
+   source = malloc(totalLength * sizeof(GLcharARB));
    if (source == NULL) {
       free((GLvoid *) offsets);
       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB");
@@ -1563,7 +1370,7 @@ _mesa_ShaderSourceARB(GLhandleARB shaderObj, GLsizei count,
          free(source);
          source = newSource;
       }
-   }      
+   }
 
    shader_source(ctx, shaderObj, source);
 
@@ -1585,7 +1392,9 @@ _mesa_UseProgramObjectARB(GLhandleARB program)
    struct gl_transform_feedback_object *obj =
       ctx->TransformFeedback.CurrentObject;
 
-   if (obj->Active) {
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   if (obj->Active && !obj->Paused) {
       _mesa_error(ctx, GL_INVALID_OPERATION,
                   "glUseProgram(transform feedback active)");
       return;
@@ -1699,11 +1508,8 @@ _mesa_ShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat,
 #endif /* FEATURE_ES2 */
 
 
-#if FEATURE_ARB_geometry_shader4
-
 void GLAPIENTRY
-_mesa_ProgramParameteriARB(GLuint program, GLenum pname,
-                           GLint value)
+_mesa_ProgramParameteriARB(GLuint program, GLenum pname, GLint value)
 {
    struct gl_shader_program *shProg;
    GET_CURRENT_CONTEXT(ctx);
@@ -1718,7 +1524,7 @@ _mesa_ProgramParameteriARB(GLuint program, GLenum pname,
    switch (pname) {
    case GL_GEOMETRY_VERTICES_OUT_ARB:
       if (value < 1 ||
-          (unsigned) value > ctx->Const.GeometryProgram.MaxGeometryOutputVertices) {
+          (unsigned) value > ctx->Const.MaxGeometryOutputVertices) {
          _mesa_error(ctx, GL_INVALID_VALUE,
                      "glProgramParameteri(GL_GEOMETRY_VERTICES_OUT_ARB=%d",
                      value);
@@ -1763,8 +1569,6 @@ _mesa_ProgramParameteriARB(GLuint program, GLenum pname,
    }
 }
 
-#endif
-
 void
 _mesa_use_shader_program(struct gl_context *ctx, GLenum type,
                         struct gl_shader_program *shProg)
@@ -1775,18 +1579,25 @@ _mesa_use_shader_program(struct gl_context *ctx, GLenum type,
       ctx->Driver.UseProgram(ctx, shProg);
 }
 
+
+/**
+ * For GL_EXT_separate_shader_objects
+ */
 void GLAPIENTRY
 _mesa_UseShaderProgramEXT(GLenum type, GLuint program)
 {
    GET_CURRENT_CONTEXT(ctx);
    struct gl_shader_program *shProg = NULL;
 
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
    if (!validate_shader_target(ctx, type)) {
       _mesa_error(ctx, GL_INVALID_ENUM, "glUseShaderProgramEXT(type)");
       return;
    }
 
-   if (ctx->TransformFeedback.CurrentObject->Active) {
+   if (ctx->TransformFeedback.CurrentObject->Active &&
+       !ctx->TransformFeedback.CurrentObject->Paused) {
       _mesa_error(ctx, GL_INVALID_OPERATION,
                   "glUseShaderProgramEXT(transform feedback is active)");
       return;
@@ -1808,6 +1619,10 @@ _mesa_UseShaderProgramEXT(GLenum type, GLuint program)
    _mesa_use_shader_program(ctx, type, shProg);
 }
 
+
+/**
+ * For GL_EXT_separate_shader_objects
+ */
 void GLAPIENTRY
 _mesa_ActiveProgramEXT(GLuint program)
 {
@@ -1820,6 +1635,10 @@ _mesa_ActiveProgramEXT(GLuint program)
    return;
 }
 
+
+/**
+ * For GL_EXT_separate_shader_objects
+ */
 GLuint GLAPIENTRY
 _mesa_CreateShaderProgramEXT(GLenum type, const GLchar *string)
 {
@@ -1868,25 +1687,29 @@ _mesa_CreateShaderProgramEXT(GLenum type, const GLchar *string)
  * Plug in shader-related functions into API dispatch table.
  */
 void
-_mesa_init_shader_dispatch(struct _glapi_table *exec)
+_mesa_init_shader_dispatch(const struct gl_context *ctx,
+                           struct _glapi_table *exec)
 {
 #if FEATURE_GL
    /* GL_ARB_vertex/fragment_shader */
-   SET_DeleteObjectARB(exec, _mesa_DeleteObjectARB);
-   SET_GetHandleARB(exec, _mesa_GetHandleARB);
-   SET_DetachObjectARB(exec, _mesa_DetachObjectARB);
-   SET_CreateShaderObjectARB(exec, _mesa_CreateShaderObjectARB);
+   if (ctx->API != API_OPENGLES2) {
+      SET_DeleteObjectARB(exec, _mesa_DeleteObjectARB);
+      SET_GetHandleARB(exec, _mesa_GetHandleARB);
+      SET_DetachObjectARB(exec, _mesa_DetachObjectARB);
+      SET_CreateShaderObjectARB(exec, _mesa_CreateShaderObjectARB);
+      SET_CreateProgramObjectARB(exec, _mesa_CreateProgramObjectARB);
+      SET_AttachObjectARB(exec, _mesa_AttachObjectARB);
+      SET_GetObjectParameterfvARB(exec, _mesa_GetObjectParameterfvARB);
+      SET_GetObjectParameterivARB(exec, _mesa_GetObjectParameterivARB);
+      SET_GetInfoLogARB(exec, _mesa_GetInfoLogARB);
+      SET_GetAttachedObjectsARB(exec, _mesa_GetAttachedObjectsARB);
+   }
+
    SET_ShaderSourceARB(exec, _mesa_ShaderSourceARB);
    SET_CompileShaderARB(exec, _mesa_CompileShaderARB);
-   SET_CreateProgramObjectARB(exec, _mesa_CreateProgramObjectARB);
-   SET_AttachObjectARB(exec, _mesa_AttachObjectARB);
    SET_LinkProgramARB(exec, _mesa_LinkProgramARB);
    SET_UseProgramObjectARB(exec, _mesa_UseProgramObjectARB);
    SET_ValidateProgramARB(exec, _mesa_ValidateProgramARB);
-   SET_GetObjectParameterfvARB(exec, _mesa_GetObjectParameterfvARB);
-   SET_GetObjectParameterivARB(exec, _mesa_GetObjectParameterivARB);
-   SET_GetInfoLogARB(exec, _mesa_GetInfoLogARB);
-   SET_GetAttachedObjectsARB(exec, _mesa_GetAttachedObjectsARB);
    SET_GetShaderSourceARB(exec, _mesa_GetShaderSourceARB);
 
    /* OpenGL 2.0 */
@@ -1904,28 +1727,37 @@ _mesa_init_shader_dispatch(struct _glapi_table *exec)
    SET_IsProgram(exec, _mesa_IsProgram);
    SET_IsShader(exec, _mesa_IsShader);
 
-#if FEATURE_ARB_vertex_shader
+   /* GL_ARB_vertex_shader */
    SET_BindAttribLocationARB(exec, _mesa_BindAttribLocationARB);
    SET_GetActiveAttribARB(exec, _mesa_GetActiveAttribARB);
    SET_GetAttribLocationARB(exec, _mesa_GetAttribLocationARB);
-#endif
 
-#if FEATURE_ARB_geometry_shader4
-   SET_ProgramParameteriARB(exec, _mesa_ProgramParameteriARB);
-#endif
+   if (ctx->API != API_OPENGLES2) {
+      SET_ProgramParameteriARB(exec, _mesa_ProgramParameteriARB);
 
-   SET_UseShaderProgramEXT(exec, _mesa_UseShaderProgramEXT);
-   SET_ActiveProgramEXT(exec, _mesa_ActiveProgramEXT);
-   SET_CreateShaderProgramEXT(exec, _mesa_CreateShaderProgramEXT);
+      SET_UseShaderProgramEXT(exec, _mesa_UseShaderProgramEXT);
+      SET_ActiveProgramEXT(exec, _mesa_ActiveProgramEXT);
+      SET_CreateShaderProgramEXT(exec, _mesa_CreateShaderProgramEXT);
+   }
 
    /* GL_EXT_gpu_shader4 / GL 3.0 */
-   SET_BindFragDataLocationEXT(exec, _mesa_BindFragDataLocation);
-   SET_GetFragDataLocationEXT(exec, _mesa_GetFragDataLocation);
+   if (ctx->API != API_OPENGLES2) {
+      SET_BindFragDataLocationEXT(exec, _mesa_BindFragDataLocation);
+   }
+   if (ctx->API != API_OPENGLES2 || _mesa_is_gles3(ctx)) {
+      SET_GetFragDataLocationEXT(exec, _mesa_GetFragDataLocation);
+   }
 
    /* GL_ARB_ES2_compatibility */
    SET_ReleaseShaderCompiler(exec, _mesa_ReleaseShaderCompiler);
    SET_GetShaderPrecisionFormat(exec, _mesa_GetShaderPrecisionFormat);
+   SET_ShaderBinary(exec, _mesa_ShaderBinary);
 
+   /* GL_ARB_blend_func_extended */
+   if (ctx->API != API_OPENGLES2) {
+      SET_BindFragDataLocationIndexed(exec, _mesa_BindFragDataLocationIndexed);
+      SET_GetFragDataIndex(exec, _mesa_GetFragDataIndex);
+   }
 #endif /* FEATURE_GL */
 }