mesa: print the Git SHA1 in GL_VERSION for ES1 and ES2.
[mesa.git] / src / mesa / main / shaderapi.c
index a311148eaa6e510c4d74ac25397173884df50ada..fd793a7abd2e05008655e20b0a908c4286dd5405 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 "talloc.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
@@ -123,68 +125,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>.
@@ -322,98 +268,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)
 {
@@ -472,10 +326,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);
+   }
 }
 
 
@@ -563,38 +419,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.
  */
@@ -615,16 +439,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.
  */
@@ -652,7 +466,6 @@ 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);
 
@@ -661,11 +474,6 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname, GLint *param
       return;
    }
 
-   if (shProg->VertexProgram)
-      attribs = shProg->VertexProgram->Base.Attributes;
-   else
-      attribs = NULL;
-
    switch (pname) {
    case GL_DELETE_STATUS:
       *params = shProg->DeletePending;
@@ -683,19 +491,30 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname, GLint *param
       *params = shProg->NumShaders;
       break;
    case GL_ACTIVE_ATTRIBUTES:
-      *params = attribs ? attribs->NumParameters : 0;
+      *params = _mesa_count_active_attribs(shProg);
       break;
    case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
-      *params = _mesa_longest_parameter_name(attribs, PROGRAM_INPUT) + 1;
+      *params = _mesa_longest_attribute_name_length(shProg);
       break;
    case GL_ACTIVE_UNIFORMS:
-      *params = shProg->Uniforms ? shProg->Uniforms->NumUniforms : 0;
+      *params = shProg->NumUserUniformStorage;
       break;
-   case GL_ACTIVE_UNIFORM_MAX_LENGTH:
-      *params = _mesa_longest_uniform_name(shProg->Uniforms);
-      if (*params > 0)
-         (*params)++;  /* add one for terminating zero */
+   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;
       break;
+   }
    case GL_PROGRAM_BINARY_LENGTH_OES:
       *params = 0;
       break;
@@ -875,7 +694,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;
    }
 
@@ -928,10 +747,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);
 }
 
 
@@ -995,6 +819,33 @@ use_shader_program(struct gl_context *ctx, GLenum type,
 
    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) {
+#if FEATURE_ARB_vertex_shader
+      case GL_VERTEX_SHADER:
+        /* Empty for now. */
+        break;
+#endif
+#if FEATURE_ARB_geometry_shader4
+      case GL_GEOMETRY_SHADER_ARB:
+        /* Empty for now. */
+        break;
+#endif
+#if FEATURE_ARB_fragment_shader
+      case GL_FRAGMENT_SHADER:
+        if (*target == ctx->Shader._CurrentFragmentProgram) {
+           _mesa_reference_shader_program(ctx,
+                                          &ctx->Shader._CurrentFragmentProgram,
+                                          NULL);
+        }
+        break;
+#endif
+      }
+
       _mesa_reference_shader_program(ctx, target, shProg);
       return true;
    }
@@ -1018,59 +869,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.
@@ -1080,9 +878,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;
    }
@@ -1107,12 +902,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)) {
-      return GL_FALSE;
-   }
-   if (fp && !validate_samplers(&fp->Base, errMsg)) {
+   if (!_mesa_sampler_uniforms_are_valid(shProg, errMsg, 100))
       return GL_FALSE;
-   }
 
    return GL_TRUE;
 }
@@ -1125,7 +916,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) {
@@ -1136,9 +927,9 @@ validate_program(struct gl_context *ctx, GLuint program)
    if (!shProg->Validated) {
       /* update info log */
       if (shProg->InfoLog) {
-         talloc_free(shProg->InfoLog);
+         ralloc_free(shProg->InfoLog);
       }
-      shProg->InfoLog = talloc_strdup(shProg, errMsg);
+      shProg->InfoLog = ralloc_strdup(shProg, errMsg);
    }
 }
 
@@ -1160,29 +951,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);
 }
 
@@ -1191,6 +965,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);
 }
 
@@ -1207,6 +983,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);
 }
 
@@ -1222,8 +1000,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);
       }
@@ -1242,6 +1026,7 @@ _mesa_DeleteProgram(GLuint name)
 {
    if (name) {
       GET_CURRENT_CONTEXT(ctx);
+      FLUSH_VERTICES(ctx, 0);
       delete_shader_program(ctx, name);
    }
 }
@@ -1252,6 +1037,7 @@ _mesa_DeleteShader(GLuint name)
 {
    if (name) {
       GET_CURRENT_CONTEXT(ctx);
+      FLUSH_VERTICES(ctx, 0);
       delete_shader(ctx, name);
    }
 }
@@ -1273,16 +1059,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)
@@ -1301,24 +1077,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)
@@ -1511,7 +1269,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)
@@ -1562,7 +1321,7 @@ _mesa_ShaderSourceARB(GLhandleARB shaderObj, GLsizei count,
          free(source);
          source = newSource;
       }
-   }      
+   }
 
    shader_source(ctx, shaderObj, source);
 
@@ -1584,7 +1343,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;
@@ -1627,20 +1388,58 @@ void GLAPIENTRY
 _mesa_GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype,
                                GLint* range, GLint* precision)
 {
+   const struct gl_program_constants *limits;
+   const struct gl_precision *p;
    GET_CURRENT_CONTEXT(ctx);
-   (void) shadertype;
-   (void) precisiontype;
-   (void) range;
-   (void) precision;
-   _mesa_error(ctx, GL_INVALID_OPERATION, __FUNCTION__);
+
+   switch (shadertype) {
+   case GL_VERTEX_SHADER:
+      limits = &ctx->Const.VertexProgram;
+      break;
+   case GL_FRAGMENT_SHADER:
+      limits = &ctx->Const.FragmentProgram;
+      break;
+   default:
+      _mesa_error(ctx, GL_INVALID_ENUM,
+                  "glGetShaderPrecisionFormat(shadertype)");
+      return;
+   }
+
+   switch (precisiontype) {
+   case GL_LOW_FLOAT:
+      p = &limits->LowFloat;
+      break;
+   case GL_MEDIUM_FLOAT:
+      p = &limits->MediumFloat;
+      break;
+   case GL_HIGH_FLOAT:
+      p = &limits->HighFloat;
+      break;
+   case GL_LOW_INT:
+      p = &limits->LowInt;
+      break;
+   case GL_MEDIUM_INT:
+      p = &limits->MediumInt;
+      break;
+   case GL_HIGH_INT:
+      p = &limits->HighInt;
+      break;
+   default:
+      _mesa_error(ctx, GL_INVALID_ENUM,
+                  "glGetShaderPrecisionFormat(precisiontype)");
+      return;
+   }
+
+   range[0] = p->RangeMin;
+   range[1] = p->RangeMax;
+   precision[0] = p->Precision;
 }
 
 
 void GLAPIENTRY
 _mesa_ReleaseShaderCompiler(void)
 {
-   GET_CURRENT_CONTEXT(ctx);
-   _mesa_error(ctx, GL_INVALID_OPERATION, __FUNCTION__);
+   _mesa_destroy_shader_compiler_caches();
 }
 
 
@@ -1663,8 +1462,7 @@ _mesa_ShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat,
 #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);
@@ -1679,7 +1477,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);
@@ -1742,12 +1540,15 @@ _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;
@@ -1816,7 +1617,7 @@ _mesa_CreateShaderProgramEXT(GLenum type, const GLchar *string)
 #endif
         }
 
-        shProg->InfoLog = talloc_strdup_append(shProg->InfoLog, sh->InfoLog);
+        ralloc_strcat(&shProg->InfoLog, sh->InfoLog);
       }
 
       delete_shader(ctx, shader);
@@ -1883,6 +1684,13 @@ _mesa_init_shader_dispatch(struct _glapi_table *exec)
    SET_BindFragDataLocationEXT(exec, _mesa_BindFragDataLocation);
    SET_GetFragDataLocationEXT(exec, _mesa_GetFragDataLocation);
 
+   /* GL_ARB_ES2_compatibility */
+   SET_ReleaseShaderCompiler(exec, _mesa_ReleaseShaderCompiler);
+   SET_GetShaderPrecisionFormat(exec, _mesa_GetShaderPrecisionFormat);
+
+   /* GL_ARB_blend_func_extended */
+   SET_BindFragDataLocationIndexed(exec, _mesa_BindFragDataLocationIndexed);
+   SET_GetFragDataIndex(exec, _mesa_GetFragDataIndex);
 #endif /* FEATURE_GL */
 }