Move many functions into new files.
authorBrian <brian@yutani.localnet.net>
Thu, 14 Dec 2006 22:01:28 +0000 (15:01 -0700)
committerBrian <brian@yutani.localnet.net>
Thu, 14 Dec 2006 22:01:28 +0000 (15:01 -0700)
src/mesa/shader/program.c
src/mesa/shader/program.h

index 6245870722eabaf9eb21a3cbbb95816170a5b5d5..c504c7c5c54325ecfaf699899b5cf80f1789d19e 100644 (file)
 #include "imports.h"
 #include "macros.h"
 #include "mtypes.h"
-#include "program.h"
 #include "nvfragparse.h"
-#include "program_instruction.h"
+#include "program.h"
+#include "prog_parameter.h"
+#include "prog_instruction.h"
+#include "prog_statevars.h"
 #include "nvvertparse.h"
 #include "atifragshader.h"
 
 
-static const char *
-make_state_string(const GLint stateTokens[6]);
-
-static GLbitfield
-make_state_flags(const GLint state[]);
-
 
 /**********************************************************************/
 /* Utility functions                                                  */
@@ -335,1725 +331,81 @@ _mesa_lookup_program(GLcontext *ctx, GLuint id)
 }
 
 
-/**********************************************************************/
-/* Program parameter functions                                        */
-/**********************************************************************/
-
-struct gl_program_parameter_list *
-_mesa_new_parameter_list(void)
-{
-   return (struct gl_program_parameter_list *)
-      _mesa_calloc(sizeof(struct gl_program_parameter_list));
-}
-
-
-/**
- * Free a parameter list and all its parameters
- */
-void
-_mesa_free_parameter_list(struct gl_program_parameter_list *paramList)
-{
-   GLuint i;
-   for (i = 0; i < paramList->NumParameters; i++) {
-      if (paramList->Parameters[i].Name)
-        _mesa_free((void *) paramList->Parameters[i].Name);
-   }
-   _mesa_free(paramList->Parameters);
-   if (paramList->ParameterValues)
-      _mesa_align_free(paramList->ParameterValues);
-   _mesa_free(paramList);
-}
-
-
-
-/**
- * Add a new parameter to a parameter list.
- * \param paramList  the list to add the parameter to
- * \param name  the parameter name, will be duplicated/copied!
- * \param values  initial parameter value, up to 4 GLfloats
- * \param size  number of elements in 'values' vector (1..4)
- * \param type  type of parameter, such as 
- * \return  index of new parameter in the list, or -1 if error (out of mem)
- */
-GLint
-_mesa_add_parameter(struct gl_program_parameter_list *paramList,
-                    const char *name, const GLfloat values[4], GLuint size,
-                    enum register_file type)
-{
-   const GLuint n = paramList->NumParameters;
-
-   if (n == paramList->Size) {
-      /* Need to grow the parameter list array */
-      if (paramList->Size == 0)
-        paramList->Size = 8;
-      else
-         paramList->Size *= 2;
-
-      /* realloc arrays */
-      paramList->Parameters = (struct gl_program_parameter *)
-        _mesa_realloc(paramList->Parameters,
-                      n * sizeof(struct gl_program_parameter),
-                      paramList->Size * sizeof(struct gl_program_parameter));
-
-      paramList->ParameterValues = (GLfloat (*)[4])
-         _mesa_align_realloc(paramList->ParameterValues,         /* old buf */
-                             n * 4 * sizeof(GLfloat),            /* old size */
-                             paramList->Size * 4 *sizeof(GLfloat), /* new sz */
-                             16);
-   }
-
-   if (!paramList->Parameters ||
-       !paramList->ParameterValues) {
-      /* out of memory */
-      paramList->NumParameters = 0;
-      paramList->Size = 0;
-      return -1;
-   }
-   else {
-      paramList->NumParameters = n + 1;
-
-      _mesa_memset(&paramList->Parameters[n], 0, 
-                  sizeof(struct gl_program_parameter));
-
-      paramList->Parameters[n].Name = name ? _mesa_strdup(name) : NULL;
-      paramList->Parameters[n].Type = type;
-      paramList->Parameters[n].Size = size;
-      if (values)
-         COPY_4V(paramList->ParameterValues[n], values);
-      return (GLint) n;
-   }
-}
-
-
-/**
- * Add a new named program parameter (Ex: NV_fragment_program DEFINE statement)
- * \return index of the new entry in the parameter list
- */
-GLint
-_mesa_add_named_parameter(struct gl_program_parameter_list *paramList,
-                          const char *name, const GLfloat values[4])
-{
-   return _mesa_add_parameter(paramList, name, values, 4, PROGRAM_NAMED_PARAM);
-}
-
-
-/**
- * Add a new named constant to the parameter list.
- * This will be used when the program contains something like this:
- *    PARAM myVals = { 0, 1, 2, 3 };
- *
- * \param paramList  the parameter list
- * \param name  the name for the constant
- * \param values  four float values
- * \return index/position of the new parameter in the parameter list
- */
-GLint
-_mesa_add_named_constant(struct gl_program_parameter_list *paramList,
-                         const char *name, const GLfloat values[4],
-                         GLuint size)
-{
-#if 0 /* disable this for now -- we need to save the name! */
-   GLint pos;
-   GLuint swizzle;
-   ASSERT(size == 4); /* XXX future feature */
-   /* check if we already have this constant */
-   if (_mesa_lookup_parameter_constant(paramList, values, 4, &pos, &swizzle)) {
-      return pos;
-   }
-#endif
-   size = 4; /** XXX fix */
-   return _mesa_add_parameter(paramList, name, values, size, PROGRAM_CONSTANT);
-}
-
-
-/**
- * Add a new unnamed constant to the parameter list.
- * This will be used when the program contains something like this:
- *    MOV r, { 0, 1, 2, 3 };
- *
- * \param paramList  the parameter list
- * \param values  four float values
- * \param swizzleOut  returns swizzle mask for accessing the constant
- * \return index/position of the new parameter in the parameter list.
- */
-GLint
-_mesa_add_unnamed_constant(struct gl_program_parameter_list *paramList,
-                           const GLfloat values[4], GLuint size,
-                           GLuint *swizzleOut)
-{
-   GLint pos;
-   GLuint swizzle;
-   ASSERT(size >= 1);
-   ASSERT(size <= 4);
-   size = 4; /* XXX temporary */
-   /* check if we already have this constant */
-   if (_mesa_lookup_parameter_constant(paramList, values,
-                                       size, &pos, &swizzle)) {
-      return pos;
-   }
-   return _mesa_add_parameter(paramList, NULL, values, size, PROGRAM_CONSTANT);
-}
-
-
-GLint
-_mesa_add_uniform(struct gl_program_parameter_list *paramList,
-                  const char *name, GLuint size)
-{
-   GLint i = _mesa_lookup_parameter_index(paramList, -1, name);
-   if (i >= 0 && paramList->Parameters[i].Type == PROGRAM_UNIFORM) {
-      /* already in list */
-      return i;
-   }
-   else {
-      assert(size == 4);
-      i = _mesa_add_parameter(paramList, name, NULL, size, PROGRAM_UNIFORM);
-      return i;
-   }
-}
-
-
-GLint
-_mesa_add_varying(struct gl_program_parameter_list *paramList,
-                  const char *name, GLuint size)
-{
-   GLint i = _mesa_lookup_parameter_index(paramList, -1, name);
-   if (i >= 0 && paramList->Parameters[i].Type == PROGRAM_VARYING) {
-      /* already in list */
-      return i;
-   }
-   else {
-      assert(size == 4);
-      i = _mesa_add_parameter(paramList, name, NULL, size, PROGRAM_VARYING);
-      return i;
-   }
-}
-
-
-
-
-#if 0 /* not used yet */
-/**
- * Returns the number of 4-component registers needed to store a piece
- * of GL state.  For matrices this may be as many as 4 registers,
- * everything else needs
- * just 1 register.
- */
-static GLuint
-sizeof_state_reference(const GLint *stateTokens)
-{
-   if (stateTokens[0] == STATE_MATRIX) {
-      GLuint rows = stateTokens[4] - stateTokens[3] + 1;
-      assert(rows >= 1);
-      assert(rows <= 4);
-      return rows;
-   }
-   else {
-      return 1;
-   }
-}
-#endif
-
-
 /**
- * Add a new state reference to the parameter list.
- * This will be used when the program contains something like this:
- *    PARAM ambient = state.material.front.ambient;
- *
- * \param paramList  the parameter list
- * \param state  an array of 6 state tokens
- * \return index of the new parameter.
+ * Return a copy of a program.
+ * XXX Problem here if the program object is actually OO-derivation
+ * made by a device driver.
  */
-GLint
-_mesa_add_state_reference(struct gl_program_parameter_list *paramList,
-                          const GLint *stateTokens)
+struct gl_program *
+_mesa_clone_program(GLcontext *ctx, const struct gl_program *prog)
 {
-   const GLuint size = 4; /* XXX fix */
-   const char *name;
-   GLint index;
-
-   /* Check if the state reference is already in the list */
-   for (index = 0; index < paramList->NumParameters; index++) {
-      GLuint i, match = 0;
-      for (i = 0; i < 6; i++) {
-         if (paramList->Parameters[index].StateIndexes[i] == stateTokens[i]) {
-            match++;
-         }
-         else {
-            break;
-         }
-      }
-      if (match == 6) {
-         /* this state reference is already in the parameter list */
-         return index;
-      }
-   }
-
-   name = make_state_string(stateTokens);
-   index = _mesa_add_parameter(paramList, name, NULL, size, PROGRAM_STATE_VAR);
-   if (index >= 0) {
-      GLuint i;
-      for (i = 0; i < 6; i++) {
-         paramList->Parameters[index].StateIndexes[i]
-            = (gl_state_index) stateTokens[i];
-      }
-      paramList->StateFlags |= make_state_flags(stateTokens);
-   }
-
-   /* free name string here since we duplicated it in add_parameter() */
-   _mesa_free((void *) name);
-
-   return index;
-}
-
+   struct gl_program *clone;
 
-/**
- * Lookup a parameter value by name in the given parameter list.
- * \return pointer to the float[4] values.
- */
-GLfloat *
-_mesa_lookup_parameter_value(const struct gl_program_parameter_list *paramList,
-                             GLsizei nameLen, const char *name)
-{
-   GLuint i = _mesa_lookup_parameter_index(paramList, nameLen, name);
-   if (i < 0)
+   clone = _mesa_new_program(ctx, prog->Target, prog->Id);
+   if (!clone)
       return NULL;
-   else
-      return paramList->ParameterValues[i];
-}
-
-
-/**
- * Given a program parameter name, find its position in the list of parameters.
- * \param paramList  the parameter list to search
- * \param nameLen  length of name (in chars).
- *                 If length is negative, assume that name is null-terminated.
- * \param name  the name to search for
- * \return index of parameter in the list.
- */
-GLint
-_mesa_lookup_parameter_index(const struct gl_program_parameter_list *paramList,
-                             GLsizei nameLen, const char *name)
-{
-   GLint i;
-
-   if (!paramList)
-      return -1;
 
-   if (nameLen == -1) {
-      /* name is null-terminated */
-      for (i = 0; i < (GLint) paramList->NumParameters; i++) {
-         if (paramList->Parameters[i].Name &&
-            _mesa_strcmp(paramList->Parameters[i].Name, name) == 0)
-            return i;
-      }
-   }
-   else {
-      /* name is not null-terminated, use nameLen */
-      for (i = 0; i < (GLint) paramList->NumParameters; i++) {
-         if (paramList->Parameters[i].Name &&
-            _mesa_strncmp(paramList->Parameters[i].Name, name, nameLen) == 0
-             && _mesa_strlen(paramList->Parameters[i].Name) == (size_t)nameLen)
-            return i;
-      }
+   assert(clone->Target == prog->Target);
+   clone->String = (GLubyte *) _mesa_strdup((char *) prog->String);
+   clone->RefCount = 1;
+   clone->Format = prog->Format;
+   clone->Instructions = _mesa_alloc_instructions(prog->NumInstructions);
+   if (!clone->Instructions) {
+      _mesa_delete_program(ctx, clone);
+      return NULL;
    }
-   return -1;
-}
-
-
-/**
- * Look for a float vector in the given parameter list.  The float vector
- * may be of length 1, 2, 3 or 4.
- * \param paramList  the parameter list to search
- * \param v  the float vector to search for
- * \param size  number of element in v
- * \param posOut  returns the position of the constant, if found
- * \param swizzleOut  returns a swizzle mask describing location of the
- *                    vector elements if found
- * \return GL_TRUE if found, GL_FALSE if not found
- */
-GLboolean
-_mesa_lookup_parameter_constant(const struct gl_program_parameter_list *paramList,
-                                const GLfloat v[], GLsizei vSize,
-                                GLint *posOut, GLuint *swizzleOut)
-{
-   GLuint i;
+   memcpy(clone->Instructions, prog->Instructions,
+          prog->NumInstructions * sizeof(struct prog_instruction));
+   clone->InputsRead = prog->InputsRead;
+   clone->OutputsWritten = prog->OutputsWritten;
+   clone->Parameters = _mesa_clone_parameter_list(prog->Parameters);
+   memcpy(clone->LocalParams, prog->LocalParams, sizeof(clone->LocalParams));
+   clone->Varying = _mesa_clone_parameter_list(prog->Varying);
+   memcpy(clone->LocalParams, prog->LocalParams, sizeof(clone->LocalParams));
+   clone->NumInstructions = prog->NumInstructions;
+   clone->NumTemporaries = prog->NumTemporaries;
+   clone->NumParameters = prog->NumParameters;
+   clone->NumAttributes = prog->NumAttributes;
+   clone->NumAddressRegs = prog->NumAddressRegs;
+   clone->NumNativeInstructions = prog->NumNativeInstructions;
+   clone->NumNativeTemporaries = prog->NumNativeTemporaries;
+   clone->NumNativeParameters = prog->NumNativeParameters;
+   clone->NumNativeAttributes = prog->NumNativeAttributes;
+   clone->NumNativeAddressRegs = prog->NumNativeAddressRegs;
 
-   assert(vSize >= 1);
-   assert(vSize <= 4);
-
-   if (!paramList)
-      return -1;
-
-   for (i = 0; i < paramList->NumParameters; i++) {
-      if (paramList->Parameters[i].Type == PROGRAM_CONSTANT) {
-         const GLint maxShift = 4 - vSize;
-         GLint shift, j;
-         for (shift = 0; shift <= maxShift; shift++) {
-            GLint matched = 0;
-            GLuint swizzle[4];
-            swizzle[0] = swizzle[1] = swizzle[2] = swizzle[3] = 0;
-            /* XXX we could do out-of-order swizzle matches too, someday */
-            for (j = 0; j < vSize; j++) {
-               assert(shift + j < 4);
-               if (paramList->ParameterValues[i][shift + j] == v[j]) {
-                  matched++;
-                  swizzle[j] = shift + j;
-                  ASSERT(swizzle[j] >= SWIZZLE_X);
-                  ASSERT(swizzle[j] <= SWIZZLE_W);
-               }
-            }
-            if (matched == vSize) {
-               /* found! */
-               *posOut = i;
-               *swizzleOut = MAKE_SWIZZLE4(swizzle[0], swizzle[1],
-                                           swizzle[2], swizzle[3]);
-               return GL_TRUE;
-            }
-         }
+   switch (prog->Target) {
+   case GL_VERTEX_PROGRAM_ARB:
+      {
+         const struct gl_vertex_program *vp
+            = (const struct gl_vertex_program *) prog;
+         struct gl_vertex_program *vpc = (struct gl_vertex_program *) clone;
+         vpc->IsPositionInvariant = vp->IsPositionInvariant;
       }
-   }
-
-   *posOut = -1;
-   return GL_FALSE;
-}
-
-
-struct gl_program_parameter_list *
-_mesa_clone_parameter_list(const struct gl_program_parameter_list *list)
-{
-   struct gl_program_parameter_list *clone;
-   GLuint i;
-
-   clone = _mesa_new_parameter_list();
-   if (!clone)
-      return NULL;
-
-   /** Not too efficient, but correct */
-   for (i = 0; i < list->NumParameters; i++) {
-      struct gl_program_parameter *p = list->Parameters + i;
-      GLint j = _mesa_add_parameter(clone, p->Name, list->ParameterValues[i],
-                                    p->Size, p->Type);
-      ASSERT(j >= 0);
-      /* copy state indexes */
-      if (p->Type == PROGRAM_STATE_VAR) {
-         GLint k;
-         struct gl_program_parameter *q = clone->Parameters + j;
-         for (k = 0; k < 6; k++) {
-            q->StateIndexes[k] = p->StateIndexes[k];
-         }
+      break;
+   case GL_FRAGMENT_PROGRAM_ARB:
+      {
+         const struct gl_fragment_program *fp
+            = (const struct gl_fragment_program *) prog;
+         struct gl_fragment_program *fpc = (struct gl_fragment_program *) clone;
+         memcpy(fpc->TexturesUsed, fp->TexturesUsed, sizeof(fp->TexturesUsed));
+         fpc->NumAluInstructions = fp->NumAluInstructions;
+         fpc->NumTexInstructions = fp->NumTexInstructions;
+         fpc->NumTexIndirections = fp->NumTexIndirections;
+         fpc->NumNativeAluInstructions = fp->NumNativeAluInstructions;
+         fpc->NumNativeTexInstructions = fp->NumNativeTexInstructions;
+         fpc->NumNativeTexIndirections = fp->NumNativeTexIndirections;
+         fpc->FogOption = fp->FogOption;
+         fpc->UsesKill = fp->UsesKill;
       }
+      break;
+   default:
+      _mesa_problem(NULL, "Unexpected target in _mesa_clone_program");
    }
 
    return clone;
 }
 
 
-/**
- * Use the list of tokens in the state[] array to find global GL state
- * and return it in <value>.  Usually, four values are returned in <value>
- * but matrix queries may return as many as 16 values.
- * This function is used for ARB vertex/fragment programs.
- * The program parser will produce the state[] values.
- */
-static void
-_mesa_fetch_state(GLcontext *ctx, const gl_state_index state[],
-                  GLfloat *value)
-{
-   switch (state[0]) {
-   case STATE_MATERIAL:
-      {
-         /* state[1] is either 0=front or 1=back side */
-         const GLuint face = (GLuint) state[1];
-         const struct gl_material *mat = &ctx->Light.Material;
-         ASSERT(face == 0 || face == 1);
-         /* we rely on tokens numbered so that _BACK_ == _FRONT_+ 1 */
-         ASSERT(MAT_ATTRIB_FRONT_AMBIENT + 1 == MAT_ATTRIB_BACK_AMBIENT);
-         /* XXX we could get rid of this switch entirely with a little
-          * work in arbprogparse.c's parse_state_single_item().
-          */
-         /* state[2] is the material attribute */
-         switch (state[2]) {
-         case STATE_AMBIENT:
-            COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_AMBIENT + face]);
-            return;
-         case STATE_DIFFUSE:
-            COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_DIFFUSE + face]);
-            return;
-         case STATE_SPECULAR:
-            COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_SPECULAR + face]);
-            return;
-         case STATE_EMISSION:
-            COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_EMISSION + face]);
-            return;
-         case STATE_SHININESS:
-            value[0] = mat->Attrib[MAT_ATTRIB_FRONT_SHININESS + face][0];
-            value[1] = 0.0F;
-            value[2] = 0.0F;
-            value[3] = 1.0F;
-            return;
-         default:
-            _mesa_problem(ctx, "Invalid material state in fetch_state");
-            return;
-         }
-      }
-   case STATE_LIGHT:
-      {
-         /* state[1] is the light number */
-         const GLuint ln = (GLuint) state[1];
-         /* state[2] is the light attribute */
-         switch (state[2]) {
-         case STATE_AMBIENT:
-            COPY_4V(value, ctx->Light.Light[ln].Ambient);
-            return;
-         case STATE_DIFFUSE:
-            COPY_4V(value, ctx->Light.Light[ln].Diffuse);
-            return;
-         case STATE_SPECULAR:
-            COPY_4V(value, ctx->Light.Light[ln].Specular);
-            return;
-         case STATE_POSITION:
-            COPY_4V(value, ctx->Light.Light[ln].EyePosition);
-            return;
-         case STATE_ATTENUATION:
-            value[0] = ctx->Light.Light[ln].ConstantAttenuation;
-            value[1] = ctx->Light.Light[ln].LinearAttenuation;
-            value[2] = ctx->Light.Light[ln].QuadraticAttenuation;
-            value[3] = ctx->Light.Light[ln].SpotExponent;
-            return;
-         case STATE_SPOT_DIRECTION:
-            COPY_3V(value, ctx->Light.Light[ln].EyeDirection);
-            value[3] = ctx->Light.Light[ln]._CosCutoff;
-            return;
-         case STATE_HALF:
-            {
-               GLfloat eye_z[] = {0, 0, 1};
-                                       
-               /* Compute infinite half angle vector:
-                *   half-vector = light_position + (0, 0, 1) 
-                * and then normalize.  w = 0
-               *
-               * light.EyePosition.w should be 0 for infinite lights.
-                */
-              ADD_3V(value, eye_z, ctx->Light.Light[ln].EyePosition);
-              NORMALIZE_3FV(value);
-              value[3] = 0;
-            }                                            
-            return;
-        case STATE_POSITION_NORMALIZED:
-            COPY_4V(value, ctx->Light.Light[ln].EyePosition);
-           NORMALIZE_3FV( value );
-            return;
-         default:
-            _mesa_problem(ctx, "Invalid light state in fetch_state");
-            return;
-         }
-      }
-   case STATE_LIGHTMODEL_AMBIENT:
-      COPY_4V(value, ctx->Light.Model.Ambient);
-      return;
-   case STATE_LIGHTMODEL_SCENECOLOR:
-      if (state[1] == 0) {
-         /* front */
-         GLint i;
-         for (i = 0; i < 3; i++) {
-            value[i] = ctx->Light.Model.Ambient[i]
-               * ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT][i]
-               + ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_EMISSION][i];
-         }
-        value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3];
-      }
-      else {
-         /* back */
-         GLint i;
-         for (i = 0; i < 3; i++) {
-            value[i] = ctx->Light.Model.Ambient[i]
-               * ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_AMBIENT][i]
-               + ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_EMISSION][i];
-         }
-        value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
-      }
-      return;
-   case STATE_LIGHTPROD:
-      {
-         const GLuint ln = (GLuint) state[1];
-         const GLuint face = (GLuint) state[2];
-         GLint i;
-         ASSERT(face == 0 || face == 1);
-         switch (state[3]) {
-            case STATE_AMBIENT:
-               for (i = 0; i < 3; i++) {
-                  value[i] = ctx->Light.Light[ln].Ambient[i] *
-                     ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT+face][i];
-               }
-               /* [3] = material alpha */
-               value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][3];
-               return;
-            case STATE_DIFFUSE:
-               for (i = 0; i < 3; i++) {
-                  value[i] = ctx->Light.Light[ln].Diffuse[i] *
-                     ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][i];
-               }
-               /* [3] = material alpha */
-               value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][3];
-               return;
-            case STATE_SPECULAR:
-               for (i = 0; i < 3; i++) {
-                  value[i] = ctx->Light.Light[ln].Specular[i] *
-                     ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_SPECULAR+face][i];
-               }
-               /* [3] = material alpha */
-               value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][3];
-               return;
-            default:
-               _mesa_problem(ctx, "Invalid lightprod state in fetch_state");
-               return;
-         }
-      }
-   case STATE_TEXGEN:
-      {
-         /* state[1] is the texture unit */
-         const GLuint unit = (GLuint) state[1];
-         /* state[2] is the texgen attribute */
-         switch (state[2]) {
-         case STATE_TEXGEN_EYE_S:
-            COPY_4V(value, ctx->Texture.Unit[unit].EyePlaneS);
-            return;
-         case STATE_TEXGEN_EYE_T:
-            COPY_4V(value, ctx->Texture.Unit[unit].EyePlaneT);
-            return;
-         case STATE_TEXGEN_EYE_R:
-            COPY_4V(value, ctx->Texture.Unit[unit].EyePlaneR);
-            return;
-         case STATE_TEXGEN_EYE_Q:
-            COPY_4V(value, ctx->Texture.Unit[unit].EyePlaneQ);
-            return;
-         case STATE_TEXGEN_OBJECT_S:
-            COPY_4V(value, ctx->Texture.Unit[unit].ObjectPlaneS);
-            return;
-         case STATE_TEXGEN_OBJECT_T:
-            COPY_4V(value, ctx->Texture.Unit[unit].ObjectPlaneT);
-            return;
-         case STATE_TEXGEN_OBJECT_R:
-            COPY_4V(value, ctx->Texture.Unit[unit].ObjectPlaneR);
-            return;
-         case STATE_TEXGEN_OBJECT_Q:
-            COPY_4V(value, ctx->Texture.Unit[unit].ObjectPlaneQ);
-            return;
-         default:
-            _mesa_problem(ctx, "Invalid texgen state in fetch_state");
-            return;
-         }
-      }
-   case STATE_TEXENV_COLOR:
-      {                
-         /* state[1] is the texture unit */
-         const GLuint unit = (GLuint) state[1];
-         COPY_4V(value, ctx->Texture.Unit[unit].EnvColor);
-      }                        
-      return;
-   case STATE_FOG_COLOR:
-      COPY_4V(value, ctx->Fog.Color);
-      return;
-   case STATE_FOG_PARAMS:
-      value[0] = ctx->Fog.Density;
-      value[1] = ctx->Fog.Start;
-      value[2] = ctx->Fog.End;
-      value[3] = 1.0F / (ctx->Fog.End - ctx->Fog.Start);
-      return;
-   case STATE_CLIPPLANE:
-      {
-         const GLuint plane = (GLuint) state[1];
-         COPY_4V(value, ctx->Transform.EyeUserPlane[plane]);
-      }
-      return;
-   case STATE_POINT_SIZE:
-      value[0] = ctx->Point.Size;
-      value[1] = ctx->Point.MinSize;
-      value[2] = ctx->Point.MaxSize;
-      value[3] = ctx->Point.Threshold;
-      return;
-   case STATE_POINT_ATTENUATION:
-      value[0] = ctx->Point.Params[0];
-      value[1] = ctx->Point.Params[1];
-      value[2] = ctx->Point.Params[2];
-      value[3] = 1.0F;
-      return;
-   case STATE_MATRIX:
-      {
-         /* state[1] = modelview, projection, texture, etc. */
-         /* state[2] = which texture matrix or program matrix */
-         /* state[3] = first row to fetch */
-         /* state[4] = last row to fetch */
-         /* state[5] = transpose, inverse or invtrans */
-
-         const GLmatrix *matrix;
-         const gl_state_index mat = state[1];
-         const GLuint index = (GLuint) state[2];
-         const GLuint firstRow = (GLuint) state[3];
-         const GLuint lastRow = (GLuint) state[4];
-         const gl_state_index modifier = state[5];
-         const GLfloat *m;
-         GLuint row, i;
-         if (mat == STATE_MODELVIEW) {
-            matrix = ctx->ModelviewMatrixStack.Top;
-         }
-         else if (mat == STATE_PROJECTION) {
-            matrix = ctx->ProjectionMatrixStack.Top;
-         }
-         else if (mat == STATE_MVP) {
-            matrix = &ctx->_ModelProjectMatrix;
-         }
-         else if (mat == STATE_TEXTURE) {
-            matrix = ctx->TextureMatrixStack[index].Top;
-         }
-         else if (mat == STATE_PROGRAM) {
-            matrix = ctx->ProgramMatrixStack[index].Top;
-         }
-         else {
-            _mesa_problem(ctx, "Bad matrix name in _mesa_fetch_state()");
-            return;
-         }
-         if (modifier == STATE_MATRIX_INVERSE ||
-             modifier == STATE_MATRIX_INVTRANS) {
-            /* Be sure inverse is up to date:
-            */
-            _math_matrix_alloc_inv( (GLmatrix *) matrix );
-           _math_matrix_analyse( (GLmatrix*) matrix );
-            m = matrix->inv;
-         }
-         else {
-            m = matrix->m;
-         }
-         if (modifier == STATE_MATRIX_TRANSPOSE ||
-             modifier == STATE_MATRIX_INVTRANS) {
-            for (i = 0, row = firstRow; row <= lastRow; row++) {
-               value[i++] = m[row * 4 + 0];
-               value[i++] = m[row * 4 + 1];
-               value[i++] = m[row * 4 + 2];
-               value[i++] = m[row * 4 + 3];
-            }
-         }
-         else {
-            for (i = 0, row = firstRow; row <= lastRow; row++) {
-               value[i++] = m[row + 0];
-               value[i++] = m[row + 4];
-               value[i++] = m[row + 8];
-               value[i++] = m[row + 12];
-            }
-         }
-      }
-      return;
-   case STATE_DEPTH_RANGE:
-      value[0] = ctx->Viewport.Near;                     /* near       */
-      value[1] = ctx->Viewport.Far;                      /* far        */
-      value[2] = ctx->Viewport.Far - ctx->Viewport.Near; /* far - near */
-      value[3] = 0;
-      return;
-   case STATE_FRAGMENT_PROGRAM:
-      {
-         /* state[1] = {STATE_ENV, STATE_LOCAL} */
-         /* state[2] = parameter index          */
-         const int idx = (int) state[2];
-         switch (state[1]) {
-            case STATE_ENV:
-               COPY_4V(value, ctx->FragmentProgram.Parameters[idx]);
-               break;
-            case STATE_LOCAL:
-               COPY_4V(value, ctx->FragmentProgram.Current->Base.LocalParams[idx]);
-               break;
-            default:
-               _mesa_problem(ctx, "Bad state switch in _mesa_fetch_state()");
-               return;
-         }
-      }
-      return;
-               
-   case STATE_VERTEX_PROGRAM:
-      {
-         /* state[1] = {STATE_ENV, STATE_LOCAL} */
-         /* state[2] = parameter index          */
-         const int idx = (int) state[2];
-         switch (state[1]) {
-            case STATE_ENV:
-               COPY_4V(value, ctx->VertexProgram.Parameters[idx]);
-               break;
-            case STATE_LOCAL:
-               COPY_4V(value, ctx->VertexProgram.Current->Base.LocalParams[idx]);
-               break;
-            default:
-               _mesa_problem(ctx, "Bad state switch in _mesa_fetch_state()");
-               return;
-         }
-      }
-      return;
-
-   case STATE_INTERNAL:
-      {
-         switch (state[1]) {
-           case STATE_NORMAL_SCALE:
-               ASSIGN_4V(value, ctx->_ModelViewInvScale, 0, 0, 1);
-               break;
-           case STATE_TEXRECT_SCALE: {
-              const int unit = (int) state[2];
-              const struct gl_texture_object *texObj = ctx->Texture.Unit[unit]._Current;
-              if (texObj) {
-                 struct gl_texture_image *texImage = texObj->Image[0][0];
-                 ASSIGN_4V(value, 1.0 / texImage->Width, 1.0 / texImage->Height, 0, 1);
-              }
-               break;
-           }
-           default:
-              /* unknown state indexes are silently ignored
-              *  should be handled by the driver.
-              */
-               return;
-         }
-      }
-      return;
-
-   default:
-      _mesa_problem(ctx, "Invalid state in _mesa_fetch_state");
-      return;
-   }
-}
-
-
-/**
- * Return a bitmask of the Mesa state flags (_NEW_* values) which would
- * indicate that the given context state may have changed.
- * The bitmask is used during validation to determine if we need to update
- * vertex/fragment program parameters (like "state.material.color") when
- * some GL state has changed.
- */
-static GLbitfield
-make_state_flags(const GLint state[])
-{
-   switch (state[0]) {
-   case STATE_MATERIAL:
-   case STATE_LIGHT:
-   case STATE_LIGHTMODEL_AMBIENT:
-   case STATE_LIGHTMODEL_SCENECOLOR:
-   case STATE_LIGHTPROD:
-      return _NEW_LIGHT;
-
-   case STATE_TEXGEN:
-   case STATE_TEXENV_COLOR:
-      return _NEW_TEXTURE;
-
-   case STATE_FOG_COLOR:
-   case STATE_FOG_PARAMS:
-      return _NEW_FOG;
-
-   case STATE_CLIPPLANE:
-      return _NEW_TRANSFORM;
-
-   case STATE_POINT_SIZE:
-   case STATE_POINT_ATTENUATION:
-      return _NEW_POINT;
-
-   case STATE_MATRIX:
-      switch (state[1]) {
-      case STATE_MODELVIEW:
-        return _NEW_MODELVIEW;
-      case STATE_PROJECTION:
-        return _NEW_PROJECTION;
-      case STATE_MVP:
-        return _NEW_MODELVIEW | _NEW_PROJECTION;
-      case STATE_TEXTURE:
-        return _NEW_TEXTURE_MATRIX;
-      case STATE_PROGRAM:
-        return _NEW_TRACK_MATRIX;
-      default:
-        _mesa_problem(NULL, "unexpected matrix in make_state_flags()");
-        return 0;
-      }
-
-   case STATE_DEPTH_RANGE:
-      return _NEW_VIEWPORT;
-
-   case STATE_FRAGMENT_PROGRAM:
-   case STATE_VERTEX_PROGRAM:
-      return _NEW_PROGRAM;
-
-   case STATE_INTERNAL:
-      switch (state[1]) {
-      case STATE_NORMAL_SCALE:
-        return _NEW_MODELVIEW;
-      case STATE_TEXRECT_SCALE:
-        return _NEW_TEXTURE;
-      default:
-         /* unknown state indexes are silently ignored and
-         *  no flag set, since it is handled by the driver.
-         */
-        return 0;
-      }
-
-   default:
-      _mesa_problem(NULL, "unexpected state[0] in make_state_flags()");
-      return 0;
-   }
-}
-
-
-static void
-append(char *dst, const char *src)
-{
-   while (*dst)
-      dst++;
-   while (*src)
-     *dst++ = *src++;
-   *dst = 0;
-}
-
-
-static void
-append_token(char *dst, gl_state_index k)
-{
-   switch (k) {
-   case STATE_MATERIAL:
-      append(dst, "material.");
-      break;
-   case STATE_LIGHT:
-      append(dst, "light");
-      break;
-   case STATE_LIGHTMODEL_AMBIENT:
-      append(dst, "lightmodel.ambient");
-      break;
-   case STATE_LIGHTMODEL_SCENECOLOR:
-      break;
-   case STATE_LIGHTPROD:
-      append(dst, "lightprod");
-      break;
-   case STATE_TEXGEN:
-      append(dst, "texgen");
-      break;
-   case STATE_FOG_COLOR:
-      append(dst, "fog.color");
-      break;
-   case STATE_FOG_PARAMS:
-      append(dst, "fog.params");
-      break;
-   case STATE_CLIPPLANE:
-      append(dst, "clip");
-      break;
-   case STATE_POINT_SIZE:
-      append(dst, "point.size");
-      break;
-   case STATE_POINT_ATTENUATION:
-      append(dst, "point.attenuation");
-      break;
-   case STATE_MATRIX:
-      append(dst, "matrix.");
-      break;
-   case STATE_MODELVIEW:
-      append(dst, "modelview");
-      break;
-   case STATE_PROJECTION:
-      append(dst, "projection");
-      break;
-   case STATE_MVP:
-      append(dst, "mvp");
-      break;
-   case STATE_TEXTURE:
-      append(dst, "texture");
-      break;
-   case STATE_PROGRAM:
-      append(dst, "program");
-      break;
-   case STATE_MATRIX_INVERSE:
-      append(dst, ".inverse");
-      break;
-   case STATE_MATRIX_TRANSPOSE:
-      append(dst, ".transpose");
-      break;
-   case STATE_MATRIX_INVTRANS:
-      append(dst, ".invtrans");
-      break;
-   case STATE_AMBIENT:
-      append(dst, "ambient");
-      break;
-   case STATE_DIFFUSE:
-      append(dst, "diffuse");
-      break;
-   case STATE_SPECULAR:
-      append(dst, "specular");
-      break;
-   case STATE_EMISSION:
-      append(dst, "emission");
-      break;
-   case STATE_SHININESS:
-      append(dst, "shininess");
-      break;
-   case STATE_HALF:
-      append(dst, "half");
-      break;
-   case STATE_POSITION:
-      append(dst, ".position");
-      break;
-   case STATE_ATTENUATION:
-      append(dst, ".attenuation");
-      break;
-   case STATE_SPOT_DIRECTION:
-      append(dst, ".spot.direction");
-      break;
-   case STATE_TEXGEN_EYE_S:
-      append(dst, "eye.s");
-      break;
-   case STATE_TEXGEN_EYE_T:
-      append(dst, "eye.t");
-      break;
-   case STATE_TEXGEN_EYE_R:
-      append(dst, "eye.r");
-      break;
-   case STATE_TEXGEN_EYE_Q:
-      append(dst, "eye.q");
-      break;
-   case STATE_TEXGEN_OBJECT_S:
-      append(dst, "object.s");
-      break;
-   case STATE_TEXGEN_OBJECT_T:
-      append(dst, "object.t");
-      break;
-   case STATE_TEXGEN_OBJECT_R:
-      append(dst, "object.r");
-      break;
-   case STATE_TEXGEN_OBJECT_Q:
-      append(dst, "object.q");
-      break;
-   case STATE_TEXENV_COLOR:
-      append(dst, "texenv");
-      break;
-   case STATE_DEPTH_RANGE:
-      append(dst, "depth.range");
-      break;
-   case STATE_VERTEX_PROGRAM:
-   case STATE_FRAGMENT_PROGRAM:
-      break;
-   case STATE_ENV:
-      append(dst, "env");
-      break;
-   case STATE_LOCAL:
-      append(dst, "local");
-      break;
-   case STATE_INTERNAL:
-   case STATE_NORMAL_SCALE:
-   case STATE_POSITION_NORMALIZED:
-      append(dst, "(internal)");
-      break;
-   default:
-      ;
-   }
-}
-
-static void
-append_face(char *dst, GLint face)
-{
-   if (face == 0)
-      append(dst, "front.");
-   else
-      append(dst, "back.");
-}
-
-static void
-append_index(char *dst, GLint index)
-{
-   char s[20];
-   _mesa_sprintf(s, "[%d].", index);
-   append(dst, s);
-}
-
-/**
- * Make a string from the given state vector.
- * For example, return "state.matrix.texture[2].inverse".
- * Use _mesa_free() to deallocate the string.
- */
-static const char *
-make_state_string(const GLint state[6])
-{
-   char str[1000] = "";
-   char tmp[30];
-
-   append(str, "state.");
-   append_token(str, (gl_state_index) state[0]);
-
-   switch (state[0]) {
-   case STATE_MATERIAL:
-      append_face(str, state[1]);
-      append_token(str, (gl_state_index) state[2]);
-      break;
-   case STATE_LIGHT:
-      append(str, "light");
-      append_index(str, state[1]); /* light number [i]. */
-      append_token(str, (gl_state_index) state[2]); /* coefficients */
-      break;
-   case STATE_LIGHTMODEL_AMBIENT:
-      append(str, "lightmodel.ambient");
-      break;
-   case STATE_LIGHTMODEL_SCENECOLOR:
-      if (state[1] == 0) {
-         append(str, "lightmodel.front.scenecolor");
-      }
-      else {
-         append(str, "lightmodel.back.scenecolor");
-      }
-      break;
-   case STATE_LIGHTPROD:
-      append_index(str, state[1]); /* light number [i]. */
-      append_face(str, state[2]);
-      append_token(str, (gl_state_index) state[3]);
-      break;
-   case STATE_TEXGEN:
-      append_index(str, state[1]); /* tex unit [i] */
-      append_token(str, (gl_state_index) state[2]); /* plane coef */
-      break;
-   case STATE_TEXENV_COLOR:
-      append_index(str, state[1]); /* tex unit [i] */
-      append(str, "color");
-      break;
-   case STATE_FOG_COLOR:
-   case STATE_FOG_PARAMS:
-      break;
-   case STATE_CLIPPLANE:
-      append_index(str, state[1]); /* plane [i] */
-      append(str, "plane");
-      break;
-   case STATE_POINT_SIZE:
-   case STATE_POINT_ATTENUATION:
-      break;
-   case STATE_MATRIX:
-      {
-         /* state[1] = modelview, projection, texture, etc. */
-         /* state[2] = which texture matrix or program matrix */
-         /* state[3] = first row to fetch */
-         /* state[4] = last row to fetch */
-         /* state[5] = transpose, inverse or invtrans */
-         const gl_state_index mat = (gl_state_index) state[1];
-         const GLuint index = (GLuint) state[2];
-         const GLuint firstRow = (GLuint) state[3];
-         const GLuint lastRow = (GLuint) state[4];
-         const gl_state_index modifier = (gl_state_index) state[5];
-         append_token(str, mat);
-         if (index)
-            append_index(str, index);
-         if (modifier)
-            append_token(str, modifier);
-         if (firstRow == lastRow)
-            _mesa_sprintf(tmp, ".row[%d]", firstRow);
-         else
-            _mesa_sprintf(tmp, ".row[%d..%d]", firstRow, lastRow);
-         append(str, tmp);
-      }
-      break;
-   case STATE_DEPTH_RANGE:
-      break;
-   case STATE_FRAGMENT_PROGRAM:
-   case STATE_VERTEX_PROGRAM:
-      /* state[1] = {STATE_ENV, STATE_LOCAL} */
-      /* state[2] = parameter index          */
-      append_token(str, (gl_state_index) state[1]);
-      append_index(str, state[2]);
-      break;
-   case STATE_INTERNAL:
-      break;
-   default:
-      _mesa_problem(NULL, "Invalid state in make_state_string");
-      break;
-   }
-
-   return _mesa_strdup(str);
-}
-
-
-/**
- * Loop over all the parameters in a parameter list.  If the parameter
- * is a GL state reference, look up the current value of that state
- * variable and put it into the parameter's Value[4] array.
- * This would be called at glBegin time when using a fragment program.
- */
-void
-_mesa_load_state_parameters(GLcontext *ctx,
-                            struct gl_program_parameter_list *paramList)
-{
-   GLuint i;
-
-   if (!paramList)
-      return;
-
-   for (i = 0; i < paramList->NumParameters; i++) {
-      if (paramList->Parameters[i].Type == PROGRAM_STATE_VAR) {
-         _mesa_fetch_state(ctx, 
-                          paramList->Parameters[i].StateIndexes,
-                           paramList->ParameterValues[i]);
-      }
-   }
-}
-
-
-/**
- * Initialize program instruction fields to defaults.
- * \param inst  first instruction to initialize
- * \param count  number of instructions to initialize
- */
-void
-_mesa_init_instructions(struct prog_instruction *inst, GLuint count)
-{
-   GLuint i;
-
-   _mesa_bzero(inst, count * sizeof(struct prog_instruction));
-
-   for (i = 0; i < count; i++) {
-      inst[i].SrcReg[0].File = PROGRAM_UNDEFINED;
-      inst[i].SrcReg[0].Swizzle = SWIZZLE_NOOP;
-      inst[i].SrcReg[1].File = PROGRAM_UNDEFINED;
-      inst[i].SrcReg[1].Swizzle = SWIZZLE_NOOP;
-      inst[i].SrcReg[2].File = PROGRAM_UNDEFINED;
-      inst[i].SrcReg[2].Swizzle = SWIZZLE_NOOP;
-
-      inst[i].DstReg.File = PROGRAM_UNDEFINED;
-      inst[i].DstReg.WriteMask = WRITEMASK_XYZW;
-      inst[i].DstReg.CondMask = COND_TR;
-      inst[i].DstReg.CondSwizzle = SWIZZLE_NOOP;
-
-      inst[i].SaturateMode = SATURATE_OFF;
-      inst[i].Precision = FLOAT32;
-   }
-}
-
-
-/**
- * Allocate an array of program instructions.
- * \param numInst  number of instructions
- * \return pointer to instruction memory
- */
-struct prog_instruction *
-_mesa_alloc_instructions(GLuint numInst)
-{
-   return (struct prog_instruction *)
-      _mesa_calloc(numInst * sizeof(struct prog_instruction));
-}
-
-
-/**
- * Reallocate memory storing an array of program instructions.
- * This is used when we need to append additional instructions onto an
- * program.
- * \param oldInst  pointer to first of old/src instructions
- * \param numOldInst  number of instructions at <oldInst>
- * \param numNewInst  desired size of new instruction array.
- * \return  pointer to start of new instruction array.
- */
-struct prog_instruction *
-_mesa_realloc_instructions(struct prog_instruction *oldInst,
-                           GLuint numOldInst, GLuint numNewInst)
-{
-   struct prog_instruction *newInst;
-
-   newInst = (struct prog_instruction *)
-      _mesa_realloc(oldInst,
-                    numOldInst * sizeof(struct prog_instruction),
-                    numNewInst * sizeof(struct prog_instruction));
-
-   return newInst;
-}
-
-
-/**
- * Return a copy of a program.
- * XXX Problem here if the program object is actually OO-derivation
- * made by a device driver.
- */
-struct gl_program *
-_mesa_clone_program(GLcontext *ctx, const struct gl_program *prog)
-{
-   struct gl_program *clone;
-
-   clone = _mesa_new_program(ctx, prog->Target, prog->Id);
-   if (!clone)
-      return NULL;
-
-   assert(clone->Target == prog->Target);
-   clone->String = (GLubyte *) _mesa_strdup((char *) prog->String);
-   clone->RefCount = 1;
-   clone->Format = prog->Format;
-   clone->Instructions = _mesa_alloc_instructions(prog->NumInstructions);
-   if (!clone->Instructions) {
-      _mesa_delete_program(ctx, clone);
-      return NULL;
-   }
-   memcpy(clone->Instructions, prog->Instructions,
-          prog->NumInstructions * sizeof(struct prog_instruction));
-   clone->InputsRead = prog->InputsRead;
-   clone->OutputsWritten = prog->OutputsWritten;
-   clone->Parameters = _mesa_clone_parameter_list(prog->Parameters);
-   memcpy(clone->LocalParams, prog->LocalParams, sizeof(clone->LocalParams));
-   clone->Varying = _mesa_clone_parameter_list(prog->Varying);
-   memcpy(clone->LocalParams, prog->LocalParams, sizeof(clone->LocalParams));
-   clone->NumInstructions = prog->NumInstructions;
-   clone->NumTemporaries = prog->NumTemporaries;
-   clone->NumParameters = prog->NumParameters;
-   clone->NumAttributes = prog->NumAttributes;
-   clone->NumAddressRegs = prog->NumAddressRegs;
-   clone->NumNativeInstructions = prog->NumNativeInstructions;
-   clone->NumNativeTemporaries = prog->NumNativeTemporaries;
-   clone->NumNativeParameters = prog->NumNativeParameters;
-   clone->NumNativeAttributes = prog->NumNativeAttributes;
-   clone->NumNativeAddressRegs = prog->NumNativeAddressRegs;
-
-   switch (prog->Target) {
-   case GL_VERTEX_PROGRAM_ARB:
-      {
-         const struct gl_vertex_program *vp
-            = (const struct gl_vertex_program *) prog;
-         struct gl_vertex_program *vpc = (struct gl_vertex_program *) clone;
-         vpc->IsPositionInvariant = vp->IsPositionInvariant;
-      }
-      break;
-   case GL_FRAGMENT_PROGRAM_ARB:
-      {
-         const struct gl_fragment_program *fp
-            = (const struct gl_fragment_program *) prog;
-         struct gl_fragment_program *fpc = (struct gl_fragment_program *) clone;
-         memcpy(fpc->TexturesUsed, fp->TexturesUsed, sizeof(fp->TexturesUsed));
-         fpc->NumAluInstructions = fp->NumAluInstructions;
-         fpc->NumTexInstructions = fp->NumTexInstructions;
-         fpc->NumTexIndirections = fp->NumTexIndirections;
-         fpc->NumNativeAluInstructions = fp->NumNativeAluInstructions;
-         fpc->NumNativeTexInstructions = fp->NumNativeTexInstructions;
-         fpc->NumNativeTexIndirections = fp->NumNativeTexIndirections;
-         fpc->FogOption = fp->FogOption;
-         fpc->UsesKill = fp->UsesKill;
-      }
-      break;
-   default:
-      _mesa_problem(NULL, "Unexpected target in _mesa_clone_program");
-   }
-
-   return clone;
-}
-
-
-
-/**
- * Basic info about each instruction
- */
-struct instruction_info
-{
-   gl_inst_opcode Opcode;
-   const char *Name;
-   GLuint NumSrcRegs;
-};
-
-/**
- * Instruction info
- * \note Opcode should equal array index!
- */
-static const struct instruction_info InstInfo[MAX_OPCODE] = {
-   { OPCODE_NOP,    "NOP",   0 },
-   { OPCODE_ABS,    "ABS",   1 },
-   { OPCODE_ADD,    "ADD",   2 },
-   { OPCODE_ARA,    "ARA",   1 },
-   { OPCODE_ARL,    "ARL",   1 },
-   { OPCODE_ARL_NV, "ARL",   1 },
-   { OPCODE_ARR,    "ARL",   1 },
-   { OPCODE_BRA,    "BRA",   0 },
-   { OPCODE_CAL,    "CAL",   0 },
-   { OPCODE_CMP,    "CMP",   3 },
-   { OPCODE_COS,    "COS",   1 },
-   { OPCODE_DDX,    "DDX",   1 },
-   { OPCODE_DDY,    "DDY",   1 },
-   { OPCODE_DP3,    "DP3",   2 },
-   { OPCODE_DP4,    "DP4",   2 },
-   { OPCODE_DPH,    "DPH",   2 },
-   { OPCODE_DST,    "DST",   2 },
-   { OPCODE_END,    "END",   0 },
-   { OPCODE_EX2,    "EX2",   1 },
-   { OPCODE_EXP,    "EXP",   1 },
-   { OPCODE_FLR,    "FLR",   1 },
-   { OPCODE_FRC,    "FRC",   1 },
-   { OPCODE_KIL,    "KIL",   1 },
-   { OPCODE_KIL_NV, "KIL",   0 },
-   { OPCODE_LG2,    "LG2",   1 },
-   { OPCODE_LIT,    "LIT",   1 },
-   { OPCODE_LOG,    "LOG",   1 },
-   { OPCODE_LRP,    "LRP",   3 },
-   { OPCODE_MAD,    "MAD",   3 },
-   { OPCODE_MAX,    "MAX",   2 },
-   { OPCODE_MIN,    "MIN",   2 },
-   { OPCODE_MOV,    "MOV",   1 },
-   { OPCODE_MUL,    "MUL",   2 },
-   { OPCODE_PK2H,   "PK2H",  1 },
-   { OPCODE_PK2US,  "PK2US", 1 },
-   { OPCODE_PK4B,   "PK4B",  1 },
-   { OPCODE_PK4UB,  "PK4UB", 1 },
-   { OPCODE_POW,    "POW",   2 },
-   { OPCODE_POPA,   "POPA",  0 },
-   { OPCODE_PRINT,  "PRINT", 1 },
-   { OPCODE_PUSHA,  "PUSHA", 0 },
-   { OPCODE_RCC,    "RCC",   1 },
-   { OPCODE_RCP,    "RCP",   1 },
-   { OPCODE_RET,    "RET",   0 },
-   { OPCODE_RFL,    "RFL",   1 },
-   { OPCODE_RSQ,    "RSQ",   1 },
-   { OPCODE_SCS,    "SCS",   1 },
-   { OPCODE_SEQ,    "SEQ",   2 },
-   { OPCODE_SFL,    "SFL",   0 },
-   { OPCODE_SGE,    "SGE",   2 },
-   { OPCODE_SGT,    "SGT",   2 },
-   { OPCODE_SIN,    "SIN",   1 },
-   { OPCODE_SLE,    "SLE",   2 },
-   { OPCODE_SLT,    "SLT",   2 },
-   { OPCODE_SNE,    "SNE",   2 },
-   { OPCODE_SSG,    "SSG",   1 },
-   { OPCODE_STR,    "STR",   0 },
-   { OPCODE_SUB,    "SUB",   2 },
-   { OPCODE_SWZ,    "SWZ",   1 },
-   { OPCODE_TEX,    "TEX",   1 },
-   { OPCODE_TXB,    "TXB",   1 },
-   { OPCODE_TXD,    "TXD",   3 },
-   { OPCODE_TXL,    "TXL",   1 },
-   { OPCODE_TXP,    "TXP",   1 },
-   { OPCODE_TXP_NV, "TXP",   1 },
-   { OPCODE_UP2H,   "UP2H",  1 },
-   { OPCODE_UP2US,  "UP2US", 1 },
-   { OPCODE_UP4B,   "UP4B",  1 },
-   { OPCODE_UP4UB,  "UP4UB", 1 },
-   { OPCODE_X2D,    "X2D",   3 },
-   { OPCODE_XPD,    "XPD",   2 }
-};
-
-
-/**
- * Return the number of src registers for the given instruction/opcode.
- */
-GLuint
-_mesa_num_inst_src_regs(gl_inst_opcode opcode)
-{
-   ASSERT(opcode == InstInfo[opcode].Opcode);
-   ASSERT(OPCODE_XPD == InstInfo[OPCODE_XPD].Opcode);
-   return InstInfo[opcode].NumSrcRegs;
-}
-
-
-/**
- * Return string name for given program opcode.
- */
-const char *
-_mesa_opcode_string(gl_inst_opcode opcode)
-{
-   ASSERT(opcode < MAX_OPCODE);
-   return InstInfo[opcode].Name;
-}
-
-/**
- * Return string name for given program/register file.
- */
-static const char *
-program_file_string(enum register_file f)
-{
-   switch (f) {
-   case PROGRAM_TEMPORARY:
-      return "TEMP";
-   case PROGRAM_LOCAL_PARAM:
-      return "LOCAL";
-   case PROGRAM_ENV_PARAM:
-      return "ENV";
-   case PROGRAM_STATE_VAR:
-      return "STATE";
-   case PROGRAM_INPUT:
-      return "INPUT";
-   case PROGRAM_OUTPUT:
-      return "OUTPUT";
-   case PROGRAM_NAMED_PARAM:
-      return "NAMED";
-   case PROGRAM_CONSTANT:
-      return "CONST";
-   case PROGRAM_UNIFORM:
-      return "UNIFORM";
-   case PROGRAM_VARYING:
-      return "VARYING";
-   case PROGRAM_WRITE_ONLY:
-      return "WRITE_ONLY";
-   case PROGRAM_ADDRESS:
-      return "ADDR";
-   default:
-      return "Unknown program file!";
-   }
-}
-
-
-/**
- * Return a string representation of the given swizzle word.
- * If extended is true, use extended (comma-separated) format.
- */
-static const char *
-swizzle_string(GLuint swizzle, GLuint negateBase, GLboolean extended)
-{
-   static const char swz[] = "xyzw01";
-   static char s[20];
-   GLuint i = 0;
-
-   if (!extended && swizzle == SWIZZLE_NOOP && negateBase == 0)
-      return ""; /* no swizzle/negation */
-
-   if (!extended)
-      s[i++] = '.';
-
-   if (negateBase & 0x1)
-      s[i++] = '-';
-   s[i++] = swz[GET_SWZ(swizzle, 0)];
-
-   if (extended) {
-      s[i++] = ',';
-   }
-
-   if (negateBase & 0x2)
-      s[i++] = '-';
-   s[i++] = swz[GET_SWZ(swizzle, 1)];
-
-   if (extended) {
-      s[i++] = ',';
-   }
-
-   if (negateBase & 0x4)
-      s[i++] = '-';
-   s[i++] = swz[GET_SWZ(swizzle, 2)];
-
-   if (extended) {
-      s[i++] = ',';
-   }
-
-   if (negateBase & 0x8)
-      s[i++] = '-';
-   s[i++] = swz[GET_SWZ(swizzle, 3)];
-
-   s[i] = 0;
-   return s;
-}
-
-
-static const char *
-writemask_string(GLuint writeMask)
-{
-   static char s[10];
-   GLuint i = 0;
-
-   if (writeMask == WRITEMASK_XYZW)
-      return "";
-
-   s[i++] = '.';
-   if (writeMask & WRITEMASK_X)
-      s[i++] = 'x';
-   if (writeMask & WRITEMASK_Y)
-      s[i++] = 'y';
-   if (writeMask & WRITEMASK_Z)
-      s[i++] = 'z';
-   if (writeMask & WRITEMASK_W)
-      s[i++] = 'w';
-
-   s[i] = 0;
-   return s;
-}
-
-static void
-print_dst_reg(const struct prog_dst_register *dstReg)
-{
-   _mesa_printf(" %s[%d]%s",
-                program_file_string((enum register_file) dstReg->File),
-                dstReg->Index,
-                writemask_string(dstReg->WriteMask));
-}
-
-static void
-print_src_reg(const struct prog_src_register *srcReg)
-{
-   _mesa_printf("%s[%d]%s",
-                program_file_string((enum register_file) srcReg->File),
-                srcReg->Index,
-                swizzle_string(srcReg->Swizzle,
-                               srcReg->NegateBase, GL_FALSE));
-}
-
-static void
-print_comment(const struct prog_instruction *inst)
-{
-   if (inst->Comment)
-      _mesa_printf(";  # %s\n", inst->Comment);
-   else
-      _mesa_printf(";\n");
-}
-
-
-void
-_mesa_print_alu_instruction(const struct prog_instruction *inst,
-                           const char *opcode_string, 
-                           GLuint numRegs)
-{
-   GLuint j;
-
-   _mesa_printf("%s", opcode_string);
-
-   /* frag prog only */
-   if (inst->SaturateMode == SATURATE_ZERO_ONE)
-      _mesa_printf("_SAT");
-
-   if (inst->DstReg.File != PROGRAM_UNDEFINED) {
-      _mesa_printf(" %s[%d]%s",
-                  program_file_string((enum register_file) inst->DstReg.File),
-                  inst->DstReg.Index,
-                  writemask_string(inst->DstReg.WriteMask));
-   }
-   else {
-      _mesa_printf(" ???");
-   }
-
-   if (numRegs > 0)
-      _mesa_printf(", ");
-
-   for (j = 0; j < numRegs; j++) {
-      print_src_reg(inst->SrcReg + j);
-      if (j + 1 < numRegs)
-        _mesa_printf(", ");
-   }
-
-   if (inst->Comment)
-      _mesa_printf("  # %s", inst->Comment);
-
-   print_comment(inst);
-}
-
-
-/**
- * Print a single vertex/fragment program instruction.
- */
-void
-_mesa_print_instruction(const struct prog_instruction *inst)
-{
-   switch (inst->Opcode) {
-   case OPCODE_PRINT:
-      _mesa_printf("PRINT '%s'", inst->Data);
-      if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) {
-         _mesa_printf(", ");
-         _mesa_printf("%s[%d]%s",
-                      program_file_string((enum register_file) inst->SrcReg[0].File),
-                      inst->SrcReg[0].Index,
-                      swizzle_string(inst->SrcReg[0].Swizzle,
-                                     inst->SrcReg[0].NegateBase, GL_FALSE));
-      }
-      if (inst->Comment)
-         _mesa_printf("  # %s", inst->Comment);
-      print_comment(inst);
-      break;
-   case OPCODE_SWZ:
-      _mesa_printf("SWZ");
-      if (inst->SaturateMode == SATURATE_ZERO_ONE)
-         _mesa_printf("_SAT");
-      print_dst_reg(&inst->DstReg);
-      _mesa_printf("%s[%d], %s",
-                   program_file_string((enum register_file) inst->SrcReg[0].File),
-                   inst->SrcReg[0].Index,
-                   swizzle_string(inst->SrcReg[0].Swizzle,
-                                  inst->SrcReg[0].NegateBase, GL_TRUE));
-      print_comment(inst);
-      break;
-   case OPCODE_TEX:
-   case OPCODE_TXP:
-   case OPCODE_TXB:
-      _mesa_printf("%s", _mesa_opcode_string(inst->Opcode));
-      if (inst->SaturateMode == SATURATE_ZERO_ONE)
-         _mesa_printf("_SAT");
-      _mesa_printf(" ");
-      print_dst_reg(&inst->DstReg);
-      _mesa_printf(", ");
-      print_src_reg(&inst->SrcReg[0]);
-      _mesa_printf(", texture[%d], ", inst->TexSrcUnit);
-      switch (inst->TexSrcTarget) {
-      case TEXTURE_1D_INDEX:   _mesa_printf("1D");    break;
-      case TEXTURE_2D_INDEX:   _mesa_printf("2D");    break;
-      case TEXTURE_3D_INDEX:   _mesa_printf("3D");    break;
-      case TEXTURE_CUBE_INDEX: _mesa_printf("CUBE");  break;
-      case TEXTURE_RECT_INDEX: _mesa_printf("RECT");  break;
-      default:
-         ;
-      }
-      print_comment(inst);
-      break;
-   case OPCODE_ARL:
-      _mesa_printf("ARL addr.x, ");
-      print_src_reg(&inst->SrcReg[0]);
-      print_comment(inst);
-      break;
-   case OPCODE_BRA:
-      _mesa_printf("BRA %u", inst->BranchTarget);
-      print_comment(inst);
-      break;
-   case OPCODE_CAL:
-      _mesa_printf("CAL %u", inst->BranchTarget);
-      print_comment(inst);
-      break;
-   case OPCODE_END:
-      _mesa_printf("END");
-      print_comment(inst);
-      break;
-   /* XXX may need other special-case instructions */
-   default:
-      /* typical alu instruction */
-      _mesa_print_alu_instruction(inst,
-                                 _mesa_opcode_string(inst->Opcode),
-                                 _mesa_num_inst_src_regs(inst->Opcode));
-      break;
-   }
-}
-
-
-/**
- * Print a vertx/fragment program to stdout.
- * XXX this function could be greatly improved.
- */
-void
-_mesa_print_program(const struct gl_program *prog)
-{
-   GLuint i;
-   for (i = 0; i < prog->NumInstructions; i++) {
-      _mesa_printf("%3d: ", i);
-      _mesa_print_instruction(prog->Instructions + i);
-   }
-}
-
-
-/**
- * Print all of a program's parameters.
- */
-void
-_mesa_print_program_parameters(GLcontext *ctx, const struct gl_program *prog)
-{
-   GLint i;
-
-   _mesa_printf("NumInstructions=%d\n", prog->NumInstructions);
-   _mesa_printf("NumTemporaries=%d\n", prog->NumTemporaries);
-   _mesa_printf("NumParameters=%d\n", prog->NumParameters);
-   _mesa_printf("NumAttributes=%d\n", prog->NumAttributes);
-   _mesa_printf("NumAddressRegs=%d\n", prog->NumAddressRegs);
-       
-   _mesa_load_state_parameters(ctx, prog->Parameters);
-                       
-#if 0
-   _mesa_printf("Local Params:\n");
-   for (i = 0; i < MAX_PROGRAM_LOCAL_PARAMS; i++){
-      const GLfloat *p = prog->LocalParams[i];
-      _mesa_printf("%2d: %f, %f, %f, %f\n", i, p[0], p[1], p[2], p[3]);
-   }
-#endif 
-
-   for (i = 0; i < prog->Parameters->NumParameters; i++){
-      struct gl_program_parameter *param = prog->Parameters->Parameters + i;
-      const GLfloat *v = prog->Parameters->ParameterValues[i];
-      _mesa_printf("param[%d] %s %s = {%.3f, %.3f, %.3f, %.3f};\n",
-                   i,
-                   program_file_string(prog->Parameters->Parameters[i].Type),
-                   param->Name, v[0], v[1], v[2], v[3]);
-   }
-}
-
 
 /**
  * Mixing ARB and NV vertex/fragment programs can be tricky.
index 98e2b536021c05919f95d9e38e072b09ce1431a5..34485776e9e9c16c96c1072add671ee879bed51f 100644 (file)
 #include "mtypes.h"
 
 
-/* for GL_ARB_v_p and GL_ARB_f_p SWZ instruction */
-#define SWIZZLE_X    0
-#define SWIZZLE_Y    1
-#define SWIZZLE_Z    2
-#define SWIZZLE_W    3
-#define SWIZZLE_ZERO 4         /* keep these values together: KW */
-#define SWIZZLE_ONE  5         /* keep these values together: KW */
-
-#define MAKE_SWIZZLE4(a,b,c,d) (((a)<<0) | ((b)<<3) | ((c)<<6) | ((d)<<9))
-#define SWIZZLE_NOOP           MAKE_SWIZZLE4(0,1,2,3)
-#define GET_SWZ(swz, idx)      (((swz) >> ((idx)*3)) & 0x7)
-#define GET_BIT(msk, idx)      (((msk) >> (idx)) & 0x1)
-
-
-#define WRITEMASK_X     0x1
-#define WRITEMASK_Y     0x2
-#define WRITEMASK_XY    0x3
-#define WRITEMASK_Z     0x4
-#define WRITEMASK_XZ    0x5
-#define WRITEMASK_YZ    0x6
-#define WRITEMASK_XYZ   0x7
-#define WRITEMASK_W     0x8
-#define WRITEMASK_XW    0x9
-#define WRITEMASK_YW    0xa
-#define WRITEMASK_XYW   0xb
-#define WRITEMASK_ZW    0xc
-#define WRITEMASK_XZW   0xd
-#define WRITEMASK_YZW   0xe
-#define WRITEMASK_XYZW  0xf
-
-
 extern struct gl_program _mesa_DummyProgram;
 
 
@@ -125,179 +94,7 @@ extern struct gl_program *
 _mesa_clone_program(GLcontext *ctx, const struct gl_program *prog);
 
 
-/**
- * Used for describing GL state referenced from inside ARB vertex and
- * fragment programs.
- * A string such as "state.light[0].ambient" gets translated into a
- * sequence of tokens such as [ STATE_LIGHT, 0, STATE_AMBIENT ].
- */
-typedef enum gl_state_index_ {
-   STATE_MATERIAL = 100,  /* start at 100 so small ints are seen as ints */
-
-   STATE_LIGHT,
-   STATE_LIGHTMODEL_AMBIENT,
-   STATE_LIGHTMODEL_SCENECOLOR,
-   STATE_LIGHTPROD,
-
-   STATE_TEXGEN,
-
-   STATE_FOG_COLOR,
-   STATE_FOG_PARAMS,
-
-   STATE_CLIPPLANE,
-
-   STATE_POINT_SIZE,
-   STATE_POINT_ATTENUATION,
-
-   STATE_MATRIX,
-   STATE_MODELVIEW,
-   STATE_PROJECTION,
-   STATE_MVP,
-   STATE_TEXTURE,
-   STATE_PROGRAM,
-   STATE_MATRIX_INVERSE,
-   STATE_MATRIX_TRANSPOSE,
-   STATE_MATRIX_INVTRANS,
-
-   STATE_AMBIENT,
-   STATE_DIFFUSE,
-   STATE_SPECULAR,
-   STATE_EMISSION,
-   STATE_SHININESS,
-   STATE_HALF, 
-
-   STATE_POSITION,
-   STATE_ATTENUATION,
-   STATE_SPOT_DIRECTION,
-
-   STATE_TEXGEN_EYE_S,
-   STATE_TEXGEN_EYE_T,
-   STATE_TEXGEN_EYE_R,
-   STATE_TEXGEN_EYE_Q,
-   STATE_TEXGEN_OBJECT_S,
-   STATE_TEXGEN_OBJECT_T,
-   STATE_TEXGEN_OBJECT_R,
-   STATE_TEXGEN_OBJECT_Q,
-
-   STATE_TEXENV_COLOR,
-       
-   STATE_DEPTH_RANGE,
-
-   STATE_VERTEX_PROGRAM,
-   STATE_FRAGMENT_PROGRAM,
-
-   STATE_ENV,
-   STATE_LOCAL,
-
-   STATE_INTERNAL,             /* Mesa additions */
-   STATE_NORMAL_SCALE,
-   STATE_TEXRECT_SCALE,
-   STATE_POSITION_NORMALIZED,   /* normalized light position */
-   STATE_INTERNAL_DRIVER       /* first available state index for drivers (must be last) */
-} gl_state_index;
-
-
-
-/**
- * Named program parameters 
- * Used for NV_fragment_program "DEFINE"d constants and "DECLARE"d parameters,
- * and ARB_fragment_program global state references.  For the later, Name
- * might be "state.light[0].diffuse", for example.
- */
-struct gl_program_parameter
-{
-   const char *Name;        /**< Null-terminated string */
-   enum register_file Type; /**< PROGRAM_NAMED_PARAM, CONSTANT or STATE_VAR */
-   GLuint Size;             /**< Number of components (1..4) */
-   /**
-    * A sequence of STATE_* tokens and integers to identify GL state.
-    */
-   gl_state_index StateIndexes[6];
-};
-
-
-/**
- * A list of the above program_parameter instances.
- */
-struct gl_program_parameter_list
-{
-   GLuint Size;           /**< allocated size of Parameters, ParameterValues */
-   GLuint NumParameters;  /**< number of parameters in arrays */
-   struct gl_program_parameter *Parameters; /**< Array [Size] */
-   GLfloat (*ParameterValues)[4];        /**< Array [Size] of GLfloat[4] */
-   GLbitfield StateFlags; /**< _NEW_* flags indicating which state changes
-                               might invalidate ParameterValues[] */
-};
-
-
-/*
- * Program parameter functions
- */
-
-extern struct gl_program_parameter_list *
-_mesa_new_parameter_list(void);
-
-extern void
-_mesa_free_parameter_list(struct gl_program_parameter_list *paramList);
-
-extern struct gl_program_parameter_list *
-_mesa_clone_parameter_list(const struct gl_program_parameter_list *list);
-
-extern GLint
-_mesa_add_parameter(struct gl_program_parameter_list *paramList,
-                    const char *name, const GLfloat values[4], GLuint size,
-                    enum register_file type);
-
-extern GLint
-_mesa_add_named_parameter(struct gl_program_parameter_list *paramList,
-                          const char *name, const GLfloat values[4]);
-
-extern GLint
-_mesa_add_named_constant(struct gl_program_parameter_list *paramList,
-                         const char *name, const GLfloat values[4],
-                         GLuint size);
-
-extern GLint
-_mesa_add_unnamed_constant(struct gl_program_parameter_list *paramList,
-                           const GLfloat values[4], GLuint size,
-                           GLuint *swizzleOut);
-
-extern GLint
-_mesa_add_uniform(struct gl_program_parameter_list *paramList,
-                  const char *name, GLuint size);
-
-extern GLint
-_mesa_add_varying(struct gl_program_parameter_list *paramList,
-                  const char *name, GLuint size);
-
-extern GLint
-_mesa_add_state_reference(struct gl_program_parameter_list *paramList,
-                          const GLint *stateTokens);
-
-extern GLfloat *
-_mesa_lookup_parameter_value(const struct gl_program_parameter_list *paramList,
-                             GLsizei nameLen, const char *name);
-
-extern GLint
-_mesa_lookup_parameter_index(const struct gl_program_parameter_list *paramList,
-                             GLsizei nameLen, const char *name);
-
-extern GLboolean
-_mesa_lookup_parameter_constant(const struct gl_program_parameter_list *paramList,
-                                const GLfloat v[], GLsizei vSize,
-                                GLint *posOut, GLuint *swizzleOut);
-
-extern void
-_mesa_load_state_parameters(GLcontext *ctx,
-                            struct gl_program_parameter_list *paramList);
-
-extern void
-_mesa_print_instruction(const struct prog_instruction *inst);
 
-void
-_mesa_print_alu_instruction(const struct prog_instruction *inst,
-                           const char *opcode_string, 
-                           GLuint numRegs);
 
 extern void
 _mesa_print_program(const struct gl_program *prog);