mesa: refactor shader api / object code
authorBrian Paul <brianp@vmware.com>
Fri, 11 Jun 2010 02:23:03 +0000 (20:23 -0600)
committerBrian Paul <brianp@vmware.com>
Fri, 11 Jun 2010 02:32:57 +0000 (20:32 -0600)
Remove the unneeded ctx->Driver hooks for shader-related functions.
Move state and API-related things into main/.

22 files changed:
src/mesa/SConscript
src/mesa/drivers/common/driverfuncs.c
src/mesa/drivers/common/meta.c
src/mesa/main/api_exec.c
src/mesa/main/context.c
src/mesa/main/dd.h
src/mesa/main/shaderapi.c [new file with mode: 0644]
src/mesa/main/shaderapi.h [new file with mode: 0644]
src/mesa/main/shaderobj.c [new file with mode: 0644]
src/mesa/main/shaderobj.h [new file with mode: 0644]
src/mesa/main/shaders.c [deleted file]
src/mesa/main/shaders.h [deleted file]
src/mesa/main/shared.c
src/mesa/main/transformfeedback.c
src/mesa/shader/shader_api.c [deleted file]
src/mesa/shader/shader_api.h [deleted file]
src/mesa/shader/slang/slang_link.c
src/mesa/shader/uniforms.c
src/mesa/shader/uniforms.h
src/mesa/sources.mak
src/mesa/state_tracker/st_cb_program.c
src/mesa/state_tracker/st_context.c

index 34b7f4e8b7cf78469282e16b36aac30ed28f1560..1f831956e1b5e4ce16261a69667d5e9ddeecd2e2 100644 (file)
@@ -83,7 +83,8 @@ if env['platform'] != 'winddk':
                'main/remap.c',
                'main/renderbuffer.c',
                'main/scissor.c',
-               'main/shaders.c',
+               'main/shaderapi.c',
+               'main/shaderobj.c',
                'main/shared.c',
                'main/state.c',
                'main/stencil.c',
@@ -216,7 +217,6 @@ if env['platform'] != 'winddk':
                'shader/prog_uniform.c',
                'shader/programopt.c',
                'shader/symbol_table.c',
-               'shader/shader_api.c',
                'shader/uniforms.c',
        ]
        
index ca5eb5c7552e24ed5fb8529fda0744bf6ad8844b..6677bc4252042ef04e15c6104a08b0b5d95ea2f4 100644 (file)
@@ -31,6 +31,7 @@
 #include "main/mipmap.h"
 #include "main/queryobj.h"
 #include "main/renderbuffer.h"
+#include "main/shaderobj.h"
 #include "main/texcompress.h"
 #include "main/texformat.h"
 #include "main/texgetimage.h"
@@ -52,7 +53,6 @@
 #endif
 
 #include "shader/program.h"
-#include "shader/shader_api.h"
 #include "tnl/tnl.h"
 #include "swrast/swrast.h"
 
@@ -208,6 +208,8 @@ _mesa_init_driver_functions(struct dd_function_table *driver)
    driver->DeleteArrayObject = _mesa_delete_array_object;
    driver->BindArrayObject = NULL;
 
+   _mesa_init_shader_object_functions(driver);
+
 #if FEATURE_EXT_transform_feedback
    _mesa_init_transform_feedback_functions(driver);
 #endif
@@ -231,10 +233,6 @@ _mesa_init_driver_functions(struct dd_function_table *driver)
    driver->EndList = NULL;
    driver->BeginCallList = NULL;
    driver->EndCallList = NULL;
-
-
-   /* XXX temporary here */
-   _mesa_init_glsl_driver_functions(driver);
 }
 
 
index fc286851663c6cb6419b08b916bccd78986571be..f808e15b33f48e5448a50ee8ee4383915fed4823 100644 (file)
@@ -51,7 +51,7 @@
 #include "main/polygon.h"
 #include "main/readpix.h"
 #include "main/scissor.h"
-#include "main/shaders.h"
+#include "main/shaderapi.h"
 #include "main/state.h"
 #include "main/stencil.h"
 #include "main/texobj.h"
index 06df97dfede6c082db985c13268973bad924df00..fd0c6c96a37a40a43451a65d321e6a4b6fb95274 100644 (file)
@@ -98,7 +98,8 @@
 #include "shader/nvprogram.h"
 #endif
 #if FEATURE_ARB_shader_objects
-#include "shaders.h"
+#include "shaderapi.h"
+#include "shader/uniforms.h"
 #endif
 #if FEATURE_ARB_sync
 #include "syncobj.h"
@@ -347,6 +348,7 @@ _mesa_create_exec_table(void)
 
 #if FEATURE_ARB_shader_objects
    _mesa_init_shader_dispatch(exec);
+   _mesa_init_shader_uniform_dispatch(exec);
 #endif
 
    /* 2. GL_EXT_blend_color */
index e140a21b35486a71f2f1b664d9395c8d95505ebf..5b79e68769042b24fe8033e71a20ff7a105d3da0 100644 (file)
 #include "remap.h"
 #include "scissor.h"
 #include "shared.h"
+#include "shaderobj.h"
 #include "simple_list.h"
 #include "state.h"
 #include "stencil.h"
 #include "vtxfmt.h"
 #include "shader/program.h"
 #include "shader/prog_print.h"
-#include "shader/shader_api.h"
 #if _HAVE_FULL_GL
 #include "math/m_matrix.h"
 #endif
index 53e44533cb3ddbdb0472c1d255cd91649d74e69a..825073ca886cd0c068f8344285ee9d7416e8a177 100644 (file)
@@ -828,54 +828,12 @@ struct dd_function_table {
     * \name GLSL-related functions (ARB extensions and OpenGL 2.x)
     */
    /*@{*/
-   void (*AttachShader)(GLcontext *ctx, GLuint program, GLuint shader);
-   void (*BindAttribLocation)(GLcontext *ctx, GLuint program, GLuint index,
-                              const GLcharARB *name);
-   void (*CompileShader)(GLcontext *ctx, GLuint shader);
-   GLuint (*CreateShader)(GLcontext *ctx, GLenum type);
-   GLuint (*CreateProgram)(GLcontext *ctx);
-   void (*DeleteProgram2)(GLcontext *ctx, GLuint program);
-   void (*DeleteShader)(GLcontext *ctx, GLuint shader);
-   void (*DetachShader)(GLcontext *ctx, GLuint program, GLuint shader);
-   void (*GetActiveAttrib)(GLcontext *ctx, GLuint program, GLuint index,
-                           GLsizei maxLength, GLsizei * length, GLint * size,
-                           GLenum * type, GLcharARB * name);
-   void (*GetActiveUniform)(GLcontext *ctx, GLuint program, GLuint index,
-                            GLsizei maxLength, GLsizei *length, GLint *size,
-                            GLenum *type, GLcharARB *name);
-   void (*GetAttachedShaders)(GLcontext *ctx, GLuint program, GLsizei maxCount,
-                              GLsizei *count, GLuint *obj);
-   GLint (*GetAttribLocation)(GLcontext *ctx, GLuint program,
-                              const GLcharARB *name);
-   GLuint (*GetHandle)(GLcontext *ctx, GLenum pname);
-   void (*GetProgramiv)(GLcontext *ctx, GLuint program,
-                        GLenum pname, GLint *params);
-   void (*GetProgramInfoLog)(GLcontext *ctx, GLuint program, GLsizei bufSize,
-                             GLsizei *length, GLchar *infoLog);
-   void (*GetShaderiv)(GLcontext *ctx, GLuint shader,
-                       GLenum pname, GLint *params);
-   void (*GetShaderInfoLog)(GLcontext *ctx, GLuint shader, GLsizei bufSize,
-                            GLsizei *length, GLchar *infoLog);
-   void (*GetShaderSource)(GLcontext *ctx, GLuint shader, GLsizei maxLength,
-                           GLsizei *length, GLcharARB *sourceOut);
-   void (*GetUniformfv)(GLcontext *ctx, GLuint program, GLint location,
-                        GLfloat *params);
-   void (*GetUniformiv)(GLcontext *ctx, GLuint program, GLint location,
-                        GLint *params);
-   GLint (*GetUniformLocation)(GLcontext *ctx, GLuint program,
-                               const GLcharARB *name);
-   GLboolean (*IsProgram)(GLcontext *ctx, GLuint name);
-   GLboolean (*IsShader)(GLcontext *ctx, GLuint name);
-   void (*LinkProgram)(GLcontext *ctx, GLuint program);
-   void (*ShaderSource)(GLcontext *ctx, GLuint shader, const GLchar *source);
-   void (*Uniform)(GLcontext *ctx, GLint location, GLsizei count,
-                   const GLvoid *values, GLenum type);
-   void (*UniformMatrix)(GLcontext *ctx, GLint cols, GLint rows,
-                         GLint location, GLsizei count,
-                         GLboolean transpose, const GLfloat *values);
-   void (*UseProgram)(GLcontext *ctx, GLuint program);
-   void (*ValidateProgram)(GLcontext *ctx, GLuint program);
-   /* XXX many more to come */
+   struct gl_shader *(*NewShader)(GLcontext *ctx, GLuint name, GLenum type);
+   void (*DeleteShader)(GLcontext *ctx, struct gl_shader *shader);
+   struct gl_shader_program *(*NewShaderProgram)(GLcontext *ctx, GLuint name);
+   void (*DeleteShaderProgram)(GLcontext *ctx,
+                               struct gl_shader_program *shProg);
+   void (*UseProgram)(GLcontext *ctx, struct gl_shader_program *shProg);
    /*@}*/
 
 
diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c
new file mode 100644 (file)
index 0000000..88edb54
--- /dev/null
@@ -0,0 +1,1552 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2004-2008  Brian Paul   All Rights Reserved.
+ * Copyright (C) 2009-2010  VMware, Inc.  All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file shaderapi.c
+ * \author Brian Paul
+ *
+ * Implementation of GLSL-related API functions.
+ * The glUniform* functions are in uniforms.c
+ *
+ *
+ * XXX things to do:
+ * 1. Check that the right error code is generated for all _mesa_error() calls.
+ * 2. Insert FLUSH_VERTICES calls in various places
+ */
+
+
+#include "main/glheader.h"
+#include "main/context.h"
+#include "main/dispatch.h"
+#include "main/hash.h"
+#include "main/shaderapi.h"
+#include "main/shaderobj.h"
+#include "shader/program.h"
+#include "shader/prog_parameter.h"
+#include "shader/prog_uniform.h"
+#include "shader/slang/slang_compile.h"
+#include "shader/slang/slang_link.h"
+
+
+/** Define this to enable shader substitution (see below) */
+#define SHADER_SUBST 0
+
+
+/**
+ * Return mask of GLSL_x flags by examining the MESA_GLSL env var.
+ */
+static GLbitfield
+get_shader_flags(void)
+{
+   GLbitfield flags = 0x0;
+   const char *env = _mesa_getenv("MESA_GLSL");
+
+   if (env) {
+      if (strstr(env, "dump"))
+         flags |= GLSL_DUMP;
+      if (strstr(env, "log"))
+         flags |= GLSL_LOG;
+      if (strstr(env, "nopvert"))
+         flags |= GLSL_NOP_VERT;
+      if (strstr(env, "nopfrag"))
+         flags |= GLSL_NOP_FRAG;
+      if (strstr(env, "nopt"))
+         flags |= GLSL_NO_OPT;
+      else if (strstr(env, "opt"))
+         flags |= GLSL_OPT;
+      if (strstr(env, "uniform"))
+         flags |= GLSL_UNIFORMS;
+      if (strstr(env, "useprog"))
+         flags |= GLSL_USE_PROG;
+   }
+
+   return flags;
+}
+
+
+/**
+ * Initialize context's shader state.
+ */
+void
+_mesa_init_shader_state(GLcontext *ctx)
+{
+   /* Device drivers may override these to control what kind of instructions
+    * are generated by the GLSL compiler.
+    */
+   ctx->Shader.EmitHighLevelInstructions = GL_TRUE;
+   ctx->Shader.EmitContReturn = GL_TRUE;
+   ctx->Shader.EmitCondCodes = GL_FALSE;
+   ctx->Shader.EmitComments = GL_FALSE;
+   ctx->Shader.Flags = get_shader_flags();
+
+   /* Default pragma settings */
+   ctx->Shader.DefaultPragmas.IgnoreOptimize = GL_FALSE;
+   ctx->Shader.DefaultPragmas.IgnoreDebug = GL_FALSE;
+   ctx->Shader.DefaultPragmas.Optimize = GL_TRUE;
+   ctx->Shader.DefaultPragmas.Debug = GL_FALSE;
+}
+
+
+/**
+ * Free the per-context shader-related state.
+ */
+void
+_mesa_free_shader_state(GLcontext *ctx)
+{
+   _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentProgram, NULL);
+}
+
+
+/**
+ * Return the size of the given GLSL datatype, in floats (components).
+ */
+GLint
+_mesa_sizeof_glsl_type(GLenum type)
+{
+   switch (type) {
+   case GL_FLOAT:
+   case GL_INT:
+   case GL_BOOL:
+   case GL_SAMPLER_1D:
+   case GL_SAMPLER_2D:
+   case GL_SAMPLER_3D:
+   case GL_SAMPLER_CUBE:
+   case GL_SAMPLER_1D_SHADOW:
+   case GL_SAMPLER_2D_SHADOW:
+   case GL_SAMPLER_2D_RECT_ARB:
+   case GL_SAMPLER_2D_RECT_SHADOW_ARB:
+   case GL_SAMPLER_1D_ARRAY_EXT:
+   case GL_SAMPLER_2D_ARRAY_EXT:
+   case GL_SAMPLER_1D_ARRAY_SHADOW_EXT:
+   case GL_SAMPLER_2D_ARRAY_SHADOW_EXT:
+   case GL_SAMPLER_CUBE_SHADOW_EXT:
+      return 1;
+   case GL_FLOAT_VEC2:
+   case GL_INT_VEC2:
+   case GL_UNSIGNED_INT_VEC2:
+   case GL_BOOL_VEC2:
+      return 2;
+   case GL_FLOAT_VEC3:
+   case GL_INT_VEC3:
+   case GL_UNSIGNED_INT_VEC3:
+   case GL_BOOL_VEC3:
+      return 3;
+   case GL_FLOAT_VEC4:
+   case GL_INT_VEC4:
+   case GL_UNSIGNED_INT_VEC4:
+   case GL_BOOL_VEC4:
+      return 4;
+   case GL_FLOAT_MAT2:
+   case GL_FLOAT_MAT2x3:
+   case GL_FLOAT_MAT2x4:
+      return 8; /* two float[4] vectors */
+   case GL_FLOAT_MAT3:
+   case GL_FLOAT_MAT3x2:
+   case GL_FLOAT_MAT3x4:
+      return 12; /* three float[4] vectors */
+   case GL_FLOAT_MAT4:
+   case GL_FLOAT_MAT4x2:
+   case GL_FLOAT_MAT4x3:
+      return 16;  /* four float[4] vectors */
+   default:
+      _mesa_problem(NULL, "Invalid type in _mesa_sizeof_glsl_type()");
+      return 1;
+   }
+}
+
+
+/**
+ * Copy string from <src> to <dst>, up to maxLength characters, returning
+ * length of <dst> in <length>.
+ * \param src  the strings source
+ * \param maxLength  max chars to copy
+ * \param length  returns number of chars copied
+ * \param dst  the string destination
+ */
+void
+_mesa_copy_string(GLchar *dst, GLsizei maxLength,
+                  GLsizei *length, const GLchar *src)
+{
+   GLsizei len;
+   for (len = 0; len < maxLength - 1 && src && src[len]; len++)
+      dst[len] = src[len];
+   if (maxLength > 0)
+      dst[len] = 0;
+   if (length)
+      *length = len;
+}
+
+
+
+/**
+ * Find the length of the longest transform feedback varying name
+ * which was specified with glTransformFeedbackVaryings().
+ */
+static GLint
+longest_feedback_varying_name(const struct gl_shader_program *shProg)
+{
+   GLuint i;
+   GLint max = 0;
+   for (i = 0; i < shProg->TransformFeedback.NumVarying; i++) {
+      GLint len = strlen(shProg->TransformFeedback.VaryingNames[i]);
+      if (len > max)
+         max = len;
+   }
+   return max;
+}
+
+
+
+static GLboolean
+is_program(GLcontext *ctx, GLuint name)
+{
+   struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, name);
+   return shProg ? GL_TRUE : GL_FALSE;
+}
+
+
+static GLboolean
+is_shader(GLcontext *ctx, GLuint name)
+{
+   struct gl_shader *shader = _mesa_lookup_shader(ctx, name);
+   return shader ? GL_TRUE : GL_FALSE;
+}
+
+
+/**
+ * Attach shader to a shader program.
+ */
+static void
+attach_shader(GLcontext *ctx, GLuint program, GLuint shader)
+{
+   struct gl_shader_program *shProg;
+   struct gl_shader *sh;
+   GLuint i, n;
+
+   shProg = _mesa_lookup_shader_program_err(ctx, program, "glAttachShader");
+   if (!shProg)
+      return;
+
+   sh = _mesa_lookup_shader_err(ctx, shader, "glAttachShader");
+   if (!sh) {
+      return;
+   }
+
+   n = shProg->NumShaders;
+   for (i = 0; i < n; i++) {
+      if (shProg->Shaders[i] == sh) {
+         /* The shader is already attched to this program.  The
+          * GL_ARB_shader_objects spec says:
+          *
+          *     "The error INVALID_OPERATION is generated by AttachObjectARB
+          *     if <obj> is already attached to <containerObj>."
+          */
+         _mesa_error(ctx, GL_INVALID_OPERATION, "glAttachShader");
+         return;
+      }
+   }
+
+   /* grow list */
+   shProg->Shaders = (struct gl_shader **)
+      _mesa_realloc(shProg->Shaders,
+                    n * sizeof(struct gl_shader *),
+                    (n + 1) * sizeof(struct gl_shader *));
+   if (!shProg->Shaders) {
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAttachShader");
+      return;
+   }
+
+   /* append */
+   shProg->Shaders[n] = NULL; /* since realloc() didn't zero the new space */
+   _mesa_reference_shader(ctx, &shProg->Shaders[n], sh);
+   shProg->NumShaders++;
+}
+
+
+static GLint
+get_attrib_location(GLcontext *ctx, GLuint program, const GLchar *name)
+{
+   struct gl_shader_program *shProg
+      = _mesa_lookup_shader_program_err(ctx, program, "glGetAttribLocation");
+
+   if (!shProg) {
+      return -1;
+   }
+
+   if (!shProg->LinkStatus) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glGetAttribLocation(program not linked)");
+      return -1;
+   }
+
+   if (!name)
+      return -1;
+
+   if (shProg->VertexProgram) {
+      const struct gl_program_parameter_list *attribs =
+         shProg->VertexProgram->Base.Attributes;
+      if (attribs) {
+         GLint i = _mesa_lookup_parameter_index(attribs, -1, name);
+         if (i >= 0) {
+            return attribs->Parameters[i].StateIndexes[0];
+         }
+      }
+   }
+   return -1;
+}
+
+
+static void
+bind_attrib_location(GLcontext *ctx, GLuint program, GLuint index,
+                     const GLchar *name)
+{
+   struct gl_shader_program *shProg;
+   const GLint size = -1; /* unknown size */
+   GLint i, oldIndex;
+   GLenum datatype = GL_FLOAT_VEC4;
+
+   shProg = _mesa_lookup_shader_program_err(ctx, program,
+                                            "glBindAttribLocation");
+   if (!shProg) {
+      return;
+   }
+
+   if (!name)
+      return;
+
+   if (strncmp(name, "gl_", 3) == 0) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glBindAttribLocation(illegal name)");
+      return;
+   }
+
+   if (index >= ctx->Const.VertexProgram.MaxAttribs) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glBindAttribLocation(index)");
+      return;
+   }
+
+   if (shProg->LinkStatus) {
+      /* get current index/location for the attribute */
+      oldIndex = get_attrib_location(ctx, program, name);
+   }
+   else {
+      oldIndex = -1;
+   }
+
+   /* this will replace the current value if it's already in the list */
+   i = _mesa_add_attribute(shProg->Attributes, name, size, datatype, index);
+   if (i < 0) {
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindAttribLocation");
+      return;
+   }
+
+   /*
+    * Note that this attribute binding won't go into effect until
+    * glLinkProgram is called again.
+    */
+}
+
+
+static GLuint
+create_shader(GLcontext *ctx, GLenum type)
+{
+   struct gl_shader *sh;
+   GLuint name;
+
+   name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);
+
+   switch (type) {
+   case GL_FRAGMENT_SHADER:
+   case GL_VERTEX_SHADER:
+      sh = ctx->Driver.NewShader(ctx, name, type);
+      break;
+   default:
+      _mesa_error(ctx, GL_INVALID_ENUM, "CreateShader(type)");
+      return 0;
+   }
+
+   _mesa_HashInsert(ctx->Shared->ShaderObjects, name, sh);
+
+   return name;
+}
+
+
+static GLuint 
+create_shader_program(GLcontext *ctx)
+{
+   GLuint name;
+   struct gl_shader_program *shProg;
+
+   name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);
+
+   shProg = ctx->Driver.NewShaderProgram(ctx, name);
+
+   _mesa_HashInsert(ctx->Shared->ShaderObjects, name, shProg);
+
+   assert(shProg->RefCount == 1);
+
+   return name;
+}
+
+
+/**
+ * Named w/ "2" to indicate OpenGL 2.x vs GL_ARB_fragment_programs's
+ * DeleteProgramARB.
+ */
+static void
+delete_shader_program(GLcontext *ctx, GLuint name)
+{
+   /*
+    * NOTE: deleting shaders/programs works a bit differently than
+    * texture objects (and buffer objects, etc).  Shader/program
+    * handles/IDs exist in the hash table until the object is really
+    * deleted (refcount==0).  With texture objects, the handle/ID is
+    * removed from the hash table in glDeleteTextures() while the tex
+    * object itself might linger until its refcount goes to zero.
+    */
+   struct gl_shader_program *shProg;
+
+   shProg = _mesa_lookup_shader_program_err(ctx, name, "glDeleteProgram");
+   if (!shProg)
+      return;
+
+   shProg->DeletePending = GL_TRUE;
+
+   /* effectively, decr shProg's refcount */
+   _mesa_reference_shader_program(ctx, &shProg, NULL);
+}
+
+
+static void
+delete_shader(GLcontext *ctx, GLuint shader)
+{
+   struct gl_shader *sh;
+
+   sh = _mesa_lookup_shader_err(ctx, shader, "glDeleteShader");
+   if (!sh)
+      return;
+
+   sh->DeletePending = GL_TRUE;
+
+   /* effectively, decr sh's refcount */
+   _mesa_reference_shader(ctx, &sh, NULL);
+}
+
+
+static void
+detach_shader(GLcontext *ctx, GLuint program, GLuint shader)
+{
+   struct gl_shader_program *shProg;
+   GLuint n;
+   GLuint i, j;
+
+   shProg = _mesa_lookup_shader_program_err(ctx, program, "glDetachShader");
+   if (!shProg)
+      return;
+
+   n = shProg->NumShaders;
+
+   for (i = 0; i < n; i++) {
+      if (shProg->Shaders[i]->Name == shader) {
+         /* found it */
+         struct gl_shader **newList;
+
+         /* release */
+         _mesa_reference_shader(ctx, &shProg->Shaders[i], NULL);
+
+         /* alloc new, smaller array */
+         newList = (struct gl_shader **)
+            malloc((n - 1) * sizeof(struct gl_shader *));
+         if (!newList) {
+            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDetachShader");
+            return;
+         }
+         for (j = 0; j < i; j++) {
+            newList[j] = shProg->Shaders[j];
+         }
+         while (++i < n)
+            newList[j++] = shProg->Shaders[i];
+         free(shProg->Shaders);
+
+         shProg->Shaders = newList;
+         shProg->NumShaders = n - 1;
+
+#ifdef DEBUG
+         /* sanity check */
+         {
+            for (j = 0; j < shProg->NumShaders; j++) {
+               assert(shProg->Shaders[j]->Type == GL_VERTEX_SHADER ||
+                      shProg->Shaders[j]->Type == GL_FRAGMENT_SHADER);
+               assert(shProg->Shaders[j]->RefCount > 0);
+            }
+         }
+#endif
+
+         return;
+      }
+   }
+
+   /* not found */
+   {
+      GLenum err;
+      if (is_shader(ctx, shader))
+         err = GL_INVALID_OPERATION;
+      else if (is_program(ctx, shader))
+         err = GL_INVALID_OPERATION;
+      else
+         err = GL_INVALID_VALUE;
+      _mesa_error(ctx, err, "glDetachProgram(shader)");
+      return;
+   }
+}
+
+
+static void
+get_active_attrib(GLcontext *ctx, GLuint program, GLuint index,
+                  GLsizei maxLength, GLsizei *length, GLint *size,
+                  GLenum *type, GLchar *nameOut)
+{
+   const struct gl_program_parameter_list *attribs = NULL;
+   struct gl_shader_program *shProg;
+
+   shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveAttrib");
+   if (!shProg)
+      return;
+
+   if (shProg->VertexProgram)
+      attribs = shProg->VertexProgram->Base.Attributes;
+
+   if (!attribs || index >= attribs->NumParameters) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(index)");
+      return;
+   }
+
+   _mesa_copy_string(nameOut, maxLength, length,
+                     attribs->Parameters[index].Name);
+
+   if (size)
+      *size = attribs->Parameters[index].Size
+         / _mesa_sizeof_glsl_type(attribs->Parameters[index].DataType);
+
+   if (type)
+      *type = attribs->Parameters[index].DataType;
+}
+
+
+/**
+ * Return list of shaders attached to shader program.
+ */
+static void
+get_attached_shaders(GLcontext *ctx, GLuint program, GLsizei maxCount,
+                     GLsizei *count, GLuint *obj)
+{
+   struct gl_shader_program *shProg =
+      _mesa_lookup_shader_program_err(ctx, program, "glGetAttachedShaders");
+   if (shProg) {
+      GLuint i;
+      for (i = 0; i < (GLuint) maxCount && i < shProg->NumShaders; i++) {
+         obj[i] = shProg->Shaders[i]->Name;
+      }
+      if (count)
+         *count = i;
+   }
+}
+
+
+/**
+ * glGetHandleARB() - return ID/name of currently bound shader program.
+ */
+static GLuint
+get_handle(GLcontext *ctx, GLenum pname)
+{
+   if (pname == GL_PROGRAM_OBJECT_ARB) {
+      if (ctx->Shader.CurrentProgram)
+         return ctx->Shader.CurrentProgram->Name;
+      else
+         return 0;
+   }
+   else {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glGetHandleARB");
+      return 0;
+   }
+}
+
+
+/**
+ * glGetProgramiv() - get shader program state.
+ * Note that this is for GLSL shader programs, not ARB vertex/fragment
+ * programs (see glGetProgramivARB).
+ */
+static void
+get_programiv(GLcontext *ctx, GLuint program, GLenum pname, GLint *params)
+{
+   const struct gl_program_parameter_list *attribs;
+   struct gl_shader_program *shProg
+      = _mesa_lookup_shader_program(ctx, program);
+
+   if (!shProg) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramiv(program)");
+      return;
+   }
+
+   if (shProg->VertexProgram)
+      attribs = shProg->VertexProgram->Base.Attributes;
+   else
+      attribs = NULL;
+
+   switch (pname) {
+   case GL_DELETE_STATUS:
+      *params = shProg->DeletePending;
+      break; 
+   case GL_LINK_STATUS:
+      *params = shProg->LinkStatus;
+      break;
+   case GL_VALIDATE_STATUS:
+      *params = shProg->Validated;
+      break;
+   case GL_INFO_LOG_LENGTH:
+      *params = shProg->InfoLog ? strlen(shProg->InfoLog) + 1 : 0;
+      break;
+   case GL_ATTACHED_SHADERS:
+      *params = shProg->NumShaders;
+      break;
+   case GL_ACTIVE_ATTRIBUTES:
+      *params = attribs ? attribs->NumParameters : 0;
+      break;
+   case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
+      *params = _mesa_longest_parameter_name(attribs, PROGRAM_INPUT) + 1;
+      break;
+   case GL_ACTIVE_UNIFORMS:
+      *params = shProg->Uniforms ? shProg->Uniforms->NumUniforms : 0;
+      break;
+   case GL_ACTIVE_UNIFORM_MAX_LENGTH:
+      *params = _mesa_longest_uniform_name(shProg->Uniforms);
+      if (*params > 0)
+         (*params)++;  /* add one for terminating zero */
+      break;
+   case GL_PROGRAM_BINARY_LENGTH_OES:
+      *params = 0;
+      break;
+#if FEATURE_EXT_transform_feedback
+   case GL_TRANSFORM_FEEDBACK_VARYINGS:
+      *params = shProg->TransformFeedback.NumVarying;
+      break;
+   case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
+      *params = longest_feedback_varying_name(shProg) + 1;
+      break;
+   case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
+      *params = shProg->TransformFeedback.BufferMode;
+      break;
+#endif
+   default:
+      _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramiv(pname)");
+      return;
+   }
+}
+
+
+/**
+ * glGetShaderiv() - get GLSL shader state
+ */
+static void
+get_shaderiv(GLcontext *ctx, GLuint name, GLenum pname, GLint *params)
+{
+   struct gl_shader *shader =
+      _mesa_lookup_shader_err(ctx, name, "glGetShaderiv");
+
+   if (!shader) {
+      return;
+   }
+
+   switch (pname) {
+   case GL_SHADER_TYPE:
+      *params = shader->Type;
+      break;
+   case GL_DELETE_STATUS:
+      *params = shader->DeletePending;
+      break;
+   case GL_COMPILE_STATUS:
+      *params = shader->CompileStatus;
+      break;
+   case GL_INFO_LOG_LENGTH:
+      *params = shader->InfoLog ? strlen(shader->InfoLog) + 1 : 0;
+      break;
+   case GL_SHADER_SOURCE_LENGTH:
+      *params = shader->Source ? strlen((char *) shader->Source) + 1 : 0;
+      break;
+   default:
+      _mesa_error(ctx, GL_INVALID_ENUM, "glGetShaderiv(pname)");
+      return;
+   }
+}
+
+
+static void
+get_program_info_log(GLcontext *ctx, GLuint program, GLsizei bufSize,
+                     GLsizei *length, GLchar *infoLog)
+{
+   struct gl_shader_program *shProg
+      = _mesa_lookup_shader_program(ctx, program);
+   if (!shProg) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramInfoLog(program)");
+      return;
+   }
+   _mesa_copy_string(infoLog, bufSize, length, shProg->InfoLog);
+}
+
+
+static void
+get_shader_info_log(GLcontext *ctx, GLuint shader, GLsizei bufSize,
+                    GLsizei *length, GLchar *infoLog)
+{
+   struct gl_shader *sh = _mesa_lookup_shader(ctx, shader);
+   if (!sh) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glGetShaderInfoLog(shader)");
+      return;
+   }
+   _mesa_copy_string(infoLog, bufSize, length, sh->InfoLog);
+}
+
+
+/**
+ * Return shader source code.
+ */
+static void
+get_shader_source(GLcontext *ctx, GLuint shader, GLsizei maxLength,
+                  GLsizei *length, GLchar *sourceOut)
+{
+   struct gl_shader *sh;
+   sh = _mesa_lookup_shader_err(ctx, shader, "glGetShaderSource");
+   if (!sh) {
+      return;
+   }
+   _mesa_copy_string(sourceOut, maxLength, length, sh->Source);
+}
+
+
+/**
+ * Set/replace shader source code.
+ */
+static void
+shader_source(GLcontext *ctx, GLuint shader, const GLchar *source)
+{
+   struct gl_shader *sh;
+
+   sh = _mesa_lookup_shader_err(ctx, shader, "glShaderSource");
+   if (!sh)
+      return;
+
+   /* free old shader source string and install new one */
+   if (sh->Source) {
+      free((void *) sh->Source);
+   }
+   sh->Source = source;
+   sh->CompileStatus = GL_FALSE;
+#ifdef DEBUG
+   sh->SourceChecksum = _mesa_str_checksum(sh->Source);
+#endif
+}
+
+
+/**
+ * Compile a shader.
+ */
+static void
+compile_shader(GLcontext *ctx, GLuint shaderObj)
+{
+   struct gl_shader *sh;
+
+   sh = _mesa_lookup_shader_err(ctx, shaderObj, "glCompileShader");
+   if (!sh)
+      return;
+
+   /* set default pragma state for shader */
+   sh->Pragmas = ctx->Shader.DefaultPragmas;
+
+   /* this call will set the sh->CompileStatus field to indicate if
+    * compilation was successful.
+    */
+   (void) _slang_compile(ctx, sh);
+}
+
+
+/**
+ * Link a program's shaders.
+ */
+static void
+link_program(GLcontext *ctx, GLuint program)
+{
+   struct gl_shader_program *shProg;
+   struct gl_transform_feedback_object *obj =
+      ctx->TransformFeedback.CurrentObject;
+
+   shProg = _mesa_lookup_shader_program_err(ctx, program, "glLinkProgram");
+   if (!shProg)
+      return;
+
+   if (obj->Active && shProg == ctx->Shader.CurrentProgram) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glLinkProgram(transform feedback active");
+      return;
+   }
+
+   FLUSH_VERTICES(ctx, _NEW_PROGRAM);
+
+   _slang_link(ctx, program, shProg);
+
+   /* debug code */
+   if (0) {
+      GLuint i;
+
+      printf("Link %u shaders in program %u: %s\n",
+                   shProg->NumShaders, shProg->Name,
+                   shProg->LinkStatus ? "Success" : "Failed");
+
+      for (i = 0; i < shProg->NumShaders; i++) {
+         printf(" shader %u, type 0x%x\n",
+                      shProg->Shaders[i]->Name,
+                      shProg->Shaders[i]->Type);
+      }
+   }
+}
+
+
+/**
+ * Print basic shader info (for debug).
+ */
+static void
+print_shader_info(const struct gl_shader_program *shProg)
+{
+   GLuint i;
+
+   printf("Mesa: glUseProgram(%u)\n", shProg->Name);
+   for (i = 0; i < shProg->NumShaders; i++) {
+      const char *s;
+      switch (shProg->Shaders[i]->Type) {
+      case GL_VERTEX_SHADER:
+         s = "vertex";
+         break;
+      case GL_FRAGMENT_SHADER:
+         s = "fragment";
+         break;
+      case GL_GEOMETRY_SHADER:
+         s = "geometry";
+         break;
+      default:
+         s = "";
+      }
+      printf("  %s shader %u, checksum %u\n", s, 
+            shProg->Shaders[i]->Name,
+            shProg->Shaders[i]->SourceChecksum);
+   }
+   if (shProg->VertexProgram)
+      printf("  vert prog %u\n", shProg->VertexProgram->Base.Id);
+   if (shProg->FragmentProgram)
+      printf("  frag prog %u\n", shProg->FragmentProgram->Base.Id);
+}
+
+
+/**
+ * Use the named shader program for subsequent rendering.
+ */
+void
+_mesa_use_program(GLcontext *ctx, GLuint program)
+{
+   struct gl_shader_program *shProg;
+   struct gl_transform_feedback_object *obj =
+      ctx->TransformFeedback.CurrentObject;
+
+   if (obj->Active) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glUseProgram(transform feedback active)");
+      return;
+   }
+
+   if (ctx->Shader.CurrentProgram &&
+       ctx->Shader.CurrentProgram->Name == program) {
+      /* no-op */
+      return;
+   }
+
+   if (program) {
+      shProg = _mesa_lookup_shader_program_err(ctx, program, "glUseProgram");
+      if (!shProg) {
+         return;
+      }
+      if (!shProg->LinkStatus) {
+         _mesa_error(ctx, GL_INVALID_OPERATION,
+                     "glUseProgram(program %u not linked)", program);
+         return;
+      }
+
+      /* debug code */
+      if (ctx->Shader.Flags & GLSL_USE_PROG) {
+         print_shader_info(shProg);
+      }
+   }
+   else {
+      shProg = NULL;
+   }
+
+   if (ctx->Shader.CurrentProgram != shProg) {
+      FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
+      _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentProgram, shProg);
+   }
+
+   if (ctx->Driver.UseProgram)
+      ctx->Driver.UseProgram(ctx, shProg);
+}
+
+
+/**
+ * Validate a program's samplers.
+ * Specifically, check that there aren't two samplers of different types
+ * pointing to the same texture unit.
+ * \return GL_TRUE if valid, GL_FALSE if invalid
+ */
+static GLboolean
+validate_samplers(GLcontext *ctx, const struct gl_program *prog, char *errMsg)
+{
+   static const char *targetName[] = {
+      "TEXTURE_2D_ARRAY",
+      "TEXTURE_1D_ARRAY",
+      "TEXTURE_CUBE",
+      "TEXTURE_3D",
+      "TEXTURE_RECT",
+      "TEXTURE_2D",
+      "TEXTURE_1D",
+   };
+   GLint targetUsed[MAX_TEXTURE_IMAGE_UNITS];
+   GLbitfield samplersUsed = prog->SamplersUsed;
+   GLuint i;
+
+   assert(Elements(targetName) == NUM_TEXTURE_TARGETS);
+
+   if (samplersUsed == 0x0)
+      return GL_TRUE;
+
+   for (i = 0; i < Elements(targetUsed); i++)
+      targetUsed[i] = -1;
+
+   /* walk over bits which are set in 'samplers' */
+   while (samplersUsed) {
+      GLuint unit;
+      gl_texture_index target;
+      GLint sampler = _mesa_ffs(samplersUsed) - 1;
+      assert(sampler >= 0);
+      assert(sampler < MAX_TEXTURE_IMAGE_UNITS);
+      unit = prog->SamplerUnits[sampler];
+      target = prog->SamplerTargets[sampler];
+      if (targetUsed[unit] != -1 && targetUsed[unit] != target) {
+         _mesa_snprintf(errMsg, 100,
+                 "Texture unit %d is accessed both as %s and %s",
+                 unit, targetName[targetUsed[unit]], targetName[target]);
+         return GL_FALSE;
+      }
+      targetUsed[unit] = target;
+      samplersUsed ^= (1 << sampler);
+   }
+
+   return GL_TRUE;
+}
+
+
+/**
+ * Do validation of the given shader program.
+ * \param errMsg  returns error message if validation fails.
+ * \return GL_TRUE if valid, GL_FALSE if invalid (and set errMsg)
+ */
+static GLboolean
+validate_shader_program(GLcontext *ctx,
+                        const struct gl_shader_program *shProg,
+                        char *errMsg)
+{
+   const struct gl_vertex_program *vp = shProg->VertexProgram;
+   const struct gl_fragment_program *fp = shProg->FragmentProgram;
+
+   if (!shProg->LinkStatus) {
+      return GL_FALSE;
+   }
+
+   /* From the GL spec, a program is invalid if any of these are true:
+
+     any two active samplers in the current program object are of
+     different types, but refer to the same texture image unit,
+
+     any active sampler in the current program object refers to a texture
+     image unit where fixed-function fragment processing accesses a
+     texture target that does not match the sampler type, or 
+
+     the sum of the number of active samplers in the program and the
+     number of texture image units enabled for fixed-function fragment
+     processing exceeds the combined limit on the total number of texture
+     image units allowed.
+   */
+
+
+   /*
+    * Check: any two active samplers in the current program object are of
+    * different types, but refer to the same texture image unit,
+    */
+   if (vp && !validate_samplers(ctx, &vp->Base, errMsg)) {
+      return GL_FALSE;
+   }
+   if (fp && !validate_samplers(ctx, &fp->Base, errMsg)) {
+      return GL_FALSE;
+   }
+
+   return GL_TRUE;
+}
+
+
+/**
+ * Called via glValidateProgram()
+ */
+static void
+validate_program(GLcontext *ctx, GLuint program)
+{
+   struct gl_shader_program *shProg;
+   char errMsg[100];
+
+   shProg = _mesa_lookup_shader_program_err(ctx, program, "glValidateProgram");
+   if (!shProg) {
+      return;
+   }
+
+   shProg->Validated = validate_shader_program(ctx, shProg, errMsg);
+   if (!shProg->Validated) {
+      /* update info log */
+      if (shProg->InfoLog) {
+         free(shProg->InfoLog);
+      }
+      shProg->InfoLog = _mesa_strdup(errMsg);
+   }
+}
+
+
+
+void GLAPIENTRY
+_mesa_AttachObjectARB(GLhandleARB program, GLhandleARB shader)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   attach_shader(ctx, program, shader);
+}
+
+
+void GLAPIENTRY
+_mesa_AttachShader(GLuint program, GLuint shader)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   attach_shader(ctx, program, shader);
+}
+
+
+void GLAPIENTRY
+_mesa_BindAttribLocationARB(GLhandleARB program, GLuint index,
+                            const GLcharARB *name)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   bind_attrib_location(ctx, program, index, name);
+}
+
+
+void GLAPIENTRY
+_mesa_CompileShaderARB(GLhandleARB shaderObj)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   compile_shader(ctx, shaderObj);
+}
+
+
+GLuint GLAPIENTRY
+_mesa_CreateShader(GLenum type)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   return create_shader(ctx, type);
+}
+
+
+GLhandleARB GLAPIENTRY
+_mesa_CreateShaderObjectARB(GLenum type)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   return create_shader(ctx, type);
+}
+
+
+GLuint GLAPIENTRY
+_mesa_CreateProgram(void)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   return create_shader_program(ctx);
+}
+
+
+GLhandleARB GLAPIENTRY
+_mesa_CreateProgramObjectARB(void)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   return create_shader_program(ctx);
+}
+
+
+void GLAPIENTRY
+_mesa_DeleteObjectARB(GLhandleARB obj)
+{
+   if (obj) {
+      GET_CURRENT_CONTEXT(ctx);
+      if (is_program(ctx, obj)) {
+         delete_shader_program(ctx, obj);
+      }
+      else if (is_shader(ctx, obj)) {
+         delete_shader(ctx, obj);
+      }
+      else {
+         /* error? */
+      }
+   }
+}
+
+
+void GLAPIENTRY
+_mesa_DeleteProgram(GLuint name)
+{
+   if (name) {
+      GET_CURRENT_CONTEXT(ctx);
+      delete_shader_program(ctx, name);
+   }
+}
+
+
+void GLAPIENTRY
+_mesa_DeleteShader(GLuint name)
+{
+   if (name) {
+      GET_CURRENT_CONTEXT(ctx);
+      delete_shader(ctx, name);
+   }
+}
+
+
+void GLAPIENTRY
+_mesa_DetachObjectARB(GLhandleARB program, GLhandleARB shader)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   detach_shader(ctx, program, shader);
+}
+
+
+void GLAPIENTRY
+_mesa_DetachShader(GLuint program, GLuint shader)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   detach_shader(ctx, program, shader);
+}
+
+
+void GLAPIENTRY
+_mesa_GetActiveAttribARB(GLhandleARB program, GLuint index,
+                         GLsizei maxLength, GLsizei * length, GLint * size,
+                         GLenum * type, GLcharARB * name)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   get_active_attrib(ctx, program, index, maxLength, length, size, type, name);
+}
+
+
+void GLAPIENTRY
+_mesa_GetAttachedObjectsARB(GLhandleARB container, GLsizei maxCount,
+                            GLsizei * count, GLhandleARB * obj)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   get_attached_shaders(ctx, container, maxCount, count, obj);
+}
+
+
+void GLAPIENTRY
+_mesa_GetAttachedShaders(GLuint program, GLsizei maxCount,
+                         GLsizei *count, GLuint *obj)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   get_attached_shaders(ctx, program, maxCount, count, obj);
+}
+
+
+GLint GLAPIENTRY
+_mesa_GetAttribLocationARB(GLhandleARB program, const GLcharARB * name)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   return get_attrib_location(ctx, program, name);
+}
+
+
+void GLAPIENTRY
+_mesa_GetInfoLogARB(GLhandleARB object, GLsizei maxLength, GLsizei * length,
+                    GLcharARB * infoLog)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   if (is_program(ctx, object)) {
+      get_program_info_log(ctx, object, maxLength, length, infoLog);
+   }
+   else if (is_shader(ctx, object)) {
+      get_shader_info_log(ctx, object, maxLength, length, infoLog);
+   }
+   else {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetInfoLogARB");
+   }
+}
+
+
+void GLAPIENTRY
+_mesa_GetObjectParameterivARB(GLhandleARB object, GLenum pname, GLint *params)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   /* Implement in terms of GetProgramiv, GetShaderiv */
+   if (is_program(ctx, object)) {
+      if (pname == GL_OBJECT_TYPE_ARB) {
+        *params = GL_PROGRAM_OBJECT_ARB;
+      }
+      else {
+        get_programiv(ctx, object, pname, params);
+      }
+   }
+   else if (is_shader(ctx, object)) {
+      if (pname == GL_OBJECT_TYPE_ARB) {
+        *params = GL_SHADER_OBJECT_ARB;
+      }
+      else {
+        get_shaderiv(ctx, object, pname, params);
+      }
+   }
+   else {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glGetObjectParameterivARB");
+   }
+}
+
+
+void GLAPIENTRY
+_mesa_GetObjectParameterfvARB(GLhandleARB object, GLenum pname,
+                              GLfloat *params)
+{
+   GLint iparams[1];  /* XXX is one element enough? */
+   _mesa_GetObjectParameterivARB(object, pname, iparams);
+   params[0] = (GLfloat) iparams[0];
+}
+
+
+void GLAPIENTRY
+_mesa_GetProgramiv(GLuint program, GLenum pname, GLint *params)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   get_programiv(ctx, program, pname, params);
+}
+
+
+void GLAPIENTRY
+_mesa_GetShaderiv(GLuint shader, GLenum pname, GLint *params)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   get_shaderiv(ctx, shader, pname, params);
+}
+
+
+void GLAPIENTRY
+_mesa_GetProgramInfoLog(GLuint program, GLsizei bufSize,
+                        GLsizei *length, GLchar *infoLog)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   get_program_info_log(ctx, program, bufSize, length, infoLog);
+}
+
+
+void GLAPIENTRY
+_mesa_GetShaderInfoLog(GLuint shader, GLsizei bufSize,
+                       GLsizei *length, GLchar *infoLog)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   get_shader_info_log(ctx, shader, bufSize, length, infoLog);
+}
+
+
+void GLAPIENTRY
+_mesa_GetShaderSourceARB(GLhandleARB shader, GLsizei maxLength,
+                         GLsizei *length, GLcharARB *sourceOut)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   get_shader_source(ctx, shader, maxLength, length, sourceOut);
+}
+
+
+GLhandleARB GLAPIENTRY
+_mesa_GetHandleARB(GLenum pname)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   return get_handle(ctx, pname);
+}
+
+
+GLboolean GLAPIENTRY
+_mesa_IsProgram(GLuint name)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   return is_program(ctx, name);
+}
+
+
+GLboolean GLAPIENTRY
+_mesa_IsShader(GLuint name)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   return is_shader(ctx, name);
+}
+
+
+void GLAPIENTRY
+_mesa_LinkProgramARB(GLhandleARB programObj)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   link_program(ctx, programObj);
+}
+
+
+
+/**
+ * Read shader source code from a file.
+ * Useful for debugging to override an app's shader.
+ */
+static GLcharARB *
+read_shader(const char *fname)
+{
+   const int max = 50*1000;
+   FILE *f = fopen(fname, "r");
+   GLcharARB *buffer, *shader;
+   int len;
+
+   if (!f) {
+      return NULL;
+   }
+
+   buffer = (char *) malloc(max);
+   len = fread(buffer, 1, max, f);
+   buffer[len] = 0;
+
+   fclose(f);
+
+   shader = _mesa_strdup(buffer);
+   free(buffer);
+
+   return shader;
+}
+
+
+/**
+ * Called via glShaderSource() and glShaderSourceARB() API functions.
+ * Basically, concatenate the source code strings into one long string
+ * and pass it to _mesa_shader_source().
+ */
+void GLAPIENTRY
+_mesa_ShaderSourceARB(GLhandleARB shaderObj, GLsizei count,
+                      const GLcharARB ** string, const GLint * length)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   GLint *offsets;
+   GLsizei i, totalLength;
+   GLcharARB *source;
+   GLuint checksum;
+
+   if (!shaderObj || string == NULL) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glShaderSourceARB");
+      return;
+   }
+
+   /*
+    * This array holds offsets of where the appropriate string ends, thus the
+    * last element will be set to the total length of the source code.
+    */
+   offsets = (GLint *) malloc(count * sizeof(GLint));
+   if (offsets == NULL) {
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB");
+      return;
+   }
+
+   for (i = 0; i < count; i++) {
+      if (string[i] == NULL) {
+         free((GLvoid *) offsets);
+         _mesa_error(ctx, GL_INVALID_OPERATION, "glShaderSourceARB(null string)");
+         return;
+      }
+      if (length == NULL || length[i] < 0)
+         offsets[i] = strlen(string[i]);
+      else
+         offsets[i] = length[i];
+      /* accumulate string lengths */
+      if (i > 0)
+         offsets[i] += offsets[i - 1];
+   }
+
+   /* Total length of source string is sum off all strings plus two.
+    * One extra byte for terminating zero, another extra byte to silence
+    * valgrind warnings in the parser/grammer code.
+    */
+   totalLength = offsets[count - 1] + 2;
+   source = (GLcharARB *) malloc(totalLength * sizeof(GLcharARB));
+   if (source == NULL) {
+      free((GLvoid *) offsets);
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB");
+      return;
+   }
+
+   for (i = 0; i < count; i++) {
+      GLint start = (i > 0) ? offsets[i - 1] : 0;
+      memcpy(source + start, string[i],
+             (offsets[i] - start) * sizeof(GLcharARB));
+   }
+   source[totalLength - 1] = '\0';
+   source[totalLength - 2] = '\0';
+
+   if (SHADER_SUBST) {
+      /* Compute the shader's source code checksum then try to open a file
+       * named newshader_<CHECKSUM>.  If it exists, use it in place of the
+       * original shader source code.  For debugging.
+       */
+      char filename[100];
+      GLcharARB *newSource;
+
+      checksum = _mesa_str_checksum(source);
+
+      _mesa_snprintf(filename, sizeof(filename), "newshader_%d", checksum);
+
+      newSource = read_shader(filename);
+      if (newSource) {
+         fprintf(stderr, "Mesa: Replacing shader %u chksum=%d with %s\n",
+                       shaderObj, checksum, filename);
+         free(source);
+         source = newSource;
+      }
+   }      
+
+   shader_source(ctx, shaderObj, source);
+
+   if (SHADER_SUBST) {
+      struct gl_shader *sh = _mesa_lookup_shader(ctx, shaderObj);
+      if (sh)
+         sh->SourceChecksum = checksum; /* save original checksum */
+   }
+
+   free(offsets);
+}
+
+
+void GLAPIENTRY
+_mesa_UseProgramObjectARB(GLhandleARB program)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   FLUSH_VERTICES(ctx, _NEW_PROGRAM);
+   _mesa_use_program(ctx, program);
+}
+
+
+void GLAPIENTRY
+_mesa_ValidateProgramARB(GLhandleARB program)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   validate_program(ctx, program);
+}
+
+#ifdef FEATURE_ES2
+
+void GLAPIENTRY
+_mesa_GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype,
+                               GLint* range, GLint* precision)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_error(ctx, GL_INVALID_OPERATION, __FUNCTION__);
+}
+
+
+void GLAPIENTRY
+_mesa_ReleaseShaderCompiler(void)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_error(ctx, GL_INVALID_OPERATION, __FUNCTION__);
+}
+
+
+void GLAPIENTRY
+_mesa_ShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat,
+                   const void* binary, GLint length)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_error(ctx, GL_INVALID_OPERATION, __FUNCTION__);
+}
+
+#endif /* FEATURE_ES2 */
+
+
+/**
+ * Plug in shader-related functions into API dispatch table.
+ */
+void
+_mesa_init_shader_dispatch(struct _glapi_table *exec)
+{
+   /* GL_ARB_vertex/fragment_shader */
+   SET_DeleteObjectARB(exec, _mesa_DeleteObjectARB);
+   SET_GetHandleARB(exec, _mesa_GetHandleARB);
+   SET_DetachObjectARB(exec, _mesa_DetachObjectARB);
+   SET_CreateShaderObjectARB(exec, _mesa_CreateShaderObjectARB);
+   SET_ShaderSourceARB(exec, _mesa_ShaderSourceARB);
+   SET_CompileShaderARB(exec, _mesa_CompileShaderARB);
+   SET_CreateProgramObjectARB(exec, _mesa_CreateProgramObjectARB);
+   SET_AttachObjectARB(exec, _mesa_AttachObjectARB);
+   SET_LinkProgramARB(exec, _mesa_LinkProgramARB);
+   SET_UseProgramObjectARB(exec, _mesa_UseProgramObjectARB);
+   SET_ValidateProgramARB(exec, _mesa_ValidateProgramARB);
+   SET_GetObjectParameterfvARB(exec, _mesa_GetObjectParameterfvARB);
+   SET_GetObjectParameterivARB(exec, _mesa_GetObjectParameterivARB);
+   SET_GetInfoLogARB(exec, _mesa_GetInfoLogARB);
+   SET_GetAttachedObjectsARB(exec, _mesa_GetAttachedObjectsARB);
+   SET_GetShaderSourceARB(exec, _mesa_GetShaderSourceARB);
+
+   /* OpenGL 2.0 */
+   SET_AttachShader(exec, _mesa_AttachShader);
+   SET_CreateProgram(exec, _mesa_CreateProgram);
+   SET_CreateShader(exec, _mesa_CreateShader);
+   SET_DeleteProgram(exec, _mesa_DeleteProgram);
+   SET_DeleteShader(exec, _mesa_DeleteShader);
+   SET_DetachShader(exec, _mesa_DetachShader);
+   SET_GetAttachedShaders(exec, _mesa_GetAttachedShaders);
+   SET_GetProgramiv(exec, _mesa_GetProgramiv);
+   SET_GetProgramInfoLog(exec, _mesa_GetProgramInfoLog);
+   SET_GetShaderiv(exec, _mesa_GetShaderiv);
+   SET_GetShaderInfoLog(exec, _mesa_GetShaderInfoLog);
+   SET_IsProgram(exec, _mesa_IsProgram);
+   SET_IsShader(exec, _mesa_IsShader);
+
+#if FEATURE_ARB_vertex_shader
+   SET_BindAttribLocationARB(exec, _mesa_BindAttribLocationARB);
+   SET_GetActiveAttribARB(exec, _mesa_GetActiveAttribARB);
+   SET_GetAttribLocationARB(exec, _mesa_GetAttribLocationARB);
+#endif
+}
+
diff --git a/src/mesa/main/shaderapi.h b/src/mesa/main/shaderapi.h
new file mode 100644 (file)
index 0000000..ec0c09a
--- /dev/null
@@ -0,0 +1,166 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2004-2007  Brian Paul   All Rights Reserved.
+ * Copyright (C) 2010  VMware, Inc.  All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef SHADERAPI_H
+#define SHADERAPI_H
+
+
+#include "glheader.h"
+#include "mtypes.h"
+
+
+extern GLint
+_mesa_sizeof_glsl_type(GLenum type);
+
+extern void
+_mesa_copy_string(GLchar *dst, GLsizei maxLength,
+                  GLsizei *length, const GLchar *src);
+
+extern void
+_mesa_use_program(GLcontext *ctx, GLuint program);
+
+
+extern void
+_mesa_init_shader_dispatch(struct _glapi_table *exec);
+
+
+
+extern void GLAPIENTRY
+_mesa_AttachObjectARB(GLhandleARB, GLhandleARB);
+
+extern void  GLAPIENTRY
+_mesa_CompileShaderARB(GLhandleARB);
+
+extern GLhandleARB GLAPIENTRY
+_mesa_CreateProgramObjectARB(void);
+
+extern GLhandleARB GLAPIENTRY
+_mesa_CreateShaderObjectARB(GLenum type);
+
+extern void GLAPIENTRY
+_mesa_DeleteObjectARB(GLhandleARB obj);
+
+extern void GLAPIENTRY
+_mesa_DetachObjectARB(GLhandleARB, GLhandleARB);
+
+extern void GLAPIENTRY
+_mesa_GetAttachedObjectsARB(GLhandleARB, GLsizei, GLsizei *, GLhandleARB *);
+
+extern GLhandleARB GLAPIENTRY
+_mesa_GetHandleARB(GLenum pname);
+
+extern void GLAPIENTRY
+_mesa_GetInfoLogARB(GLhandleARB, GLsizei, GLsizei *, GLcharARB *);
+
+extern void GLAPIENTRY
+_mesa_GetObjectParameterfvARB(GLhandleARB, GLenum, GLfloat *);
+
+extern void GLAPIENTRY
+_mesa_GetObjectParameterivARB(GLhandleARB, GLenum, GLint *);
+
+extern void GLAPIENTRY
+_mesa_GetShaderSourceARB(GLhandleARB, GLsizei, GLsizei *, GLcharARB *);
+
+extern GLboolean GLAPIENTRY
+_mesa_IsProgram(GLuint name);
+
+extern GLboolean GLAPIENTRY
+_mesa_IsShader(GLuint name);
+
+extern void GLAPIENTRY
+_mesa_LinkProgramARB(GLhandleARB programObj);
+
+extern void GLAPIENTRY
+_mesa_ShaderSourceARB(GLhandleARB, GLsizei, const GLcharARB* *, const GLint *);
+
+extern void GLAPIENTRY
+_mesa_UseProgramObjectARB(GLhandleARB);
+
+extern void GLAPIENTRY
+_mesa_ValidateProgramARB(GLhandleARB);
+
+
+extern void GLAPIENTRY
+_mesa_BindAttribLocationARB(GLhandleARB, GLuint, const GLcharARB *);
+
+extern void GLAPIENTRY
+_mesa_GetActiveAttribARB(GLhandleARB, GLuint, GLsizei, GLsizei *, GLint *,
+                         GLenum *, GLcharARB *);
+
+extern GLint GLAPIENTRY
+_mesa_GetAttribLocationARB(GLhandleARB, const GLcharARB *);
+
+
+
+extern void GLAPIENTRY
+_mesa_AttachShader(GLuint program, GLuint shader);
+
+extern GLuint GLAPIENTRY
+_mesa_CreateShader(GLenum);
+
+extern GLuint GLAPIENTRY
+_mesa_CreateProgram(void);
+
+extern void GLAPIENTRY
+_mesa_DeleteProgram(GLuint program);
+
+extern void GLAPIENTRY
+_mesa_DeleteShader(GLuint shader);
+
+extern void GLAPIENTRY
+_mesa_DetachShader(GLuint program, GLuint shader);
+
+extern void GLAPIENTRY
+_mesa_GetAttachedShaders(GLuint program, GLsizei maxCount,
+                         GLsizei *count, GLuint *obj);
+
+extern void GLAPIENTRY
+_mesa_GetProgramiv(GLuint program, GLenum pname, GLint *params);
+
+extern void GLAPIENTRY
+_mesa_GetProgramInfoLog(GLuint program, GLsizei bufSize,
+                        GLsizei *length, GLchar *infoLog);
+
+extern void GLAPIENTRY
+_mesa_GetShaderiv(GLuint shader, GLenum pname, GLint *params);
+
+extern void GLAPIENTRY
+_mesa_GetShaderInfoLog(GLuint shader, GLsizei bufSize,
+                       GLsizei *length, GLchar *infoLog);
+
+
+extern void GLAPIENTRY
+_mesa_GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype,
+                               GLint *range, GLint *precision);
+
+extern void GLAPIENTRY
+_mesa_ReleaseShaderCompiler(void);
+
+extern void GLAPIENTRY
+_mesa_ShaderBinary(GLint n, const GLuint *shaders, GLenum binaryformat,
+                   const void* binary, GLint length);
+
+
+#endif /* SHADERAPI_H */
diff --git a/src/mesa/main/shaderobj.c b/src/mesa/main/shaderobj.c
new file mode 100644 (file)
index 0000000..01ed3c5
--- /dev/null
@@ -0,0 +1,386 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2004-2008  Brian Paul   All Rights Reserved.
+ * Copyright (C) 2009-2010  VMware, Inc.  All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file shaderobj.c
+ * \author Brian Paul
+ *
+ */
+
+
+#include "main/glheader.h"
+#include "main/context.h"
+#include "main/dispatch.h"
+#include "main/hash.h"
+#include "main/shaderobj.h"
+#include "shader/program.h"
+#include "shader/prog_parameter.h"
+#include "shader/prog_uniform.h"
+
+
+/**********************************************************************/
+/*** Shader object functions                                        ***/
+/**********************************************************************/
+
+
+/**
+ * Set ptr to point to sh.
+ * If ptr is pointing to another shader, decrement its refcount (and delete
+ * if refcount hits zero).
+ * Then set ptr to point to sh, incrementing its refcount.
+ */
+void
+_mesa_reference_shader(GLcontext *ctx, struct gl_shader **ptr,
+                       struct gl_shader *sh)
+{
+   assert(ptr);
+   if (*ptr == sh) {
+      /* no-op */
+      return;
+   }
+   if (*ptr) {
+      /* Unreference the old shader */
+      GLboolean deleteFlag = GL_FALSE;
+      struct gl_shader *old = *ptr;
+
+      ASSERT(old->RefCount > 0);
+      old->RefCount--;
+      /*printf("SHADER DECR %p (%d) to %d\n",
+        (void*) old, old->Name, old->RefCount);*/
+      deleteFlag = (old->RefCount == 0);
+
+      if (deleteFlag) {
+         _mesa_HashRemove(ctx->Shared->ShaderObjects, old->Name);
+         ctx->Driver.DeleteShader(ctx, old);
+      }
+
+      *ptr = NULL;
+   }
+   assert(!*ptr);
+
+   if (sh) {
+      /* reference new */
+      sh->RefCount++;
+      /*printf("SHADER INCR %p (%d) to %d\n",
+        (void*) sh, sh->Name, sh->RefCount);*/
+      *ptr = sh;
+   }
+}
+
+
+/**
+ * Allocate a new gl_shader object, initialize it.
+ * Called via ctx->Driver.NewShader()
+ */
+static struct gl_shader *
+_mesa_new_shader(GLcontext *ctx, GLuint name, GLenum type)
+{
+   struct gl_shader *shader;
+   assert(type == GL_FRAGMENT_SHADER || type == GL_VERTEX_SHADER);
+   shader = CALLOC_STRUCT(gl_shader);
+   if (shader) {
+      shader->Type = type;
+      shader->Name = name;
+      shader->RefCount = 1;
+   }
+   return shader;
+}
+
+
+/**
+ * Delete a shader object.
+ * Called via ctx->Driver.DeleteShader().
+ */
+static void
+__mesa_delete_shader(GLcontext *ctx, struct gl_shader *sh)
+{
+   if (sh->Source)
+      free((void *) sh->Source);
+   if (sh->InfoLog)
+      free(sh->InfoLog);
+   _mesa_reference_program(ctx, &sh->Program, NULL);
+   free(sh);
+}
+
+
+/**
+ * Lookup a GLSL shader object.
+ */
+struct gl_shader *
+_mesa_lookup_shader(GLcontext *ctx, GLuint name)
+{
+   if (name) {
+      struct gl_shader *sh = (struct gl_shader *)
+         _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
+      /* Note that both gl_shader and gl_shader_program objects are kept
+       * in the same hash table.  Check the object's type to be sure it's
+       * what we're expecting.
+       */
+      if (sh && sh->Type == GL_SHADER_PROGRAM_MESA) {
+         return NULL;
+      }
+      return sh;
+   }
+   return NULL;
+}
+
+
+/**
+ * As above, but record an error if shader is not found.
+ */
+struct gl_shader *
+_mesa_lookup_shader_err(GLcontext *ctx, GLuint name, const char *caller)
+{
+   if (!name) {
+      _mesa_error(ctx, GL_INVALID_VALUE, caller);
+      return NULL;
+   }
+   else {
+      struct gl_shader *sh = (struct gl_shader *)
+         _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
+      if (!sh) {
+         _mesa_error(ctx, GL_INVALID_VALUE, caller);
+         return NULL;
+      }
+      if (sh->Type == GL_SHADER_PROGRAM_MESA) {
+         _mesa_error(ctx, GL_INVALID_OPERATION, caller);
+         return NULL;
+      }
+      return sh;
+   }
+}
+
+
+
+/**********************************************************************/
+/*** Shader Program object functions                                ***/
+/**********************************************************************/
+
+
+/**
+ * Set ptr to point to shProg.
+ * If ptr is pointing to another object, decrement its refcount (and delete
+ * if refcount hits zero).
+ * Then set ptr to point to shProg, incrementing its refcount.
+ */
+void
+_mesa_reference_shader_program(GLcontext *ctx,
+                               struct gl_shader_program **ptr,
+                               struct gl_shader_program *shProg)
+{
+   assert(ptr);
+   if (*ptr == shProg) {
+      /* no-op */
+      return;
+   }
+   if (*ptr) {
+      /* Unreference the old shader program */
+      GLboolean deleteFlag = GL_FALSE;
+      struct gl_shader_program *old = *ptr;
+
+      ASSERT(old->RefCount > 0);
+      old->RefCount--;
+#if 0
+      printf("ShaderProgram %p ID=%u  RefCount-- to %d\n",
+             (void *) old, old->Name, old->RefCount);
+#endif
+      deleteFlag = (old->RefCount == 0);
+
+      if (deleteFlag) {
+         _mesa_HashRemove(ctx->Shared->ShaderObjects, old->Name);
+         ctx->Driver.DeleteShaderProgram(ctx, old);
+      }
+
+      *ptr = NULL;
+   }
+   assert(!*ptr);
+
+   if (shProg) {
+      shProg->RefCount++;
+#if 0
+      printf("ShaderProgram %p ID=%u  RefCount++ to %d\n",
+             (void *) shProg, shProg->Name, shProg->RefCount);
+#endif
+      *ptr = shProg;
+   }
+}
+
+
+/**
+ * Allocate a new gl_shader_program object, initialize it.
+ * Called via ctx->Driver.NewShaderProgram()
+ */
+static struct gl_shader_program *
+_mesa_new_shader_program(GLcontext *ctx, GLuint name)
+{
+   struct gl_shader_program *shProg;
+   shProg = CALLOC_STRUCT(gl_shader_program);
+   if (shProg) {
+      shProg->Type = GL_SHADER_PROGRAM_MESA;
+      shProg->Name = name;
+      shProg->RefCount = 1;
+      shProg->Attributes = _mesa_new_parameter_list();
+   }
+   return shProg;
+}
+
+
+/**
+ * Clear (free) the shader program state that gets produced by linking.
+ */
+void
+_mesa_clear_shader_program_data(GLcontext *ctx,
+                                struct gl_shader_program *shProg)
+{
+   _mesa_reference_vertprog(ctx, &shProg->VertexProgram, NULL);
+   _mesa_reference_fragprog(ctx, &shProg->FragmentProgram, NULL);
+
+   if (shProg->Uniforms) {
+      _mesa_free_uniform_list(shProg->Uniforms);
+      shProg->Uniforms = NULL;
+   }
+
+   if (shProg->Varying) {
+      _mesa_free_parameter_list(shProg->Varying);
+      shProg->Varying = NULL;
+   }
+}
+
+
+/**
+ * Free all the data that hangs off a shader program object, but not the
+ * object itself.
+ */
+void
+_mesa_free_shader_program_data(GLcontext *ctx,
+                               struct gl_shader_program *shProg)
+{
+   GLuint i;
+
+   assert(shProg->Type == GL_SHADER_PROGRAM_MESA);
+
+   _mesa_clear_shader_program_data(ctx, shProg);
+
+   if (shProg->Attributes) {
+      _mesa_free_parameter_list(shProg->Attributes);
+      shProg->Attributes = NULL;
+   }
+
+   /* detach shaders */
+   for (i = 0; i < shProg->NumShaders; i++) {
+      _mesa_reference_shader(ctx, &shProg->Shaders[i], NULL);
+   }
+   shProg->NumShaders = 0;
+
+   if (shProg->Shaders) {
+      free(shProg->Shaders);
+      shProg->Shaders = NULL;
+   }
+
+   if (shProg->InfoLog) {
+      free(shProg->InfoLog);
+      shProg->InfoLog = NULL;
+   }
+
+   /* Transform feedback varying vars */
+   for (i = 0; i < shProg->TransformFeedback.NumVarying; i++) {
+      free(shProg->TransformFeedback.VaryingNames[i]);
+   }
+   free(shProg->TransformFeedback.VaryingNames);
+   shProg->TransformFeedback.VaryingNames = NULL;
+   shProg->TransformFeedback.NumVarying = 0;
+}
+
+
+/**
+ * Free/delete a shader program object.
+ * Called via ctx->Driver.DeleteShaderProgram().
+ */
+static void
+__mesa_delete_shader_program(GLcontext *ctx, struct gl_shader_program *shProg)
+{
+   _mesa_free_shader_program_data(ctx, shProg);
+
+   free(shProg);
+}
+
+
+/**
+ * Lookup a GLSL program object.
+ */
+struct gl_shader_program *
+_mesa_lookup_shader_program(GLcontext *ctx, GLuint name)
+{
+   struct gl_shader_program *shProg;
+   if (name) {
+      shProg = (struct gl_shader_program *)
+         _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
+      /* Note that both gl_shader and gl_shader_program objects are kept
+       * in the same hash table.  Check the object's type to be sure it's
+       * what we're expecting.
+       */
+      if (shProg && shProg->Type != GL_SHADER_PROGRAM_MESA) {
+         return NULL;
+      }
+      return shProg;
+   }
+   return NULL;
+}
+
+
+/**
+ * As above, but record an error if program is not found.
+ */
+struct gl_shader_program *
+_mesa_lookup_shader_program_err(GLcontext *ctx, GLuint name,
+                                const char *caller)
+{
+   if (!name) {
+      _mesa_error(ctx, GL_INVALID_VALUE, caller);
+      return NULL;
+   }
+   else {
+      struct gl_shader_program *shProg = (struct gl_shader_program *)
+         _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
+      if (!shProg) {
+         _mesa_error(ctx, GL_INVALID_VALUE, caller);
+         return NULL;
+      }
+      if (shProg->Type != GL_SHADER_PROGRAM_MESA) {
+         _mesa_error(ctx, GL_INVALID_OPERATION, caller);
+         return NULL;
+      }
+      return shProg;
+   }
+}
+
+
+void
+_mesa_init_shader_object_functions(struct dd_function_table *driver)
+{
+   driver->NewShader = _mesa_new_shader;
+   driver->DeleteShader = __mesa_delete_shader;
+   driver->NewShaderProgram = _mesa_new_shader_program;
+   driver->DeleteShaderProgram = __mesa_delete_shader_program;
+}
diff --git a/src/mesa/main/shaderobj.h b/src/mesa/main/shaderobj.h
new file mode 100644 (file)
index 0000000..d6b37b4
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5.3
+ *
+ * Copyright (C) 2004-2007  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef SHADEROBJ_H
+#define SHADEROBJ_H
+
+
+#include "glheader.h"
+#include "mtypes.h"
+
+
+extern void
+_mesa_reference_shader(GLcontext *ctx, struct gl_shader **ptr,
+                       struct gl_shader *sh);
+
+extern struct gl_shader *
+_mesa_lookup_shader(GLcontext *ctx, GLuint name);
+
+extern struct gl_shader *
+_mesa_lookup_shader_err(GLcontext *ctx, GLuint name, const char *caller);
+
+
+
+extern void
+_mesa_reference_shader_program(GLcontext *ctx,
+                               struct gl_shader_program **ptr,
+                               struct gl_shader_program *shProg);
+
+extern struct gl_shader_program *
+_mesa_lookup_shader_program(GLcontext *ctx, GLuint name);
+
+extern struct gl_shader_program *
+_mesa_lookup_shader_program_err(GLcontext *ctx, GLuint name,
+                                const char *caller);
+
+extern void
+_mesa_clear_shader_program_data(GLcontext *ctx,
+                                struct gl_shader_program *shProg);
+
+extern void
+_mesa_free_shader_program_data(GLcontext *ctx,
+                               struct gl_shader_program *shProg);
+
+
+
+extern void
+_mesa_init_shader_object_functions(struct dd_function_table *driver);
+
+extern void
+_mesa_init_shader_state(GLcontext *ctx);
+
+extern void
+_mesa_free_shader_state(GLcontext *ctx);
+
+
+#endif /* SHADEROBJ_H */
diff --git a/src/mesa/main/shaders.c b/src/mesa/main/shaders.c
deleted file mode 100644 (file)
index 65f1ee3..0000000
+++ /dev/null
@@ -1,932 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  7.3
- *
- * Copyright (C) 2004-2008  Brian Paul   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-
-#include "glheader.h"
-#include "context.h"
-#include "shaders.h"
-#include "shader/shader_api.h"
-#include "main/dispatch.h"
-
-
-/** Define this to enable shader substitution (see below) */
-#define SHADER_SUBST 0
-
-
-
-/**
- * These are basically just wrappers/adaptors for calling the
- * ctx->Driver.foobar() GLSL-related functions.
- *
- * Things are biased toward the OpenGL 2.0 functions rather than the
- * ARB extensions (i.e. the ARB functions are layered on the 2.0 functions).
- *
- * The general idea here is to allow enough modularity such that a
- * completely different GLSL implemenation can be plugged in and co-exist
- * with Mesa's native GLSL code.
- */
-
-
-
-void GLAPIENTRY
-_mesa_AttachObjectARB(GLhandleARB program, GLhandleARB shader)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.AttachShader(ctx, program, shader);
-}
-
-
-void GLAPIENTRY
-_mesa_AttachShader(GLuint program, GLuint shader)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.AttachShader(ctx, program, shader);
-}
-
-
-void GLAPIENTRY
-_mesa_BindAttribLocationARB(GLhandleARB program, GLuint index,
-                            const GLcharARB *name)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.BindAttribLocation(ctx, program, index, name);
-}
-
-
-void GLAPIENTRY
-_mesa_CompileShaderARB(GLhandleARB shaderObj)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.CompileShader(ctx, shaderObj);
-}
-
-
-GLuint GLAPIENTRY
-_mesa_CreateShader(GLenum type)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   return ctx->Driver.CreateShader(ctx, type);
-}
-
-
-GLhandleARB GLAPIENTRY
-_mesa_CreateShaderObjectARB(GLenum type)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   return ctx->Driver.CreateShader(ctx, type);
-}
-
-
-GLuint GLAPIENTRY
-_mesa_CreateProgram(void)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   return ctx->Driver.CreateProgram(ctx);
-}
-
-
-GLhandleARB GLAPIENTRY
-_mesa_CreateProgramObjectARB(void)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   return ctx->Driver.CreateProgram(ctx);
-}
-
-
-void GLAPIENTRY
-_mesa_DeleteObjectARB(GLhandleARB obj)
-{
-   if (obj) {
-      GET_CURRENT_CONTEXT(ctx);
-      if (ctx->Driver.IsProgram(ctx, obj)) {
-         ctx->Driver.DeleteProgram2(ctx, obj);
-      }
-      else if (ctx->Driver.IsShader(ctx, obj)) {
-         ctx->Driver.DeleteShader(ctx, obj);
-      }
-      else {
-         /* error? */
-      }
-   }
-}
-
-
-void GLAPIENTRY
-_mesa_DeleteProgram(GLuint name)
-{
-   if (name) {
-      GET_CURRENT_CONTEXT(ctx);
-      ctx->Driver.DeleteProgram2(ctx, name);
-   }
-}
-
-
-void GLAPIENTRY
-_mesa_DeleteShader(GLuint name)
-{
-   if (name) {
-      GET_CURRENT_CONTEXT(ctx);
-      ctx->Driver.DeleteShader(ctx, name);
-   }
-}
-
-
-void GLAPIENTRY
-_mesa_DetachObjectARB(GLhandleARB program, GLhandleARB shader)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.DetachShader(ctx, program, shader);
-}
-
-
-void GLAPIENTRY
-_mesa_DetachShader(GLuint program, GLuint shader)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.DetachShader(ctx, program, shader);
-}
-
-
-void GLAPIENTRY
-_mesa_GetActiveAttribARB(GLhandleARB program, GLuint index,
-                         GLsizei maxLength, GLsizei * length, GLint * size,
-                         GLenum * type, GLcharARB * name)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.GetActiveAttrib(ctx, program, index, maxLength, length, size,
-                               type, name);
-}
-
-
-void GLAPIENTRY
-_mesa_GetActiveUniformARB(GLhandleARB program, GLuint index,
-                          GLsizei maxLength, GLsizei * length, GLint * size,
-                          GLenum * type, GLcharARB * name)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.GetActiveUniform(ctx, program, index, maxLength, length, size,
-                                type, name);
-}
-
-
-void GLAPIENTRY
-_mesa_GetAttachedObjectsARB(GLhandleARB container, GLsizei maxCount,
-                            GLsizei * count, GLhandleARB * obj)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.GetAttachedShaders(ctx, container, maxCount, count, obj);
-}
-
-
-void GLAPIENTRY
-_mesa_GetAttachedShaders(GLuint program, GLsizei maxCount,
-                         GLsizei *count, GLuint *obj)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.GetAttachedShaders(ctx, program, maxCount, count, obj);
-}
-
-
-GLint GLAPIENTRY
-_mesa_GetAttribLocationARB(GLhandleARB program, const GLcharARB * name)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   return ctx->Driver.GetAttribLocation(ctx, program, name);
-}
-
-
-void GLAPIENTRY
-_mesa_GetInfoLogARB(GLhandleARB object, GLsizei maxLength, GLsizei * length,
-                    GLcharARB * infoLog)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   /* Implement in terms of GetProgramInfoLog, GetShaderInfoLog */
-   if (ctx->Driver.IsProgram(ctx, object)) {
-      ctx->Driver.GetProgramInfoLog(ctx, object, maxLength, length, infoLog);
-   }
-   else if (ctx->Driver.IsShader(ctx, object)) {
-      ctx->Driver.GetShaderInfoLog(ctx, object, maxLength, length, infoLog);
-   }
-   else {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetInfoLogARB");
-   }
-}
-
-
-void GLAPIENTRY
-_mesa_GetObjectParameterivARB(GLhandleARB object, GLenum pname, GLint *params)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   /* Implement in terms of GetProgramiv, GetShaderiv */
-   if (ctx->Driver.IsProgram(ctx, object)) {
-      if (pname == GL_OBJECT_TYPE_ARB) {
-        *params = GL_PROGRAM_OBJECT_ARB;
-      }
-      else {
-        ctx->Driver.GetProgramiv(ctx, object, pname, params);
-      }
-   }
-   else if (ctx->Driver.IsShader(ctx, object)) {
-      if (pname == GL_OBJECT_TYPE_ARB) {
-        *params = GL_SHADER_OBJECT_ARB;
-      }
-      else {
-        ctx->Driver.GetShaderiv(ctx, object, pname, params);
-      }
-   }
-   else {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glGetObjectParameterivARB");
-   }
-}
-
-
-void GLAPIENTRY
-_mesa_GetObjectParameterfvARB(GLhandleARB object, GLenum pname,
-                              GLfloat *params)
-{
-   GLint iparams[1];  /* XXX is one element enough? */
-   _mesa_GetObjectParameterivARB(object, pname, iparams);
-   params[0] = (GLfloat) iparams[0];
-}
-
-
-void GLAPIENTRY
-_mesa_GetProgramiv(GLuint program, GLenum pname, GLint *params)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.GetProgramiv(ctx, program, pname, params);
-}
-
-
-void GLAPIENTRY
-_mesa_GetShaderiv(GLuint shader, GLenum pname, GLint *params)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.GetShaderiv(ctx, shader, pname, params);
-}
-
-
-void GLAPIENTRY
-_mesa_GetProgramInfoLog(GLuint program, GLsizei bufSize,
-                        GLsizei *length, GLchar *infoLog)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.GetProgramInfoLog(ctx, program, bufSize, length, infoLog);
-}
-
-
-void GLAPIENTRY
-_mesa_GetShaderInfoLog(GLuint shader, GLsizei bufSize,
-                       GLsizei *length, GLchar *infoLog)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.GetShaderInfoLog(ctx, shader, bufSize, length, infoLog);
-}
-
-
-void GLAPIENTRY
-_mesa_GetShaderSourceARB(GLhandleARB shader, GLsizei maxLength,
-                         GLsizei *length, GLcharARB *sourceOut)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.GetShaderSource(ctx, shader, maxLength, length, sourceOut);
-}
-
-
-void GLAPIENTRY
-_mesa_GetUniformfvARB(GLhandleARB program, GLint location, GLfloat * params)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.GetUniformfv(ctx, program, location, params);
-}
-
-
-void GLAPIENTRY
-_mesa_GetUniformivARB(GLhandleARB program, GLint location, GLint * params)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.GetUniformiv(ctx, program, location, params);
-}
-
-
-
-#if 0
-GLint GLAPIENTRY
-_mesa_GetUniformLocation(GLuint program, const GLcharARB *name)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   return ctx->Driver.GetUniformLocation(ctx, program, name);
-}
-#endif
-
-
-GLhandleARB GLAPIENTRY
-_mesa_GetHandleARB(GLenum pname)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   return ctx->Driver.GetHandle(ctx, pname);
-}
-
-
-GLint GLAPIENTRY
-_mesa_GetUniformLocationARB(GLhandleARB programObj, const GLcharARB *name)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   return ctx->Driver.GetUniformLocation(ctx, programObj, name);
-}
-
-
-GLboolean GLAPIENTRY
-_mesa_IsProgram(GLuint name)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   return ctx->Driver.IsProgram(ctx, name);
-}
-
-
-GLboolean GLAPIENTRY
-_mesa_IsShader(GLuint name)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   return ctx->Driver.IsShader(ctx, name);
-}
-
-
-void GLAPIENTRY
-_mesa_LinkProgramARB(GLhandleARB programObj)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.LinkProgram(ctx, programObj);
-}
-
-
-
-/**
- * Read shader source code from a file.
- * Useful for debugging to override an app's shader.
- */
-static GLcharARB *
-_mesa_read_shader(const char *fname)
-{
-   const int max = 50*1000;
-   FILE *f = fopen(fname, "r");
-   GLcharARB *buffer, *shader;
-   int len;
-
-   if (!f) {
-      return NULL;
-   }
-
-   buffer = (char *) malloc(max);
-   len = fread(buffer, 1, max, f);
-   buffer[len] = 0;
-
-   fclose(f);
-
-   shader = _mesa_strdup(buffer);
-   free(buffer);
-
-   return shader;
-}
-
-
-/**
- * Called via glShaderSource() and glShaderSourceARB() API functions.
- * Basically, concatenate the source code strings into one long string
- * and pass it to ctx->Driver.ShaderSource().
- */
-void GLAPIENTRY
-_mesa_ShaderSourceARB(GLhandleARB shaderObj, GLsizei count,
-                      const GLcharARB ** string, const GLint * length)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   GLint *offsets;
-   GLsizei i, totalLength;
-   GLcharARB *source;
-   GLuint checksum;
-
-   if (!shaderObj || string == NULL) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glShaderSourceARB");
-      return;
-   }
-
-   /*
-    * This array holds offsets of where the appropriate string ends, thus the
-    * last element will be set to the total length of the source code.
-    */
-   offsets = (GLint *) malloc(count * sizeof(GLint));
-   if (offsets == NULL) {
-      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB");
-      return;
-   }
-
-   for (i = 0; i < count; i++) {
-      if (string[i] == NULL) {
-         free((GLvoid *) offsets);
-         _mesa_error(ctx, GL_INVALID_OPERATION, "glShaderSourceARB(null string)");
-         return;
-      }
-      if (length == NULL || length[i] < 0)
-         offsets[i] = strlen(string[i]);
-      else
-         offsets[i] = length[i];
-      /* accumulate string lengths */
-      if (i > 0)
-         offsets[i] += offsets[i - 1];
-   }
-
-   /* Total length of source string is sum off all strings plus two.
-    * One extra byte for terminating zero, another extra byte to silence
-    * valgrind warnings in the parser/grammer code.
-    */
-   totalLength = offsets[count - 1] + 2;
-   source = (GLcharARB *) malloc(totalLength * sizeof(GLcharARB));
-   if (source == NULL) {
-      free((GLvoid *) offsets);
-      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB");
-      return;
-   }
-
-   for (i = 0; i < count; i++) {
-      GLint start = (i > 0) ? offsets[i - 1] : 0;
-      memcpy(source + start, string[i],
-             (offsets[i] - start) * sizeof(GLcharARB));
-   }
-   source[totalLength - 1] = '\0';
-   source[totalLength - 2] = '\0';
-
-   if (SHADER_SUBST) {
-      /* Compute the shader's source code checksum then try to open a file
-       * named newshader_<CHECKSUM>.  If it exists, use it in place of the
-       * original shader source code.  For debugging.
-       */
-      char filename[100];
-      GLcharARB *newSource;
-
-      checksum = _mesa_str_checksum(source);
-
-      _mesa_snprintf(filename, sizeof(filename), "newshader_%d", checksum);
-
-      newSource = _mesa_read_shader(filename);
-      if (newSource) {
-         fprintf(stderr, "Mesa: Replacing shader %u chksum=%d with %s\n",
-                       shaderObj, checksum, filename);
-         free(source);
-         source = newSource;
-      }
-   }      
-
-   ctx->Driver.ShaderSource(ctx, shaderObj, source);
-
-   if (SHADER_SUBST) {
-      struct gl_shader *sh = _mesa_lookup_shader(ctx, shaderObj);
-      if (sh)
-         sh->SourceChecksum = checksum; /* save original checksum */
-   }
-
-   free(offsets);
-}
-
-
-void GLAPIENTRY
-_mesa_Uniform1fARB(GLint location, GLfloat v0)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.Uniform(ctx, location, 1, &v0, GL_FLOAT);
-}
-
-void GLAPIENTRY
-_mesa_Uniform2fARB(GLint location, GLfloat v0, GLfloat v1)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   GLfloat v[2];
-   v[0] = v0;
-   v[1] = v1;
-   ctx->Driver.Uniform(ctx, location, 1, v, GL_FLOAT_VEC2);
-}
-
-void GLAPIENTRY
-_mesa_Uniform3fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   GLfloat v[3];
-   v[0] = v0;
-   v[1] = v1;
-   v[2] = v2;
-   ctx->Driver.Uniform(ctx, location, 1, v, GL_FLOAT_VEC3);
-}
-
-void GLAPIENTRY
-_mesa_Uniform4fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2,
-                   GLfloat v3)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   GLfloat v[4];
-   v[0] = v0;
-   v[1] = v1;
-   v[2] = v2;
-   v[3] = v3;
-   ctx->Driver.Uniform(ctx, location, 1, v, GL_FLOAT_VEC4);
-}
-
-void GLAPIENTRY
-_mesa_Uniform1iARB(GLint location, GLint v0)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.Uniform(ctx, location, 1, &v0, GL_INT);
-}
-
-void GLAPIENTRY
-_mesa_Uniform2iARB(GLint location, GLint v0, GLint v1)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   GLint v[2];
-   v[0] = v0;
-   v[1] = v1;
-   ctx->Driver.Uniform(ctx, location, 1, v, GL_INT_VEC2);
-}
-
-void GLAPIENTRY
-_mesa_Uniform3iARB(GLint location, GLint v0, GLint v1, GLint v2)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   GLint v[3];
-   v[0] = v0;
-   v[1] = v1;
-   v[2] = v2;
-   ctx->Driver.Uniform(ctx, location, 1, v, GL_INT_VEC3);
-}
-
-void GLAPIENTRY
-_mesa_Uniform4iARB(GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   GLint v[4];
-   v[0] = v0;
-   v[1] = v1;
-   v[2] = v2;
-   v[3] = v3;
-   ctx->Driver.Uniform(ctx, location, 1, v, GL_INT_VEC4);
-}
-
-void GLAPIENTRY
-_mesa_Uniform1fvARB(GLint location, GLsizei count, const GLfloat * value)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.Uniform(ctx, location, count, value, GL_FLOAT);
-}
-
-void GLAPIENTRY
-_mesa_Uniform2fvARB(GLint location, GLsizei count, const GLfloat * value)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.Uniform(ctx, location, count, value, GL_FLOAT_VEC2);
-}
-
-void GLAPIENTRY
-_mesa_Uniform3fvARB(GLint location, GLsizei count, const GLfloat * value)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.Uniform(ctx, location, count, value, GL_FLOAT_VEC3);
-}
-
-void GLAPIENTRY
-_mesa_Uniform4fvARB(GLint location, GLsizei count, const GLfloat * value)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.Uniform(ctx, location, count, value, GL_FLOAT_VEC4);
-}
-
-void GLAPIENTRY
-_mesa_Uniform1ivARB(GLint location, GLsizei count, const GLint * value)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.Uniform(ctx, location, count, value, GL_INT);
-}
-
-void GLAPIENTRY
-_mesa_Uniform2ivARB(GLint location, GLsizei count, const GLint * value)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.Uniform(ctx, location, count, value, GL_INT_VEC2);
-}
-
-void GLAPIENTRY
-_mesa_Uniform3ivARB(GLint location, GLsizei count, const GLint * value)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.Uniform(ctx, location, count, value, GL_INT_VEC3);
-}
-
-void GLAPIENTRY
-_mesa_Uniform4ivARB(GLint location, GLsizei count, const GLint * value)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.Uniform(ctx, location, count, value, GL_INT_VEC4);
-}
-
-
-/** OpenGL 3.0 GLuint-valued functions **/
-void GLAPIENTRY
-_mesa_Uniform1ui(GLint location, GLuint v0)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.Uniform(ctx, location, 1, &v0, GL_UNSIGNED_INT);
-}
-
-void GLAPIENTRY
-_mesa_Uniform2ui(GLint location, GLuint v0, GLuint v1)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   GLuint v[2];
-   v[0] = v0;
-   v[1] = v1;
-   ctx->Driver.Uniform(ctx, location, 1, v, GL_UNSIGNED_INT_VEC2);
-}
-
-void GLAPIENTRY
-_mesa_Uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   GLuint v[3];
-   v[0] = v0;
-   v[1] = v1;
-   v[2] = v2;
-   ctx->Driver.Uniform(ctx, location, 1, v, GL_UNSIGNED_INT_VEC3);
-}
-
-void GLAPIENTRY
-_mesa_Uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   GLuint v[4];
-   v[0] = v0;
-   v[1] = v1;
-   v[2] = v2;
-   v[3] = v3;
-   ctx->Driver.Uniform(ctx, location, 1, v, GL_UNSIGNED_INT_VEC4);
-}
-
-void GLAPIENTRY
-_mesa_Uniform1uiv(GLint location, GLsizei count, const GLuint *value)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.Uniform(ctx, location, count, value, GL_UNSIGNED_INT);
-}
-
-void GLAPIENTRY
-_mesa_Uniform2uiv(GLint location, GLsizei count, const GLuint *value)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.Uniform(ctx, location, count, value, GL_UNSIGNED_INT_VEC2);
-}
-
-void GLAPIENTRY
-_mesa_Uniform3uiv(GLint location, GLsizei count, const GLuint *value)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.Uniform(ctx, location, count, value, GL_UNSIGNED_INT_VEC3);
-}
-
-void GLAPIENTRY
-_mesa_Uniform4uiv(GLint location, GLsizei count, const GLuint *value)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.Uniform(ctx, location, count, value, GL_UNSIGNED_INT_VEC4);
-}
-
-
-
-void GLAPIENTRY
-_mesa_UniformMatrix2fvARB(GLint location, GLsizei count, GLboolean transpose,
-                          const GLfloat * value)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.UniformMatrix(ctx, 2, 2, location, count, transpose, value);
-}
-
-void GLAPIENTRY
-_mesa_UniformMatrix3fvARB(GLint location, GLsizei count, GLboolean transpose,
-                          const GLfloat * value)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.UniformMatrix(ctx, 3, 3, location, count, transpose, value);
-}
-
-void GLAPIENTRY
-_mesa_UniformMatrix4fvARB(GLint location, GLsizei count, GLboolean transpose,
-                          const GLfloat * value)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.UniformMatrix(ctx, 4, 4, location, count, transpose, value);
-}
-
-
-/**
- * Non-square UniformMatrix are OpenGL 2.1
- */
-void GLAPIENTRY
-_mesa_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose,
-                         const GLfloat *value)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.UniformMatrix(ctx, 2, 3, location, count, transpose, value);
-}
-
-void GLAPIENTRY
-_mesa_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose,
-                         const GLfloat *value)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.UniformMatrix(ctx, 3, 2, location, count, transpose, value);
-}
-
-void GLAPIENTRY
-_mesa_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose,
-                         const GLfloat *value)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.UniformMatrix(ctx, 2, 4, location, count, transpose, value);
-}
-
-void GLAPIENTRY
-_mesa_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose,
-                         const GLfloat *value)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.UniformMatrix(ctx, 4, 2, location, count, transpose, value);
-}
-
-void GLAPIENTRY
-_mesa_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose,
-                         const GLfloat *value)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.UniformMatrix(ctx, 3, 4, location, count, transpose, value);
-}
-
-void GLAPIENTRY
-_mesa_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose,
-                         const GLfloat *value)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.UniformMatrix(ctx, 4, 3, location, count, transpose, value);
-}
-
-
-void GLAPIENTRY
-_mesa_UseProgramObjectARB(GLhandleARB program)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   FLUSH_VERTICES(ctx, _NEW_PROGRAM);
-   ctx->Driver.UseProgram(ctx, program);
-}
-
-
-void GLAPIENTRY
-_mesa_ValidateProgramARB(GLhandleARB program)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.ValidateProgram(ctx, program);
-}
-
-#if FEATURE_ES2
-
-void GLAPIENTRY
-_mesa_GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype,
-                               GLint* range, GLint* precision)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   _mesa_error(ctx, GL_INVALID_OPERATION, __FUNCTION__);
-}
-
-
-void GLAPIENTRY
-_mesa_ReleaseShaderCompiler(void)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   _mesa_error(ctx, GL_INVALID_OPERATION, __FUNCTION__);
-}
-
-
-void GLAPIENTRY
-_mesa_ShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat,
-                   const void* binary, GLint length)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   _mesa_error(ctx, GL_INVALID_OPERATION, __FUNCTION__);
-}
-
-#endif
-
-
-/**
- * Plug in shader-related functions into API dispatch table.
- */
-void
-_mesa_init_shader_dispatch(struct _glapi_table *exec)
-{
-#if FEATURE_GL
-   /* GL_ARB_vertex/fragment_shader */
-   SET_DeleteObjectARB(exec, _mesa_DeleteObjectARB);
-   SET_GetHandleARB(exec, _mesa_GetHandleARB);
-   SET_DetachObjectARB(exec, _mesa_DetachObjectARB);
-   SET_CreateShaderObjectARB(exec, _mesa_CreateShaderObjectARB);
-   SET_ShaderSourceARB(exec, _mesa_ShaderSourceARB);
-   SET_CompileShaderARB(exec, _mesa_CompileShaderARB);
-   SET_CreateProgramObjectARB(exec, _mesa_CreateProgramObjectARB);
-   SET_AttachObjectARB(exec, _mesa_AttachObjectARB);
-   SET_LinkProgramARB(exec, _mesa_LinkProgramARB);
-   SET_UseProgramObjectARB(exec, _mesa_UseProgramObjectARB);
-   SET_ValidateProgramARB(exec, _mesa_ValidateProgramARB);
-   SET_Uniform1fARB(exec, _mesa_Uniform1fARB);
-   SET_Uniform2fARB(exec, _mesa_Uniform2fARB);
-   SET_Uniform3fARB(exec, _mesa_Uniform3fARB);
-   SET_Uniform4fARB(exec, _mesa_Uniform4fARB);
-   SET_Uniform1iARB(exec, _mesa_Uniform1iARB);
-   SET_Uniform2iARB(exec, _mesa_Uniform2iARB);
-   SET_Uniform3iARB(exec, _mesa_Uniform3iARB);
-   SET_Uniform4iARB(exec, _mesa_Uniform4iARB);
-   SET_Uniform1fvARB(exec, _mesa_Uniform1fvARB);
-   SET_Uniform2fvARB(exec, _mesa_Uniform2fvARB);
-   SET_Uniform3fvARB(exec, _mesa_Uniform3fvARB);
-   SET_Uniform4fvARB(exec, _mesa_Uniform4fvARB);
-   SET_Uniform1ivARB(exec, _mesa_Uniform1ivARB);
-   SET_Uniform2ivARB(exec, _mesa_Uniform2ivARB);
-   SET_Uniform3ivARB(exec, _mesa_Uniform3ivARB);
-   SET_Uniform4ivARB(exec, _mesa_Uniform4ivARB);
-   SET_UniformMatrix2fvARB(exec, _mesa_UniformMatrix2fvARB);
-   SET_UniformMatrix3fvARB(exec, _mesa_UniformMatrix3fvARB);
-   SET_UniformMatrix4fvARB(exec, _mesa_UniformMatrix4fvARB);
-   SET_GetObjectParameterfvARB(exec, _mesa_GetObjectParameterfvARB);
-   SET_GetObjectParameterivARB(exec, _mesa_GetObjectParameterivARB);
-   SET_GetInfoLogARB(exec, _mesa_GetInfoLogARB);
-   SET_GetAttachedObjectsARB(exec, _mesa_GetAttachedObjectsARB);
-   SET_GetUniformLocationARB(exec, _mesa_GetUniformLocationARB);
-   SET_GetActiveUniformARB(exec, _mesa_GetActiveUniformARB);
-   SET_GetUniformfvARB(exec, _mesa_GetUniformfvARB);
-   SET_GetUniformivARB(exec, _mesa_GetUniformivARB);
-   SET_GetShaderSourceARB(exec, _mesa_GetShaderSourceARB);
-
-   /* OpenGL 2.0 */
-   SET_AttachShader(exec, _mesa_AttachShader);
-   SET_CreateProgram(exec, _mesa_CreateProgram);
-   SET_CreateShader(exec, _mesa_CreateShader);
-   SET_DeleteProgram(exec, _mesa_DeleteProgram);
-   SET_DeleteShader(exec, _mesa_DeleteShader);
-   SET_DetachShader(exec, _mesa_DetachShader);
-   SET_GetAttachedShaders(exec, _mesa_GetAttachedShaders);
-   SET_GetProgramiv(exec, _mesa_GetProgramiv);
-   SET_GetProgramInfoLog(exec, _mesa_GetProgramInfoLog);
-   SET_GetShaderiv(exec, _mesa_GetShaderiv);
-   SET_GetShaderInfoLog(exec, _mesa_GetShaderInfoLog);
-   SET_IsProgram(exec, _mesa_IsProgram);
-   SET_IsShader(exec, _mesa_IsShader);
-
-   /* OpenGL 2.1 */
-   SET_UniformMatrix2x3fv(exec, _mesa_UniformMatrix2x3fv);
-   SET_UniformMatrix3x2fv(exec, _mesa_UniformMatrix3x2fv);
-   SET_UniformMatrix2x4fv(exec, _mesa_UniformMatrix2x4fv);
-   SET_UniformMatrix4x2fv(exec, _mesa_UniformMatrix4x2fv);
-   SET_UniformMatrix3x4fv(exec, _mesa_UniformMatrix3x4fv);
-   SET_UniformMatrix4x3fv(exec, _mesa_UniformMatrix4x3fv);
-
-#if FEATURE_ARB_vertex_shader
-   SET_BindAttribLocationARB(exec, _mesa_BindAttribLocationARB);
-   SET_GetActiveAttribARB(exec, _mesa_GetActiveAttribARB);
-   SET_GetAttribLocationARB(exec, _mesa_GetAttribLocationARB);
-#endif
-
-   /* 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;
-#endif /* FEATURE_GL */
-}
diff --git a/src/mesa/main/shaders.h b/src/mesa/main/shaders.h
deleted file mode 100644 (file)
index af65b2d..0000000
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.5.3
- *
- * Copyright (C) 2004-2007  Brian Paul   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-
-#ifndef SHADERS_H
-#define SHADERS_H
-
-
-#include "glheader.h"
-#include "mtypes.h"
-
-extern void
-_mesa_init_shader_dispatch(struct _glapi_table *exec);
-
-extern void GLAPIENTRY
-_mesa_DeleteObjectARB(GLhandleARB obj);
-
-extern GLhandleARB GLAPIENTRY
-_mesa_GetHandleARB(GLenum pname);
-
-extern void GLAPIENTRY
-_mesa_DetachObjectARB (GLhandleARB, GLhandleARB);
-
-extern GLhandleARB GLAPIENTRY
-_mesa_CreateShaderObjectARB (GLenum);
-
-extern void GLAPIENTRY
-_mesa_ShaderSourceARB (GLhandleARB, GLsizei, const GLcharARB* *, const GLint *);
-
-extern void  GLAPIENTRY
-_mesa_CompileShaderARB (GLhandleARB);
-
-extern GLhandleARB GLAPIENTRY
-_mesa_CreateProgramObjectARB (void);
-
-extern void GLAPIENTRY
-_mesa_AttachObjectARB (GLhandleARB, GLhandleARB);
-
-extern void GLAPIENTRY
-_mesa_LinkProgramARB (GLhandleARB);
-
-extern void GLAPIENTRY
-_mesa_UseProgramObjectARB (GLhandleARB);
-
-extern void GLAPIENTRY
-_mesa_ValidateProgramARB (GLhandleARB);
-
-extern void GLAPIENTRY
-_mesa_Uniform1fARB (GLint, GLfloat);
-
-extern void GLAPIENTRY
-_mesa_Uniform2fARB (GLint, GLfloat, GLfloat);
-
-extern void GLAPIENTRY
-_mesa_Uniform3fARB (GLint, GLfloat, GLfloat, GLfloat);
-
-extern void GLAPIENTRY
-_mesa_Uniform4fARB (GLint, GLfloat, GLfloat, GLfloat, GLfloat);
-
-extern void GLAPIENTRY
-_mesa_Uniform1iARB (GLint, GLint);
-
-extern void GLAPIENTRY
-_mesa_Uniform2iARB (GLint, GLint, GLint);
-
-extern void GLAPIENTRY
-_mesa_Uniform3iARB (GLint, GLint, GLint, GLint);
-
-extern void GLAPIENTRY
-_mesa_Uniform4iARB (GLint, GLint, GLint, GLint, GLint);
-
-extern void GLAPIENTRY
-_mesa_Uniform1fvARB (GLint, GLsizei, const GLfloat *);
-
-extern void GLAPIENTRY
-_mesa_Uniform2fvARB (GLint, GLsizei, const GLfloat *);
-
-extern void GLAPIENTRY
-_mesa_Uniform3fvARB (GLint, GLsizei, const GLfloat *);
-
-extern void GLAPIENTRY
-_mesa_Uniform4fvARB (GLint, GLsizei, const GLfloat *);
-
-extern void GLAPIENTRY
-_mesa_Uniform1ivARB (GLint, GLsizei, const GLint *);
-
-extern void GLAPIENTRY
-_mesa_Uniform2ivARB (GLint, GLsizei, const GLint *);
-
-extern void GLAPIENTRY
-_mesa_Uniform3ivARB (GLint, GLsizei, const GLint *);
-
-extern void GLAPIENTRY
-_mesa_Uniform4ivARB (GLint, GLsizei, const GLint *);
-
-extern void GLAPIENTRY
-_mesa_Uniform1ui(GLint location, GLuint v0);
-
-extern void GLAPIENTRY
-_mesa_Uniform2ui(GLint location, GLuint v0, GLuint v1);
-
-extern void GLAPIENTRY
-_mesa_Uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2);
-
-extern void GLAPIENTRY
-_mesa_Uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
-
-extern void GLAPIENTRY
-_mesa_Uniform1uiv(GLint location, GLsizei count, const GLuint *value);
-
-extern void GLAPIENTRY
-_mesa_Uniform2uiv(GLint location, GLsizei count, const GLuint *value);
-
-extern void GLAPIENTRY
-_mesa_Uniform3uiv(GLint location, GLsizei count, const GLuint *value);
-
-extern void GLAPIENTRY
-_mesa_Uniform4uiv(GLint location, GLsizei count, const GLuint *value);
-
-
-extern void GLAPIENTRY
-_mesa_UniformMatrix2fvARB (GLint, GLsizei, GLboolean, const GLfloat *);
-
-extern void GLAPIENTRY
-_mesa_UniformMatrix3fvARB (GLint, GLsizei, GLboolean, const GLfloat *);
-
-extern void GLAPIENTRY
-_mesa_UniformMatrix4fvARB (GLint, GLsizei, GLboolean, const GLfloat *);
-
-extern void GLAPIENTRY
-_mesa_GetObjectParameterfvARB (GLhandleARB, GLenum, GLfloat *);
-
-extern void GLAPIENTRY
-_mesa_GetObjectParameterivARB (GLhandleARB, GLenum, GLint *);
-
-extern void GLAPIENTRY
-_mesa_GetInfoLogARB (GLhandleARB, GLsizei, GLsizei *, GLcharARB *);
-
-extern void GLAPIENTRY
-_mesa_GetAttachedObjectsARB (GLhandleARB, GLsizei, GLsizei *, GLhandleARB *);
-
-extern GLint GLAPIENTRY
-_mesa_GetUniformLocationARB (GLhandleARB, const GLcharARB *);
-
-extern void GLAPIENTRY
-_mesa_GetActiveUniformARB (GLhandleARB, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLcharARB *);
-
-extern void GLAPIENTRY
-_mesa_GetUniformfvARB (GLhandleARB, GLint, GLfloat *);
-
-extern void GLAPIENTRY
-_mesa_GetUniformivARB (GLhandleARB, GLint, GLint *);
-
-extern void GLAPIENTRY
-_mesa_GetShaderSourceARB (GLhandleARB, GLsizei, GLsizei *, GLcharARB *);
-
-#if FEATURE_ARB_vertex_shader
-
-extern void GLAPIENTRY
-_mesa_BindAttribLocationARB (GLhandleARB, GLuint, const GLcharARB *);
-
-extern void GLAPIENTRY
-_mesa_GetActiveAttribARB (GLhandleARB, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLcharARB *);
-
-extern GLint GLAPIENTRY
-_mesa_GetAttribLocationARB (GLhandleARB, const GLcharARB *);
-
-#endif /* FEATURE_ARB_vertex_shader */
-
-
-/* 2.0 */
-extern void GLAPIENTRY
-_mesa_AttachShader(GLuint program, GLuint shader);
-
-extern GLuint GLAPIENTRY
-_mesa_CreateShader(GLenum);
-
-extern GLuint GLAPIENTRY
-_mesa_CreateProgram(void);
-
-extern void GLAPIENTRY
-_mesa_DeleteProgram(GLuint program);
-
-extern void GLAPIENTRY
-_mesa_DeleteShader(GLuint shader);
-
-extern void GLAPIENTRY
-_mesa_DetachShader(GLuint program, GLuint shader);
-
-extern void GLAPIENTRY
-_mesa_GetAttachedShaders(GLuint program, GLsizei maxCount,
-                         GLsizei *count, GLuint *obj);
-
-extern void GLAPIENTRY
-_mesa_GetProgramiv(GLuint program, GLenum pname, GLint *params);
-
-extern void GLAPIENTRY
-_mesa_GetProgramInfoLog(GLuint program, GLsizei bufSize,
-                        GLsizei *length, GLchar *infoLog);
-
-extern void GLAPIENTRY
-_mesa_GetShaderiv(GLuint shader, GLenum pname, GLint *params);
-
-extern void GLAPIENTRY
-_mesa_GetShaderInfoLog(GLuint shader, GLsizei bufSize,
-                       GLsizei *length, GLchar *infoLog);
-
-extern GLboolean GLAPIENTRY
-_mesa_IsProgram(GLuint program);
-
-extern GLboolean GLAPIENTRY
-_mesa_IsShader(GLuint shader);
-
-
-
-/* 2.1 */
-extern void GLAPIENTRY
-_mesa_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose,
-                         const GLfloat *value);
-
-extern void GLAPIENTRY
-_mesa_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose,
-                         const GLfloat *value);
-
-extern void GLAPIENTRY
-_mesa_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose,
-                         const GLfloat *value);
-
-extern void GLAPIENTRY
-_mesa_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose,
-                         const GLfloat *value);
-
-extern void GLAPIENTRY
-_mesa_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose,
-                         const GLfloat *value);
-
-extern void GLAPIENTRY
-_mesa_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose,
-                         const GLfloat *value);
-
-/* GLES 2.0 */
-extern void GLAPIENTRY
-_mesa_GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype,
-                               GLint* range, GLint* precision);
-
-extern void GLAPIENTRY
-_mesa_ReleaseShaderCompiler(void);
-
-extern void GLAPIENTRY
-_mesa_ShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat,
-                   const void* binary, GLint length);
-
-#endif /* SHADERS_H */
index e364e24048ff97a83c53fd07f3f9e1a82d7a4fc0..b327faec36af6b61b2080fcf61983dfdbd8aedc6 100644 (file)
 #include "bufferobj.h"
 #include "shared.h"
 #include "shader/program.h"
-#include "shader/shader_api.h"
 #include "dlist.h"
 #if FEATURE_ATI_fragment_shader
 #include "shader/atifragshader.h"
 #endif
+#include "shaderobj.h"
 #if FEATURE_ARB_sync
 #include "syncobj.h"
 #endif
@@ -228,12 +228,12 @@ delete_shader_cb(GLuint id, void *data, void *userData)
    GLcontext *ctx = (GLcontext *) userData;
    struct gl_shader *sh = (struct gl_shader *) data;
    if (sh->Type == GL_FRAGMENT_SHADER || sh->Type == GL_VERTEX_SHADER) {
-      _mesa_free_shader(ctx, sh);
+      ctx->Driver.DeleteShader(ctx, sh);
    }
    else {
       struct gl_shader_program *shProg = (struct gl_shader_program *) data;
       ASSERT(shProg->Type == GL_SHADER_PROGRAM_MESA);
-      _mesa_free_shader_program(ctx, shProg);
+      ctx->Driver.DeleteShaderProgram(ctx, shProg);
    }
 }
 
index 050ebf02701684d58056c6fbae0f03a80340e83c..68a14d47c8e0c7188528970938835a9e95e9963d 100644 (file)
 #include "context.h"
 #include "hash.h"
 #include "transformfeedback.h"
+#include "shaderapi.h"
+#include "shaderobj.h"
 #include "main/dispatch.h"
 
 #include "shader/prog_parameter.h"
-#include "shader/shader_api.h"
+//#include "shader/shader_api.h"
 
 
 #if FEATURE_EXT_transform_feedback
diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c
deleted file mode 100644 (file)
index c414e89..0000000
+++ /dev/null
@@ -1,1424 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  7.6
- *
- * Copyright (C) 2004-2008  Brian Paul   All Rights Reserved.
- * Copyright (C) 2009  VMware, Inc.  All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/**
- * \file shader_api.c
- * Implementation of GLSL-related API functions
- * \author Brian Paul
- */
-
-/**
- * XXX things to do:
- * 1. Check that the right error code is generated for all _mesa_error() calls.
- * 2. Insert FLUSH_VERTICES calls in various places
- */
-
-
-#include "main/glheader.h"
-#include "main/context.h"
-#include "main/hash.h"
-#include "shader/program.h"
-#include "shader/prog_parameter.h"
-#include "shader/prog_uniform.h"
-#include "shader/shader_api.h"
-#include "shader/uniforms.h"
-#include "shader/slang/slang_compile.h"
-#include "shader/slang/slang_link.h"
-
-
-/**
- * Allocate a new gl_shader_program object, initialize it.
- */
-static struct gl_shader_program *
-_mesa_new_shader_program(GLcontext *ctx, GLuint name)
-{
-   struct gl_shader_program *shProg;
-   shProg = CALLOC_STRUCT(gl_shader_program);
-   if (shProg) {
-      shProg->Type = GL_SHADER_PROGRAM_MESA;
-      shProg->Name = name;
-      shProg->RefCount = 1;
-      shProg->Attributes = _mesa_new_parameter_list();
-   }
-   return shProg;
-}
-
-
-/**
- * Clear (free) the shader program state that gets produced by linking.
- */
-void
-_mesa_clear_shader_program_data(GLcontext *ctx,
-                                struct gl_shader_program *shProg)
-{
-   _mesa_reference_vertprog(ctx, &shProg->VertexProgram, NULL);
-   _mesa_reference_fragprog(ctx, &shProg->FragmentProgram, NULL);
-
-   if (shProg->Uniforms) {
-      _mesa_free_uniform_list(shProg->Uniforms);
-      shProg->Uniforms = NULL;
-   }
-
-   if (shProg->Varying) {
-      _mesa_free_parameter_list(shProg->Varying);
-      shProg->Varying = NULL;
-   }
-}
-
-
-/**
- * Free all the data that hangs off a shader program object, but not the
- * object itself.
- */
-void
-_mesa_free_shader_program_data(GLcontext *ctx,
-                               struct gl_shader_program *shProg)
-{
-   GLuint i;
-
-   assert(shProg->Type == GL_SHADER_PROGRAM_MESA);
-
-   _mesa_clear_shader_program_data(ctx, shProg);
-
-   if (shProg->Attributes) {
-      _mesa_free_parameter_list(shProg->Attributes);
-      shProg->Attributes = NULL;
-   }
-
-   /* detach shaders */
-   for (i = 0; i < shProg->NumShaders; i++) {
-      _mesa_reference_shader(ctx, &shProg->Shaders[i], NULL);
-   }
-   shProg->NumShaders = 0;
-
-   if (shProg->Shaders) {
-      free(shProg->Shaders);
-      shProg->Shaders = NULL;
-   }
-
-   if (shProg->InfoLog) {
-      free(shProg->InfoLog);
-      shProg->InfoLog = NULL;
-   }
-
-   /* Transform feedback varying vars */
-   for (i = 0; i < shProg->TransformFeedback.NumVarying; i++) {
-      free(shProg->TransformFeedback.VaryingNames[i]);
-   }
-   free(shProg->TransformFeedback.VaryingNames);
-   shProg->TransformFeedback.VaryingNames = NULL;
-   shProg->TransformFeedback.NumVarying = 0;
-}
-
-
-/**
- * Free/delete a shader program object.
- */
-void
-_mesa_free_shader_program(GLcontext *ctx, struct gl_shader_program *shProg)
-{
-   _mesa_free_shader_program_data(ctx, shProg);
-
-   free(shProg);
-}
-
-
-/**
- * Set ptr to point to shProg.
- * If ptr is pointing to another object, decrement its refcount (and delete
- * if refcount hits zero).
- * Then set ptr to point to shProg, incrementing its refcount.
- */
-/* XXX this could be static */
-void
-_mesa_reference_shader_program(GLcontext *ctx,
-                               struct gl_shader_program **ptr,
-                               struct gl_shader_program *shProg)
-{
-   assert(ptr);
-   if (*ptr == shProg) {
-      /* no-op */
-      return;
-   }
-   if (*ptr) {
-      /* Unreference the old shader program */
-      GLboolean deleteFlag = GL_FALSE;
-      struct gl_shader_program *old = *ptr;
-
-      ASSERT(old->RefCount > 0);
-      old->RefCount--;
-#if 0
-      printf("ShaderProgram %p ID=%u  RefCount-- to %d\n",
-             (void *) old, old->Name, old->RefCount);
-#endif
-      deleteFlag = (old->RefCount == 0);
-
-      if (deleteFlag) {
-         _mesa_HashRemove(ctx->Shared->ShaderObjects, old->Name);
-         _mesa_free_shader_program(ctx, old);
-      }
-
-      *ptr = NULL;
-   }
-   assert(!*ptr);
-
-   if (shProg) {
-      shProg->RefCount++;
-#if 0
-      printf("ShaderProgram %p ID=%u  RefCount++ to %d\n",
-             (void *) shProg, shProg->Name, shProg->RefCount);
-#endif
-      *ptr = shProg;
-   }
-}
-
-
-/**
- * Lookup a GLSL program object.
- */
-struct gl_shader_program *
-_mesa_lookup_shader_program(GLcontext *ctx, GLuint name)
-{
-   struct gl_shader_program *shProg;
-   if (name) {
-      shProg = (struct gl_shader_program *)
-         _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
-      /* Note that both gl_shader and gl_shader_program objects are kept
-       * in the same hash table.  Check the object's type to be sure it's
-       * what we're expecting.
-       */
-      if (shProg && shProg->Type != GL_SHADER_PROGRAM_MESA) {
-         return NULL;
-      }
-      return shProg;
-   }
-   return NULL;
-}
-
-
-/**
- * As above, but record an error if program is not found.
- */
-struct gl_shader_program *
-_mesa_lookup_shader_program_err(GLcontext *ctx, GLuint name,
-                                const char *caller)
-{
-   if (!name) {
-      _mesa_error(ctx, GL_INVALID_VALUE, caller);
-      return NULL;
-   }
-   else {
-      struct gl_shader_program *shProg = (struct gl_shader_program *)
-         _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
-      if (!shProg) {
-         _mesa_error(ctx, GL_INVALID_VALUE, caller);
-         return NULL;
-      }
-      if (shProg->Type != GL_SHADER_PROGRAM_MESA) {
-         _mesa_error(ctx, GL_INVALID_OPERATION, caller);
-         return NULL;
-      }
-      return shProg;
-   }
-}
-
-
-
-
-/**
- * Allocate a new gl_shader object, initialize it.
- */
-struct gl_shader *
-_mesa_new_shader(GLcontext *ctx, GLuint name, GLenum type)
-{
-   struct gl_shader *shader;
-   assert(type == GL_FRAGMENT_SHADER || type == GL_VERTEX_SHADER);
-   shader = CALLOC_STRUCT(gl_shader);
-   if (shader) {
-      shader->Type = type;
-      shader->Name = name;
-      shader->RefCount = 1;
-   }
-   return shader;
-}
-
-
-void
-_mesa_free_shader(GLcontext *ctx, struct gl_shader *sh)
-{
-   if (sh->Source)
-      free((void *) sh->Source);
-   if (sh->InfoLog)
-      free(sh->InfoLog);
-   _mesa_reference_program(ctx, &sh->Program, NULL);
-   free(sh);
-}
-
-
-/**
- * Set ptr to point to sh.
- * If ptr is pointing to another shader, decrement its refcount (and delete
- * if refcount hits zero).
- * Then set ptr to point to sh, incrementing its refcount.
- */
-/* XXX this could be static */
-void
-_mesa_reference_shader(GLcontext *ctx, struct gl_shader **ptr,
-                       struct gl_shader *sh)
-{
-   assert(ptr);
-   if (*ptr == sh) {
-      /* no-op */
-      return;
-   }
-   if (*ptr) {
-      /* Unreference the old shader */
-      GLboolean deleteFlag = GL_FALSE;
-      struct gl_shader *old = *ptr;
-
-      ASSERT(old->RefCount > 0);
-      old->RefCount--;
-      /*printf("SHADER DECR %p (%d) to %d\n",
-        (void*) old, old->Name, old->RefCount);*/
-      deleteFlag = (old->RefCount == 0);
-
-      if (deleteFlag) {
-         _mesa_HashRemove(ctx->Shared->ShaderObjects, old->Name);
-         _mesa_free_shader(ctx, old);
-      }
-
-      *ptr = NULL;
-   }
-   assert(!*ptr);
-
-   if (sh) {
-      /* reference new */
-      sh->RefCount++;
-      /*printf("SHADER INCR %p (%d) to %d\n",
-        (void*) sh, sh->Name, sh->RefCount);*/
-      *ptr = sh;
-   }
-}
-
-
-/**
- * Lookup a GLSL shader object.
- */
-struct gl_shader *
-_mesa_lookup_shader(GLcontext *ctx, GLuint name)
-{
-   if (name) {
-      struct gl_shader *sh = (struct gl_shader *)
-         _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
-      /* Note that both gl_shader and gl_shader_program objects are kept
-       * in the same hash table.  Check the object's type to be sure it's
-       * what we're expecting.
-       */
-      if (sh && sh->Type == GL_SHADER_PROGRAM_MESA) {
-         return NULL;
-      }
-      return sh;
-   }
-   return NULL;
-}
-
-
-/**
- * As above, but record an error if shader is not found.
- */
-static struct gl_shader *
-_mesa_lookup_shader_err(GLcontext *ctx, GLuint name, const char *caller)
-{
-   if (!name) {
-      _mesa_error(ctx, GL_INVALID_VALUE, caller);
-      return NULL;
-   }
-   else {
-      struct gl_shader *sh = (struct gl_shader *)
-         _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
-      if (!sh) {
-         _mesa_error(ctx, GL_INVALID_VALUE, caller);
-         return NULL;
-      }
-      if (sh->Type == GL_SHADER_PROGRAM_MESA) {
-         _mesa_error(ctx, GL_INVALID_OPERATION, caller);
-         return NULL;
-      }
-      return sh;
-   }
-}
-
-
-/**
- * Return mask of GLSL_x flags by examining the MESA_GLSL env var.
- */
-static GLbitfield
-get_shader_flags(void)
-{
-   GLbitfield flags = 0x0;
-   const char *env = _mesa_getenv("MESA_GLSL");
-
-   if (env) {
-      if (strstr(env, "dump"))
-         flags |= GLSL_DUMP;
-      if (strstr(env, "log"))
-         flags |= GLSL_LOG;
-      if (strstr(env, "nopvert"))
-         flags |= GLSL_NOP_VERT;
-      if (strstr(env, "nopfrag"))
-         flags |= GLSL_NOP_FRAG;
-      if (strstr(env, "nopt"))
-         flags |= GLSL_NO_OPT;
-      else if (strstr(env, "opt"))
-         flags |= GLSL_OPT;
-      if (strstr(env, "uniform"))
-         flags |= GLSL_UNIFORMS;
-      if (strstr(env, "useprog"))
-         flags |= GLSL_USE_PROG;
-   }
-
-   return flags;
-}
-
-
-/**
- * Find the length of the longest transform feedback varying name
- * which was specified with glTransformFeedbackVaryings().
- */
-static GLint
-longest_feedback_varying_name(const struct gl_shader_program *shProg)
-{
-   GLuint i;
-   GLint max = 0;
-   for (i = 0; i < shProg->TransformFeedback.NumVarying; i++) {
-      GLint len = strlen(shProg->TransformFeedback.VaryingNames[i]);
-      if (len > max)
-         max = len;
-   }
-   return max;
-}
-
-
-
-/**
- * Initialize context's shader state.
- */
-void
-_mesa_init_shader_state(GLcontext * ctx)
-{
-   /* Device drivers may override these to control what kind of instructions
-    * are generated by the GLSL compiler.
-    */
-   ctx->Shader.EmitHighLevelInstructions = GL_TRUE;
-   ctx->Shader.EmitContReturn = GL_TRUE;
-   ctx->Shader.EmitCondCodes = GL_FALSE;
-   ctx->Shader.EmitComments = GL_FALSE;
-   ctx->Shader.Flags = get_shader_flags();
-
-   /* Default pragma settings */
-   ctx->Shader.DefaultPragmas.IgnoreOptimize = GL_FALSE;
-   ctx->Shader.DefaultPragmas.IgnoreDebug = GL_FALSE;
-   ctx->Shader.DefaultPragmas.Optimize = GL_TRUE;
-   ctx->Shader.DefaultPragmas.Debug = GL_FALSE;
-}
-
-
-/**
- * Free the per-context shader-related state.
- */
-void
-_mesa_free_shader_state(GLcontext *ctx)
-{
-   _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentProgram, NULL);
-}
-
-
-/**
- * Copy string from <src> to <dst>, up to maxLength characters, returning
- * length of <dst> in <length>.
- * \param src  the strings source
- * \param maxLength  max chars to copy
- * \param length  returns number of chars copied
- * \param dst  the string destination
- */
-void
-_mesa_copy_string(GLchar *dst, GLsizei maxLength,
-                  GLsizei *length, const GLchar *src)
-{
-   GLsizei len;
-   for (len = 0; len < maxLength - 1 && src && src[len]; len++)
-      dst[len] = src[len];
-   if (maxLength > 0)
-      dst[len] = 0;
-   if (length)
-      *length = len;
-}
-
-
-static GLboolean
-_mesa_is_program(GLcontext *ctx, GLuint name)
-{
-   struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, name);
-   return shProg ? GL_TRUE : GL_FALSE;
-}
-
-
-static GLboolean
-_mesa_is_shader(GLcontext *ctx, GLuint name)
-{
-   struct gl_shader *shader = _mesa_lookup_shader(ctx, name);
-   return shader ? GL_TRUE : GL_FALSE;
-}
-
-
-/**
- * Called via ctx->Driver.AttachShader()
- */
-static void
-_mesa_attach_shader(GLcontext *ctx, GLuint program, GLuint shader)
-{
-   struct gl_shader_program *shProg;
-   struct gl_shader *sh;
-   GLuint i, n;
-
-   shProg = _mesa_lookup_shader_program_err(ctx, program, "glAttachShader");
-   if (!shProg)
-      return;
-
-   sh = _mesa_lookup_shader_err(ctx, shader, "glAttachShader");
-   if (!sh) {
-      return;
-   }
-
-   n = shProg->NumShaders;
-   for (i = 0; i < n; i++) {
-      if (shProg->Shaders[i] == sh) {
-         /* The shader is already attched to this program.  The
-          * GL_ARB_shader_objects spec says:
-          *
-          *     "The error INVALID_OPERATION is generated by AttachObjectARB
-          *     if <obj> is already attached to <containerObj>."
-          */
-         _mesa_error(ctx, GL_INVALID_OPERATION, "glAttachShader");
-         return;
-      }
-   }
-
-   /* grow list */
-   shProg->Shaders = (struct gl_shader **)
-      _mesa_realloc(shProg->Shaders,
-                    n * sizeof(struct gl_shader *),
-                    (n + 1) * sizeof(struct gl_shader *));
-   if (!shProg->Shaders) {
-      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAttachShader");
-      return;
-   }
-
-   /* append */
-   shProg->Shaders[n] = NULL; /* since realloc() didn't zero the new space */
-   _mesa_reference_shader(ctx, &shProg->Shaders[n], sh);
-   shProg->NumShaders++;
-}
-
-
-static GLint
-_mesa_get_attrib_location(GLcontext *ctx, GLuint program,
-                          const GLchar *name)
-{
-   struct gl_shader_program *shProg
-      = _mesa_lookup_shader_program_err(ctx, program, "glGetAttribLocation");
-
-   if (!shProg) {
-      return -1;
-   }
-
-   if (!shProg->LinkStatus) {
-      _mesa_error(ctx, GL_INVALID_OPERATION,
-                  "glGetAttribLocation(program not linked)");
-      return -1;
-   }
-
-   if (!name)
-      return -1;
-
-   if (shProg->VertexProgram) {
-      const struct gl_program_parameter_list *attribs =
-         shProg->VertexProgram->Base.Attributes;
-      if (attribs) {
-         GLint i = _mesa_lookup_parameter_index(attribs, -1, name);
-         if (i >= 0) {
-            return attribs->Parameters[i].StateIndexes[0];
-         }
-      }
-   }
-   return -1;
-}
-
-
-static void
-_mesa_bind_attrib_location(GLcontext *ctx, GLuint program, GLuint index,
-                           const GLchar *name)
-{
-   struct gl_shader_program *shProg;
-   const GLint size = -1; /* unknown size */
-   GLint i, oldIndex;
-   GLenum datatype = GL_FLOAT_VEC4;
-
-   shProg = _mesa_lookup_shader_program_err(ctx, program,
-                                            "glBindAttribLocation");
-   if (!shProg) {
-      return;
-   }
-
-   if (!name)
-      return;
-
-   if (strncmp(name, "gl_", 3) == 0) {
-      _mesa_error(ctx, GL_INVALID_OPERATION,
-                  "glBindAttribLocation(illegal name)");
-      return;
-   }
-
-   if (index >= ctx->Const.VertexProgram.MaxAttribs) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glBindAttribLocation(index)");
-      return;
-   }
-
-   if (shProg->LinkStatus) {
-      /* get current index/location for the attribute */
-      oldIndex = _mesa_get_attrib_location(ctx, program, name);
-   }
-   else {
-      oldIndex = -1;
-   }
-
-   /* this will replace the current value if it's already in the list */
-   i = _mesa_add_attribute(shProg->Attributes, name, size, datatype, index);
-   if (i < 0) {
-      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindAttribLocation");
-      return;
-   }
-
-   /*
-    * Note that this attribute binding won't go into effect until
-    * glLinkProgram is called again.
-    */
-}
-
-
-static GLuint
-_mesa_create_shader(GLcontext *ctx, GLenum type)
-{
-   struct gl_shader *sh;
-   GLuint name;
-
-   name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);
-
-   switch (type) {
-   case GL_FRAGMENT_SHADER:
-   case GL_VERTEX_SHADER:
-      sh = _mesa_new_shader(ctx, name, type);
-      break;
-   default:
-      _mesa_error(ctx, GL_INVALID_ENUM, "CreateShader(type)");
-      return 0;
-   }
-
-   _mesa_HashInsert(ctx->Shared->ShaderObjects, name, sh);
-
-   return name;
-}
-
-
-static GLuint 
-_mesa_create_program(GLcontext *ctx)
-{
-   GLuint name;
-   struct gl_shader_program *shProg;
-
-   name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);
-   shProg = _mesa_new_shader_program(ctx, name);
-
-   _mesa_HashInsert(ctx->Shared->ShaderObjects, name, shProg);
-
-   assert(shProg->RefCount == 1);
-
-   return name;
-}
-
-
-/**
- * Named w/ "2" to indicate OpenGL 2.x vs GL_ARB_fragment_programs's
- * DeleteProgramARB.
- */
-static void
-_mesa_delete_program2(GLcontext *ctx, GLuint name)
-{
-   /*
-    * NOTE: deleting shaders/programs works a bit differently than
-    * texture objects (and buffer objects, etc).  Shader/program
-    * handles/IDs exist in the hash table until the object is really
-    * deleted (refcount==0).  With texture objects, the handle/ID is
-    * removed from the hash table in glDeleteTextures() while the tex
-    * object itself might linger until its refcount goes to zero.
-    */
-   struct gl_shader_program *shProg;
-
-   shProg = _mesa_lookup_shader_program_err(ctx, name, "glDeleteProgram");
-   if (!shProg)
-      return;
-
-   shProg->DeletePending = GL_TRUE;
-
-   /* effectively, decr shProg's refcount */
-   _mesa_reference_shader_program(ctx, &shProg, NULL);
-}
-
-
-static void
-_mesa_delete_shader(GLcontext *ctx, GLuint shader)
-{
-   struct gl_shader *sh;
-
-   sh = _mesa_lookup_shader_err(ctx, shader, "glDeleteShader");
-   if (!sh)
-      return;
-
-   sh->DeletePending = GL_TRUE;
-
-   /* effectively, decr sh's refcount */
-   _mesa_reference_shader(ctx, &sh, NULL);
-}
-
-
-static void
-_mesa_detach_shader(GLcontext *ctx, GLuint program, GLuint shader)
-{
-   struct gl_shader_program *shProg;
-   GLuint n;
-   GLuint i, j;
-
-   shProg = _mesa_lookup_shader_program_err(ctx, program, "glDetachShader");
-   if (!shProg)
-      return;
-
-   n = shProg->NumShaders;
-
-   for (i = 0; i < n; i++) {
-      if (shProg->Shaders[i]->Name == shader) {
-         /* found it */
-         struct gl_shader **newList;
-
-         /* release */
-         _mesa_reference_shader(ctx, &shProg->Shaders[i], NULL);
-
-         /* alloc new, smaller array */
-         newList = (struct gl_shader **)
-            malloc((n - 1) * sizeof(struct gl_shader *));
-         if (!newList) {
-            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDetachShader");
-            return;
-         }
-         for (j = 0; j < i; j++) {
-            newList[j] = shProg->Shaders[j];
-         }
-         while (++i < n)
-            newList[j++] = shProg->Shaders[i];
-         free(shProg->Shaders);
-
-         shProg->Shaders = newList;
-         shProg->NumShaders = n - 1;
-
-#ifdef DEBUG
-         /* sanity check */
-         {
-            for (j = 0; j < shProg->NumShaders; j++) {
-               assert(shProg->Shaders[j]->Type == GL_VERTEX_SHADER ||
-                      shProg->Shaders[j]->Type == GL_FRAGMENT_SHADER);
-               assert(shProg->Shaders[j]->RefCount > 0);
-            }
-         }
-#endif
-
-         return;
-      }
-   }
-
-   /* not found */
-   {
-      GLenum err;
-      if (_mesa_is_shader(ctx, shader))
-         err = GL_INVALID_OPERATION;
-      else if (_mesa_is_program(ctx, shader))
-         err = GL_INVALID_OPERATION;
-      else
-         err = GL_INVALID_VALUE;
-      _mesa_error(ctx, err, "glDetachProgram(shader)");
-      return;
-   }
-}
-
-
-/**
- * Return the size of the given GLSL datatype, in floats (components).
- */
-GLint
-_mesa_sizeof_glsl_type(GLenum type)
-{
-   switch (type) {
-   case GL_FLOAT:
-   case GL_INT:
-   case GL_BOOL:
-   case GL_SAMPLER_1D:
-   case GL_SAMPLER_2D:
-   case GL_SAMPLER_3D:
-   case GL_SAMPLER_CUBE:
-   case GL_SAMPLER_1D_SHADOW:
-   case GL_SAMPLER_2D_SHADOW:
-   case GL_SAMPLER_2D_RECT_ARB:
-   case GL_SAMPLER_2D_RECT_SHADOW_ARB:
-   case GL_SAMPLER_1D_ARRAY_EXT:
-   case GL_SAMPLER_2D_ARRAY_EXT:
-   case GL_SAMPLER_1D_ARRAY_SHADOW_EXT:
-   case GL_SAMPLER_2D_ARRAY_SHADOW_EXT:
-   case GL_SAMPLER_CUBE_SHADOW_EXT:
-      return 1;
-   case GL_FLOAT_VEC2:
-   case GL_INT_VEC2:
-   case GL_UNSIGNED_INT_VEC2:
-   case GL_BOOL_VEC2:
-      return 2;
-   case GL_FLOAT_VEC3:
-   case GL_INT_VEC3:
-   case GL_UNSIGNED_INT_VEC3:
-   case GL_BOOL_VEC3:
-      return 3;
-   case GL_FLOAT_VEC4:
-   case GL_INT_VEC4:
-   case GL_UNSIGNED_INT_VEC4:
-   case GL_BOOL_VEC4:
-      return 4;
-   case GL_FLOAT_MAT2:
-   case GL_FLOAT_MAT2x3:
-   case GL_FLOAT_MAT2x4:
-      return 8; /* two float[4] vectors */
-   case GL_FLOAT_MAT3:
-   case GL_FLOAT_MAT3x2:
-   case GL_FLOAT_MAT3x4:
-      return 12; /* three float[4] vectors */
-   case GL_FLOAT_MAT4:
-   case GL_FLOAT_MAT4x2:
-   case GL_FLOAT_MAT4x3:
-      return 16;  /* four float[4] vectors */
-   default:
-      _mesa_problem(NULL, "Invalid type in _mesa_sizeof_glsl_type()");
-      return 1;
-   }
-}
-
-
-static void
-_mesa_get_active_attrib(GLcontext *ctx, GLuint program, GLuint index,
-                        GLsizei maxLength, GLsizei *length, GLint *size,
-                        GLenum *type, GLchar *nameOut)
-{
-   const struct gl_program_parameter_list *attribs = NULL;
-   struct gl_shader_program *shProg;
-
-   shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveAttrib");
-   if (!shProg)
-      return;
-
-   if (shProg->VertexProgram)
-      attribs = shProg->VertexProgram->Base.Attributes;
-
-   if (!attribs || index >= attribs->NumParameters) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(index)");
-      return;
-   }
-
-   _mesa_copy_string(nameOut, maxLength, length,
-                     attribs->Parameters[index].Name);
-
-   if (size)
-      *size = attribs->Parameters[index].Size
-         / _mesa_sizeof_glsl_type(attribs->Parameters[index].DataType);
-
-   if (type)
-      *type = attribs->Parameters[index].DataType;
-}
-
-
-/**
- * Called via ctx->Driver.GetAttachedShaders().
- */
-static void
-_mesa_get_attached_shaders(GLcontext *ctx, GLuint program, GLsizei maxCount,
-                           GLsizei *count, GLuint *obj)
-{
-   struct gl_shader_program *shProg =
-      _mesa_lookup_shader_program_err(ctx, program, "glGetAttachedShaders");
-   if (shProg) {
-      GLuint i;
-      for (i = 0; i < (GLuint) maxCount && i < shProg->NumShaders; i++) {
-         obj[i] = shProg->Shaders[i]->Name;
-      }
-      if (count)
-         *count = i;
-   }
-}
-
-
-/** glGetHandleARB() - return ID/name of currently bound shader program */
-static GLuint
-_mesa_get_handle(GLcontext *ctx, GLenum pname)
-{
-   if (pname == GL_PROGRAM_OBJECT_ARB) {
-      if (ctx->Shader.CurrentProgram)
-         return ctx->Shader.CurrentProgram->Name;
-      else
-         return 0;
-   }
-   else {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glGetHandleARB");
-      return 0;
-   }
-}
-
-
-/**
- * glGetProgramiv() - get shader program state.
- * Note that this is for GLSL shader programs, not ARB vertex/fragment
- * programs (see glGetProgramivARB).
- */
-static void
-_mesa_get_programiv(GLcontext *ctx, GLuint program,
-                    GLenum pname, GLint *params)
-{
-   const struct gl_program_parameter_list *attribs;
-   struct gl_shader_program *shProg
-      = _mesa_lookup_shader_program(ctx, program);
-
-   if (!shProg) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramiv(program)");
-      return;
-   }
-
-   if (shProg->VertexProgram)
-      attribs = shProg->VertexProgram->Base.Attributes;
-   else
-      attribs = NULL;
-
-   switch (pname) {
-   case GL_DELETE_STATUS:
-      *params = shProg->DeletePending;
-      break; 
-   case GL_LINK_STATUS:
-      *params = shProg->LinkStatus;
-      break;
-   case GL_VALIDATE_STATUS:
-      *params = shProg->Validated;
-      break;
-   case GL_INFO_LOG_LENGTH:
-      *params = shProg->InfoLog ? strlen(shProg->InfoLog) + 1 : 0;
-      break;
-   case GL_ATTACHED_SHADERS:
-      *params = shProg->NumShaders;
-      break;
-   case GL_ACTIVE_ATTRIBUTES:
-      *params = attribs ? attribs->NumParameters : 0;
-      break;
-   case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
-      *params = _mesa_longest_parameter_name(attribs, PROGRAM_INPUT) + 1;
-      break;
-   case GL_ACTIVE_UNIFORMS:
-      *params = shProg->Uniforms ? shProg->Uniforms->NumUniforms : 0;
-      break;
-   case GL_ACTIVE_UNIFORM_MAX_LENGTH:
-      *params = _mesa_longest_uniform_name(shProg->Uniforms);
-      if (*params > 0)
-         (*params)++;  /* add one for terminating zero */
-      break;
-   case GL_PROGRAM_BINARY_LENGTH_OES:
-      *params = 0;
-      break;
-#if FEATURE_EXT_transform_feedback
-   case GL_TRANSFORM_FEEDBACK_VARYINGS:
-      *params = shProg->TransformFeedback.NumVarying;
-      break;
-   case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
-      *params = longest_feedback_varying_name(shProg) + 1;
-      break;
-   case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
-      *params = shProg->TransformFeedback.BufferMode;
-      break;
-#endif
-   default:
-      _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramiv(pname)");
-      return;
-   }
-}
-
-
-/** glGetShaderiv() - get GLSL shader state */
-static void
-_mesa_get_shaderiv(GLcontext *ctx, GLuint name, GLenum pname, GLint *params)
-{
-   struct gl_shader *shader = _mesa_lookup_shader_err(ctx, name, "glGetShaderiv");
-
-   if (!shader) {
-      return;
-   }
-
-   switch (pname) {
-   case GL_SHADER_TYPE:
-      *params = shader->Type;
-      break;
-   case GL_DELETE_STATUS:
-      *params = shader->DeletePending;
-      break;
-   case GL_COMPILE_STATUS:
-      *params = shader->CompileStatus;
-      break;
-   case GL_INFO_LOG_LENGTH:
-      *params = shader->InfoLog ? strlen(shader->InfoLog) + 1 : 0;
-      break;
-   case GL_SHADER_SOURCE_LENGTH:
-      *params = shader->Source ? strlen((char *) shader->Source) + 1 : 0;
-      break;
-   default:
-      _mesa_error(ctx, GL_INVALID_ENUM, "glGetShaderiv(pname)");
-      return;
-   }
-}
-
-
-static void
-_mesa_get_program_info_log(GLcontext *ctx, GLuint program, GLsizei bufSize,
-                           GLsizei *length, GLchar *infoLog)
-{
-   struct gl_shader_program *shProg
-      = _mesa_lookup_shader_program(ctx, program);
-   if (!shProg) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramInfoLog(program)");
-      return;
-   }
-   _mesa_copy_string(infoLog, bufSize, length, shProg->InfoLog);
-}
-
-
-static void
-_mesa_get_shader_info_log(GLcontext *ctx, GLuint shader, GLsizei bufSize,
-                          GLsizei *length, GLchar *infoLog)
-{
-   struct gl_shader *sh = _mesa_lookup_shader(ctx, shader);
-   if (!sh) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glGetShaderInfoLog(shader)");
-      return;
-   }
-   _mesa_copy_string(infoLog, bufSize, length, sh->InfoLog);
-}
-
-
-/**
- * Called via ctx->Driver.GetShaderSource().
- */
-static void
-_mesa_get_shader_source(GLcontext *ctx, GLuint shader, GLsizei maxLength,
-                        GLsizei *length, GLchar *sourceOut)
-{
-   struct gl_shader *sh;
-   sh = _mesa_lookup_shader_err(ctx, shader, "glGetShaderSource");
-   if (!sh) {
-      return;
-   }
-   _mesa_copy_string(sourceOut, maxLength, length, sh->Source);
-}
-
-
-/**
- * Called via ctx->Driver.ShaderSource()
- */
-static void
-_mesa_shader_source(GLcontext *ctx, GLuint shader, const GLchar *source)
-{
-   struct gl_shader *sh;
-
-   sh = _mesa_lookup_shader_err(ctx, shader, "glShaderSource");
-   if (!sh)
-      return;
-
-   /* free old shader source string and install new one */
-   if (sh->Source) {
-      free((void *) sh->Source);
-   }
-   sh->Source = source;
-   sh->CompileStatus = GL_FALSE;
-#ifdef DEBUG
-   sh->SourceChecksum = _mesa_str_checksum(sh->Source);
-#endif
-}
-
-
-/**
- * Called via ctx->Driver.CompileShader()
- */
-static void
-_mesa_compile_shader(GLcontext *ctx, GLuint shaderObj)
-{
-   struct gl_shader *sh;
-
-   sh = _mesa_lookup_shader_err(ctx, shaderObj, "glCompileShader");
-   if (!sh)
-      return;
-
-   /* set default pragma state for shader */
-   sh->Pragmas = ctx->Shader.DefaultPragmas;
-
-   /* this call will set the sh->CompileStatus field to indicate if
-    * compilation was successful.
-    */
-   (void) _slang_compile(ctx, sh);
-}
-
-
-/**
- * Called via ctx->Driver.LinkProgram()
- */
-static void
-_mesa_link_program(GLcontext *ctx, GLuint program)
-{
-   struct gl_shader_program *shProg;
-   struct gl_transform_feedback_object *obj =
-      ctx->TransformFeedback.CurrentObject;
-
-   shProg = _mesa_lookup_shader_program_err(ctx, program, "glLinkProgram");
-   if (!shProg)
-      return;
-
-   if (obj->Active && shProg == ctx->Shader.CurrentProgram) {
-      _mesa_error(ctx, GL_INVALID_OPERATION,
-                  "glLinkProgram(transform feedback active");
-      return;
-   }
-
-   FLUSH_VERTICES(ctx, _NEW_PROGRAM);
-
-   _slang_link(ctx, program, shProg);
-
-   /* debug code */
-   if (0) {
-      GLuint i;
-
-      printf("Link %u shaders in program %u: %s\n",
-                   shProg->NumShaders, shProg->Name,
-                   shProg->LinkStatus ? "Success" : "Failed");
-
-      for (i = 0; i < shProg->NumShaders; i++) {
-         printf(" shader %u, type 0x%x\n",
-                      shProg->Shaders[i]->Name,
-                      shProg->Shaders[i]->Type);
-      }
-   }
-}
-
-
-/**
- * Print basic shader info (for debug).
- */
-static void
-print_shader_info(const struct gl_shader_program *shProg)
-{
-   GLuint i;
-
-   printf("Mesa: glUseProgram(%u)\n", shProg->Name);
-   for (i = 0; i < shProg->NumShaders; i++) {
-      const char *s;
-      switch (shProg->Shaders[i]->Type) {
-      case GL_VERTEX_SHADER:
-         s = "vertex";
-         break;
-      case GL_FRAGMENT_SHADER:
-         s = "fragment";
-         break;
-      case GL_GEOMETRY_SHADER:
-         s = "geometry";
-         break;
-      default:
-         s = "";
-      }
-      printf("  %s shader %u, checksum %u\n", s, 
-            shProg->Shaders[i]->Name,
-            shProg->Shaders[i]->SourceChecksum);
-   }
-   if (shProg->VertexProgram)
-      printf("  vert prog %u\n", shProg->VertexProgram->Base.Id);
-   if (shProg->FragmentProgram)
-      printf("  frag prog %u\n", shProg->FragmentProgram->Base.Id);
-}
-
-
-/**
- * Called via ctx->Driver.UseProgram()
- */
-void
-_mesa_use_program(GLcontext *ctx, GLuint program)
-{
-   struct gl_shader_program *shProg;
-   struct gl_transform_feedback_object *obj =
-      ctx->TransformFeedback.CurrentObject;
-
-   if (obj->Active) {
-      _mesa_error(ctx, GL_INVALID_OPERATION,
-                  "glUseProgram(transform feedback active)");
-      return;
-   }
-
-   if (ctx->Shader.CurrentProgram &&
-       ctx->Shader.CurrentProgram->Name == program) {
-      /* no-op */
-      return;
-   }
-
-   if (program) {
-      shProg = _mesa_lookup_shader_program_err(ctx, program, "glUseProgram");
-      if (!shProg) {
-         return;
-      }
-      if (!shProg->LinkStatus) {
-         _mesa_error(ctx, GL_INVALID_OPERATION,
-                     "glUseProgram(program %u not linked)", program);
-         return;
-      }
-
-      /* debug code */
-      if (ctx->Shader.Flags & GLSL_USE_PROG) {
-         print_shader_info(shProg);
-      }
-   }
-   else {
-      shProg = NULL;
-   }
-
-   if (ctx->Shader.CurrentProgram != shProg) {
-      FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
-      _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentProgram, shProg);
-   }
-}
-
-
-
-/**
- * Update the vertex/fragment program's TexturesUsed array.
- *
- * This needs to be called after glUniform(set sampler var) is called.
- * A call to glUniform(samplerVar, value) causes a sampler to point to a
- * particular texture unit.  We know the sampler's texture target
- * (1D/2D/3D/etc) from compile time but the sampler's texture unit is
- * set by glUniform() calls.
- *
- * So, scan the program->SamplerUnits[] and program->SamplerTargets[]
- * information to update the prog->TexturesUsed[] values.
- * Each value of TexturesUsed[unit] is one of zero, TEXTURE_1D_INDEX,
- * TEXTURE_2D_INDEX, TEXTURE_3D_INDEX, etc.
- * We'll use that info for state validation before rendering.
- */
-void
-_mesa_update_shader_textures_used(struct gl_program *prog)
-{
-   GLuint s;
-
-   memset(prog->TexturesUsed, 0, sizeof(prog->TexturesUsed));
-
-   for (s = 0; s < MAX_SAMPLERS; s++) {
-      if (prog->SamplersUsed & (1 << s)) {
-         GLuint unit = prog->SamplerUnits[s];
-         GLuint tgt = prog->SamplerTargets[s];
-         assert(unit < MAX_TEXTURE_IMAGE_UNITS);
-         assert(tgt < NUM_TEXTURE_TARGETS);
-         prog->TexturesUsed[unit] |= (1 << tgt);
-      }
-   }
-}
-
-
-/**
- * Validate a program's samplers.
- * Specifically, check that there aren't two samplers of different types
- * pointing to the same texture unit.
- * \return GL_TRUE if valid, GL_FALSE if invalid
- */
-static GLboolean
-validate_samplers(GLcontext *ctx, const struct gl_program *prog, char *errMsg)
-{
-   static const char *targetName[] = {
-      "TEXTURE_2D_ARRAY",
-      "TEXTURE_1D_ARRAY",
-      "TEXTURE_CUBE",
-      "TEXTURE_3D",
-      "TEXTURE_RECT",
-      "TEXTURE_2D",
-      "TEXTURE_1D",
-   };
-   GLint targetUsed[MAX_TEXTURE_IMAGE_UNITS];
-   GLbitfield samplersUsed = prog->SamplersUsed;
-   GLuint i;
-
-   assert(Elements(targetName) == NUM_TEXTURE_TARGETS);
-
-   if (samplersUsed == 0x0)
-      return GL_TRUE;
-
-   for (i = 0; i < Elements(targetUsed); i++)
-      targetUsed[i] = -1;
-
-   /* walk over bits which are set in 'samplers' */
-   while (samplersUsed) {
-      GLuint unit;
-      gl_texture_index target;
-      GLint sampler = _mesa_ffs(samplersUsed) - 1;
-      assert(sampler >= 0);
-      assert(sampler < MAX_TEXTURE_IMAGE_UNITS);
-      unit = prog->SamplerUnits[sampler];
-      target = prog->SamplerTargets[sampler];
-      if (targetUsed[unit] != -1 && targetUsed[unit] != target) {
-         _mesa_snprintf(errMsg, 100,
-                 "Texture unit %d is accessed both as %s and %s",
-                 unit, targetName[targetUsed[unit]], targetName[target]);
-         return GL_FALSE;
-      }
-      targetUsed[unit] = target;
-      samplersUsed ^= (1 << sampler);
-   }
-
-   return GL_TRUE;
-}
-
-
-/**
- * Do validation of the given shader program.
- * \param errMsg  returns error message if validation fails.
- * \return GL_TRUE if valid, GL_FALSE if invalid (and set errMsg)
- */
-GLboolean
-_mesa_validate_shader_program(GLcontext *ctx,
-                              const struct gl_shader_program *shProg,
-                              char *errMsg)
-{
-   const struct gl_vertex_program *vp = shProg->VertexProgram;
-   const struct gl_fragment_program *fp = shProg->FragmentProgram;
-
-   if (!shProg->LinkStatus) {
-      return GL_FALSE;
-   }
-
-   /* From the GL spec, a program is invalid if any of these are true:
-
-     any two active samplers in the current program object are of
-     different types, but refer to the same texture image unit,
-
-     any active sampler in the current program object refers to a texture
-     image unit where fixed-function fragment processing accesses a
-     texture target that does not match the sampler type, or 
-
-     the sum of the number of active samplers in the program and the
-     number of texture image units enabled for fixed-function fragment
-     processing exceeds the combined limit on the total number of texture
-     image units allowed.
-   */
-
-
-   /*
-    * Check: any two active samplers in the current program object are of
-    * different types, but refer to the same texture image unit,
-    */
-   if (vp && !validate_samplers(ctx, &vp->Base, errMsg)) {
-      return GL_FALSE;
-   }
-   if (fp && !validate_samplers(ctx, &fp->Base, errMsg)) {
-      return GL_FALSE;
-   }
-
-   return GL_TRUE;
-}
-
-
-/**
- * Called via glValidateProgram()
- */
-static void
-_mesa_validate_program(GLcontext *ctx, GLuint program)
-{
-   struct gl_shader_program *shProg;
-   char errMsg[100];
-
-   shProg = _mesa_lookup_shader_program_err(ctx, program, "glValidateProgram");
-   if (!shProg) {
-      return;
-   }
-
-   shProg->Validated = _mesa_validate_shader_program(ctx, shProg, errMsg);
-   if (!shProg->Validated) {
-      /* update info log */
-      if (shProg->InfoLog) {
-         free(shProg->InfoLog);
-      }
-      shProg->InfoLog = _mesa_strdup(errMsg);
-   }
-}
-
-
-/**
- * Plug in Mesa's GLSL functions into the device driver function table.
- */
-void
-_mesa_init_glsl_driver_functions(struct dd_function_table *driver)
-{
-   driver->AttachShader = _mesa_attach_shader;
-   driver->BindAttribLocation = _mesa_bind_attrib_location;
-   driver->CompileShader = _mesa_compile_shader;
-   driver->CreateProgram = _mesa_create_program;
-   driver->CreateShader = _mesa_create_shader;
-   driver->DeleteProgram2 = _mesa_delete_program2;
-   driver->DeleteShader = _mesa_delete_shader;
-   driver->DetachShader = _mesa_detach_shader;
-   driver->GetActiveAttrib = _mesa_get_active_attrib;
-   driver->GetAttachedShaders = _mesa_get_attached_shaders;
-   driver->GetAttribLocation = _mesa_get_attrib_location;
-   driver->GetHandle = _mesa_get_handle;
-   driver->GetProgramiv = _mesa_get_programiv;
-   driver->GetProgramInfoLog = _mesa_get_program_info_log;
-   driver->GetShaderiv = _mesa_get_shaderiv;
-   driver->GetShaderInfoLog = _mesa_get_shader_info_log;
-   driver->GetShaderSource = _mesa_get_shader_source;
-   driver->IsProgram = _mesa_is_program;
-   driver->IsShader = _mesa_is_shader;
-   driver->LinkProgram = _mesa_link_program;
-   driver->ShaderSource = _mesa_shader_source;
-   driver->UseProgram = _mesa_use_program;
-   driver->ValidateProgram = _mesa_validate_program;
-
-   _mesa_init_uniform_functions(driver);
-}
diff --git a/src/mesa/shader/shader_api.h b/src/mesa/shader/shader_api.h
deleted file mode 100644 (file)
index 9743a23..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  7.6
- *
- * Copyright (C) 2004-2006  Brian Paul   All Rights Reserved.
- * Copyright (C) 2009  VMware, Inc.  All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-
-#ifndef SHADER_API_H
-#define SHADER_API_H
-
-
-#include "main/glheader.h"
-#include "main/mtypes.h"
-
-
-/**
- * Internal functions
- */
-
-extern void
-_mesa_init_shader_state(GLcontext * ctx);
-
-extern void
-_mesa_free_shader_state(GLcontext *ctx);
-
-
-extern void
-_mesa_copy_string(GLchar *dst, GLsizei maxLength,
-                  GLsizei *length, const GLchar *src);
-
-extern GLint
-_mesa_sizeof_glsl_type(GLenum type);
-
-
-/*
-extern struct gl_shader_program *
-_mesa_new_shader_program(GLcontext *ctx, GLuint name);
-*/
-extern void
-_mesa_clear_shader_program_data(GLcontext *ctx,
-                                struct gl_shader_program *shProg);
-
-extern void
-_mesa_free_shader_program_data(GLcontext *ctx,
-                               struct gl_shader_program *shProg);
-
-extern void
-_mesa_free_shader_program(GLcontext *ctx, struct gl_shader_program *shProg);
-
-extern void
-_mesa_reference_shader_program(GLcontext *ctx,
-                               struct gl_shader_program **ptr,
-                               struct gl_shader_program *shProg);
-
-extern struct gl_shader_program *
-_mesa_lookup_shader_program(GLcontext *ctx, GLuint name);
-
-
-extern struct gl_shader_program *
-_mesa_lookup_shader_program_err(GLcontext *ctx, GLuint name,
-                                const char *caller);
-
-extern struct gl_shader *
-_mesa_new_shader(GLcontext *ctx, GLuint name, GLenum type);
-
-extern void
-_mesa_free_shader(GLcontext *ctx, struct gl_shader *sh);
-
-extern void
-_mesa_reference_shader(GLcontext *ctx, struct gl_shader **ptr,
-                       struct gl_shader *sh);
-
-extern struct gl_shader *
-_mesa_lookup_shader(GLcontext *ctx, GLuint name);
-
-
-extern void
-_mesa_update_shader_textures_used(struct gl_program *prog);
-
-
-extern void
-_mesa_use_program(GLcontext *ctx, GLuint program);
-
-
-extern GLboolean
-_mesa_validate_shader_program(GLcontext *ctx,
-                              const struct gl_shader_program *shProg,
-                              char *errMsg);
-
-extern void
-_mesa_init_glsl_driver_functions(struct dd_function_table *driver);
-
-
-#endif /* SHADER_API_H */
index 2d003ef9c36cad732eb77fbac29bc6efaf7ed99a..6b1c1532455001bd0537efbf61caf8db2656cbf7 100644 (file)
 #include "main/imports.h"
 #include "main/context.h"
 #include "main/macros.h"
+#include "main/shaderapi.h"
+#include "main/shaderobj.h"
 #include "shader/program.h"
 #include "shader/prog_instruction.h"
 #include "shader/prog_parameter.h"
 #include "shader/prog_print.h"
 #include "shader/prog_statevars.h"
 #include "shader/prog_uniform.h"
-#include "shader/shader_api.h"
+#include "shader/uniforms.h"
 #include "slang_builtin.h"
 #include "slang_link.h"
 
@@ -873,7 +875,7 @@ get_main_shader(GLcontext *ctx,
           !shader->Main ||
           shader->UnresolvedRefs) {
          link_error(shProg, "Unresolved symbols");
-         _mesa_free_shader(ctx, shader);
+         ctx->Driver.DeleteShader(ctx, shader);
          return NULL;
       }
    }
index b1fb90d020b55409f5d13b656846504960efb4e1..ed1efe5c29873bf2e46d3e69489844308a0482d1 100644 (file)
 
 #include "main/glheader.h"
 #include "main/context.h"
+#include "main/dispatch.h"
+#include "main/shaderapi.h"
+#include "main/shaderobj.h"
+#include "uniforms.h"
 #include "shader/prog_parameter.h"
 #include "shader/prog_statevars.h"
 #include "shader/prog_uniform.h"
-#include "shader/shader_api.h"
-#include "uniforms.h"
 
 
 
@@ -141,7 +143,7 @@ get_uniform_parameter(const struct gl_shader_program *shProg, GLuint index)
 
 
 /**
- * Called via ctx->Driver.GetActiveUniform().
+ * Called by glGetActiveUniform().
  */
 static void
 _mesa_get_active_uniform(GLcontext *ctx, GLuint program, GLuint index,
@@ -367,7 +369,7 @@ split_location_offset(GLint *location, GLint *offset)
 
 
 /**
- * Called via ctx->Driver.GetUniformfv().
+ * Called via glGetUniformfv().
  */
 static void
 _mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location,
@@ -399,7 +401,7 @@ _mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location,
 
 
 /**
- * Called via ctx->Driver.GetUniformiv().
+ * Called via glGetUniformiv().
  * \sa _mesa_get_uniformfv, only difference is a cast.
  */
 static void
@@ -432,7 +434,7 @@ _mesa_get_uniformiv(GLcontext *ctx, GLuint program, GLint location,
 
 
 /**
- * Called via ctx->Driver.GetUniformLocation().
+ * Called via glGetUniformLocation().
  *
  * The return value will encode two values, the uniform location and an
  * offset (used for arrays, structs).
@@ -508,6 +510,41 @@ _mesa_get_uniform_location(GLcontext *ctx, GLuint program, const GLchar *name)
 }
 
 
+
+/**
+ * Update the vertex/fragment program's TexturesUsed array.
+ *
+ * This needs to be called after glUniform(set sampler var) is called.
+ * A call to glUniform(samplerVar, value) causes a sampler to point to a
+ * particular texture unit.  We know the sampler's texture target
+ * (1D/2D/3D/etc) from compile time but the sampler's texture unit is
+ * set by glUniform() calls.
+ *
+ * So, scan the program->SamplerUnits[] and program->SamplerTargets[]
+ * information to update the prog->TexturesUsed[] values.
+ * Each value of TexturesUsed[unit] is one of zero, TEXTURE_1D_INDEX,
+ * TEXTURE_2D_INDEX, TEXTURE_3D_INDEX, etc.
+ * We'll use that info for state validation before rendering.
+ */
+void
+_mesa_update_shader_textures_used(struct gl_program *prog)
+{
+   GLuint s;
+
+   memset(prog->TexturesUsed, 0, sizeof(prog->TexturesUsed));
+
+   for (s = 0; s < MAX_SAMPLERS; s++) {
+      if (prog->SamplersUsed & (1 << s)) {
+         GLuint unit = prog->SamplerUnits[s];
+         GLuint tgt = prog->SamplerTargets[s];
+         assert(unit < MAX_TEXTURE_IMAGE_UNITS);
+         assert(tgt < NUM_TEXTURE_TARGETS);
+         prog->TexturesUsed[unit] |= (1 << tgt);
+      }
+   }
+}
+
+
 /**
  * Check if the type given by userType is allowed to set a uniform of the
  * target type.  Generally, equivalence is required, but setting Boolean
@@ -697,7 +734,7 @@ set_program_uniform(GLcontext *ctx, struct gl_program *program,
 
 
 /**
- * Called via ctx->Driver.Uniform().
+ * Called via glUniform*() functions.
  */
 static void
 _mesa_uniform(GLcontext *ctx, GLint location, GLsizei count,
@@ -859,7 +896,7 @@ set_program_uniform_matrix(GLcontext *ctx, struct gl_program *program,
 
 
 /**
- * Called by ctx->Driver.UniformMatrix().
+ * Called by glUniformMatrix*() functions.
  * Note: cols=2, rows=4  ==>  array[2] of vec4
  */
 static void
@@ -924,14 +961,374 @@ _mesa_uniform_matrix(GLcontext *ctx, GLint cols, GLint rows,
 }
 
 
+void GLAPIENTRY
+_mesa_Uniform1fARB(GLint location, GLfloat v0)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform(ctx, location, 1, &v0, GL_FLOAT);
+}
+
+void GLAPIENTRY
+_mesa_Uniform2fARB(GLint location, GLfloat v0, GLfloat v1)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   GLfloat v[2];
+   v[0] = v0;
+   v[1] = v1;
+   _mesa_uniform(ctx, location, 1, v, GL_FLOAT_VEC2);
+}
+
+void GLAPIENTRY
+_mesa_Uniform3fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   GLfloat v[3];
+   v[0] = v0;
+   v[1] = v1;
+   v[2] = v2;
+   _mesa_uniform(ctx, location, 1, v, GL_FLOAT_VEC3);
+}
+
+void GLAPIENTRY
+_mesa_Uniform4fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2,
+                   GLfloat v3)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   GLfloat v[4];
+   v[0] = v0;
+   v[1] = v1;
+   v[2] = v2;
+   v[3] = v3;
+   _mesa_uniform(ctx, 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);
+}
+
+void GLAPIENTRY
+_mesa_Uniform2iARB(GLint location, GLint v0, GLint v1)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   GLint v[2];
+   v[0] = v0;
+   v[1] = v1;
+   _mesa_uniform(ctx, location, 1, v, GL_INT_VEC2);
+}
+
+void GLAPIENTRY
+_mesa_Uniform3iARB(GLint location, GLint v0, GLint v1, GLint v2)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   GLint v[3];
+   v[0] = v0;
+   v[1] = v1;
+   v[2] = v2;
+   _mesa_uniform(ctx, location, 1, v, GL_INT_VEC3);
+}
+
+void GLAPIENTRY
+_mesa_Uniform4iARB(GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   GLint v[4];
+   v[0] = v0;
+   v[1] = v1;
+   v[2] = v2;
+   v[3] = v3;
+   _mesa_uniform(ctx, 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);
+}
+
+void GLAPIENTRY
+_mesa_Uniform2fvARB(GLint location, GLsizei count, const GLfloat * value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform(ctx, 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);
+}
+
+void GLAPIENTRY
+_mesa_Uniform4fvARB(GLint location, GLsizei count, const GLfloat * value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform(ctx, 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);
+}
+
+void GLAPIENTRY
+_mesa_Uniform2ivARB(GLint location, GLsizei count, const GLint * value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform(ctx, 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);
+}
+
+void GLAPIENTRY
+_mesa_Uniform4ivARB(GLint location, GLsizei count, const GLint * value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform(ctx, location, count, value, GL_INT_VEC4);
+}
+
+
+/** OpenGL 3.0 GLuint-valued functions **/
+void GLAPIENTRY
+_mesa_Uniform1ui(GLint location, GLuint v0)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform(ctx, location, 1, &v0, GL_UNSIGNED_INT);
+}
+
+void GLAPIENTRY
+_mesa_Uniform2ui(GLint location, GLuint v0, GLuint v1)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   GLuint v[2];
+   v[0] = v0;
+   v[1] = v1;
+   _mesa_uniform(ctx, location, 1, v, GL_UNSIGNED_INT_VEC2);
+}
+
+void GLAPIENTRY
+_mesa_Uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   GLuint v[3];
+   v[0] = v0;
+   v[1] = v1;
+   v[2] = v2;
+   _mesa_uniform(ctx, location, 1, v, GL_UNSIGNED_INT_VEC3);
+}
+
+void GLAPIENTRY
+_mesa_Uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   GLuint v[4];
+   v[0] = v0;
+   v[1] = v1;
+   v[2] = v2;
+   v[3] = v3;
+   _mesa_uniform(ctx, 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);
+}
+
+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);
+}
+
+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);
+}
+
+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);
+}
+
+
+
+void GLAPIENTRY
+_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);
+}
+
+void GLAPIENTRY
+_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);
+}
+
+void GLAPIENTRY
+_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);
+}
+
+
+/**
+ * Non-square UniformMatrix are OpenGL 2.1
+ */
+void GLAPIENTRY
+_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);
+}
+
+void GLAPIENTRY
+_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);
+}
+
+void GLAPIENTRY
+_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);
+}
+
+void GLAPIENTRY
+_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);
+}
+
+void GLAPIENTRY
+_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);
+}
+
+void GLAPIENTRY
+_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);
+}
+
 
+void GLAPIENTRY
+_mesa_GetUniformfvARB(GLhandleARB program, GLint location, GLfloat *params)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_get_uniformfv(ctx, program, location, params);
+}
+
+
+void GLAPIENTRY
+_mesa_GetUniformivARB(GLhandleARB program, GLint location, GLint *params)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_get_uniformiv(ctx, program, location, params);
+}
+
+
+GLint GLAPIENTRY
+_mesa_GetUniformLocationARB(GLhandleARB programObj, const GLcharARB *name)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   return _mesa_get_uniform_location(ctx, programObj, name);
+}
+
+
+void GLAPIENTRY
+_mesa_GetActiveUniformARB(GLhandleARB program, GLuint index,
+                          GLsizei maxLength, GLsizei * length, GLint * size,
+                          GLenum * type, GLcharARB * name)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_get_active_uniform(ctx, program, index, maxLength, length, size,
+                            type, name);
+}
+
+
+/**
+ * Plug in shader uniform-related functions into API dispatch table.
+ */
 void
-_mesa_init_uniform_functions(struct dd_function_table *driver)
-{
-   driver->GetActiveUniform = _mesa_get_active_uniform;
-   driver->GetUniformfv = _mesa_get_uniformfv;
-   driver->GetUniformiv = _mesa_get_uniformiv;
-   driver->GetUniformLocation = _mesa_get_uniform_location;
-   driver->Uniform = _mesa_uniform;
-   driver->UniformMatrix = _mesa_uniform_matrix;
+_mesa_init_shader_uniform_dispatch(struct _glapi_table *exec)
+{
+   SET_Uniform1fARB(exec, _mesa_Uniform1fARB);
+   SET_Uniform2fARB(exec, _mesa_Uniform2fARB);
+   SET_Uniform3fARB(exec, _mesa_Uniform3fARB);
+   SET_Uniform4fARB(exec, _mesa_Uniform4fARB);
+   SET_Uniform1iARB(exec, _mesa_Uniform1iARB);
+   SET_Uniform2iARB(exec, _mesa_Uniform2iARB);
+   SET_Uniform3iARB(exec, _mesa_Uniform3iARB);
+   SET_Uniform4iARB(exec, _mesa_Uniform4iARB);
+   SET_Uniform1fvARB(exec, _mesa_Uniform1fvARB);
+   SET_Uniform2fvARB(exec, _mesa_Uniform2fvARB);
+   SET_Uniform3fvARB(exec, _mesa_Uniform3fvARB);
+   SET_Uniform4fvARB(exec, _mesa_Uniform4fvARB);
+   SET_Uniform1ivARB(exec, _mesa_Uniform1ivARB);
+   SET_Uniform2ivARB(exec, _mesa_Uniform2ivARB);
+   SET_Uniform3ivARB(exec, _mesa_Uniform3ivARB);
+   SET_Uniform4ivARB(exec, _mesa_Uniform4ivARB);
+   SET_UniformMatrix2fvARB(exec, _mesa_UniformMatrix2fvARB);
+   SET_UniformMatrix3fvARB(exec, _mesa_UniformMatrix3fvARB);
+   SET_UniformMatrix4fvARB(exec, _mesa_UniformMatrix4fvARB);
+
+   SET_GetActiveUniformARB(exec, _mesa_GetActiveUniformARB);
+   SET_GetUniformLocationARB(exec, _mesa_GetUniformLocationARB);
+   SET_GetUniformfvARB(exec, _mesa_GetUniformfvARB);
+   SET_GetUniformivARB(exec, _mesa_GetUniformivARB);
+
+   /* OpenGL 2.1 */
+   SET_UniformMatrix2x3fv(exec, _mesa_UniformMatrix2x3fv);
+   SET_UniformMatrix3x2fv(exec, _mesa_UniformMatrix3x2fv);
+   SET_UniformMatrix2x4fv(exec, _mesa_UniformMatrix2x4fv);
+   SET_UniformMatrix4x2fv(exec, _mesa_UniformMatrix4x2fv);
+   SET_UniformMatrix3x4fv(exec, _mesa_UniformMatrix3x4fv);
+   SET_UniformMatrix4x3fv(exec, _mesa_UniformMatrix4x3fv);
+
+   /* 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;
 }
index 52984dedadbdfb53c6c1a378165e01da4e9d648a..29f77cb35a021669e5cc256aec4d2d72829e5e71 100644 (file)
 #define UNIFORMS_H
 
 
+extern void GLAPIENTRY
+_mesa_Uniform1fARB(GLint, GLfloat);
+
+extern void GLAPIENTRY
+_mesa_Uniform2fARB(GLint, GLfloat, GLfloat);
+
+extern void GLAPIENTRY
+_mesa_Uniform3fARB(GLint, GLfloat, GLfloat, GLfloat);
+
+extern void GLAPIENTRY
+_mesa_Uniform4fARB(GLint, GLfloat, GLfloat, GLfloat, GLfloat);
+
+extern void GLAPIENTRY
+_mesa_Uniform1iARB(GLint, GLint);
+
+extern void GLAPIENTRY
+_mesa_Uniform2iARB(GLint, GLint, GLint);
+
+extern void GLAPIENTRY
+_mesa_Uniform3iARB(GLint, GLint, GLint, GLint);
+
+extern void GLAPIENTRY
+_mesa_Uniform4iARB(GLint, GLint, GLint, GLint, GLint);
+
+extern void GLAPIENTRY
+_mesa_Uniform1fvARB(GLint, GLsizei, const GLfloat *);
+
+extern void GLAPIENTRY
+_mesa_Uniform2fvARB(GLint, GLsizei, const GLfloat *);
+
+extern void GLAPIENTRY
+_mesa_Uniform3fvARB(GLint, GLsizei, const GLfloat *);
+
+extern void GLAPIENTRY
+_mesa_Uniform4fvARB(GLint, GLsizei, const GLfloat *);
+
+extern void GLAPIENTRY
+_mesa_Uniform1ivARB(GLint, GLsizei, const GLint *);
+
+extern void GLAPIENTRY
+_mesa_Uniform2ivARB(GLint, GLsizei, const GLint *);
+
+extern void GLAPIENTRY
+_mesa_Uniform3ivARB(GLint, GLsizei, const GLint *);
+
+extern void GLAPIENTRY
+_mesa_Uniform4ivARB(GLint, GLsizei, const GLint *);
+
+extern void GLAPIENTRY
+_mesa_Uniform1ui(GLint location, GLuint v0);
+
+extern void GLAPIENTRY
+_mesa_Uniform2ui(GLint location, GLuint v0, GLuint v1);
+
+extern void GLAPIENTRY
+_mesa_Uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2);
+
+extern void GLAPIENTRY
+_mesa_Uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+
+extern void GLAPIENTRY
+_mesa_Uniform1uiv(GLint location, GLsizei count, const GLuint *value);
+
+extern void GLAPIENTRY
+_mesa_Uniform2uiv(GLint location, GLsizei count, const GLuint *value);
+
+extern void GLAPIENTRY
+_mesa_Uniform3uiv(GLint location, GLsizei count, const GLuint *value);
+
+extern void GLAPIENTRY
+_mesa_Uniform4uiv(GLint location, GLsizei count, const GLuint *value);
+
+
+extern void GLAPIENTRY
+_mesa_UniformMatrix2fvARB(GLint, GLsizei, GLboolean, const GLfloat *);
+
+extern void GLAPIENTRY
+_mesa_UniformMatrix3fvARB(GLint, GLsizei, GLboolean, const GLfloat *);
+
+extern void GLAPIENTRY
+_mesa_UniformMatrix4fvARB(GLint, GLsizei, GLboolean, const GLfloat *);
+
+extern void GLAPIENTRY
+_mesa_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose,
+                         const GLfloat *value);
+
+extern void GLAPIENTRY
+_mesa_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose,
+                         const GLfloat *value);
+
+extern void GLAPIENTRY
+_mesa_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose,
+                         const GLfloat *value);
+
+extern void GLAPIENTRY
+_mesa_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose,
+                         const GLfloat *value);
+
+extern void GLAPIENTRY
+_mesa_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose,
+                         const GLfloat *value);
+
+extern void GLAPIENTRY
+_mesa_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose,
+                         const GLfloat *value);
+
+
+extern void GLAPIENTRY
+_mesa_GetActiveUniformARB(GLhandleARB, GLuint, GLsizei, GLsizei *,
+                          GLint *, GLenum *, GLcharARB *);
+
+extern void GLAPIENTRY
+_mesa_GetUniformfvARB(GLhandleARB, GLint, GLfloat *);
+
+extern void GLAPIENTRY
+_mesa_GetUniformivARB(GLhandleARB, GLint, GLint *);
+
+extern GLint GLAPIENTRY
+_mesa_GetUniformLocationARB(GLhandleARB, const GLcharARB *);
+
+
+
 extern void
-_mesa_init_uniform_functions(struct dd_function_table *driver);
+_mesa_update_shader_textures_used(struct gl_program *prog);
 
 
+extern void
+_mesa_init_shader_uniform_dispatch(struct _glapi_table *exec);
+
 #endif /* UNIFORMS_H */
index ddd63cea0b4d52f27449e10781bf4dbbcb0cc034..85471dd8179118a87b581ecbb47d4ac323af8d55 100644 (file)
@@ -66,7 +66,8 @@ MAIN_SOURCES = \
        main/remap.c \
        main/renderbuffer.c \
        main/scissor.c \
-       main/shaders.c \
+       main/shaderapi.c \
+       main/shaderobj.c \
        main/shared.c \
        main/state.c \
        main/stencil.c \
@@ -247,7 +248,6 @@ SHADER_SOURCES = \
        shader/prog_uniform.c \
        shader/programopt.c \
        shader/symbol_table.c \
-       shader/shader_api.c \
        shader/uniforms.c
 
 SLANG_SOURCES =        \
index 2361b2eddfeaedca69423a1a60946b8e902ebe87..d0c9772e8efd1b0e91390af00384c600757639e0 100644 (file)
 #include "main/glheader.h"
 #include "main/macros.h"
 #include "main/enums.h"
+#include "main/shaderapi.h"
+#include "main/shaderobj.h"
 #include "shader/prog_instruction.h"
 #include "shader/prog_parameter.h"
 #include "shader/program.h"
-#include "shader/shader_api.h"
 
 #include "cso_cache/cso_context.h"
 #include "draw/draw_context.h"
@@ -75,15 +76,12 @@ static void st_bind_program( GLcontext *ctx,
  * Called via ctx->Driver.UseProgram() to bind a linked GLSL program
  * (vertex shader + fragment shader).
  */
-static void st_use_program( GLcontext *ctx,
-                           GLuint program )
+static void st_use_program( GLcontext *ctx, struct gl_shader_program *shProg)
 {
    struct st_context *st = st_context(ctx);
 
    st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM;
    st->dirty.st |= ST_NEW_VERTEX_PROGRAM;
-
-   _mesa_use_program(ctx, program);
 }
 
 
index 0bf030e98763d550ffdbd7fb1afd56b46fe48a4c..4b809b61143658a60ac6756bbd513945e2cddd4b 100644 (file)
@@ -27,8 +27,8 @@
 
 #include "main/imports.h"
 #include "main/context.h"
+#include "main/shaderobj.h"
 #include "vbo/vbo.h"
-#include "shader/shader_api.h"
 #include "glapi/glapi.h"
 #include "st_context.h"
 #include "st_debug.h"
@@ -254,7 +254,7 @@ void st_destroy_context( struct st_context *st )
 
 void st_init_driver_functions(struct dd_function_table *functions)
 {
-   _mesa_init_glsl_driver_functions(functions);
+   _mesa_init_shader_object_functions(functions);
 
    st_init_accum_functions(functions);
    st_init_blit_functions(functions);