mesa: Change OES_point_sprite to depend on ARB_point_sprite
[mesa.git] / src / mesa / main / uniforms.c
index aac4177f4081eed27a87a0b8f1fc2871fd9afcc4..aee2e6b4e9bc52579e3154c6a3204f733e8c76a8 100644 (file)
@@ -3,6 +3,7 @@
  *
  * Copyright (C) 2004-2008  Brian Paul   All Rights Reserved.
  * Copyright (C) 2009-2010  VMware, Inc.  All Rights Reserved.
+ * Copyright © 2010 Intel Corporation
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
 #include "main/glheader.h"
 #include "main/context.h"
 #include "main/dispatch.h"
+#include "main/mfeatures.h"
+#include "main/mtypes.h"
 #include "main/shaderapi.h"
 #include "main/shaderobj.h"
 #include "main/uniforms.h"
 #include "program/prog_parameter.h"
 #include "program/prog_statevars.h"
 #include "program/prog_uniform.h"
-
+#include "program/prog_instruction.h"
 
 
 static GLenum
@@ -79,6 +82,238 @@ base_uniform_type(GLenum type)
    }
 }
 
+static struct gl_builtin_uniform_element gl_DepthRange_elements[] = {
+   {"near", {STATE_DEPTH_RANGE, 0, 0}, SWIZZLE_XXXX},
+   {"far", {STATE_DEPTH_RANGE, 0, 0}, SWIZZLE_YYYY},
+   {"diff", {STATE_DEPTH_RANGE, 0, 0}, SWIZZLE_ZZZZ},
+};
+
+static struct gl_builtin_uniform_element gl_ClipPlane_elements[] = {
+   {NULL, {STATE_CLIPPLANE, 0, 0}, SWIZZLE_XYZW}
+};
+
+static struct gl_builtin_uniform_element gl_Point_elements[] = {
+   {"size", {STATE_POINT_SIZE}, SWIZZLE_XXXX},
+   {"sizeMin", {STATE_POINT_SIZE}, SWIZZLE_YYYY},
+   {"sizeMax", {STATE_POINT_SIZE}, SWIZZLE_ZZZZ},
+   {"fadeThresholdSize", {STATE_POINT_SIZE}, SWIZZLE_WWWW},
+   {"distanceConstantAttenuation", {STATE_POINT_ATTENUATION}, SWIZZLE_XXXX},
+   {"distanceLinearAttenuation", {STATE_POINT_ATTENUATION}, SWIZZLE_YYYY},
+   {"distanceQuadraticAttenuation", {STATE_POINT_ATTENUATION}, SWIZZLE_ZZZZ},
+};
+
+static struct gl_builtin_uniform_element gl_FrontMaterial_elements[] = {
+   {"emission", {STATE_MATERIAL, 0, STATE_EMISSION}, SWIZZLE_XYZW},
+   {"ambient", {STATE_MATERIAL, 0, STATE_AMBIENT}, SWIZZLE_XYZW},
+   {"diffuse", {STATE_MATERIAL, 0, STATE_DIFFUSE}, SWIZZLE_XYZW},
+   {"specular", {STATE_MATERIAL, 0, STATE_SPECULAR}, SWIZZLE_XYZW},
+   {"shininess", {STATE_MATERIAL, 0, STATE_SHININESS}, SWIZZLE_XXXX},
+};
+
+static struct gl_builtin_uniform_element gl_BackMaterial_elements[] = {
+   {"emission", {STATE_MATERIAL, 1, STATE_EMISSION}, SWIZZLE_XYZW},
+   {"ambient", {STATE_MATERIAL, 1, STATE_AMBIENT}, SWIZZLE_XYZW},
+   {"diffuse", {STATE_MATERIAL, 1, STATE_DIFFUSE}, SWIZZLE_XYZW},
+   {"specular", {STATE_MATERIAL, 1, STATE_SPECULAR}, SWIZZLE_XYZW},
+   {"shininess", {STATE_MATERIAL, 1, STATE_SHININESS}, SWIZZLE_XXXX},
+};
+
+static struct gl_builtin_uniform_element gl_LightSource_elements[] = {
+   {"ambient", {STATE_LIGHT, 0, STATE_AMBIENT}, SWIZZLE_XYZW},
+   {"diffuse", {STATE_LIGHT, 0, STATE_DIFFUSE}, SWIZZLE_XYZW},
+   {"specular", {STATE_LIGHT, 0, STATE_SPECULAR}, SWIZZLE_XYZW},
+   {"position", {STATE_LIGHT, 0, STATE_POSITION}, SWIZZLE_XYZW},
+   {"halfVector", {STATE_LIGHT, 0, STATE_HALF_VECTOR}, SWIZZLE_XYZW},
+   {"spotDirection", {STATE_LIGHT, 0, STATE_SPOT_DIRECTION},
+    MAKE_SWIZZLE4(SWIZZLE_X,
+                 SWIZZLE_Y,
+                 SWIZZLE_Z,
+                 SWIZZLE_Z)},
+   {"spotCosCutoff", {STATE_LIGHT, 0, STATE_SPOT_DIRECTION}, SWIZZLE_WWWW},
+   {"spotCutoff", {STATE_LIGHT, 0, STATE_SPOT_CUTOFF}, SWIZZLE_XXXX},
+   {"spotExponent", {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_WWWW},
+   {"constantAttenuation", {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_XXXX},
+   {"linearAttenuation", {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_YYYY},
+   {"quadraticAttenuation", {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_ZZZZ},
+};
+
+static struct gl_builtin_uniform_element gl_LightModel_elements[] = {
+   {"ambient", {STATE_LIGHTMODEL_AMBIENT, 0}, SWIZZLE_XYZW},
+};
+
+static struct gl_builtin_uniform_element gl_FrontLightModelProduct_elements[] = {
+   {"sceneColor", {STATE_LIGHTMODEL_SCENECOLOR, 0}, SWIZZLE_XYZW},
+};
+
+static struct gl_builtin_uniform_element gl_BackLightModelProduct_elements[] = {
+   {"sceneColor", {STATE_LIGHTMODEL_SCENECOLOR, 1}, SWIZZLE_XYZW},
+};
+
+static struct gl_builtin_uniform_element gl_FrontLightProduct_elements[] = {
+   {"ambient", {STATE_LIGHTPROD, 0, 0, STATE_AMBIENT}, SWIZZLE_XYZW},
+   {"diffuse", {STATE_LIGHTPROD, 0, 0, STATE_DIFFUSE}, SWIZZLE_XYZW},
+   {"specular", {STATE_LIGHTPROD, 0, 0, STATE_SPECULAR}, SWIZZLE_XYZW},
+};
+
+static struct gl_builtin_uniform_element gl_BackLightProduct_elements[] = {
+   {"ambient", {STATE_LIGHTPROD, 0, 1, STATE_AMBIENT}, SWIZZLE_XYZW},
+   {"diffuse", {STATE_LIGHTPROD, 0, 1, STATE_DIFFUSE}, SWIZZLE_XYZW},
+   {"specular", {STATE_LIGHTPROD, 0, 1, STATE_SPECULAR}, SWIZZLE_XYZW},
+};
+
+static struct gl_builtin_uniform_element gl_TextureEnvColor_elements[] = {
+   {NULL, {STATE_TEXENV_COLOR, 0}, SWIZZLE_XYZW},
+};
+
+static struct gl_builtin_uniform_element gl_EyePlaneS_elements[] = {
+   {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_S}, SWIZZLE_XYZW},
+};
+
+static struct gl_builtin_uniform_element gl_EyePlaneT_elements[] = {
+   {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_T}, SWIZZLE_XYZW},
+};
+
+static struct gl_builtin_uniform_element gl_EyePlaneR_elements[] = {
+   {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_R}, SWIZZLE_XYZW},
+};
+
+static struct gl_builtin_uniform_element gl_EyePlaneQ_elements[] = {
+   {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_Q}, SWIZZLE_XYZW},
+};
+
+static struct gl_builtin_uniform_element gl_ObjectPlaneS_elements[] = {
+   {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_S}, SWIZZLE_XYZW},
+};
+
+static struct gl_builtin_uniform_element gl_ObjectPlaneT_elements[] = {
+   {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_T}, SWIZZLE_XYZW},
+};
+
+static struct gl_builtin_uniform_element gl_ObjectPlaneR_elements[] = {
+   {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_R}, SWIZZLE_XYZW},
+};
+
+static struct gl_builtin_uniform_element gl_ObjectPlaneQ_elements[] = {
+   {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_Q}, SWIZZLE_XYZW},
+};
+
+static struct gl_builtin_uniform_element gl_Fog_elements[] = {
+   {"color", {STATE_FOG_COLOR}, SWIZZLE_XYZW},
+   {"density", {STATE_FOG_PARAMS}, SWIZZLE_XXXX},
+   {"start", {STATE_FOG_PARAMS}, SWIZZLE_YYYY},
+   {"end", {STATE_FOG_PARAMS}, SWIZZLE_ZZZZ},
+   {"scale", {STATE_FOG_PARAMS}, SWIZZLE_WWWW},
+};
+
+static struct gl_builtin_uniform_element gl_NormalScale_elements[] = {
+   {NULL, {STATE_NORMAL_SCALE}, SWIZZLE_XXXX},
+};
+
+#define MATRIX(name, statevar, modifier)                               \
+   static struct gl_builtin_uniform_element name ## _elements[] = {    \
+      { NULL, { statevar, 0, 0, 0, modifier}, SWIZZLE_XYZW },          \
+      { NULL, { statevar, 0, 1, 1, modifier}, SWIZZLE_XYZW },          \
+      { NULL, { statevar, 0, 2, 2, modifier}, SWIZZLE_XYZW },          \
+      { NULL, { statevar, 0, 3, 3, modifier}, SWIZZLE_XYZW },          \
+   }
+
+MATRIX(gl_ModelViewMatrix,
+       STATE_MODELVIEW_MATRIX, STATE_MATRIX_TRANSPOSE);
+MATRIX(gl_ModelViewMatrixInverse,
+       STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVTRANS);
+MATRIX(gl_ModelViewMatrixTranspose,
+       STATE_MODELVIEW_MATRIX, 0);
+MATRIX(gl_ModelViewMatrixInverseTranspose,
+       STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVERSE);
+
+MATRIX(gl_ProjectionMatrix,
+       STATE_PROJECTION_MATRIX, STATE_MATRIX_TRANSPOSE);
+MATRIX(gl_ProjectionMatrixInverse,
+       STATE_PROJECTION_MATRIX, STATE_MATRIX_INVTRANS);
+MATRIX(gl_ProjectionMatrixTranspose,
+       STATE_PROJECTION_MATRIX, 0);
+MATRIX(gl_ProjectionMatrixInverseTranspose,
+       STATE_PROJECTION_MATRIX, STATE_MATRIX_INVERSE);
+
+MATRIX(gl_ModelViewProjectionMatrix,
+       STATE_MVP_MATRIX, STATE_MATRIX_TRANSPOSE);
+MATRIX(gl_ModelViewProjectionMatrixInverse,
+       STATE_MVP_MATRIX, STATE_MATRIX_INVTRANS);
+MATRIX(gl_ModelViewProjectionMatrixTranspose,
+       STATE_MVP_MATRIX, 0);
+MATRIX(gl_ModelViewProjectionMatrixInverseTranspose,
+       STATE_MVP_MATRIX, STATE_MATRIX_INVERSE);
+
+MATRIX(gl_TextureMatrix,
+       STATE_TEXTURE_MATRIX, STATE_MATRIX_TRANSPOSE);
+MATRIX(gl_TextureMatrixInverse,
+       STATE_TEXTURE_MATRIX, STATE_MATRIX_INVTRANS);
+MATRIX(gl_TextureMatrixTranspose,
+       STATE_TEXTURE_MATRIX, 0);
+MATRIX(gl_TextureMatrixInverseTranspose,
+       STATE_TEXTURE_MATRIX, STATE_MATRIX_INVERSE);
+
+static struct gl_builtin_uniform_element gl_NormalMatrix_elements[] = {
+   { NULL, { STATE_MODELVIEW_MATRIX, 0, 0, 0, STATE_MATRIX_INVERSE},
+     SWIZZLE_XYZW },
+   { NULL, { STATE_MODELVIEW_MATRIX, 0, 1, 1, STATE_MATRIX_INVERSE},
+     SWIZZLE_XYZW },
+   { NULL, { STATE_MODELVIEW_MATRIX, 0, 2, 2, STATE_MATRIX_INVERSE},
+     SWIZZLE_XYZW },
+};
+
+#undef MATRIX
+
+#define STATEVAR(name) {#name, name ## _elements, Elements(name ## _elements)}
+
+const struct gl_builtin_uniform_desc _mesa_builtin_uniform_desc[] = {
+   STATEVAR(gl_DepthRange),
+   STATEVAR(gl_ClipPlane),
+   STATEVAR(gl_Point),
+   STATEVAR(gl_FrontMaterial),
+   STATEVAR(gl_BackMaterial),
+   STATEVAR(gl_LightSource),
+   STATEVAR(gl_LightModel),
+   STATEVAR(gl_FrontLightModelProduct),
+   STATEVAR(gl_BackLightModelProduct),
+   STATEVAR(gl_FrontLightProduct),
+   STATEVAR(gl_BackLightProduct),
+   STATEVAR(gl_TextureEnvColor),
+   STATEVAR(gl_EyePlaneS),
+   STATEVAR(gl_EyePlaneT),
+   STATEVAR(gl_EyePlaneR),
+   STATEVAR(gl_EyePlaneQ),
+   STATEVAR(gl_ObjectPlaneS),
+   STATEVAR(gl_ObjectPlaneT),
+   STATEVAR(gl_ObjectPlaneR),
+   STATEVAR(gl_ObjectPlaneQ),
+   STATEVAR(gl_Fog),
+
+   STATEVAR(gl_ModelViewMatrix),
+   STATEVAR(gl_ModelViewMatrixInverse),
+   STATEVAR(gl_ModelViewMatrixTranspose),
+   STATEVAR(gl_ModelViewMatrixInverseTranspose),
+
+   STATEVAR(gl_ProjectionMatrix),
+   STATEVAR(gl_ProjectionMatrixInverse),
+   STATEVAR(gl_ProjectionMatrixTranspose),
+   STATEVAR(gl_ProjectionMatrixInverseTranspose),
+
+   STATEVAR(gl_ModelViewProjectionMatrix),
+   STATEVAR(gl_ModelViewProjectionMatrixInverse),
+   STATEVAR(gl_ModelViewProjectionMatrixTranspose),
+   STATEVAR(gl_ModelViewProjectionMatrixInverseTranspose),
+
+   STATEVAR(gl_TextureMatrix),
+   STATEVAR(gl_TextureMatrixInverse),
+   STATEVAR(gl_TextureMatrixTranspose),
+   STATEVAR(gl_TextureMatrixInverseTranspose),
+
+   STATEVAR(gl_NormalMatrix),
+   STATEVAR(gl_NormalScale),
+
+   {NULL, NULL, 0}
+};
 
 static GLboolean
 is_boolean_type(GLenum type)
@@ -132,6 +367,11 @@ get_uniform_parameter(const struct gl_shader_program *shProg, GLuint index)
       progPos = shProg->Uniforms->Uniforms[index].FragPos;
       if (progPos >= 0) {
          prog = &shProg->FragmentProgram->Base;
+      } else {
+         progPos = shProg->Uniforms->Uniforms[index].GeomPos;
+         if (progPos >= 0) {
+            prog = &shProg->GeometryProgram->Base;
+         }
       }
    }
 
@@ -146,7 +386,7 @@ get_uniform_parameter(const struct gl_shader_program *shProg, GLuint index)
  * Called by glGetActiveUniform().
  */
 static void
-_mesa_get_active_uniform(GLcontext *ctx, GLuint program, GLuint index,
+_mesa_get_active_uniform(struct gl_context *ctx, GLuint program, GLuint index,
                          GLsizei maxLength, GLsizei *length, GLint *size,
                          GLenum *type, GLchar *nameOut)
 {
@@ -172,6 +412,11 @@ _mesa_get_active_uniform(GLcontext *ctx, GLuint program, GLuint index,
       progPos = shProg->Uniforms->Uniforms[index].FragPos;
       if (progPos >= 0) {
          prog = &shProg->FragmentProgram->Base;
+      } else {
+         progPos = shProg->Uniforms->Uniforms[index].GeomPos;
+         if (progPos >= 0) {
+            prog = &shProg->GeometryProgram->Base;
+         }
       }
    }
 
@@ -268,7 +513,7 @@ get_uniform_rows_cols(const struct gl_program_parameter *p,
          *cols = p->Size;
       }
       else {
-         *rows = p->Size / 4 + 1;
+         *rows = (p->Size + 3) / 4;
          if (p->Size % 4 == 0)
             *cols = 4;
          else
@@ -284,7 +529,7 @@ get_uniform_rows_cols(const struct gl_program_parameter *p,
  * to the shader program and return the program parameter position.
  */
 static void
-lookup_uniform_parameter(GLcontext *ctx, GLuint program, GLint location,
+lookup_uniform_parameter(struct gl_context *ctx, GLuint program, GLint location,
                          struct gl_program **progOut, GLint *paramPosOut)
 {
    struct gl_shader_program *shProg
@@ -310,6 +555,11 @@ lookup_uniform_parameter(GLcontext *ctx, GLuint program, GLint location,
             progPos = shProg->Uniforms->Uniforms[location].FragPos;
             if (progPos >= 0) {
                prog = &shProg->FragmentProgram->Base;
+            } else {
+               progPos = shProg->Uniforms->Uniforms[location].GeomPos;
+               if (progPos >= 0) {
+                  prog = &shProg->GeometryProgram->Base;
+               }
             }
          }
       }
@@ -372,7 +622,7 @@ split_location_offset(GLint *location, GLint *offset)
  * Called via glGetUniformfv().
  */
 static void
-_mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location,
+_mesa_get_uniformfv(struct gl_context *ctx, GLuint program, GLint location,
                     GLfloat *params)
 {
    struct gl_program *prog;
@@ -405,7 +655,7 @@ _mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location,
  * \sa _mesa_get_uniformfv, only difference is a cast.
  */
 static void
-_mesa_get_uniformiv(GLcontext *ctx, GLuint program, GLint location,
+_mesa_get_uniformiv(struct gl_context *ctx, GLuint program, GLint location,
                     GLint *params)
 {
    struct gl_program *prog;
@@ -433,23 +683,52 @@ _mesa_get_uniformiv(GLcontext *ctx, GLuint program, GLint location,
 }
 
 
+/**
+ * Called via glGetUniformuiv().
+ * New in GL_EXT_gpu_shader4, OpenGL 3.0
+ * \sa _mesa_get_uniformfv, only difference is a cast.
+ */
+static void
+_mesa_get_uniformuiv(struct gl_context *ctx, GLuint program, GLint location,
+                     GLuint *params)
+{
+   struct gl_program *prog;
+   GLint paramPos;
+   GLint offset;
+
+   split_location_offset(&location, &offset);
+
+   lookup_uniform_parameter(ctx, program, location, &prog, &paramPos);
+
+   if (prog) {
+      const struct gl_program_parameter *p =
+         &prog->Parameters->Parameters[paramPos];
+      GLint rows, cols, i, j, k;
+
+      get_uniform_rows_cols(p, &rows, &cols);
+
+      k = 0;
+      for (i = 0; i < rows; i++) {
+         for (j = 0; j < cols; j++ ) {
+            params[k++] = (GLuint) prog->Parameters->ParameterValues[paramPos+i][j];
+         }
+      }
+   }
+}
+
+
 /**
  * Called via glGetUniformLocation().
  *
  * The return value will encode two values, the uniform location and an
  * offset (used for arrays, structs).
  */
-static GLint
-_mesa_get_uniform_location(GLcontext *ctx, GLuint program, const GLchar *name)
+GLint
+_mesa_get_uniform_location(struct gl_context *ctx, struct gl_shader_program *shProg,
+                          const GLchar *name)
 {
    GLint offset = 0, location = -1;
 
-   struct gl_shader_program *shProg =
-      _mesa_lookup_shader_program_err(ctx, program, "glGetUniformLocation");
-
-   if (!shProg)
-      return -1;
-
    if (shProg->LinkStatus == GL_FALSE) {
       _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfv(program)");
       return -1;
@@ -594,7 +873,7 @@ compatible_types(GLenum userType, GLenum targetType)
  * \param values  the new values, of datatype 'type'
  */
 static void
-set_program_uniform(GLcontext *ctx, struct gl_program *program,
+set_program_uniform(struct gl_context *ctx, struct gl_program *program,
                     GLint index, GLint offset,
                     GLenum type, GLsizei count, GLint elems,
                     const void *values)
@@ -736,11 +1015,11 @@ set_program_uniform(GLcontext *ctx, struct gl_program *program,
 /**
  * Called via glUniform*() functions.
  */
-static void
-_mesa_uniform(GLcontext *ctx, GLint location, GLsizei count,
+void
+_mesa_uniform(struct gl_context *ctx, struct gl_shader_program *shProg,
+             GLint location, GLsizei count,
               const GLvoid *values, GLenum type)
 {
-   struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
    struct gl_uniform *uniform;
    GLint elems, offset;
 
@@ -824,6 +1103,15 @@ _mesa_uniform(GLcontext *ctx, GLint location, GLsizei count,
       }
    }
 
+   if (shProg->GeometryProgram) {
+      /* convert uniform location to program parameter index */
+      GLint index = uniform->GeomPos;
+      if (index >= 0) {
+         set_program_uniform(ctx, &shProg->GeometryProgram->Base,
+                             index, offset, type, count, elems, values);
+      }
+   }
+
    uniform->Initialized = GL_TRUE;
 }
 
@@ -832,7 +1120,7 @@ _mesa_uniform(GLcontext *ctx, GLint location, GLsizei count,
  * Set a matrix-valued program parameter.
  */
 static void
-set_program_uniform_matrix(GLcontext *ctx, struct gl_program *program,
+set_program_uniform_matrix(struct gl_context *ctx, struct gl_program *program,
                            GLuint index, GLuint offset,
                            GLuint count, GLuint rows, GLuint cols,
                            GLboolean transpose, const GLfloat *values)
@@ -899,12 +1187,12 @@ set_program_uniform_matrix(GLcontext *ctx, struct gl_program *program,
  * Called by glUniformMatrix*() functions.
  * Note: cols=2, rows=4  ==>  array[2] of vec4
  */
-static void
-_mesa_uniform_matrix(GLcontext *ctx, GLint cols, GLint rows,
+void
+_mesa_uniform_matrix(struct gl_context *ctx, struct gl_shader_program *shProg,
+                    GLint cols, GLint rows,
                      GLint location, GLsizei count,
                      GLboolean transpose, const GLfloat *values)
 {
-   struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
    struct gl_uniform *uniform;
    GLint offset;
 
@@ -957,6 +1245,16 @@ _mesa_uniform_matrix(GLcontext *ctx, GLint cols, GLint rows,
       }
    }
 
+   if (shProg->GeometryProgram) {
+      /* convert uniform location to program parameter index */
+      GLint index = uniform->GeomPos;
+      if (index >= 0) {
+         set_program_uniform_matrix(ctx, &shProg->GeometryProgram->Base,
+                                    index, offset,
+                                    count, rows, cols, transpose, values);
+      }
+   }
+
    uniform->Initialized = GL_TRUE;
 }
 
@@ -965,7 +1263,7 @@ void GLAPIENTRY
 _mesa_Uniform1fARB(GLint location, GLfloat v0)
 {
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_uniform(ctx, location, 1, &v0, GL_FLOAT);
+   _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, &v0, GL_FLOAT);
 }
 
 void GLAPIENTRY
@@ -975,7 +1273,7 @@ _mesa_Uniform2fARB(GLint location, GLfloat v0, GLfloat v1)
    GLfloat v[2];
    v[0] = v0;
    v[1] = v1;
-   _mesa_uniform(ctx, location, 1, v, GL_FLOAT_VEC2);
+   _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_FLOAT_VEC2);
 }
 
 void GLAPIENTRY
@@ -986,7 +1284,7 @@ _mesa_Uniform3fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
    v[0] = v0;
    v[1] = v1;
    v[2] = v2;
-   _mesa_uniform(ctx, location, 1, v, GL_FLOAT_VEC3);
+   _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_FLOAT_VEC3);
 }
 
 void GLAPIENTRY
@@ -999,14 +1297,14 @@ _mesa_Uniform4fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2,
    v[1] = v1;
    v[2] = v2;
    v[3] = v3;
-   _mesa_uniform(ctx, location, 1, v, GL_FLOAT_VEC4);
+   _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_FLOAT_VEC4);
 }
 
 void GLAPIENTRY
 _mesa_Uniform1iARB(GLint location, GLint v0)
 {
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_uniform(ctx, location, 1, &v0, GL_INT);
+   _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, &v0, GL_INT);
 }
 
 void GLAPIENTRY
@@ -1016,7 +1314,7 @@ _mesa_Uniform2iARB(GLint location, GLint v0, GLint v1)
    GLint v[2];
    v[0] = v0;
    v[1] = v1;
-   _mesa_uniform(ctx, location, 1, v, GL_INT_VEC2);
+   _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_INT_VEC2);
 }
 
 void GLAPIENTRY
@@ -1027,7 +1325,7 @@ _mesa_Uniform3iARB(GLint location, GLint v0, GLint v1, GLint v2)
    v[0] = v0;
    v[1] = v1;
    v[2] = v2;
-   _mesa_uniform(ctx, location, 1, v, GL_INT_VEC3);
+   _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_INT_VEC3);
 }
 
 void GLAPIENTRY
@@ -1039,63 +1337,63 @@ _mesa_Uniform4iARB(GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
    v[1] = v1;
    v[2] = v2;
    v[3] = v3;
-   _mesa_uniform(ctx, location, 1, v, GL_INT_VEC4);
+   _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_INT_VEC4);
 }
 
 void GLAPIENTRY
 _mesa_Uniform1fvARB(GLint location, GLsizei count, const GLfloat * value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_uniform(ctx, location, count, value, GL_FLOAT);
+   _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_FLOAT);
 }
 
 void GLAPIENTRY
 _mesa_Uniform2fvARB(GLint location, GLsizei count, const GLfloat * value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_uniform(ctx, location, count, value, GL_FLOAT_VEC2);
+   _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_FLOAT_VEC2);
 }
 
 void GLAPIENTRY
 _mesa_Uniform3fvARB(GLint location, GLsizei count, const GLfloat * value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_uniform(ctx, location, count, value, GL_FLOAT_VEC3);
+   _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_FLOAT_VEC3);
 }
 
 void GLAPIENTRY
 _mesa_Uniform4fvARB(GLint location, GLsizei count, const GLfloat * value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_uniform(ctx, location, count, value, GL_FLOAT_VEC4);
+   _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_FLOAT_VEC4);
 }
 
 void GLAPIENTRY
 _mesa_Uniform1ivARB(GLint location, GLsizei count, const GLint * value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_uniform(ctx, location, count, value, GL_INT);
+   _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_INT);
 }
 
 void GLAPIENTRY
 _mesa_Uniform2ivARB(GLint location, GLsizei count, const GLint * value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_uniform(ctx, location, count, value, GL_INT_VEC2);
+   _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_INT_VEC2);
 }
 
 void GLAPIENTRY
 _mesa_Uniform3ivARB(GLint location, GLsizei count, const GLint * value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_uniform(ctx, location, count, value, GL_INT_VEC3);
+   _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_INT_VEC3);
 }
 
 void GLAPIENTRY
 _mesa_Uniform4ivARB(GLint location, GLsizei count, const GLint * value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_uniform(ctx, location, count, value, GL_INT_VEC4);
+   _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_INT_VEC4);
 }
 
 
@@ -1104,7 +1402,7 @@ void GLAPIENTRY
 _mesa_Uniform1ui(GLint location, GLuint v0)
 {
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_uniform(ctx, location, 1, &v0, GL_UNSIGNED_INT);
+   _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, &v0, GL_UNSIGNED_INT);
 }
 
 void GLAPIENTRY
@@ -1114,7 +1412,7 @@ _mesa_Uniform2ui(GLint location, GLuint v0, GLuint v1)
    GLuint v[2];
    v[0] = v0;
    v[1] = v1;
-   _mesa_uniform(ctx, location, 1, v, GL_UNSIGNED_INT_VEC2);
+   _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_UNSIGNED_INT_VEC2);
 }
 
 void GLAPIENTRY
@@ -1125,7 +1423,7 @@ _mesa_Uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)
    v[0] = v0;
    v[1] = v1;
    v[2] = v2;
-   _mesa_uniform(ctx, location, 1, v, GL_UNSIGNED_INT_VEC3);
+   _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_UNSIGNED_INT_VEC3);
 }
 
 void GLAPIENTRY
@@ -1137,35 +1435,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, location, 1, v, GL_UNSIGNED_INT_VEC4);
+   _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_UNSIGNED_INT_VEC4);
 }
 
 void GLAPIENTRY
 _mesa_Uniform1uiv(GLint location, GLsizei count, const GLuint *value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_uniform(ctx, location, count, value, GL_UNSIGNED_INT);
+   _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_UNSIGNED_INT);
 }
 
 void GLAPIENTRY
 _mesa_Uniform2uiv(GLint location, GLsizei count, const GLuint *value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_uniform(ctx, location, count, value, GL_UNSIGNED_INT_VEC2);
+   _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_UNSIGNED_INT_VEC2);
 }
 
 void GLAPIENTRY
 _mesa_Uniform3uiv(GLint location, GLsizei count, const GLuint *value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_uniform(ctx, location, count, value, GL_UNSIGNED_INT_VEC3);
+   _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_UNSIGNED_INT_VEC3);
 }
 
 void GLAPIENTRY
 _mesa_Uniform4uiv(GLint location, GLsizei count, const GLuint *value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_uniform(ctx, location, count, value, GL_UNSIGNED_INT_VEC4);
+   _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_UNSIGNED_INT_VEC4);
 }
 
 
@@ -1175,7 +1473,8 @@ _mesa_UniformMatrix2fvARB(GLint location, GLsizei count, GLboolean transpose,
                           const GLfloat * value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_uniform_matrix(ctx, 2, 2, location, count, transpose, value);
+   _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
+                       2, 2, location, count, transpose, value);
 }
 
 void GLAPIENTRY
@@ -1183,7 +1482,8 @@ _mesa_UniformMatrix3fvARB(GLint location, GLsizei count, GLboolean transpose,
                           const GLfloat * value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_uniform_matrix(ctx, 3, 3, location, count, transpose, value);
+   _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
+                       3, 3, location, count, transpose, value);
 }
 
 void GLAPIENTRY
@@ -1191,7 +1491,8 @@ _mesa_UniformMatrix4fvARB(GLint location, GLsizei count, GLboolean transpose,
                           const GLfloat * value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_uniform_matrix(ctx, 4, 4, location, count, transpose, value);
+   _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
+                       4, 4, location, count, transpose, value);
 }
 
 
@@ -1203,7 +1504,8 @@ _mesa_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose,
                          const GLfloat *value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_uniform_matrix(ctx, 2, 3, location, count, transpose, value);
+   _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
+                       2, 3, location, count, transpose, value);
 }
 
 void GLAPIENTRY
@@ -1211,7 +1513,8 @@ _mesa_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose,
                          const GLfloat *value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_uniform_matrix(ctx, 3, 2, location, count, transpose, value);
+   _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
+                       3, 2, location, count, transpose, value);
 }
 
 void GLAPIENTRY
@@ -1219,7 +1522,8 @@ _mesa_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose,
                          const GLfloat *value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_uniform_matrix(ctx, 2, 4, location, count, transpose, value);
+   _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
+                       2, 4, location, count, transpose, value);
 }
 
 void GLAPIENTRY
@@ -1227,7 +1531,8 @@ _mesa_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose,
                          const GLfloat *value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_uniform_matrix(ctx, 4, 2, location, count, transpose, value);
+   _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
+                       4, 2, location, count, transpose, value);
 }
 
 void GLAPIENTRY
@@ -1235,7 +1540,8 @@ _mesa_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose,
                          const GLfloat *value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_uniform_matrix(ctx, 3, 4, location, count, transpose, value);
+   _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
+                       3, 4, location, count, transpose, value);
 }
 
 void GLAPIENTRY
@@ -1243,7 +1549,8 @@ _mesa_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose,
                          const GLfloat *value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_uniform_matrix(ctx, 4, 3, location, count, transpose, value);
+   _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
+                       4, 3, location, count, transpose, value);
 }
 
 
@@ -1263,11 +1570,29 @@ _mesa_GetUniformivARB(GLhandleARB program, GLint location, GLint *params)
 }
 
 
+/* GL3 */
+void GLAPIENTRY
+_mesa_GetUniformuiv(GLhandleARB program, GLint location, GLuint *params)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_get_uniformuiv(ctx, program, location, params);
+}
+
+
+
 GLint GLAPIENTRY
 _mesa_GetUniformLocationARB(GLhandleARB programObj, const GLcharARB *name)
 {
+   struct gl_shader_program *shProg;
+
    GET_CURRENT_CONTEXT(ctx);
-   return _mesa_get_uniform_location(ctx, programObj, name);
+
+   shProg = _mesa_lookup_shader_program_err(ctx, programObj,
+                                           "glGetUniformLocation");
+   if (!shProg)
+      return -1;
+
+   return _mesa_get_uniform_location(ctx, shProg, name);
 }
 
 
@@ -1288,6 +1613,7 @@ _mesa_GetActiveUniformARB(GLhandleARB program, GLuint index,
 void
 _mesa_init_shader_uniform_dispatch(struct _glapi_table *exec)
 {
+#if FEATURE_GL
    SET_Uniform1fARB(exec, _mesa_Uniform1fARB);
    SET_Uniform2fARB(exec, _mesa_Uniform2fARB);
    SET_Uniform3fARB(exec, _mesa_Uniform3fARB);
@@ -1323,12 +1649,16 @@ _mesa_init_shader_uniform_dispatch(struct _glapi_table *exec)
 
    /* OpenGL 3.0 */
    /* XXX finish dispatch */
-   (void) _mesa_Uniform1ui;
-   (void) _mesa_Uniform2ui;
-   (void) _mesa_Uniform3ui;
-   (void) _mesa_Uniform4ui;
-   (void) _mesa_Uniform1uiv;
-   (void) _mesa_Uniform2uiv;
-   (void) _mesa_Uniform3uiv;
-   (void) _mesa_Uniform4uiv;
+   SET_Uniform1uiEXT(exec, _mesa_Uniform1ui);
+   SET_Uniform2uiEXT(exec, _mesa_Uniform2ui);
+   SET_Uniform3uiEXT(exec, _mesa_Uniform3ui);
+   SET_Uniform4uiEXT(exec, _mesa_Uniform4ui);
+   SET_Uniform1uivEXT(exec, _mesa_Uniform1uiv);
+   SET_Uniform2uivEXT(exec, _mesa_Uniform2uiv);
+   SET_Uniform3uivEXT(exec, _mesa_Uniform3uiv);
+   SET_Uniform4uivEXT(exec, _mesa_Uniform4uiv);
+   SET_GetUniformuivEXT(exec, _mesa_GetUniformuiv);
+
+
+#endif /* FEATURE_GL */
 }