mesa/version: only enable GL4.1 with correct limits.
[mesa.git] / src / mesa / main / uniforms.c
index 0d0cbf57eb74d7b3b0fd184c7175214ab548a2ae..ba87d3900aff45ef4c30f3d1137ffc4a4776c76c 100644 (file)
 
 #include "main/glheader.h"
 #include "main/context.h"
-#include "main/dispatch.h"
 #include "main/shaderapi.h"
 #include "main/shaderobj.h"
 #include "main/uniforms.h"
 #include "main/enums.h"
-#include "ir_uniform.h"
-#include "glsl_types.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.
  * TEXTURE_2D_INDEX, TEXTURE_3D_INDEX, etc.
  * We'll use that info for state validation before rendering.
  */
+static inline void
+update_single_shader_texture_used(struct gl_shader_program *shProg,
+                                  struct gl_program *prog,
+                                  GLuint unit, GLuint target)
+{
+   gl_shader_stage prog_stage =
+      _mesa_program_enum_to_shader_stage(prog->Target);
+
+   assert(unit < ARRAY_SIZE(prog->TexturesUsed));
+   assert(target < NUM_TEXTURE_TARGETS);
+
+   /* From section 7.10 (Samplers) of the OpenGL 4.5 spec:
+    *
+    * "It is not allowed to have variables of different sampler types pointing
+    *  to the same texture image unit within a program object."
+    */
+   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 << target))
+         shProg->SamplersValidated = GL_FALSE;
+   }
+
+   prog->TexturesUsed[unit] |= (1 << target);
+}
+
 void
 _mesa_update_shader_textures_used(struct gl_shader_program *shProg,
-                                 struct gl_program *prog)
+                                  struct gl_program *prog)
 {
+   GLbitfield mask = prog->SamplersUsed;
+   ASSERTED gl_shader_stage prog_stage =
+      _mesa_program_enum_to_shader_stage(prog->Target);
    GLuint s;
-   struct gl_shader *shader =
-      shProg->_LinkedShaders[_mesa_program_enum_to_shader_stage(prog->Target)];
 
-   assert(shader);
+   assert(shProg->_LinkedShaders[prog_stage]);
 
-   memcpy(prog->SamplerUnits, shader->SamplerUnits, sizeof(prog->SamplerUnits));
    memset(prog->TexturesUsed, 0, sizeof(prog->TexturesUsed));
 
-   for (s = 0; s < MAX_SAMPLERS; s++) {
-      if (prog->SamplersUsed & (1 << s)) {
-         GLuint unit = shader->SamplerUnits[s];
-         GLuint tgt = shader->SamplerTargets[s];
-         assert(unit < Elements(prog->TexturesUsed));
-         assert(tgt < NUM_TEXTURE_TARGETS);
-         prog->TexturesUsed[unit] |= (1 << tgt);
+   while (mask) {
+      s = u_bit_scan(&mask);
+
+      update_single_shader_texture_used(shProg, prog,
+                                        prog->SamplerUnits[s],
+                                        prog->sh.SamplerTargets[s]);
+   }
+
+   if (unlikely(prog->sh.HasBoundBindlessSampler)) {
+      /* Loop over bindless samplers bound to texture units.
+       */
+      for (s = 0; s < prog->sh.NumBindlessSamplers; s++) {
+         struct gl_bindless_sampler *sampler = &prog->sh.BindlessSamplers[s];
+
+         if (!sampler->bound)
+            continue;
+
+         update_single_shader_texture_used(shProg, prog, sampler->unit,
+                                           sampler->target);
       }
    }
 }
@@ -137,7 +183,7 @@ void GLAPIENTRY
 _mesa_Uniform1f(GLint location, GLfloat v0)
 {
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, 1, &v0, GL_FLOAT);
+   _mesa_uniform(location, 1, &v0, ctx, ctx->_Shader->ActiveProgram, GLSL_TYPE_FLOAT, 1);
 }
 
 void GLAPIENTRY
@@ -147,7 +193,7 @@ _mesa_Uniform2f(GLint location, GLfloat v0, GLfloat v1)
    GLfloat v[2];
    v[0] = v0;
    v[1] = v1;
-   _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, 1, v, GL_FLOAT_VEC2);
+   _mesa_uniform(location, 1, v, ctx, ctx->_Shader->ActiveProgram, GLSL_TYPE_FLOAT, 2);
 }
 
 void GLAPIENTRY
@@ -158,7 +204,7 @@ _mesa_Uniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
    v[0] = v0;
    v[1] = v1;
    v[2] = v2;
-   _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, 1, v, GL_FLOAT_VEC3);
+   _mesa_uniform(location, 1, v, ctx, ctx->_Shader->ActiveProgram, GLSL_TYPE_FLOAT, 3);
 }
 
 void GLAPIENTRY
@@ -171,14 +217,14 @@ _mesa_Uniform4f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2,
    v[1] = v1;
    v[2] = v2;
    v[3] = v3;
-   _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, 1, v, GL_FLOAT_VEC4);
+   _mesa_uniform(location, 1, v, ctx, ctx->_Shader->ActiveProgram, GLSL_TYPE_FLOAT, 4);
 }
 
 void GLAPIENTRY
 _mesa_Uniform1i(GLint location, GLint v0)
 {
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, 1, &v0, GL_INT);
+   _mesa_uniform(location, 1, &v0, ctx, ctx->_Shader->ActiveProgram, GLSL_TYPE_INT, 1);
 }
 
 void GLAPIENTRY
@@ -188,7 +234,7 @@ _mesa_Uniform2i(GLint location, GLint v0, GLint v1)
    GLint v[2];
    v[0] = v0;
    v[1] = v1;
-   _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, 1, v, GL_INT_VEC2);
+   _mesa_uniform(location, 1, v, ctx, ctx->_Shader->ActiveProgram, GLSL_TYPE_INT, 2);
 }
 
 void GLAPIENTRY
@@ -199,7 +245,7 @@ _mesa_Uniform3i(GLint location, GLint v0, GLint v1, GLint v2)
    v[0] = v0;
    v[1] = v1;
    v[2] = v2;
-   _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, 1, v, GL_INT_VEC3);
+   _mesa_uniform(location, 1, v, ctx, ctx->_Shader->ActiveProgram, GLSL_TYPE_INT, 3);
 }
 
 void GLAPIENTRY
@@ -211,65 +257,82 @@ _mesa_Uniform4i(GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
    v[1] = v1;
    v[2] = v2;
    v[3] = v3;
-   _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, 1, v, GL_INT_VEC4);
+   _mesa_uniform(location, 1, v, ctx, ctx->_Shader->ActiveProgram, GLSL_TYPE_INT, 4);
 }
 
 void GLAPIENTRY
 _mesa_Uniform1fv(GLint location, GLsizei count, const GLfloat * value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, count, value, GL_FLOAT);
+   _mesa_uniform(location, count, value, ctx, ctx->_Shader->ActiveProgram, GLSL_TYPE_FLOAT, 1);
 }
 
 void GLAPIENTRY
 _mesa_Uniform2fv(GLint location, GLsizei count, const GLfloat * value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, count, value, GL_FLOAT_VEC2);
+   _mesa_uniform(location, count, value, ctx, ctx->_Shader->ActiveProgram, GLSL_TYPE_FLOAT, 2);
 }
 
 void GLAPIENTRY
 _mesa_Uniform3fv(GLint location, GLsizei count, const GLfloat * value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, count, value, GL_FLOAT_VEC3);
+   _mesa_uniform(location, count, value, ctx, ctx->_Shader->ActiveProgram, GLSL_TYPE_FLOAT, 3);
 }
 
 void GLAPIENTRY
 _mesa_Uniform4fv(GLint location, GLsizei count, const GLfloat * value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, count, value, GL_FLOAT_VEC4);
+   _mesa_uniform(location, count, value, ctx, ctx->_Shader->ActiveProgram, GLSL_TYPE_FLOAT, 4);
 }
 
 void GLAPIENTRY
 _mesa_Uniform1iv(GLint location, GLsizei count, const GLint * value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, count, value, GL_INT);
+   _mesa_uniform(location, count, value, ctx, ctx->_Shader->ActiveProgram, GLSL_TYPE_INT, 1);
 }
 
 void GLAPIENTRY
 _mesa_Uniform2iv(GLint location, GLsizei count, const GLint * value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, count, value, GL_INT_VEC2);
+   _mesa_uniform(location, count, value, ctx, ctx->_Shader->ActiveProgram, GLSL_TYPE_INT, 2);
 }
 
 void GLAPIENTRY
 _mesa_Uniform3iv(GLint location, GLsizei count, const GLint * value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, count, value, GL_INT_VEC3);
+   _mesa_uniform(location, count, value, ctx, ctx->_Shader->ActiveProgram, GLSL_TYPE_INT, 3);
 }
 
 void GLAPIENTRY
 _mesa_Uniform4iv(GLint location, GLsizei count, const GLint * value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, count, value, GL_INT_VEC4);
+   _mesa_uniform(location, count, value, ctx, ctx->_Shader->ActiveProgram, GLSL_TYPE_INT, 4);
+}
+
+void GLAPIENTRY
+_mesa_UniformHandleui64ARB(GLint location, GLuint64 value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform_handle(location, 1, &value, ctx, ctx->_Shader->ActiveProgram);
+}
+
+void GLAPIENTRY
+_mesa_UniformHandleui64vARB(GLint location, GLsizei count,
+                            const GLuint64 *value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform_handle(location, count, value, ctx,
+                        ctx->_Shader->ActiveProgram);
 }
 
+
 /** Same as above with direct state access **/
 void GLAPIENTRY
 _mesa_ProgramUniform1f(GLuint program, GLint location, GLfloat v0)
@@ -278,7 +341,7 @@ _mesa_ProgramUniform1f(GLuint program, GLint location, GLfloat v0)
    struct gl_shader_program *shProg =
       _mesa_lookup_shader_program_err(ctx, program,
             "glProgramUniform1f");
-   _mesa_uniform(ctx, shProg, location, 1, &v0, GL_FLOAT);
+   _mesa_uniform(location, 1, &v0, ctx, shProg, GLSL_TYPE_FLOAT, 1);
 }
 
 void GLAPIENTRY
@@ -290,7 +353,7 @@ _mesa_ProgramUniform2f(GLuint program, GLint location, GLfloat v0, GLfloat v1)
    v[0] = v0;
    v[1] = v1;
    shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniform2f");
-   _mesa_uniform(ctx, shProg, location, 1, v, GL_FLOAT_VEC2);
+   _mesa_uniform(location, 1, v, ctx, shProg, GLSL_TYPE_FLOAT, 2);
 }
 
 void GLAPIENTRY
@@ -304,7 +367,7 @@ _mesa_ProgramUniform3f(GLuint program, GLint location, GLfloat v0, GLfloat v1,
    v[1] = v1;
    v[2] = v2;
    shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniform3f");
-   _mesa_uniform(ctx, shProg, location, 1, v, GL_FLOAT_VEC3);
+   _mesa_uniform(location, 1, v, ctx, shProg, GLSL_TYPE_FLOAT, 3);
 }
 
 void GLAPIENTRY
@@ -319,7 +382,7 @@ _mesa_ProgramUniform4f(GLuint program, GLint location, GLfloat v0, GLfloat v1,
    v[2] = v2;
    v[3] = v3;
    shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniform4f");
-   _mesa_uniform(ctx, shProg, location, 1, v, GL_FLOAT_VEC4);
+   _mesa_uniform(location, 1, v, ctx, shProg, GLSL_TYPE_FLOAT, 4);
 }
 
 void GLAPIENTRY
@@ -329,7 +392,7 @@ _mesa_ProgramUniform1i(GLuint program, GLint location, GLint v0)
    struct gl_shader_program *shProg =
       _mesa_lookup_shader_program_err(ctx, program,
             "glProgramUniform1i");
-   _mesa_uniform(ctx, shProg, location, 1, &v0, GL_INT);
+   _mesa_uniform(location, 1, &v0, ctx, shProg, GLSL_TYPE_INT, 1);
 }
 
 void GLAPIENTRY
@@ -341,7 +404,7 @@ _mesa_ProgramUniform2i(GLuint program, GLint location, GLint v0, GLint v1)
    v[0] = v0;
    v[1] = v1;
    shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniform2i");
-   _mesa_uniform(ctx, shProg, location, 1, v, GL_INT_VEC2);
+   _mesa_uniform(location, 1, v, ctx, shProg, GLSL_TYPE_INT, 2);
 }
 
 void GLAPIENTRY
@@ -355,7 +418,7 @@ _mesa_ProgramUniform3i(GLuint program, GLint location, GLint v0, GLint v1,
    v[1] = v1;
    v[2] = v2;
    shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniform3i");
-   _mesa_uniform(ctx, shProg, location, 1, v, GL_INT_VEC3);
+   _mesa_uniform(location, 1, v, ctx, shProg, GLSL_TYPE_INT, 3);
 }
 
 void GLAPIENTRY
@@ -370,7 +433,7 @@ _mesa_ProgramUniform4i(GLuint program, GLint location, GLint v0, GLint v1,
    v[2] = v2;
    v[3] = v3;
    shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniform4i");
-   _mesa_uniform(ctx, shProg, location, 1, v, GL_INT_VEC4);
+   _mesa_uniform(location, 1, v, ctx, shProg, GLSL_TYPE_INT, 4);
 }
 
 void GLAPIENTRY
@@ -381,7 +444,7 @@ _mesa_ProgramUniform1fv(GLuint program, GLint location, GLsizei count,
    struct gl_shader_program *shProg =
       _mesa_lookup_shader_program_err(ctx, program,
             "glProgramUniform1fv");
-   _mesa_uniform(ctx, shProg, location, count, value, GL_FLOAT);
+   _mesa_uniform(location, count, value, ctx, shProg, GLSL_TYPE_FLOAT, 1);
 }
 
 void GLAPIENTRY
@@ -392,7 +455,7 @@ _mesa_ProgramUniform2fv(GLuint program, GLint location, GLsizei count,
    struct gl_shader_program *shProg =
       _mesa_lookup_shader_program_err(ctx, program,
             "glProgramUniform2fv");
-   _mesa_uniform(ctx, shProg, location, count, value, GL_FLOAT_VEC2);
+   _mesa_uniform(location, count, value, ctx, shProg, GLSL_TYPE_FLOAT, 2);
 }
 
 void GLAPIENTRY
@@ -403,7 +466,7 @@ _mesa_ProgramUniform3fv(GLuint program, GLint location, GLsizei count,
    struct gl_shader_program *shProg =
       _mesa_lookup_shader_program_err(ctx, program,
             "glProgramUniform3fv");
-   _mesa_uniform(ctx, shProg, location, count, value, GL_FLOAT_VEC3);
+   _mesa_uniform(location, count, value, ctx, shProg, GLSL_TYPE_FLOAT, 3);
 }
 
 void GLAPIENTRY
@@ -414,7 +477,7 @@ _mesa_ProgramUniform4fv(GLuint program, GLint location, GLsizei count,
    struct gl_shader_program *shProg =
       _mesa_lookup_shader_program_err(ctx, program,
             "glProgramUniform4fv");
-   _mesa_uniform(ctx, shProg, location, count, value, GL_FLOAT_VEC4);
+   _mesa_uniform(location, count, value, ctx, shProg, GLSL_TYPE_FLOAT, 4);
 }
 
 void GLAPIENTRY
@@ -425,7 +488,7 @@ _mesa_ProgramUniform1iv(GLuint program, GLint location, GLsizei count,
    struct gl_shader_program *shProg =
       _mesa_lookup_shader_program_err(ctx, program,
             "glProgramUniform1iv");
-   _mesa_uniform(ctx, shProg, location, count, value, GL_INT);
+   _mesa_uniform(location, count, value, ctx, shProg, GLSL_TYPE_INT, 1);
 }
 
 void GLAPIENTRY
@@ -436,7 +499,7 @@ _mesa_ProgramUniform2iv(GLuint program, GLint location, GLsizei count,
    struct gl_shader_program *shProg =
       _mesa_lookup_shader_program_err(ctx, program,
             "glProgramUniform2iv");
-   _mesa_uniform(ctx, shProg, location, count, value, GL_INT_VEC2);
+   _mesa_uniform(location, count, value, ctx, shProg, GLSL_TYPE_INT, 2);
 }
 
 void GLAPIENTRY
@@ -447,7 +510,7 @@ _mesa_ProgramUniform3iv(GLuint program, GLint location, GLsizei count,
    struct gl_shader_program *shProg =
       _mesa_lookup_shader_program_err(ctx, program,
             "glProgramUniform3iv");
-   _mesa_uniform(ctx, shProg, location, count, value, GL_INT_VEC3);
+   _mesa_uniform(location, count, value, ctx, shProg, GLSL_TYPE_INT, 3);
 }
 
 void GLAPIENTRY
@@ -458,7 +521,29 @@ _mesa_ProgramUniform4iv(GLuint program, GLint location, GLsizei count,
    struct gl_shader_program *shProg =
       _mesa_lookup_shader_program_err(ctx, program,
             "glProgramUniform4iv");
-   _mesa_uniform(ctx, shProg, location, count, value, GL_INT_VEC4);
+   _mesa_uniform(location, count, value, ctx, shProg, GLSL_TYPE_INT, 4);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniformHandleui64ARB(GLuint program, GLint location,
+                                  GLuint64 value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_shader_program *shProg =
+      _mesa_lookup_shader_program_err(ctx, program,
+            "glProgramUniformHandleui64ARB");
+   _mesa_uniform_handle(location, 1, &value, ctx, shProg);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniformHandleui64vARB(GLuint program, GLint location,
+                                   GLsizei count, const GLuint64 *values)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_shader_program *shProg =
+      _mesa_lookup_shader_program_err(ctx, program,
+            "glProgramUniformHandleui64vARB");
+   _mesa_uniform_handle(location, count, values, ctx, shProg);
 }
 
 
@@ -467,7 +552,7 @@ void GLAPIENTRY
 _mesa_Uniform1ui(GLint location, GLuint v0)
 {
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, 1, &v0, GL_UNSIGNED_INT);
+   _mesa_uniform(location, 1, &v0, ctx, ctx->_Shader->ActiveProgram, GLSL_TYPE_UINT, 1);
 }
 
 void GLAPIENTRY
@@ -477,7 +562,7 @@ _mesa_Uniform2ui(GLint location, GLuint v0, GLuint v1)
    GLuint v[2];
    v[0] = v0;
    v[1] = v1;
-   _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, 1, v, GL_UNSIGNED_INT_VEC2);
+   _mesa_uniform(location, 1, v, ctx, ctx->_Shader->ActiveProgram, GLSL_TYPE_UINT, 2);
 }
 
 void GLAPIENTRY
@@ -488,7 +573,7 @@ _mesa_Uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)
    v[0] = v0;
    v[1] = v1;
    v[2] = v2;
-   _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, 1, v, GL_UNSIGNED_INT_VEC3);
+   _mesa_uniform(location, 1, v, ctx, ctx->_Shader->ActiveProgram, GLSL_TYPE_UINT, 3);
 }
 
 void GLAPIENTRY
@@ -500,35 +585,35 @@ _mesa_Uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
    v[1] = v1;
    v[2] = v2;
    v[3] = v3;
-   _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, 1, v, GL_UNSIGNED_INT_VEC4);
+   _mesa_uniform(location, 1, v, ctx, ctx->_Shader->ActiveProgram, GLSL_TYPE_UINT, 4);
 }
 
 void GLAPIENTRY
 _mesa_Uniform1uiv(GLint location, GLsizei count, const GLuint *value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, count, value, GL_UNSIGNED_INT);
+   _mesa_uniform(location, count, value, ctx, ctx->_Shader->ActiveProgram, GLSL_TYPE_UINT, 1);
 }
 
 void GLAPIENTRY
 _mesa_Uniform2uiv(GLint location, GLsizei count, const GLuint *value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, count, value, GL_UNSIGNED_INT_VEC2);
+   _mesa_uniform(location, count, value, ctx, ctx->_Shader->ActiveProgram, GLSL_TYPE_UINT, 2);
 }
 
 void GLAPIENTRY
 _mesa_Uniform3uiv(GLint location, GLsizei count, const GLuint *value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, count, value, GL_UNSIGNED_INT_VEC3);
+   _mesa_uniform(location, count, value, ctx, ctx->_Shader->ActiveProgram, GLSL_TYPE_UINT, 3);
 }
 
 void GLAPIENTRY
 _mesa_Uniform4uiv(GLint location, GLsizei count, const GLuint *value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, count, value, GL_UNSIGNED_INT_VEC4);
+   _mesa_uniform(location, count, value, ctx, ctx->_Shader->ActiveProgram, GLSL_TYPE_UINT, 4);
 }
 
 
@@ -538,8 +623,8 @@ _mesa_UniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose,
                           const GLfloat * value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
-                       2, 2, location, count, transpose, value);
+   _mesa_uniform_matrix(location, count, transpose, value,
+                        ctx, ctx->_Shader->ActiveProgram, 2, 2, GLSL_TYPE_FLOAT);
 }
 
 void GLAPIENTRY
@@ -547,8 +632,8 @@ _mesa_UniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose,
                           const GLfloat * value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
-                       3, 3, location, count, transpose, value);
+   _mesa_uniform_matrix(location, count, transpose, value,
+                        ctx, ctx->_Shader->ActiveProgram, 3, 3, GLSL_TYPE_FLOAT);
 }
 
 void GLAPIENTRY
@@ -556,8 +641,8 @@ _mesa_UniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose,
                           const GLfloat * value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
-                       4, 4, location, count, transpose, value);
+   _mesa_uniform_matrix(location, count, transpose, value,
+                        ctx, ctx->_Shader->ActiveProgram, 4, 4, GLSL_TYPE_FLOAT);
 }
 
 /** Same as above with direct state access **/
@@ -569,7 +654,7 @@ _mesa_ProgramUniform1ui(GLuint program, GLint location, GLuint v0)
    struct gl_shader_program *shProg =
       _mesa_lookup_shader_program_err(ctx, program,
             "glProgramUniform1ui");
-   _mesa_uniform(ctx, shProg, location, 1, &v0, GL_UNSIGNED_INT);
+   _mesa_uniform(location, 1, &v0, ctx, shProg, GLSL_TYPE_UINT, 1);
 }
 
 void GLAPIENTRY
@@ -582,7 +667,7 @@ _mesa_ProgramUniform2ui(GLuint program, GLint location, GLuint v0, GLuint v1)
    v[1] = v1;
    shProg = _mesa_lookup_shader_program_err(ctx, program,
                                             "glProgramUniform2ui");
-   _mesa_uniform(ctx, shProg, location, 1, v, GL_UNSIGNED_INT_VEC2);
+   _mesa_uniform(location, 1, v, ctx, shProg, GLSL_TYPE_UINT, 2);
 }
 
 void GLAPIENTRY
@@ -597,7 +682,7 @@ _mesa_ProgramUniform3ui(GLuint program, GLint location, GLuint v0, GLuint v1,
    v[2] = v2;
    shProg = _mesa_lookup_shader_program_err(ctx, program,
                                             "glProgramUniform3ui");
-   _mesa_uniform(ctx, shProg, location, 1, v, GL_UNSIGNED_INT_VEC3);
+   _mesa_uniform(location, 1, v, ctx, shProg, GLSL_TYPE_UINT, 3);
 }
 
 void GLAPIENTRY
@@ -612,7 +697,7 @@ _mesa_ProgramUniform4ui(GLuint program, GLint location, GLuint v0, GLuint v1,
    v[2] = v2;
    v[3] = v3;
    shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniform4ui");
-   _mesa_uniform(ctx, shProg, location, 1, v, GL_UNSIGNED_INT_VEC4);
+   _mesa_uniform(location, 1, v, ctx, shProg, GLSL_TYPE_UINT, 4);
 }
 
 void GLAPIENTRY
@@ -623,7 +708,7 @@ _mesa_ProgramUniform1uiv(GLuint program, GLint location, GLsizei count,
    struct gl_shader_program *shProg =
       _mesa_lookup_shader_program_err(ctx, program,
             "glProgramUniform1uiv");
-   _mesa_uniform(ctx, shProg, location, count, value, GL_UNSIGNED_INT);
+   _mesa_uniform(location, count, value, ctx, shProg, GLSL_TYPE_UINT, 1);
 }
 
 void GLAPIENTRY
@@ -634,7 +719,7 @@ _mesa_ProgramUniform2uiv(GLuint program, GLint location, GLsizei count,
    struct gl_shader_program *shProg =
       _mesa_lookup_shader_program_err(ctx, program,
             "glProgramUniform2uiv");
-   _mesa_uniform(ctx, shProg, location, count, value, GL_UNSIGNED_INT_VEC2);
+   _mesa_uniform(location, count, value, ctx, shProg, GLSL_TYPE_UINT, 2);
 }
 
 void GLAPIENTRY
@@ -645,7 +730,7 @@ _mesa_ProgramUniform3uiv(GLuint program, GLint location, GLsizei count,
    struct gl_shader_program *shProg =
       _mesa_lookup_shader_program_err(ctx, program,
             "glProgramUniform3uiv");
-   _mesa_uniform(ctx, shProg, location, count, value, GL_UNSIGNED_INT_VEC3);
+   _mesa_uniform(location, count, value, ctx, shProg, GLSL_TYPE_UINT, 3);
 }
 
 void GLAPIENTRY
@@ -656,7 +741,7 @@ _mesa_ProgramUniform4uiv(GLuint program, GLint location, GLsizei count,
    struct gl_shader_program *shProg =
       _mesa_lookup_shader_program_err(ctx, program,
             "glProgramUniform4uiv");
-   _mesa_uniform(ctx, shProg, location, count, value, GL_UNSIGNED_INT_VEC4);
+   _mesa_uniform(location, count, value, ctx, shProg, GLSL_TYPE_UINT, 4);
 }
 
 
@@ -669,7 +754,7 @@ _mesa_ProgramUniformMatrix2fv(GLuint program, GLint location, GLsizei count,
    struct gl_shader_program *shProg =
       _mesa_lookup_shader_program_err(ctx, program,
             "glProgramUniformMatrix2fv");
-   _mesa_uniform_matrix(ctx, shProg, 2, 2, location, count, transpose, value);
+   _mesa_uniform_matrix(location, count, transpose, value, ctx, shProg, 2, 2, GLSL_TYPE_FLOAT);
 }
 
 void GLAPIENTRY
@@ -680,7 +765,7 @@ _mesa_ProgramUniformMatrix3fv(GLuint program, GLint location, GLsizei count,
    struct gl_shader_program *shProg =
       _mesa_lookup_shader_program_err(ctx, program,
             "glProgramUniformMatrix3fv");
-   _mesa_uniform_matrix(ctx, shProg, 3, 3, location, count, transpose, value);
+   _mesa_uniform_matrix(location, count, transpose, value, ctx, shProg, 3, 3, GLSL_TYPE_FLOAT);
 }
 
 void GLAPIENTRY
@@ -691,7 +776,7 @@ _mesa_ProgramUniformMatrix4fv(GLuint program, GLint location, GLsizei count,
    struct gl_shader_program *shProg =
       _mesa_lookup_shader_program_err(ctx, program,
             "glProgramUniformMatrix4fv");
-   _mesa_uniform_matrix(ctx, shProg, 4, 4, location, count, transpose, value);
+   _mesa_uniform_matrix(location, count, transpose, value, ctx, shProg, 4, 4, GLSL_TYPE_FLOAT);
 }
 
 
@@ -703,8 +788,8 @@ _mesa_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose,
                          const GLfloat *value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
-                       2, 3, location, count, transpose, value);
+   _mesa_uniform_matrix(location, count, transpose, value,
+                        ctx, ctx->_Shader->ActiveProgram, 2, 3, GLSL_TYPE_FLOAT);
 }
 
 void GLAPIENTRY
@@ -712,8 +797,8 @@ _mesa_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose,
                          const GLfloat *value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
-                       3, 2, location, count, transpose, value);
+   _mesa_uniform_matrix(location, count, transpose, value,
+                        ctx, ctx->_Shader->ActiveProgram, 3, 2, GLSL_TYPE_FLOAT);
 }
 
 void GLAPIENTRY
@@ -721,8 +806,8 @@ _mesa_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose,
                          const GLfloat *value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
-                       2, 4, location, count, transpose, value);
+   _mesa_uniform_matrix(location, count, transpose, value,
+                        ctx, ctx->_Shader->ActiveProgram, 2, 4, GLSL_TYPE_FLOAT);
 }
 
 void GLAPIENTRY
@@ -730,8 +815,8 @@ _mesa_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose,
                          const GLfloat *value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
-                       4, 2, location, count, transpose, value);
+   _mesa_uniform_matrix(location, count, transpose, value,
+                        ctx, ctx->_Shader->ActiveProgram, 4, 2, GLSL_TYPE_FLOAT);
 }
 
 void GLAPIENTRY
@@ -739,8 +824,8 @@ _mesa_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose,
                          const GLfloat *value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
-                       3, 4, location, count, transpose, value);
+   _mesa_uniform_matrix(location, count, transpose, value,
+                        ctx, ctx->_Shader->ActiveProgram, 3, 4, GLSL_TYPE_FLOAT);
 }
 
 void GLAPIENTRY
@@ -748,8 +833,8 @@ _mesa_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose,
                          const GLfloat *value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
-                       4, 3, location, count, transpose, value);
+   _mesa_uniform_matrix(location, count, transpose, value,
+                        ctx, ctx->_Shader->ActiveProgram, 4, 3, GLSL_TYPE_FLOAT);
 }
 
 /** Same as above with direct state access **/
@@ -762,7 +847,7 @@ _mesa_ProgramUniformMatrix2x3fv(GLuint program, GLint location, GLsizei count,
    struct gl_shader_program *shProg =
       _mesa_lookup_shader_program_err(ctx, program,
             "glProgramUniformMatrix2x3fv");
-   _mesa_uniform_matrix(ctx, shProg, 2, 3, location, count, transpose, value);
+   _mesa_uniform_matrix(location, count, transpose, value, ctx, shProg, 2, 3, GLSL_TYPE_FLOAT);
 }
 
 void GLAPIENTRY
@@ -773,7 +858,7 @@ _mesa_ProgramUniformMatrix3x2fv(GLuint program, GLint location, GLsizei count,
    struct gl_shader_program *shProg =
       _mesa_lookup_shader_program_err(ctx, program,
             "glProgramUniformMatrix3x2fv");
-   _mesa_uniform_matrix(ctx, shProg, 3, 2, location, count, transpose, value);
+   _mesa_uniform_matrix(location, count, transpose, value, ctx, shProg, 3, 2, GLSL_TYPE_FLOAT);
 }
 
 void GLAPIENTRY
@@ -784,7 +869,7 @@ _mesa_ProgramUniformMatrix2x4fv(GLuint program, GLint location, GLsizei count,
    struct gl_shader_program *shProg =
       _mesa_lookup_shader_program_err(ctx, program,
             "glProgramUniformMatrix2x4fv");
-   _mesa_uniform_matrix(ctx, shProg, 2, 4, location, count, transpose, value);
+   _mesa_uniform_matrix(location, count, transpose, value, ctx, shProg, 2, 4, GLSL_TYPE_FLOAT);
 }
 
 void GLAPIENTRY
@@ -795,7 +880,7 @@ _mesa_ProgramUniformMatrix4x2fv(GLuint program, GLint location, GLsizei count,
    struct gl_shader_program *shProg =
       _mesa_lookup_shader_program_err(ctx, program,
             "glProgramUniformMatrix4x2fv");
-   _mesa_uniform_matrix(ctx, shProg, 4, 2, location, count, transpose, value);
+   _mesa_uniform_matrix(location, count, transpose, value, ctx, shProg, 4, 2, GLSL_TYPE_FLOAT);
 }
 
 void GLAPIENTRY
@@ -806,7 +891,7 @@ _mesa_ProgramUniformMatrix3x4fv(GLuint program, GLint location, GLsizei count,
    struct gl_shader_program *shProg =
       _mesa_lookup_shader_program_err(ctx, program,
             "glProgramUniformMatrix3x4fv");
-   _mesa_uniform_matrix(ctx, shProg, 3, 4, location, count, transpose, value);
+   _mesa_uniform_matrix(location, count, transpose, value, ctx, shProg, 3, 4, GLSL_TYPE_FLOAT);
 }
 
 void GLAPIENTRY
@@ -817,7 +902,7 @@ _mesa_ProgramUniformMatrix4x3fv(GLuint program, GLint location, GLsizei count,
    struct gl_shader_program *shProg =
       _mesa_lookup_shader_program_err(ctx, program,
             "glProgramUniformMatrix4x3fv");
-   _mesa_uniform_matrix(ctx, shProg, 4, 3, location, count, transpose, value);
+   _mesa_uniform_matrix(location, count, transpose, value, ctx, shProg, 4, 3, GLSL_TYPE_FLOAT);
 }
 
 
@@ -874,16 +959,7 @@ _mesa_GetnUniformdvARB(GLuint program, GLint location,
 {
    GET_CURRENT_CONTEXT(ctx);
 
-   (void) program;
-   (void) location;
-   (void) bufSize;
-   (void) params;
-
-   /*
    _mesa_get_uniform(ctx, program, location, bufSize, GLSL_TYPE_DOUBLE, params);
-   */
-   _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformdvARB"
-               "(GL_ARB_gpu_shader_fp64 not implemented)");
 }
 
 void GLAPIENTRY
@@ -892,18 +968,44 @@ _mesa_GetUniformdv(GLuint program, GLint location, GLdouble *params)
    _mesa_GetnUniformdvARB(program, location, INT_MAX, params);
 }
 
+void GLAPIENTRY
+_mesa_GetnUniformi64vARB(GLuint program, GLint location,
+                         GLsizei bufSize, GLint64 *params)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_get_uniform(ctx, program, location, bufSize, GLSL_TYPE_INT64, params);
+}
+void GLAPIENTRY
+_mesa_GetUniformi64vARB(GLuint program, GLint location, GLint64 *params)
+{
+   _mesa_GetnUniformi64vARB(program, location, INT_MAX, params);
+}
+
+void GLAPIENTRY
+_mesa_GetnUniformui64vARB(GLuint program, GLint location,
+                         GLsizei bufSize, GLuint64 *params)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_get_uniform(ctx, program, location, bufSize, GLSL_TYPE_UINT64, params);
+}
+
+void GLAPIENTRY
+_mesa_GetUniformui64vARB(GLuint program, GLint location, GLuint64 *params)
+{
+   _mesa_GetnUniformui64vARB(program, location, INT_MAX, params);
+}
+
 
 GLint GLAPIENTRY
 _mesa_GetUniformLocation(GLuint programObj, const GLcharARB *name)
 {
    struct gl_shader_program *shProg;
-   GLuint index, offset;
 
    GET_CURRENT_CONTEXT(ctx);
 
    shProg = _mesa_lookup_shader_program_err(ctx, programObj,
                                            "glGetUniformLocation");
-   if (!shProg)
+   if (!shProg || !name)
       return -1;
 
    /* Page 80 (page 94 of the PDF) of the OpenGL 2.1 spec says:
@@ -911,29 +1013,24 @@ _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 == LINKING_FAILURE) {
       _mesa_error(ctx, GL_INVALID_OPERATION,
                  "glGetUniformLocation(program not linked)");
       return -1;
    }
 
-   index = _mesa_get_uniform_location(ctx, shProg, name, &offset);
-   if (index == GL_INVALID_INDEX)
-      return -1;
+   return _mesa_program_resource_location(shProg, GL_UNIFORM, name);
+}
 
-   /* From the GL_ARB_uniform_buffer_object spec:
-    *
-    *     "The value -1 will be returned if <name> does not correspond to an
-    *      active uniform variable name in <program>, if <name> is associated
-    *      with a named uniform block, or if <name> starts with the reserved
-    *      prefix "gl_"."
-    */
-   if (shProg->UniformStorage[index].block_index != -1 ||
-       shProg->UniformStorage[index].atomic_buffer_index != -1)
-      return -1;
+GLint GLAPIENTRY
+_mesa_GetUniformLocation_no_error(GLuint programObj, const GLcharARB *name)
+{
+   GET_CURRENT_CONTEXT(ctx);
+
+   struct gl_shader_program *shProg =
+      _mesa_lookup_shader_program(ctx, programObj);
 
-   /* location in remap table + array element offset */
-   return shProg->UniformStorage[index].remap_location + offset;
+   return _mesa_program_resource_location(shProg, GL_UNIFORM, name);
 }
 
 GLuint GLAPIENTRY
@@ -941,7 +1038,6 @@ _mesa_GetUniformBlockIndex(GLuint program,
                           const GLchar *uniformBlockName)
 {
    GET_CURRENT_CONTEXT(ctx);
-   GLuint i;
    struct gl_shader_program *shProg;
 
    if (!ctx->Extensions.ARB_uniform_buffer_object) {
@@ -954,12 +1050,13 @@ _mesa_GetUniformBlockIndex(GLuint program,
    if (!shProg)
       return GL_INVALID_INDEX;
 
-   for (i = 0; i < shProg->NumUniformBlocks; i++) {
-      if (!strcmp(shProg->UniformBlocks[i].Name, uniformBlockName))
-        return i;
-   }
+   struct gl_program_resource *res =
+      _mesa_program_resource_find_name(shProg, GL_UNIFORM_BLOCK,
+                                       uniformBlockName, NULL);
+   if (!res)
+      return GL_INVALID_INDEX;
 
-   return GL_INVALID_INDEX;
+   return _mesa_program_resource_index(shProg, res);
 }
 
 void GLAPIENTRY
@@ -989,12 +1086,38 @@ _mesa_GetUniformIndices(GLuint program,
    }
 
    for (i = 0; i < uniformCount; i++) {
-      unsigned offset;
-      uniformIndices[i] = _mesa_get_uniform_location(ctx, shProg,
-                                                    uniformNames[i], &offset);
+      struct gl_program_resource *res =
+         _mesa_program_resource_find_name(shProg, GL_UNIFORM, uniformNames[i],
+                                          NULL);
+      uniformIndices[i] = _mesa_program_resource_index(shProg, res);
+   }
+}
+
+static void
+uniform_block_binding(struct gl_context *ctx, struct gl_shader_program *shProg,
+                      GLuint uniformBlockIndex, GLuint uniformBlockBinding)
+{
+   if (shProg->data->UniformBlocks[uniformBlockIndex].Binding !=
+       uniformBlockBinding) {
+
+      FLUSH_VERTICES(ctx, 0);
+      ctx->NewDriverState |= ctx->DriverFlags.NewUniformBuffer;
+
+      shProg->data->UniformBlocks[uniformBlockIndex].Binding =
+         uniformBlockBinding;
    }
 }
 
+void GLAPIENTRY
+_mesa_UniformBlockBinding_no_error(GLuint program, GLuint uniformBlockIndex,
+                                   GLuint uniformBlockBinding)
+{
+   GET_CURRENT_CONTEXT(ctx);
+
+   struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, program);
+   uniform_block_binding(ctx, shProg, uniformBlockIndex, uniformBlockBinding);
+}
+
 void GLAPIENTRY
 _mesa_UniformBlockBinding(GLuint program,
                          GLuint uniformBlockIndex,
@@ -1013,10 +1136,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;
    }
 
@@ -1027,120 +1150,186 @@ _mesa_UniformBlockBinding(GLuint program,
       return;
    }
 
-   if (shProg->UniformBlocks[uniformBlockIndex].Binding !=
-       uniformBlockBinding) {
-      int i;
+   uniform_block_binding(ctx, shProg, uniformBlockIndex, uniformBlockBinding);
+}
+
+static void
+shader_storage_block_binding(struct gl_context *ctx,
+                             struct gl_shader_program *shProg,
+                             GLuint shaderStorageBlockIndex,
+                             GLuint shaderStorageBlockBinding)
+{
+   if (shProg->data->ShaderStorageBlocks[shaderStorageBlockIndex].Binding !=
+       shaderStorageBlockBinding) {
 
       FLUSH_VERTICES(ctx, 0);
-      ctx->NewDriverState |= ctx->DriverFlags.NewUniformBuffer;
+      ctx->NewDriverState |= ctx->DriverFlags.NewShaderStorageBuffer;
 
-      shProg->UniformBlocks[uniformBlockIndex].Binding = uniformBlockBinding;
+      shProg->data->ShaderStorageBlocks[shaderStorageBlockIndex].Binding =
+         shaderStorageBlockBinding;
+   }
+}
 
-      for (i = 0; i < MESA_SHADER_STAGES; i++) {
-        int stage_index = shProg->UniformBlockStageIndex[i][uniformBlockIndex];
+void GLAPIENTRY
+_mesa_ShaderStorageBlockBinding_no_error(GLuint program,
+                                         GLuint shaderStorageBlockIndex,
+                                         GLuint shaderStorageBlockBinding)
+{
+   GET_CURRENT_CONTEXT(ctx);
 
-        if (stage_index != -1) {
-           struct gl_shader *sh = shProg->_LinkedShaders[i];
-           sh->UniformBlocks[stage_index].Binding = uniformBlockBinding;
-        }
-      }
-   }
+   struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, program);
+   shader_storage_block_binding(ctx, shProg, shaderStorageBlockIndex,
+                                shaderStorageBlockBinding);
 }
 
 void GLAPIENTRY
-_mesa_GetActiveUniformBlockiv(GLuint program,
-                             GLuint uniformBlockIndex,
-                             GLenum pname,
-                             GLint *params)
+_mesa_ShaderStorageBlockBinding(GLuint program,
+                               GLuint shaderStorageBlockIndex,
+                               GLuint shaderStorageBlockBinding)
 {
    GET_CURRENT_CONTEXT(ctx);
    struct gl_shader_program *shProg;
-   struct gl_uniform_block *block;
-   unsigned i;
 
-   if (!ctx->Extensions.ARB_uniform_buffer_object) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetActiveUniformBlockiv");
+   if (!ctx->Extensions.ARB_shader_storage_buffer_object) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glShaderStorageBlockBinding");
       return;
    }
 
    shProg = _mesa_lookup_shader_program_err(ctx, program,
-                                           "glGetActiveUniformBlockiv");
+                                           "glShaderStorageBlockBinding");
    if (!shProg)
       return;
 
-   if (uniformBlockIndex >= shProg->NumUniformBlocks) {
+   if (shaderStorageBlockIndex >= shProg->data->NumShaderStorageBlocks) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                 "glShaderStorageBlockBinding(block index %u >= %u)",
+                  shaderStorageBlockIndex,
+                  shProg->data->NumShaderStorageBlocks);
+      return;
+   }
+
+   if (shaderStorageBlockBinding >= ctx->Const.MaxShaderStorageBufferBindings) {
       _mesa_error(ctx, GL_INVALID_VALUE,
-                 "glGetActiveUniformBlockiv(block index %u >= %u)",
-                 uniformBlockIndex, shProg->NumUniformBlocks);
+                 "glShaderStorageBlockBinding(block binding %u >= %u)",
+                 shaderStorageBlockBinding,
+                  ctx->Const.MaxShaderStorageBufferBindings);
       return;
    }
 
-   block = &shProg->UniformBlocks[uniformBlockIndex];
+   shader_storage_block_binding(ctx, shProg, shaderStorageBlockIndex,
+                                shaderStorageBlockBinding);
+}
+
+/**
+ * Generic program resource property query.
+ */
+static void
+mesa_bufferiv(struct gl_shader_program *shProg, GLenum type,
+              GLuint index, GLenum pname, GLint *params, const char *caller)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_program_resource *res =
+      _mesa_program_resource_find_index(shProg, type, index);
+
+   if (!res) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "%s(bufferindex %d)", caller, index);
+      return;
+   }
 
    switch (pname) {
    case GL_UNIFORM_BLOCK_BINDING:
-      params[0] = block->Binding;
+   case GL_ATOMIC_COUNTER_BUFFER_BINDING:
+      _mesa_program_resource_prop(shProg, res, index, GL_BUFFER_BINDING,
+                                  params, caller);
       return;
-
    case GL_UNIFORM_BLOCK_DATA_SIZE:
-      params[0] = block->UniformBufferSize;
+   case GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE:
+      _mesa_program_resource_prop(shProg, res, index, GL_BUFFER_DATA_SIZE,
+                                  params, caller);
       return;
-
    case GL_UNIFORM_BLOCK_NAME_LENGTH:
-      params[0] = strlen(block->Name) + 1;
+      _mesa_program_resource_prop(shProg, res, index, GL_NAME_LENGTH,
+                                  params, caller);
       return;
-
-   case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS: {
-      unsigned count = 0;
-
-      for (i = 0; i < block->NumUniforms; i++) {
-        unsigned offset;
-         const int idx =
-            _mesa_get_uniform_location(ctx, shProg,
-                                       block->Uniforms[i].IndexName,
-                                       &offset);
-         if (idx != -1)
-            count++;
-      }
-
-      params[0] = count;
+   case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
+   case GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS:
+      _mesa_program_resource_prop(shProg, res, index, GL_NUM_ACTIVE_VARIABLES,
+                                  params, caller);
+      return;
+   case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
+   case GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES:
+      _mesa_program_resource_prop(shProg, res, index, GL_ACTIVE_VARIABLES,
+                                  params, caller);
+      return;
+   case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
+   case GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER:
+      _mesa_program_resource_prop(shProg, res, index,
+                                  GL_REFERENCED_BY_VERTEX_SHADER, params,
+                                  caller);
       return;
-   }
-
-   case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES: {
-      unsigned count = 0;
-
-      for (i = 0; i < block->NumUniforms; i++) {
-        unsigned offset;
-         const int idx =
-            _mesa_get_uniform_location(ctx, shProg,
-                                       block->Uniforms[i].IndexName,
-                                       &offset);
 
-         if (idx != -1)
-            params[count++] = idx;
-      }
+   case GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER:
+   case GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER:
+      _mesa_program_resource_prop(shProg, res, index,
+                                  GL_REFERENCED_BY_TESS_CONTROL_SHADER, params,
+                                  caller);
       return;
-   }
 
-   case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
-      params[0] = shProg->UniformBlockStageIndex[MESA_SHADER_VERTEX][uniformBlockIndex] != -1;
+   case GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER:
+   case GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER:
+      _mesa_program_resource_prop(shProg, res, index,
+                                  GL_REFERENCED_BY_TESS_EVALUATION_SHADER, params,
+                                  caller);
       return;
 
    case GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER:
-      params[0] = shProg->UniformBlockStageIndex[MESA_SHADER_GEOMETRY][uniformBlockIndex] != -1;
+   case GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER:
+      _mesa_program_resource_prop(shProg, res, index,
+                                  GL_REFERENCED_BY_GEOMETRY_SHADER, params,
+                                  caller);
       return;
-
    case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
-      params[0] = shProg->UniformBlockStageIndex[MESA_SHADER_FRAGMENT][uniformBlockIndex] != -1;
+   case GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER:
+      _mesa_program_resource_prop(shProg, res, index,
+                                  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,
-                 "glGetActiveUniformBlockiv(pname 0x%x (%s))",
-                 pname, _mesa_lookup_enum_by_nr(pname));
+                  "%s(pname 0x%x (%s))", caller, pname,
+                  _mesa_enum_to_string(pname));
+      return;
+   }
+}
+
+
+void GLAPIENTRY
+_mesa_GetActiveUniformBlockiv(GLuint program,
+                             GLuint uniformBlockIndex,
+                             GLenum pname,
+                             GLint *params)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_shader_program *shProg;
+
+   if (!ctx->Extensions.ARB_uniform_buffer_object) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetActiveUniformBlockiv");
       return;
    }
+
+   shProg = _mesa_lookup_shader_program_err(ctx, program,
+                                           "glGetActiveUniformBlockiv");
+   if (!shProg)
+      return;
+
+   mesa_bufferiv(shProg, GL_UNIFORM_BLOCK, uniformBlockIndex, pname, params,
+                 "glGetActiveUniformBlockiv");
 }
 
 void GLAPIENTRY
@@ -1152,7 +1341,6 @@ _mesa_GetActiveUniformBlockName(GLuint program,
 {
    GET_CURRENT_CONTEXT(ctx);
    struct gl_shader_program *shProg;
-   struct gl_uniform_block *block;
 
    if (!ctx->Extensions.ARB_uniform_buffer_object) {
       _mesa_error(ctx, GL_INVALID_OPERATION, "glGetActiveUniformBlockiv");
@@ -1171,18 +1359,11 @@ _mesa_GetActiveUniformBlockName(GLuint program,
    if (!shProg)
       return;
 
-   if (uniformBlockIndex >= shProg->NumUniformBlocks) {
-      _mesa_error(ctx, GL_INVALID_VALUE,
-                 "glGetActiveUniformBlockiv(block index %u >= %u)",
-                 uniformBlockIndex, shProg->NumUniformBlocks);
-      return;
-   }
-
-   block = &shProg->UniformBlocks[uniformBlockIndex];
-
-   if (uniformBlockName) {
-      _mesa_copy_string(uniformBlockName, bufSize, length, block->Name);
-   }
+   if (uniformBlockName)
+      _mesa_get_program_resource_name(shProg, GL_UNIFORM_BLOCK,
+                                      uniformBlockIndex, bufSize, length,
+                                      uniformBlockName,
+                                      "glGetActiveUniformBlockName");
 }
 
 void GLAPIENTRY
@@ -1194,7 +1375,7 @@ _mesa_GetActiveUniformName(GLuint program, GLuint uniformIndex,
    struct gl_shader_program *shProg;
 
    if (!ctx->Extensions.ARB_uniform_buffer_object) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetActiveUniformBlockiv");
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetActiveUniformName");
       return;
    }
 
@@ -1210,54 +1391,8 @@ _mesa_GetActiveUniformName(GLuint program, GLuint uniformIndex,
    if (!shProg)
       return;
 
-   if (uniformIndex >= shProg->NumUserUniformStorage) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(index)");
-      return;
-   }
-
-   if (uniformName) {
-      _mesa_get_uniform_name(& shProg->UniformStorage[uniformIndex],
-                             bufSize, length, uniformName);
-   }
-}
-
-void
-_mesa_get_uniform_name(const struct gl_uniform_storage *uni,
-                       GLsizei maxLength, GLsizei *length,
-                       GLchar *nameOut)
-{
-   GLsizei localLength;
-
-   if (length == NULL)
-      length = &localLength;
-
-   _mesa_copy_string(nameOut, maxLength, length, uni->name);
-
-   /* Page 61 (page 73 of the PDF) in section 2.11 of the OpenGL ES 3.0
-    * spec says:
-    *
-    *     "If the active uniform is an array, the uniform name returned in
-    *     name will always be the name of the uniform array appended with
-    *     "[0]"."
-    *
-    * The same text also appears in the OpenGL 4.2 spec.  It does not,
-    * however, appear in any previous spec.  Previous specifications are
-    * ambiguous in this regard.  However, either name can later be passed
-    * to glGetUniformLocation (and related APIs), so there shouldn't be any
-    * harm in always appending "[0]" to uniform array names.
-    */
-   if (uni->array_elements != 0) {
-      int i;
-
-      /* The comparison is strange because *length does *NOT* include the
-       * terminating NUL, but maxLength does.
-       */
-      for (i = 0; i < 3 && (*length + i + 1) < maxLength; i++)
-         nameOut[*length + i] = "[0]"[i];
-
-      nameOut[*length + i] = '\0';
-      *length += i;
-   }
+   _mesa_get_program_resource_name(shProg, GL_UNIFORM, uniformIndex, bufSize,
+                                   length, uniformName, "glGetActiveUniformName");
 }
 
 void GLAPIENTRY
@@ -1266,8 +1401,6 @@ _mesa_GetActiveAtomicCounterBufferiv(GLuint program, GLuint bufferIndex,
 {
    GET_CURRENT_CONTEXT(ctx);
    struct gl_shader_program *shProg;
-   struct gl_active_atomic_buffer *ab;
-   GLuint i;
 
    if (!ctx->Extensions.ARB_shader_atomic_counters) {
       _mesa_error(ctx, GL_INVALID_OPERATION,
@@ -1280,47 +1413,680 @@ _mesa_GetActiveAtomicCounterBufferiv(GLuint program, GLuint bufferIndex,
    if (!shProg)
       return;
 
-   if (bufferIndex >= shProg->NumAtomicBuffers) {
-      _mesa_error(ctx, GL_INVALID_VALUE,
-                  "glGetActiveAtomicCounterBufferiv(bufferIndex)");
-      return;
-   }
+   mesa_bufferiv(shProg, GL_ATOMIC_COUNTER_BUFFER, bufferIndex, pname, params,
+                 "glGetActiveAtomicCounterBufferiv");
+}
 
-   ab = &shProg->AtomicBuffers[bufferIndex];
+void GLAPIENTRY
+_mesa_Uniform1d(GLint location, GLdouble v0)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform(location, 1, &v0, ctx, ctx->_Shader->ActiveProgram, GLSL_TYPE_DOUBLE, 1);
+}
 
-   switch (pname) {
-   case GL_ATOMIC_COUNTER_BUFFER_BINDING:
-      params[0] = ab->Binding;
-      return;
-   case GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE:
-      params[0] = ab->MinimumSize;
-      return;
-   case GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS:
-      params[0] = ab->NumUniforms;
-      return;
-   case GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES:
-      for (i = 0; i < ab->NumUniforms; ++i)
-         params[i] = ab->Uniforms[i];
-      return;
-   case GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER:
-      params[0] = ab->StageReferences[MESA_SHADER_VERTEX];
-      return;
-   case GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER:
-      params[0] = ab->StageReferences[MESA_SHADER_GEOMETRY];
-      return;
-   case GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER:
-      params[0] = ab->StageReferences[MESA_SHADER_FRAGMENT];
-      return;
-   case GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER:
-      params[0] = GL_FALSE;
-      return;
-   case GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER:
-      params[0] = GL_FALSE;
-      return;
-   default:
-      _mesa_error(ctx, GL_INVALID_ENUM,
-                  "glGetActiveAtomicCounterBufferiv(pname 0x%x (%s))",
-                  pname, _mesa_lookup_enum_by_nr(pname));
-      return;
-   }
+void GLAPIENTRY
+_mesa_Uniform2d(GLint location, GLdouble v0, GLdouble v1)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   GLdouble v[2];
+   v[0] = v0;
+   v[1] = v1;
+   _mesa_uniform(location, 1, v, ctx, ctx->_Shader->ActiveProgram, GLSL_TYPE_DOUBLE, 2);
+}
+
+void GLAPIENTRY
+_mesa_Uniform3d(GLint location, GLdouble v0, GLdouble v1, GLdouble v2)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   GLdouble v[3];
+   v[0] = v0;
+   v[1] = v1;
+   v[2] = v2;
+   _mesa_uniform(location, 1, v, ctx, ctx->_Shader->ActiveProgram, GLSL_TYPE_DOUBLE, 3);
+}
+
+void GLAPIENTRY
+_mesa_Uniform4d(GLint location, GLdouble v0, GLdouble v1, GLdouble v2,
+                GLdouble v3)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   GLdouble v[4];
+   v[0] = v0;
+   v[1] = v1;
+   v[2] = v2;
+   v[3] = v3;
+   _mesa_uniform(location, 1, v, ctx, ctx->_Shader->ActiveProgram, GLSL_TYPE_DOUBLE, 4);
+}
+
+void GLAPIENTRY
+_mesa_Uniform1dv(GLint location, GLsizei count, const GLdouble * value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform(location, count, value, ctx, ctx->_Shader->ActiveProgram, GLSL_TYPE_DOUBLE, 1);
+}
+
+void GLAPIENTRY
+_mesa_Uniform2dv(GLint location, GLsizei count, const GLdouble * value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform(location, count, value, ctx, ctx->_Shader->ActiveProgram, GLSL_TYPE_DOUBLE, 2);
+}
+
+void GLAPIENTRY
+_mesa_Uniform3dv(GLint location, GLsizei count, const GLdouble * value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform(location, count, value, ctx, ctx->_Shader->ActiveProgram, GLSL_TYPE_DOUBLE, 3);
+}
+
+void GLAPIENTRY
+_mesa_Uniform4dv(GLint location, GLsizei count, const GLdouble * value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform(location, count, value, ctx, ctx->_Shader->ActiveProgram, GLSL_TYPE_DOUBLE, 4);
+}
+
+void GLAPIENTRY
+_mesa_UniformMatrix2dv(GLint location, GLsizei count, GLboolean transpose,
+                       const GLdouble * value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform_matrix(location, count, transpose, value,
+                        ctx, ctx->_Shader->ActiveProgram, 2, 2, GLSL_TYPE_DOUBLE);
+}
+
+void GLAPIENTRY
+_mesa_UniformMatrix3dv(GLint location, GLsizei count, GLboolean transpose,
+                       const GLdouble * value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform_matrix(location, count, transpose, value,
+                        ctx, ctx->_Shader->ActiveProgram, 3, 3, GLSL_TYPE_DOUBLE);
+}
+
+void GLAPIENTRY
+_mesa_UniformMatrix4dv(GLint location, GLsizei count, GLboolean transpose,
+                       const GLdouble * value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform_matrix(location, count, transpose, value,
+                        ctx, ctx->_Shader->ActiveProgram, 4, 4, GLSL_TYPE_DOUBLE);
+}
+
+void GLAPIENTRY
+_mesa_UniformMatrix2x3dv(GLint location, GLsizei count, GLboolean transpose,
+                         const GLdouble *value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform_matrix(location, count, transpose, value,
+                        ctx, ctx->_Shader->ActiveProgram, 2, 3, GLSL_TYPE_DOUBLE);
+}
+
+void GLAPIENTRY
+_mesa_UniformMatrix3x2dv(GLint location, GLsizei count, GLboolean transpose,
+                         const GLdouble *value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform_matrix(location, count, transpose, value,
+                        ctx, ctx->_Shader->ActiveProgram, 3, 2, GLSL_TYPE_DOUBLE);
+}
+
+void GLAPIENTRY
+_mesa_UniformMatrix2x4dv(GLint location, GLsizei count, GLboolean transpose,
+                         const GLdouble *value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform_matrix(location, count, transpose, value,
+                        ctx, ctx->_Shader->ActiveProgram, 2, 4, GLSL_TYPE_DOUBLE);
+}
+
+void GLAPIENTRY
+_mesa_UniformMatrix4x2dv(GLint location, GLsizei count, GLboolean transpose,
+                         const GLdouble *value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform_matrix(location, count, transpose, value,
+                        ctx, ctx->_Shader->ActiveProgram, 4, 2, GLSL_TYPE_DOUBLE);
+}
+
+void GLAPIENTRY
+_mesa_UniformMatrix3x4dv(GLint location, GLsizei count, GLboolean transpose,
+                         const GLdouble *value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform_matrix(location, count, transpose, value,
+                        ctx, ctx->_Shader->ActiveProgram, 3, 4, GLSL_TYPE_DOUBLE);
+}
+
+void GLAPIENTRY
+_mesa_UniformMatrix4x3dv(GLint location, GLsizei count, GLboolean transpose,
+                         const GLdouble *value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform_matrix(location, count, transpose, value,
+                        ctx, ctx->_Shader->ActiveProgram, 4, 3, GLSL_TYPE_DOUBLE);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniform1d(GLuint program, GLint location, GLdouble v0)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_shader_program *shProg =
+      _mesa_lookup_shader_program_err(ctx, program,
+            "glProgramUniform1d");
+   _mesa_uniform(location, 1, &v0, ctx, shProg, GLSL_TYPE_DOUBLE, 1);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniform2d(GLuint program, GLint location, GLdouble v0, GLdouble v1)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   GLdouble v[2];
+   struct gl_shader_program *shProg;
+   v[0] = v0;
+   v[1] = v1;
+   shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniform2d");
+   _mesa_uniform(location, 1, v, ctx, shProg, GLSL_TYPE_DOUBLE, 2);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniform3d(GLuint program, GLint location, GLdouble v0, GLdouble v1,
+                       GLdouble v2)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   GLdouble v[3];
+   struct gl_shader_program *shProg;
+   v[0] = v0;
+   v[1] = v1;
+   v[2] = v2;
+   shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniform3d");
+   _mesa_uniform(location, 1, v, ctx, shProg, GLSL_TYPE_DOUBLE, 3);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniform4d(GLuint program, GLint location, GLdouble v0, GLdouble v1,
+                       GLdouble v2, GLdouble v3)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   GLdouble v[4];
+   struct gl_shader_program *shProg;
+   v[0] = v0;
+   v[1] = v1;
+   v[2] = v2;
+   v[3] = v3;
+   shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniform4d");
+   _mesa_uniform(location, 1, v, ctx, shProg, GLSL_TYPE_DOUBLE, 4);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniform1dv(GLuint program, GLint location, GLsizei count,
+                        const GLdouble * value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_shader_program *shProg =
+      _mesa_lookup_shader_program_err(ctx, program,
+            "glProgramUniform1dv");
+   _mesa_uniform(location, count, value, ctx, shProg, GLSL_TYPE_DOUBLE, 1);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniform2dv(GLuint program, GLint location, GLsizei count,
+                        const GLdouble * value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_shader_program *shProg =
+      _mesa_lookup_shader_program_err(ctx, program,
+            "glProgramUniform2dv");
+   _mesa_uniform(location, count, value, ctx, shProg, GLSL_TYPE_DOUBLE, 2);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniform3dv(GLuint program, GLint location, GLsizei count,
+                        const GLdouble * value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_shader_program *shProg =
+      _mesa_lookup_shader_program_err(ctx, program,
+            "glProgramUniform3dv");
+   _mesa_uniform(location, count, value, ctx, shProg, GLSL_TYPE_DOUBLE, 3);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniform4dv(GLuint program, GLint location, GLsizei count,
+                        const GLdouble * value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_shader_program *shProg =
+      _mesa_lookup_shader_program_err(ctx, program,
+            "glProgramUniform4dv");
+   _mesa_uniform(location, count, value, ctx, shProg, GLSL_TYPE_DOUBLE, 4);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniformMatrix2dv(GLuint program, GLint location, GLsizei count,
+                              GLboolean transpose, const GLdouble * value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_shader_program *shProg =
+      _mesa_lookup_shader_program_err(ctx, program,
+            "glProgramUniformMatrix2dv");
+   _mesa_uniform_matrix(location, count, transpose, value,
+                        ctx, shProg, 2, 2, GLSL_TYPE_DOUBLE);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniformMatrix3dv(GLuint program, GLint location, GLsizei count,
+                              GLboolean transpose, const GLdouble * value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_shader_program *shProg =
+      _mesa_lookup_shader_program_err(ctx, program,
+            "glProgramUniformMatrix3dv");
+   _mesa_uniform_matrix(location, count, transpose, value,
+                        ctx, shProg, 3, 3, GLSL_TYPE_DOUBLE);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniformMatrix4dv(GLuint program, GLint location, GLsizei count,
+                              GLboolean transpose, const GLdouble * value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_shader_program *shProg =
+      _mesa_lookup_shader_program_err(ctx, program,
+            "glProgramUniformMatrix4dv");
+   _mesa_uniform_matrix(location, count, transpose, value,
+                        ctx, shProg, 4, 4, GLSL_TYPE_DOUBLE);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniformMatrix2x3dv(GLuint program, GLint location, GLsizei count,
+                                GLboolean transpose, const GLdouble * value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_shader_program *shProg =
+      _mesa_lookup_shader_program_err(ctx, program,
+            "glProgramUniformMatrix2x3dv");
+   _mesa_uniform_matrix(location, count, transpose, value,
+                        ctx, shProg, 2, 3, GLSL_TYPE_DOUBLE);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniformMatrix3x2dv(GLuint program, GLint location, GLsizei count,
+                                GLboolean transpose, const GLdouble * value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_shader_program *shProg =
+      _mesa_lookup_shader_program_err(ctx, program,
+            "glProgramUniformMatrix3x2dv");
+   _mesa_uniform_matrix(location, count, transpose, value,
+                        ctx, shProg, 3, 2, GLSL_TYPE_DOUBLE);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniformMatrix2x4dv(GLuint program, GLint location, GLsizei count,
+                                GLboolean transpose, const GLdouble * value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_shader_program *shProg =
+      _mesa_lookup_shader_program_err(ctx, program,
+            "glProgramUniformMatrix2x4dv");
+   _mesa_uniform_matrix(location, count, transpose, value,
+                        ctx, shProg, 2, 4, GLSL_TYPE_DOUBLE);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniformMatrix4x2dv(GLuint program, GLint location, GLsizei count,
+                                GLboolean transpose, const GLdouble * value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_shader_program *shProg =
+      _mesa_lookup_shader_program_err(ctx, program,
+            "glProgramUniformMatrix4x2dv");
+   _mesa_uniform_matrix(location, count, transpose, value,
+                        ctx, shProg, 4, 2, GLSL_TYPE_DOUBLE);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniformMatrix3x4dv(GLuint program, GLint location, GLsizei count,
+                                GLboolean transpose, const GLdouble * value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_shader_program *shProg =
+      _mesa_lookup_shader_program_err(ctx, program,
+            "glProgramUniformMatrix3x4dv");
+   _mesa_uniform_matrix(location, count, transpose, value,
+                        ctx, shProg, 3, 4, GLSL_TYPE_DOUBLE);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniformMatrix4x3dv(GLuint program, GLint location, GLsizei count,
+                                GLboolean transpose, const GLdouble * value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_shader_program *shProg =
+      _mesa_lookup_shader_program_err(ctx, program,
+            "glProgramUniformMatrix4x3dv");
+   _mesa_uniform_matrix(location, count, transpose, value,
+                        ctx, shProg, 4, 3, GLSL_TYPE_DOUBLE);
+}
+
+void GLAPIENTRY
+_mesa_Uniform1i64ARB(GLint location, GLint64 v0)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform(location, 1, &v0, ctx, ctx->_Shader->ActiveProgram, GLSL_TYPE_INT64, 1);
+}
+
+void GLAPIENTRY
+_mesa_Uniform2i64ARB(GLint location, GLint64 v0, GLint64 v1)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   int64_t v[2];
+   v[0] = v0;
+   v[1] = v1;
+   _mesa_uniform(location, 1, v, ctx, ctx->_Shader->ActiveProgram, GLSL_TYPE_INT64, 2);
+}
+
+void GLAPIENTRY
+_mesa_Uniform3i64ARB(GLint location, GLint64 v0, GLint64 v1, GLint64 v2)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   int64_t v[3];
+   v[0] = v0;
+   v[1] = v1;
+   v[2] = v2;
+   _mesa_uniform(location, 1, v, ctx, ctx->_Shader->ActiveProgram, GLSL_TYPE_INT64, 3);
+}
+
+void GLAPIENTRY
+_mesa_Uniform4i64ARB(GLint location,  GLint64 v0, GLint64 v1, GLint64 v2, GLint64 v3)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   int64_t v[4];
+   v[0] = v0;
+   v[1] = v1;
+   v[2] = v2;
+   v[3] = v3;
+   _mesa_uniform(location, 1, v, ctx, ctx->_Shader->ActiveProgram, GLSL_TYPE_INT64, 4);
+}
+
+void GLAPIENTRY
+_mesa_Uniform1i64vARB(GLint location, GLsizei count, const GLint64 *value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform(location, count, value, ctx, ctx->_Shader->ActiveProgram, GLSL_TYPE_INT64, 1);
+}
+
+void GLAPIENTRY
+_mesa_Uniform2i64vARB(GLint location,  GLsizei count, const GLint64 *value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform(location, count, value, ctx, ctx->_Shader->ActiveProgram, GLSL_TYPE_INT64, 2);
+}
+
+void GLAPIENTRY
+_mesa_Uniform3i64vARB(GLint location,  GLsizei count, const GLint64 *value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform(location, count, value, ctx, ctx->_Shader->ActiveProgram, GLSL_TYPE_INT64, 3);
+}
+
+void GLAPIENTRY
+_mesa_Uniform4i64vARB(GLint location,  GLsizei count, const GLint64 *value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform(location, count, value, ctx, ctx->_Shader->ActiveProgram, GLSL_TYPE_INT64, 4);
+}
+
+void GLAPIENTRY
+_mesa_Uniform1ui64ARB(GLint location,  GLuint64 v0)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform(location, 1, &v0, ctx, ctx->_Shader->ActiveProgram, GLSL_TYPE_UINT64, 1);
+}
+
+void GLAPIENTRY
+_mesa_Uniform2ui64ARB(GLint location,  GLuint64 v0, GLuint64 v1)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   uint64_t v[2];
+   v[0] = v0;
+   v[1] = v1;
+   _mesa_uniform(location, 1, v, ctx, ctx->_Shader->ActiveProgram, GLSL_TYPE_UINT64, 2);
+}
+
+void GLAPIENTRY
+_mesa_Uniform3ui64ARB(GLint location, GLuint64 v0, GLuint64 v1, GLuint64 v2)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   uint64_t v[3];
+   v[0] = v0;
+   v[1] = v1;
+   v[2] = v2;
+   _mesa_uniform(location, 1, v, ctx, ctx->_Shader->ActiveProgram, GLSL_TYPE_UINT64, 3);
+}
+
+void GLAPIENTRY
+_mesa_Uniform4ui64ARB(GLint location,  GLuint64 v0, GLuint64 v1, GLuint64 v2, GLuint64 v3)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   uint64_t v[4];
+   v[0] = v0;
+   v[1] = v1;
+   v[2] = v2;
+   v[3] = v3;
+   _mesa_uniform(location, 1, v, ctx, ctx->_Shader->ActiveProgram, GLSL_TYPE_UINT64, 4);
+}
+
+void GLAPIENTRY
+_mesa_Uniform1ui64vARB(GLint location,  GLsizei count, const GLuint64 *value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform(location, count, value, ctx, ctx->_Shader->ActiveProgram, GLSL_TYPE_UINT64, 1);
+}
+
+void GLAPIENTRY
+_mesa_Uniform2ui64vARB(GLint location,  GLsizei count, const GLuint64 *value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform(location, count, value, ctx, ctx->_Shader->ActiveProgram, GLSL_TYPE_UINT64, 2);
+}
+
+void GLAPIENTRY
+_mesa_Uniform3ui64vARB(GLint location,  GLsizei count, const GLuint64 *value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform(location, count, value, ctx, ctx->_Shader->ActiveProgram, GLSL_TYPE_UINT64, 3);
+}
+
+void GLAPIENTRY
+_mesa_Uniform4ui64vARB(GLint location,  GLsizei count, const GLuint64 *value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform(location, count, value, ctx, ctx->_Shader->ActiveProgram, GLSL_TYPE_UINT64, 4);
+}
+
+/* DSA entrypoints */
+void GLAPIENTRY
+_mesa_ProgramUniform1i64ARB(GLuint program, GLint location, GLint64 v0)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_shader_program *shProg =
+      _mesa_lookup_shader_program_err(ctx, program,
+            "glProgramUniform1i64ARB");
+   _mesa_uniform(location, 1, &v0, ctx, shProg, GLSL_TYPE_INT64, 1);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniform2i64ARB(GLuint program, GLint location, GLint64 v0, GLint64 v1)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_shader_program *shProg =
+      _mesa_lookup_shader_program_err(ctx, program,
+                                      "glProgramUniform2i64ARB");
+   int64_t v[2];
+   v[0] = v0;
+   v[1] = v1;
+   _mesa_uniform(location, 1, v, ctx, shProg, GLSL_TYPE_INT64, 2);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniform3i64ARB(GLuint program, GLint location, GLint64 v0, GLint64 v1, GLint64 v2)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_shader_program *shProg =
+      _mesa_lookup_shader_program_err(ctx, program,
+                                      "glProgramUniform3i64ARB");
+   int64_t v[3];
+   v[0] = v0;
+   v[1] = v1;
+   v[2] = v2;
+   _mesa_uniform(location, 1, v, ctx, shProg, GLSL_TYPE_INT64, 3);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniform4i64ARB(GLuint program, GLint location,  GLint64 v0, GLint64 v1, GLint64 v2, GLint64 v3)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_shader_program *shProg =
+      _mesa_lookup_shader_program_err(ctx, program,
+                                      "glProgramUniform4i64ARB");
+   int64_t v[4];
+   v[0] = v0;
+   v[1] = v1;
+   v[2] = v2;
+   v[3] = v3;
+   _mesa_uniform(location, 1, v, ctx, shProg, GLSL_TYPE_INT64, 4);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniform1i64vARB(GLuint program, GLint location, GLsizei count, const GLint64 *value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_shader_program *shProg =
+      _mesa_lookup_shader_program_err(ctx, program,
+                                      "glProgramUniform1i64vARB");
+   _mesa_uniform(location, count, value, ctx, shProg, GLSL_TYPE_INT64, 1);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniform2i64vARB(GLuint program, GLint location,  GLsizei count, const GLint64 *value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_shader_program *shProg =
+      _mesa_lookup_shader_program_err(ctx, program,
+                                      "glProgramUniform2i64vARB");
+   _mesa_uniform(location, count, value, ctx, shProg, GLSL_TYPE_INT64, 2);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniform3i64vARB(GLuint program, GLint location,  GLsizei count, const GLint64 *value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_shader_program *shProg =
+      _mesa_lookup_shader_program_err(ctx, program,
+                                      "glProgramUniform3i64vARB");
+   _mesa_uniform(location, count, value, ctx, shProg, GLSL_TYPE_INT64, 3);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniform4i64vARB(GLuint program, GLint location,  GLsizei count, const GLint64 *value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_shader_program *shProg =
+      _mesa_lookup_shader_program_err(ctx, program,
+                                      "glProgramUniform4i64vARB");
+   _mesa_uniform(location, count, value, ctx, shProg, GLSL_TYPE_INT64, 4);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniform1ui64ARB(GLuint program, GLint location,  GLuint64 v0)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_shader_program *shProg =
+      _mesa_lookup_shader_program_err(ctx, program,
+                                      "glProgramUniform1ui64ARB");
+   _mesa_uniform(location, 1, &v0, ctx, shProg, GLSL_TYPE_UINT64, 1);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniform2ui64ARB(GLuint program, GLint location,  GLuint64 v0, GLuint64 v1)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_shader_program *shProg =
+      _mesa_lookup_shader_program_err(ctx, program,
+                                      "glProgramUniform2ui64ARB");
+   uint64_t v[2];
+   v[0] = v0;
+   v[1] = v1;
+   _mesa_uniform(location, 1, v, ctx, shProg, GLSL_TYPE_UINT64, 2);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniform3ui64ARB(GLuint program, GLint location, GLuint64 v0, GLuint64 v1, GLuint64 v2)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_shader_program *shProg =
+      _mesa_lookup_shader_program_err(ctx, program,
+                                      "glProgramUniform3ui64ARB");
+   uint64_t v[3];
+   v[0] = v0;
+   v[1] = v1;
+   v[2] = v2;
+   _mesa_uniform(location, 1, v, ctx, shProg, GLSL_TYPE_UINT64, 3);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniform4ui64ARB(GLuint program, GLint location,  GLuint64 v0, GLuint64 v1, GLuint64 v2, GLuint64 v3)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_shader_program *shProg =
+      _mesa_lookup_shader_program_err(ctx, program,
+                                      "glProgramUniform4ui64ARB");
+   uint64_t v[4];
+   v[0] = v0;
+   v[1] = v1;
+   v[2] = v2;
+   v[3] = v3;
+   _mesa_uniform(location, 1, v, ctx, shProg, GLSL_TYPE_UINT64, 4);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniform1ui64vARB(GLuint program, GLint location,  GLsizei count, const GLuint64 *value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_shader_program *shProg =
+      _mesa_lookup_shader_program_err(ctx, program,
+                                      "glProgramUniform1ui64vARB");
+   _mesa_uniform(location, count, value, ctx, shProg, GLSL_TYPE_UINT64, 1);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniform2ui64vARB(GLuint program, GLint location,  GLsizei count, const GLuint64 *value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_shader_program *shProg =
+      _mesa_lookup_shader_program_err(ctx, program,
+                                      "glProgramUniform2ui64vARB");
+   _mesa_uniform(location, count, value, ctx, shProg, GLSL_TYPE_UINT64, 2);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniform3ui64vARB(GLuint program, GLint location,  GLsizei count, const GLuint64 *value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_shader_program *shProg =
+      _mesa_lookup_shader_program_err(ctx, program,
+                                      "glProgramUniform3ui64vARB");
+   _mesa_uniform(location, count, value, ctx, shProg, GLSL_TYPE_UINT64, 3);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniform4ui64vARB(GLuint program, GLint location,  GLsizei count, const GLuint64 *value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_shader_program *shProg =
+      _mesa_lookup_shader_program_err(ctx, program,
+                                      "glProgramUniform4ui64vARB");
+   _mesa_uniform(location, count, value, ctx, shProg, GLSL_TYPE_UINT64, 4);
 }