mesa: refactor: move glTexEnv-related functions into new texenv.c file
[mesa.git] / src / mesa / main / texstate.c
index 1b45eae42c37bb7befb8cc74bfbbbc9808863e19..448fc539121251a60568522062a49ffa461d24c7 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Mesa 3-D graphics library
- * Version:  6.5.3
+ * Version:  7.1
  *
  * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
  *
@@ -30,7 +30,9 @@
 
 #include "glheader.h"
 #include "colormac.h"
+#if FEATURE_colortable
 #include "colortab.h"
+#endif
 #include "context.h"
 #include "enums.h"
 #include "macros.h"
@@ -154,6 +156,10 @@ _mesa_copy_texture_state( const GLcontext *src, GLcontext *dst )
                            src->Texture.Unit[i].CurrentCubeMap);
       copy_texture_binding(src, &dst->Texture.Unit[i].CurrentRect,
                            src->Texture.Unit[i].CurrentRect);
+      copy_texture_binding(src, &dst->Texture.Unit[i].Current1DArray,
+                           src->Texture.Unit[i].Current1DArray);
+      copy_texture_binding(src, &dst->Texture.Unit[i].Current2DArray,
+                           src->Texture.Unit[i].Current2DArray);
 
       _mesa_unlock_context_textures(dst);
    }
@@ -234,6 +240,9 @@ calculate_derived_texenv( struct gl_tex_env_combine_state *state,
       return;
    }
 
+   if (mode == GL_REPLACE_EXT)
+      mode = GL_REPLACE;
+
    switch (mode) {
    case GL_REPLACE:
    case GL_MODULATE:
@@ -312,851 +321,33 @@ calculate_derived_texenv( struct gl_tex_env_combine_state *state,
 }
 
 
-void GLAPIENTRY
-_mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param )
-{
-   GLuint maxUnit;
-   GET_CURRENT_CONTEXT(ctx);
-   struct gl_texture_unit *texUnit;
-   ASSERT_OUTSIDE_BEGIN_END(ctx);
-
-   maxUnit = (target == GL_POINT_SPRITE_NV && pname == GL_COORD_REPLACE_NV)
-      ? ctx->Const.MaxTextureCoordUnits : ctx->Const.MaxTextureImageUnits;
-   if (ctx->Texture.CurrentUnit >= maxUnit) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glTexEnvfv(current unit)");
-      return;
-   }
-
-   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
-
-#define TE_ERROR(errCode, msg, value)                          \
-   _mesa_error(ctx, errCode, msg, _mesa_lookup_enum_by_nr(value));
-
-   if (target == GL_TEXTURE_ENV) {
-      switch (pname) {
-      case GL_TEXTURE_ENV_MODE:
-         {
-            const GLenum mode = (GLenum) (GLint) *param;
-           if (texUnit->EnvMode == mode)
-              return;
-            if (mode == GL_MODULATE ||
-                mode == GL_BLEND ||
-                mode == GL_DECAL ||
-                mode == GL_REPLACE ||
-                (mode == GL_ADD && ctx->Extensions.EXT_texture_env_add) ||
-                (mode == GL_COMBINE &&
-                 (ctx->Extensions.EXT_texture_env_combine ||
-                  ctx->Extensions.ARB_texture_env_combine))) {
-               /* legal */
-               FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-               texUnit->EnvMode = mode;
-            }
-            else {
-               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
-               return;
-            }
-         }
-         break;
-      case GL_TEXTURE_ENV_COLOR:
-         {
-            GLfloat tmp[4];
-            tmp[0] = CLAMP( param[0], 0.0F, 1.0F );
-            tmp[1] = CLAMP( param[1], 0.0F, 1.0F );
-            tmp[2] = CLAMP( param[2], 0.0F, 1.0F );
-            tmp[3] = CLAMP( param[3], 0.0F, 1.0F );
-            if (TEST_EQ_4V(tmp, texUnit->EnvColor))
-               return;
-            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-            COPY_4FV(texUnit->EnvColor, tmp);
-         }
-         break;
-      case GL_COMBINE_RGB:
-        if (ctx->Extensions.EXT_texture_env_combine ||
-             ctx->Extensions.ARB_texture_env_combine) {
-           const GLenum mode = (GLenum) (GLint) *param;
-           if (texUnit->Combine.ModeRGB == mode)
-              return;
-           switch (mode) {
-           case GL_REPLACE:
-           case GL_MODULATE:
-           case GL_ADD:
-           case GL_ADD_SIGNED:
-           case GL_INTERPOLATE:
-               /* OK */
-              break;
-            case GL_SUBTRACT:
-               if (!ctx->Extensions.ARB_texture_env_combine) {
-                  TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
-                  return;
-               }
-               break;
-           case GL_DOT3_RGB_EXT:
-           case GL_DOT3_RGBA_EXT:
-              if (!ctx->Extensions.EXT_texture_env_dot3) {
-                  TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
-                 return;
-              }
-              break;
-           case GL_DOT3_RGB:
-           case GL_DOT3_RGBA:
-              if (!ctx->Extensions.ARB_texture_env_dot3) {
-                  TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
-                 return;
-              }
-              break;
-           case GL_MODULATE_ADD_ATI:
-           case GL_MODULATE_SIGNED_ADD_ATI:
-           case GL_MODULATE_SUBTRACT_ATI:
-              if (!ctx->Extensions.ATI_texture_env_combine3) {
-                  TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
-                 return;
-              }
-              break;
-           default:
-               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
-              return;
-           }
-           FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-           texUnit->Combine.ModeRGB = mode;
-        }
-        else {
-            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
-           return;
-        }
-         break;
-      case GL_COMBINE_ALPHA:
-        if (ctx->Extensions.EXT_texture_env_combine ||
-             ctx->Extensions.ARB_texture_env_combine) {
-           const GLenum mode = (GLenum) (GLint) *param;
-           if (texUnit->Combine.ModeA == mode)
-              return;
-            switch (mode) {
-           case GL_REPLACE:
-           case GL_MODULATE:
-           case GL_ADD:
-           case GL_ADD_SIGNED:
-           case GL_INTERPOLATE:
-              /* OK */
-              break;
-           case GL_SUBTRACT:
-              if (!ctx->Extensions.ARB_texture_env_combine) {
-                 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
-                 return;
-              }
-              break;
-           case GL_MODULATE_ADD_ATI:
-           case GL_MODULATE_SIGNED_ADD_ATI:
-           case GL_MODULATE_SUBTRACT_ATI:
-              if (!ctx->Extensions.ATI_texture_env_combine3) {
-                  TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
-                 return;
-              }
-              break;
-           default:
-              TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
-              return;
-           }
-           FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-           texUnit->Combine.ModeA = mode;
-        }
-        else {
-            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
-           return;
-        }
-        break;
-      case GL_SOURCE0_RGB:
-      case GL_SOURCE1_RGB:
-      case GL_SOURCE2_RGB:
-        if (ctx->Extensions.EXT_texture_env_combine ||
-            ctx->Extensions.ARB_texture_env_combine) {
-           const GLenum source = (GLenum) (GLint) *param;
-           const GLuint s = pname - GL_SOURCE0_RGB;
-           if (texUnit->Combine.SourceRGB[s] == source)
-              return;
-            if (source == GL_TEXTURE ||
-                source == GL_CONSTANT ||
-                source == GL_PRIMARY_COLOR ||
-                source == GL_PREVIOUS ||
-                (ctx->Extensions.ARB_texture_env_crossbar &&
-                 source >= GL_TEXTURE0 &&
-                 source < GL_TEXTURE0 + ctx->Const.MaxTextureUnits) ||
-                (ctx->Extensions.ATI_texture_env_combine3 &&
-                 (source == GL_ZERO || source == GL_ONE))) {
-               /* legal */
-              FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-              texUnit->Combine.SourceRGB[s] = source;
-            }
-            else {
-               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", source);
-              return;
-           }
-        }
-        else {
-            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
-           return;
-        }
-        break;
-      case GL_SOURCE0_ALPHA:
-      case GL_SOURCE1_ALPHA:
-      case GL_SOURCE2_ALPHA:
-        if (ctx->Extensions.EXT_texture_env_combine ||
-             ctx->Extensions.ARB_texture_env_combine) {
-           const GLenum source = (GLenum) (GLint) *param;
-           const GLuint s = pname - GL_SOURCE0_ALPHA;
-           if (texUnit->Combine.SourceA[s] == source)
-              return;
-            if (source == GL_TEXTURE ||
-                source == GL_CONSTANT ||
-                source == GL_PRIMARY_COLOR ||
-                source == GL_PREVIOUS ||
-                (ctx->Extensions.ARB_texture_env_crossbar &&
-                 source >= GL_TEXTURE0 &&
-                 source < GL_TEXTURE0 + ctx->Const.MaxTextureUnits) ||
-               (ctx->Extensions.ATI_texture_env_combine3 &&
-                 (source == GL_ZERO || source == GL_ONE))) {
-               /* legal */
-              FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-              texUnit->Combine.SourceA[s] = source;
-            }
-            else {
-               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", source);
-              return;
-           }
-        }
-        else {
-            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
-           return;
-        }
-        break;
-      case GL_OPERAND0_RGB:
-      case GL_OPERAND1_RGB:
-        if (ctx->Extensions.EXT_texture_env_combine ||
-            ctx->Extensions.ARB_texture_env_combine) {
-           const GLenum operand = (GLenum) (GLint) *param;
-           const GLuint s = pname - GL_OPERAND0_RGB;
-           if (texUnit->Combine.OperandRGB[s] == operand)
-              return;
-           switch (operand) {
-           case GL_SRC_COLOR:
-           case GL_ONE_MINUS_SRC_COLOR:
-           case GL_SRC_ALPHA:
-           case GL_ONE_MINUS_SRC_ALPHA:
-              FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-              texUnit->Combine.OperandRGB[s] = operand;
-              break;
-           default:
-               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
-              return;
-           }
-        }
-        else {
-            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
-           return;
-        }
-        break;
-      case GL_OPERAND0_ALPHA:
-      case GL_OPERAND1_ALPHA:
-        if (ctx->Extensions.EXT_texture_env_combine ||
-             ctx->Extensions.ARB_texture_env_combine) {
-           const GLenum operand = (GLenum) (GLint) *param;
-           if (texUnit->Combine.OperandA[pname-GL_OPERAND0_ALPHA] == operand)
-              return;
-           switch (operand) {
-           case GL_SRC_ALPHA:
-           case GL_ONE_MINUS_SRC_ALPHA:
-              FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-              texUnit->Combine.OperandA[pname-GL_OPERAND0_ALPHA] = operand;
-              break;
-           default:
-               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
-              return;
-           }
-        }
-        else {
-            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
-           return;
-        }
-        break;
-      case GL_OPERAND2_RGB:
-        if (ctx->Extensions.ARB_texture_env_combine) {
-           const GLenum operand = (GLenum) (GLint) *param;
-           if (texUnit->Combine.OperandRGB[2] == operand)
-              return;
-           switch (operand) {
-           case GL_SRC_COLOR:           /* ARB combine only */
-           case GL_ONE_MINUS_SRC_COLOR: /* ARB combine only */
-           case GL_SRC_ALPHA:
-           case GL_ONE_MINUS_SRC_ALPHA: /* ARB combine only */
-              FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-              texUnit->Combine.OperandRGB[2] = operand;
-               break;
-           default:
-               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
-              return;
-           }
-        }
-        else if (ctx->Extensions.EXT_texture_env_combine) {
-           const GLenum operand = (GLenum) (GLint) *param;
-           if (texUnit->Combine.OperandRGB[2] == operand)
-              return;
-           /* operand must be GL_SRC_ALPHA which is the initial value - thus
-              don't need to actually compare the operand to the possible value */
-           else {
-               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
-              return;
-           }
-        }
-        else {
-            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
-           return;
-        }
-        break;
-      case GL_OPERAND2_ALPHA:
-        if (ctx->Extensions.ARB_texture_env_combine) {
-           const GLenum operand = (GLenum) (GLint) *param;
-           if (texUnit->Combine.OperandA[2] == operand)
-              return;
-           switch (operand) {
-           case GL_SRC_ALPHA:
-           case GL_ONE_MINUS_SRC_ALPHA: /* ARB combine only */
-              FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-              texUnit->Combine.OperandA[2] = operand;
-              break;
-           default:
-               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
-              return;
-           }
-        }
-        else if (ctx->Extensions.EXT_texture_env_combine) {
-           const GLenum operand = (GLenum) (GLint) *param;
-           if (texUnit->Combine.OperandA[2] == operand)
-              return;
-           /* operand must be GL_SRC_ALPHA which is the initial value - thus
-              don't need to actually compare the operand to the possible value */
-           else {
-               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
-              return;
-           }
-        }
-        else {
-            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
-           return;
-        }
-        break;
-      case GL_RGB_SCALE:
-        if (ctx->Extensions.EXT_texture_env_combine ||
-             ctx->Extensions.ARB_texture_env_combine) {
-           GLuint newshift;
-           if (*param == 1.0) {
-              newshift = 0;
-           }
-           else if (*param == 2.0) {
-              newshift = 1;
-           }
-           else if (*param == 4.0) {
-              newshift = 2;
-           }
-           else {
-              _mesa_error( ctx, GL_INVALID_VALUE,
-                            "glTexEnv(GL_RGB_SCALE not 1, 2 or 4)" );
-              return;
-           }
-           if (texUnit->Combine.ScaleShiftRGB == newshift)
-              return;
-           FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-           texUnit->Combine.ScaleShiftRGB = newshift;
-        }
-        else {
-            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
-           return;
-        }
-        break;
-      case GL_ALPHA_SCALE:
-        if (ctx->Extensions.EXT_texture_env_combine ||
-             ctx->Extensions.ARB_texture_env_combine) {
-           GLuint newshift;
-           if (*param == 1.0) {
-              newshift = 0;
-           }
-           else if (*param == 2.0) {
-              newshift = 1;
-           }
-           else if (*param == 4.0) {
-              newshift = 2;
-           }
-           else {
-              _mesa_error( ctx, GL_INVALID_VALUE,
-                            "glTexEnv(GL_ALPHA_SCALE not 1, 2 or 4)" );
-              return;
-           }
-           if (texUnit->Combine.ScaleShiftA == newshift)
-              return;
-           FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-           texUnit->Combine.ScaleShiftA = newshift;
-        }
-        else {
-            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
-           return;
-        }
-        break;
-      default:
-        _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(pname)" );
-        return;
-      }
-   }
-   else if (target == GL_TEXTURE_FILTER_CONTROL_EXT) {
-      /* GL_EXT_texture_lod_bias */
-      if (!ctx->Extensions.EXT_texture_lod_bias) {
-        _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(target=0x%x)", target );
-        return;
-      }
-      if (pname == GL_TEXTURE_LOD_BIAS_EXT) {
-        if (texUnit->LodBias == param[0])
-           return;
-        FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-         texUnit->LodBias = param[0];
-      }
-      else {
-         TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
-        return;
-      }
-   }
-   else if (target == GL_POINT_SPRITE_NV) {
-      /* GL_ARB_point_sprite / GL_NV_point_sprite */
-      if (!ctx->Extensions.NV_point_sprite
-         && !ctx->Extensions.ARB_point_sprite) {
-        _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(target=0x%x)", target );
-        return;
-      }
-      if (pname == GL_COORD_REPLACE_NV) {
-         const GLenum value = (GLenum) param[0];
-         if (value == GL_TRUE || value == GL_FALSE) {
-            /* It's kind of weird to set point state via glTexEnv,
-             * but that's what the spec calls for.
-             */
-            const GLboolean state = (GLboolean) value;
-            if (ctx->Point.CoordReplace[ctx->Texture.CurrentUnit] == state)
-               return;
-            FLUSH_VERTICES(ctx, _NEW_POINT);
-            ctx->Point.CoordReplace[ctx->Texture.CurrentUnit] = state;
-         }
-         else {
-            _mesa_error( ctx, GL_INVALID_VALUE, "glTexEnv(param=0x%x)", value);
-            return;
-         }
-      }
-      else {
-         _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(pname=0x%x)", pname );
-         return;
-      }
-   }
-   else {
-      _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(target=0x%x)",target );
-      return;
-   }
-
-   if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE))
-      _mesa_debug(ctx, "glTexEnv %s %s %.1f(%s) ...\n",
-                  _mesa_lookup_enum_by_nr(target),
-                  _mesa_lookup_enum_by_nr(pname),
-                  *param,
-                  _mesa_lookup_enum_by_nr((GLenum) (GLint) *param));
-
-   /* Tell device driver about the new texture environment */
-   if (ctx->Driver.TexEnv) {
-      (*ctx->Driver.TexEnv)( ctx, target, pname, param );
-   }
-}
-
-
-void GLAPIENTRY
-_mesa_TexEnvf( GLenum target, GLenum pname, GLfloat param )
-{
-   _mesa_TexEnvfv( target, pname, &param );
-}
-
-
-
-void GLAPIENTRY
-_mesa_TexEnvi( GLenum target, GLenum pname, GLint param )
-{
-   GLfloat p[4];
-   p[0] = (GLfloat) param;
-   p[1] = p[2] = p[3] = 0.0;
-   _mesa_TexEnvfv( target, pname, p );
-}
-
-
-void GLAPIENTRY
-_mesa_TexEnviv( GLenum target, GLenum pname, const GLint *param )
-{
-   GLfloat p[4];
-   if (pname == GL_TEXTURE_ENV_COLOR) {
-      p[0] = INT_TO_FLOAT( param[0] );
-      p[1] = INT_TO_FLOAT( param[1] );
-      p[2] = INT_TO_FLOAT( param[2] );
-      p[3] = INT_TO_FLOAT( param[3] );
-   }
-   else {
-      p[0] = (GLfloat) param[0];
-      p[1] = p[2] = p[3] = 0;  /* init to zero, just to be safe */
-   }
-   _mesa_TexEnvfv( target, pname, p );
-}
-
-
-void GLAPIENTRY
-_mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params )
-{
-   GLuint maxUnit;
-   const struct gl_texture_unit *texUnit;
-   GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END(ctx);
-
-   maxUnit = (target == GL_POINT_SPRITE_NV && pname == GL_COORD_REPLACE_NV)
-      ? ctx->Const.MaxTextureCoordUnits : ctx->Const.MaxTextureImageUnits;
-   if (ctx->Texture.CurrentUnit >= maxUnit) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexEnvfv(current unit)");
-      return;
-   }
-
-   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
-
-   if (target == GL_TEXTURE_ENV) {
-      switch (pname) {
-         case GL_TEXTURE_ENV_MODE:
-            *params = ENUM_TO_FLOAT(texUnit->EnvMode);
-            break;
-         case GL_TEXTURE_ENV_COLOR:
-            COPY_4FV( params, texUnit->EnvColor );
-            break;
-         case GL_COMBINE_RGB:
-            if (ctx->Extensions.EXT_texture_env_combine ||
-                ctx->Extensions.ARB_texture_env_combine) {
-               *params = (GLfloat) texUnit->Combine.ModeRGB;
-            }
-            else {
-               _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
-            }
-            break;
-         case GL_COMBINE_ALPHA:
-            if (ctx->Extensions.EXT_texture_env_combine ||
-                ctx->Extensions.ARB_texture_env_combine) {
-               *params = (GLfloat) texUnit->Combine.ModeA;
-            }
-            else {
-               _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
-            }
-            break;
-         case GL_SOURCE0_RGB:
-         case GL_SOURCE1_RGB:
-         case GL_SOURCE2_RGB:
-            if (ctx->Extensions.EXT_texture_env_combine ||
-                ctx->Extensions.ARB_texture_env_combine) {
-              const unsigned rgb_idx = pname - GL_SOURCE0_RGB;
-               *params = (GLfloat) texUnit->Combine.SourceRGB[rgb_idx];
-            }
-            else {
-               _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
-            }
-            break;
-         case GL_SOURCE0_ALPHA:
-         case GL_SOURCE1_ALPHA:
-         case GL_SOURCE2_ALPHA:
-            if (ctx->Extensions.EXT_texture_env_combine ||
-                ctx->Extensions.ARB_texture_env_combine) {
-              const unsigned alpha_idx = pname - GL_SOURCE0_ALPHA;
-               *params = (GLfloat) texUnit->Combine.SourceA[alpha_idx];
-            }
-            else {
-               _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
-            }
-            break;
-         case GL_OPERAND0_RGB:
-         case GL_OPERAND1_RGB:
-         case GL_OPERAND2_RGB:
-            if (ctx->Extensions.EXT_texture_env_combine ||
-                ctx->Extensions.ARB_texture_env_combine) {
-              const unsigned op_rgb = pname - GL_OPERAND0_RGB;
-               *params = (GLfloat) texUnit->Combine.OperandRGB[op_rgb];
-            }
-            else {
-               _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
-            }
-            break;
-         case GL_OPERAND0_ALPHA:
-         case GL_OPERAND1_ALPHA:
-         case GL_OPERAND2_ALPHA:
-            if (ctx->Extensions.EXT_texture_env_combine ||
-                ctx->Extensions.ARB_texture_env_combine) {
-              const unsigned op_alpha = pname - GL_OPERAND0_ALPHA;
-               *params = (GLfloat) texUnit->Combine.OperandA[op_alpha];
-            }
-            else {
-               _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
-            }
-            break;
-         case GL_RGB_SCALE:
-            if (ctx->Extensions.EXT_texture_env_combine ||
-                ctx->Extensions.ARB_texture_env_combine) {
-               if (texUnit->Combine.ScaleShiftRGB == 0)
-                  *params = 1.0;
-               else if (texUnit->Combine.ScaleShiftRGB == 1)
-                  *params = 2.0;
-               else
-                  *params = 4.0;
-            }
-            else {
-               _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
-               return;
-            }
-            break;
-         case GL_ALPHA_SCALE:
-            if (ctx->Extensions.EXT_texture_env_combine ||
-                ctx->Extensions.ARB_texture_env_combine) {
-               if (texUnit->Combine.ScaleShiftA == 0)
-                  *params = 1.0;
-               else if (texUnit->Combine.ScaleShiftA == 1)
-                  *params = 2.0;
-               else
-                  *params = 4.0;
-            }
-            else {
-               _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
-               return;
-            }
-            break;
-         default:
-            _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname=0x%x)", pname);
-      }
-   }
-   else if (target == GL_TEXTURE_FILTER_CONTROL_EXT) {
-      /* GL_EXT_texture_lod_bias */
-      if (!ctx->Extensions.EXT_texture_lod_bias) {
-        _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(target)" );
-        return;
-      }
-      if (pname == GL_TEXTURE_LOD_BIAS_EXT) {
-         *params = texUnit->LodBias;
-      }
-      else {
-         _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)" );
-        return;
-      }
-   }
-   else if (target == GL_POINT_SPRITE_NV) {
-      /* GL_ARB_point_sprite / GL_NV_point_sprite */
-      if (!ctx->Extensions.NV_point_sprite
-         && !ctx->Extensions.ARB_point_sprite) {
-         _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(target)" );
-         return;
-      }
-      if (pname == GL_COORD_REPLACE_NV) {
-         *params = (GLfloat) ctx->Point.CoordReplace[ctx->Texture.CurrentUnit];
-      }
-      else {
-         _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)" );
-         return;
-      }
-   }
-   else {
-      _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(target)" );
-      return;
-   }
-}
-
-
-void GLAPIENTRY
-_mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params )
-{
-   GLuint maxUnit;
-   const struct gl_texture_unit *texUnit;
-   GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END(ctx);
-
-   maxUnit = (target == GL_POINT_SPRITE_NV && pname == GL_COORD_REPLACE_NV)
-      ? ctx->Const.MaxTextureCoordUnits : ctx->Const.MaxTextureImageUnits;
-   if (ctx->Texture.CurrentUnit >= maxUnit) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexEnviv(current unit)");
-      return;
-   }
-
-   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
-
-   if (target == GL_TEXTURE_ENV) {
-      switch (pname) {
-         case GL_TEXTURE_ENV_MODE:
-            *params = (GLint) texUnit->EnvMode;
-            break;
-         case GL_TEXTURE_ENV_COLOR:
-            params[0] = FLOAT_TO_INT( texUnit->EnvColor[0] );
-            params[1] = FLOAT_TO_INT( texUnit->EnvColor[1] );
-            params[2] = FLOAT_TO_INT( texUnit->EnvColor[2] );
-            params[3] = FLOAT_TO_INT( texUnit->EnvColor[3] );
-            break;
-         case GL_COMBINE_RGB:
-            if (ctx->Extensions.EXT_texture_env_combine ||
-                ctx->Extensions.ARB_texture_env_combine) {
-               *params = (GLint) texUnit->Combine.ModeRGB;
-            }
-            else {
-               _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
-            }
-            break;
-         case GL_COMBINE_ALPHA:
-            if (ctx->Extensions.EXT_texture_env_combine ||
-                ctx->Extensions.ARB_texture_env_combine) {
-               *params = (GLint) texUnit->Combine.ModeA;
-            }
-            else {
-               _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
-            }
-            break;
-         case GL_SOURCE0_RGB:
-         case GL_SOURCE1_RGB:
-         case GL_SOURCE2_RGB:
-            if (ctx->Extensions.EXT_texture_env_combine ||
-                ctx->Extensions.ARB_texture_env_combine) {
-              const unsigned rgb_idx = pname - GL_SOURCE0_RGB;
-               *params = (GLint) texUnit->Combine.SourceRGB[rgb_idx];
-            }
-            else {
-               _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
-            }
-            break;
-         case GL_SOURCE0_ALPHA:
-         case GL_SOURCE1_ALPHA:
-         case GL_SOURCE2_ALPHA:
-            if (ctx->Extensions.EXT_texture_env_combine ||
-                ctx->Extensions.ARB_texture_env_combine) {
-              const unsigned alpha_idx = pname - GL_SOURCE0_ALPHA;
-               *params = (GLint) texUnit->Combine.SourceA[alpha_idx];
-            }
-            else {
-               _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
-            }
-            break;
-         case GL_OPERAND0_RGB:
-         case GL_OPERAND1_RGB:
-         case GL_OPERAND2_RGB:
-            if (ctx->Extensions.EXT_texture_env_combine ||
-                ctx->Extensions.ARB_texture_env_combine) {
-              const unsigned op_rgb = pname - GL_OPERAND0_RGB;
-               *params = (GLint) texUnit->Combine.OperandRGB[op_rgb];
-            }
-            else {
-               _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
-            }
-            break;
-         case GL_OPERAND0_ALPHA:
-         case GL_OPERAND1_ALPHA:
-         case GL_OPERAND2_ALPHA:
-            if (ctx->Extensions.EXT_texture_env_combine ||
-                ctx->Extensions.ARB_texture_env_combine) {
-              const unsigned op_alpha = pname - GL_OPERAND0_ALPHA;
-               *params = (GLint) texUnit->Combine.OperandA[op_alpha];
-            }
-            else {
-               _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
-            }
-            break;
-         case GL_RGB_SCALE:
-            if (ctx->Extensions.EXT_texture_env_combine ||
-                ctx->Extensions.ARB_texture_env_combine) {
-               if (texUnit->Combine.ScaleShiftRGB == 0)
-                  *params = 1;
-               else if (texUnit->Combine.ScaleShiftRGB == 1)
-                  *params = 2;
-               else
-                  *params = 4;
-            }
-            else {
-               _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
-               return;
-            }
-            break;
-         case GL_ALPHA_SCALE:
-            if (ctx->Extensions.EXT_texture_env_combine ||
-                ctx->Extensions.ARB_texture_env_combine) {
-               if (texUnit->Combine.ScaleShiftA == 0)
-                  *params = 1;
-               else if (texUnit->Combine.ScaleShiftA == 1)
-                  *params = 2;
-               else
-                  *params = 4;
-            }
-            else {
-               _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
-               return;
-            }
-            break;
-         default:
-            _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname=0x%x)",
-                        pname);
-      }
-   }
-   else if (target == GL_TEXTURE_FILTER_CONTROL_EXT) {
-      /* GL_EXT_texture_lod_bias */
-      if (!ctx->Extensions.EXT_texture_lod_bias) {
-        _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(target)" );
-        return;
-      }
-      if (pname == GL_TEXTURE_LOD_BIAS_EXT) {
-         *params = (GLint) texUnit->LodBias;
-      }
-      else {
-         _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)" );
-        return;
-      }
-   }
-   else if (target == GL_POINT_SPRITE_NV) {
-      /* GL_ARB_point_sprite / GL_NV_point_sprite */
-      if (!ctx->Extensions.NV_point_sprite
-         && !ctx->Extensions.ARB_point_sprite) {
-         _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(target)" );
-         return;
-      }
-      if (pname == GL_COORD_REPLACE_NV) {
-         *params = (GLint) ctx->Point.CoordReplace[ctx->Texture.CurrentUnit];
-      }
-      else {
-         _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)" );
-         return;
-      }
-   }
-   else {
-      _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(target)" );
-      return;
-   }
-}
-
-
-
-
 /**********************************************************************/
 /*                       Texture Parameters                           */
 /**********************************************************************/
 
+/**
+ * Check if a coordinate wrap mode is supported for the texture target.
+ * \return GL_TRUE if legal, GL_FALSE otherwise
+ */
 static GLboolean 
-_mesa_validate_texture_wrap_mode(GLcontext * ctx,
-                                GLenum target, GLenum eparam)
+validate_texture_wrap_mode(GLcontext * ctx, GLenum target, GLenum wrap)
 {
    const struct gl_extensions * const e = & ctx->Extensions;
 
-   if (eparam == GL_CLAMP || eparam == GL_CLAMP_TO_EDGE ||
-       (eparam == GL_CLAMP_TO_BORDER && e->ARB_texture_border_clamp)) {
+   if (wrap == GL_CLAMP || wrap == GL_CLAMP_TO_EDGE ||
+       (wrap == GL_CLAMP_TO_BORDER && e->ARB_texture_border_clamp)) {
       /* any texture target */
       return GL_TRUE;
    }
    else if (target != GL_TEXTURE_RECTANGLE_NV &&
-           (eparam == GL_REPEAT ||
-            (eparam == GL_MIRRORED_REPEAT &&
+           (wrap == GL_REPEAT ||
+            (wrap == GL_MIRRORED_REPEAT &&
              e->ARB_texture_mirrored_repeat) ||
-            (eparam == GL_MIRROR_CLAMP_EXT &&
+            (wrap == GL_MIRROR_CLAMP_EXT &&
              (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp)) ||
-            (eparam == GL_MIRROR_CLAMP_TO_EDGE_EXT &&
+            (wrap == GL_MIRROR_CLAMP_TO_EDGE_EXT &&
              (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp)) ||
-            (eparam == GL_MIRROR_CLAMP_TO_BORDER_EXT &&
+            (wrap == GL_MIRROR_CLAMP_TO_BORDER_EXT &&
              (e->EXT_texture_mirror_clamp)))) {
       /* non-rectangle texture */
       return GL_TRUE;
@@ -1212,14 +403,28 @@ _mesa_TexParameterfv( GLenum target, GLenum pname, const GLfloat *params )
             _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(target)" );
             return;
          }
-         texObj = texUnit->CurrentCubeMap;
+         texObj = texUnit->CurrentCubeMap;
+         break;
+      case GL_TEXTURE_RECTANGLE_NV:
+         if (!ctx->Extensions.NV_texture_rectangle) {
+            _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(target)" );
+            return;
+         }
+         texObj = texUnit->CurrentRect;
+         break;
+      case GL_TEXTURE_1D_ARRAY_EXT:
+         if (!ctx->Extensions.MESA_texture_array) {
+            _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(target)" );
+            return;
+         }
+         texObj = texUnit->Current1DArray;
          break;
-      case GL_TEXTURE_RECTANGLE_NV:
-         if (!ctx->Extensions.NV_texture_rectangle) {
+      case GL_TEXTURE_2D_ARRAY_EXT:
+         if (!ctx->Extensions.MESA_texture_array) {
             _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(target)" );
             return;
          }
-         texObj = texUnit->CurrentRect;
+         texObj = texUnit->Current2DArray;
          break;
       default:
          _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(target)" );
@@ -1265,7 +470,7 @@ _mesa_TexParameterfv( GLenum target, GLenum pname, const GLfloat *params )
       case GL_TEXTURE_WRAP_S:
          if (texObj->WrapS == eparam)
             return;
-         if (_mesa_validate_texture_wrap_mode(ctx, texObj->Target, eparam)) {
+         if (validate_texture_wrap_mode(ctx, texObj->Target, eparam)) {
             FLUSH_VERTICES(ctx, _NEW_TEXTURE);
             texObj->WrapS = eparam;
          }
@@ -1276,7 +481,7 @@ _mesa_TexParameterfv( GLenum target, GLenum pname, const GLfloat *params )
       case GL_TEXTURE_WRAP_T:
          if (texObj->WrapT == eparam)
             return;
-         if (_mesa_validate_texture_wrap_mode(ctx, texObj->Target, eparam)) {
+         if (validate_texture_wrap_mode(ctx, texObj->Target, eparam)) {
             FLUSH_VERTICES(ctx, _NEW_TEXTURE);
             texObj->WrapT = eparam;
          }
@@ -1287,7 +492,7 @@ _mesa_TexParameterfv( GLenum target, GLenum pname, const GLfloat *params )
       case GL_TEXTURE_WRAP_R:
          if (texObj->WrapR == eparam)
             return;
-         if (_mesa_validate_texture_wrap_mode(ctx, texObj->Target, eparam)) {
+         if (validate_texture_wrap_mode(ctx, texObj->Target, eparam)) {
             FLUSH_VERTICES(ctx, _NEW_TEXTURE);
             texObj->WrapR = eparam;
          }
@@ -1497,7 +702,7 @@ _mesa_TexParameterfv( GLenum target, GLenum pname, const GLfloat *params )
          return;
    }
 
-   texObj->Complete = GL_FALSE;
+   texObj->_Complete = GL_FALSE;
 
    if (ctx->Driver.TexParameter) {
       (*ctx->Driver.TexParameter)( ctx, target, texObj, pname, params );
@@ -1574,6 +779,12 @@ tex_image_dimensions(GLcontext *ctx, GLenum target)
       case GL_TEXTURE_RECTANGLE_NV:
       case GL_PROXY_TEXTURE_RECTANGLE_NV:
          return ctx->Extensions.NV_texture_rectangle ? 2 : 0;
+      case GL_TEXTURE_1D_ARRAY_EXT:
+      case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
+         return ctx->Extensions.MESA_texture_array ? 2 : 0;
+      case GL_TEXTURE_2D_ARRAY_EXT:
+      case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
+         return ctx->Extensions.MESA_texture_array ? 3 : 0;
       default:
          _mesa_problem(ctx, "bad target in _mesa_tex_target_dimensions()");
          return 0;
@@ -2111,574 +1322,6 @@ _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params )
 
 
 
-
-/**********************************************************************/
-/*                    Texture Coord Generation                        */
-/**********************************************************************/
-
-#if FEATURE_texgen
-void GLAPIENTRY
-_mesa_TexGenfv( GLenum coord, GLenum pname, const GLfloat *params )
-{
-   GET_CURRENT_CONTEXT(ctx);
-   struct gl_texture_unit *texUnit;
-   ASSERT_OUTSIDE_BEGIN_END(ctx);
-
-   if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE))
-      _mesa_debug(ctx, "glTexGen %s %s %.1f(%s)...\n",
-                  _mesa_lookup_enum_by_nr(coord),
-                  _mesa_lookup_enum_by_nr(pname),
-                  *params,
-                 _mesa_lookup_enum_by_nr((GLenum) (GLint) *params));
-
-   if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glTexGen(current unit)");
-      return;
-   }
-
-   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
-
-   switch (coord) {
-      case GL_S:
-         if (pname==GL_TEXTURE_GEN_MODE) {
-           GLenum mode = (GLenum) (GLint) *params;
-           GLbitfield bits;
-           switch (mode) {
-           case GL_OBJECT_LINEAR:
-              bits = TEXGEN_OBJ_LINEAR;
-              break;
-           case GL_EYE_LINEAR:
-              bits = TEXGEN_EYE_LINEAR;
-              break;
-           case GL_REFLECTION_MAP_NV:
-              bits = TEXGEN_REFLECTION_MAP_NV;
-              break;
-           case GL_NORMAL_MAP_NV:
-              bits = TEXGEN_NORMAL_MAP_NV;
-              break;
-           case GL_SPHERE_MAP:
-              bits = TEXGEN_SPHERE_MAP;
-              break;
-           default:
-              _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
-              return;
-           }
-           if (texUnit->GenModeS == mode)
-              return;
-           FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-           texUnit->GenModeS = mode;
-           texUnit->_GenBitS = bits;
-        }
-        else if (pname==GL_OBJECT_PLANE) {
-           if (TEST_EQ_4V(texUnit->ObjectPlaneS, params))
-               return;
-           FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-            COPY_4FV(texUnit->ObjectPlaneS, params);
-        }
-        else if (pname==GL_EYE_PLANE) {
-           GLfloat tmp[4];
-            /* Transform plane equation by the inverse modelview matrix */
-            if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) {
-               _math_matrix_analyse( ctx->ModelviewMatrixStack.Top );
-            }
-            _mesa_transform_vector( tmp, params, ctx->ModelviewMatrixStack.Top->inv );
-           if (TEST_EQ_4V(texUnit->EyePlaneS, tmp))
-              return;
-           FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-           COPY_4FV(texUnit->EyePlaneS, tmp);
-        }
-        else {
-           _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
-           return;
-        }
-        break;
-      case GL_T:
-         if (pname==GL_TEXTURE_GEN_MODE) {
-           GLenum mode = (GLenum) (GLint) *params;
-           GLbitfield bitt;
-           switch (mode) {
-               case GL_OBJECT_LINEAR:
-                  bitt = TEXGEN_OBJ_LINEAR;
-                  break;
-               case GL_EYE_LINEAR:
-                  bitt = TEXGEN_EYE_LINEAR;
-                  break;
-               case GL_REFLECTION_MAP_NV:
-                  bitt = TEXGEN_REFLECTION_MAP_NV;
-                  break;
-               case GL_NORMAL_MAP_NV:
-                  bitt = TEXGEN_NORMAL_MAP_NV;
-                  break;
-               case GL_SPHERE_MAP:
-                  bitt = TEXGEN_SPHERE_MAP;
-                  break;
-               default:
-                  _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
-                  return;
-           }
-           if (texUnit->GenModeT == mode)
-              return;
-           FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-           texUnit->GenModeT = mode;
-           texUnit->_GenBitT = bitt;
-        }
-        else if (pname==GL_OBJECT_PLANE) {
-           if (TEST_EQ_4V(texUnit->ObjectPlaneT, params))
-               return;
-           FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-            COPY_4FV(texUnit->ObjectPlaneT, params);
-        }
-        else if (pname==GL_EYE_PLANE) {
-           GLfloat tmp[4];
-            /* Transform plane equation by the inverse modelview matrix */
-           if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) {
-               _math_matrix_analyse( ctx->ModelviewMatrixStack.Top );
-            }
-            _mesa_transform_vector( tmp, params, ctx->ModelviewMatrixStack.Top->inv );
-           if (TEST_EQ_4V(texUnit->EyePlaneT, tmp))
-               return;
-           FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-           COPY_4FV(texUnit->EyePlaneT, tmp);
-        }
-        else {
-           _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
-           return;
-        }
-        break;
-      case GL_R:
-         if (pname==GL_TEXTURE_GEN_MODE) {
-           GLenum mode = (GLenum) (GLint) *params;
-           GLbitfield bitr;
-           switch (mode) {
-           case GL_OBJECT_LINEAR:
-              bitr = TEXGEN_OBJ_LINEAR;
-              break;
-           case GL_REFLECTION_MAP_NV:
-              bitr = TEXGEN_REFLECTION_MAP_NV;
-              break;
-           case GL_NORMAL_MAP_NV:
-              bitr = TEXGEN_NORMAL_MAP_NV;
-              break;
-           case GL_EYE_LINEAR:
-              bitr = TEXGEN_EYE_LINEAR;
-              break;
-           default:
-              _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
-              return;
-           }
-           if (texUnit->GenModeR == mode)
-              return;
-           FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-           texUnit->GenModeR = mode;
-           texUnit->_GenBitR = bitr;
-        }
-        else if (pname==GL_OBJECT_PLANE) {
-           if (TEST_EQ_4V(texUnit->ObjectPlaneR, params))
-               return;
-           FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-           COPY_4FV(texUnit->ObjectPlaneR, params);
-        }
-        else if (pname==GL_EYE_PLANE) {
-           GLfloat tmp[4];
-            /* Transform plane equation by the inverse modelview matrix */
-            if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) {
-               _math_matrix_analyse( ctx->ModelviewMatrixStack.Top );
-            }
-            _mesa_transform_vector( tmp, params, ctx->ModelviewMatrixStack.Top->inv );
-           if (TEST_EQ_4V(texUnit->EyePlaneR, tmp))
-              return;
-           FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-           COPY_4FV(texUnit->EyePlaneR, tmp);
-        }
-        else {
-           _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
-           return;
-        }
-        break;
-      case GL_Q:
-         if (pname==GL_TEXTURE_GEN_MODE) {
-           GLenum mode = (GLenum) (GLint) *params;
-           GLbitfield bitq;
-           switch (mode) {
-           case GL_OBJECT_LINEAR:
-              bitq = TEXGEN_OBJ_LINEAR;
-              break;
-           case GL_EYE_LINEAR:
-              bitq = TEXGEN_EYE_LINEAR;
-              break;
-           default:
-              _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
-              return;
-           }
-           if (texUnit->GenModeQ == mode)
-              return;
-           FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-           texUnit->GenModeQ = mode;
-           texUnit->_GenBitQ = bitq;
-        }
-        else if (pname==GL_OBJECT_PLANE) {
-           if (TEST_EQ_4V(texUnit->ObjectPlaneQ, params))
-               return;
-           FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-            COPY_4FV(texUnit->ObjectPlaneQ, params);
-        }
-        else if (pname==GL_EYE_PLANE) {
-           GLfloat tmp[4];
-            /* Transform plane equation by the inverse modelview matrix */
-            if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) {
-               _math_matrix_analyse( ctx->ModelviewMatrixStack.Top );
-            }
-            _mesa_transform_vector( tmp, params, ctx->ModelviewMatrixStack.Top->inv );
-           if (TEST_EQ_4V(texUnit->EyePlaneQ, tmp))
-              return;
-           FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-           COPY_4FV(texUnit->EyePlaneQ, tmp);
-        }
-        else {
-           _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
-           return;
-        }
-        break;
-      default:
-         _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(coord)" );
-        return;
-   }
-
-   if (ctx->Driver.TexGen)
-      ctx->Driver.TexGen( ctx, coord, pname, params );
-}
-
-
-void GLAPIENTRY
-_mesa_TexGeniv(GLenum coord, GLenum pname, const GLint *params )
-{
-   GLfloat p[4];
-   p[0] = (GLfloat) params[0];
-   if (pname == GL_TEXTURE_GEN_MODE) {
-      p[1] = p[2] = p[3] = 0.0F;
-   }
-   else {
-      p[1] = (GLfloat) params[1];
-      p[2] = (GLfloat) params[2];
-      p[3] = (GLfloat) params[3];
-   }
-   _mesa_TexGenfv(coord, pname, p);
-}
-
-
-void GLAPIENTRY
-_mesa_TexGend(GLenum coord, GLenum pname, GLdouble param )
-{
-   GLfloat p = (GLfloat) param;
-   _mesa_TexGenfv( coord, pname, &p );
-}
-
-
-void GLAPIENTRY
-_mesa_TexGendv(GLenum coord, GLenum pname, const GLdouble *params )
-{
-   GLfloat p[4];
-   p[0] = (GLfloat) params[0];
-   if (pname == GL_TEXTURE_GEN_MODE) {
-      p[1] = p[2] = p[3] = 0.0F;
-   }
-   else {
-      p[1] = (GLfloat) params[1];
-      p[2] = (GLfloat) params[2];
-      p[3] = (GLfloat) params[3];
-   }
-   _mesa_TexGenfv( coord, pname, p );
-}
-
-
-void GLAPIENTRY
-_mesa_TexGenf( GLenum coord, GLenum pname, GLfloat param )
-{
-   _mesa_TexGenfv(coord, pname, &param);
-}
-
-
-void GLAPIENTRY
-_mesa_TexGeni( GLenum coord, GLenum pname, GLint param )
-{
-   _mesa_TexGeniv( coord, pname, &param );
-}
-
-
-
-void GLAPIENTRY
-_mesa_GetTexGendv( GLenum coord, GLenum pname, GLdouble *params )
-{
-   const struct gl_texture_unit *texUnit;
-   GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END(ctx);
-
-   if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexGendv(current unit)");
-      return;
-   }
-
-   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
-
-   switch (coord) {
-      case GL_S:
-         if (pname==GL_TEXTURE_GEN_MODE) {
-            params[0] = ENUM_TO_DOUBLE(texUnit->GenModeS);
-        }
-        else if (pname==GL_OBJECT_PLANE) {
-            COPY_4V( params, texUnit->ObjectPlaneS );
-        }
-        else if (pname==GL_EYE_PLANE) {
-            COPY_4V( params, texUnit->EyePlaneS );
-        }
-        else {
-           _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
-           return;
-        }
-        break;
-      case GL_T:
-         if (pname==GL_TEXTURE_GEN_MODE) {
-            params[0] = ENUM_TO_DOUBLE(texUnit->GenModeT);
-        }
-        else if (pname==GL_OBJECT_PLANE) {
-            COPY_4V( params, texUnit->ObjectPlaneT );
-        }
-        else if (pname==GL_EYE_PLANE) {
-            COPY_4V( params, texUnit->EyePlaneT );
-        }
-        else {
-           _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
-           return;
-        }
-        break;
-      case GL_R:
-         if (pname==GL_TEXTURE_GEN_MODE) {
-            params[0] = ENUM_TO_DOUBLE(texUnit->GenModeR);
-        }
-        else if (pname==GL_OBJECT_PLANE) {
-            COPY_4V( params, texUnit->ObjectPlaneR );
-        }
-        else if (pname==GL_EYE_PLANE) {
-            COPY_4V( params, texUnit->EyePlaneR );
-        }
-        else {
-           _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
-           return;
-        }
-        break;
-      case GL_Q:
-         if (pname==GL_TEXTURE_GEN_MODE) {
-            params[0] = ENUM_TO_DOUBLE(texUnit->GenModeQ);
-        }
-        else if (pname==GL_OBJECT_PLANE) {
-            COPY_4V( params, texUnit->ObjectPlaneQ );
-        }
-        else if (pname==GL_EYE_PLANE) {
-            COPY_4V( params, texUnit->EyePlaneQ );
-        }
-        else {
-           _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
-           return;
-        }
-        break;
-      default:
-         _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(coord)" );
-        return;
-   }
-}
-
-
-
-void GLAPIENTRY
-_mesa_GetTexGenfv( GLenum coord, GLenum pname, GLfloat *params )
-{
-   const struct gl_texture_unit *texUnit;
-   GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END(ctx);
-
-   if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexGenfv(current unit)");
-      return;
-   }
-
-   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
-
-   switch (coord) {
-      case GL_S:
-         if (pname==GL_TEXTURE_GEN_MODE) {
-            params[0] = ENUM_TO_FLOAT(texUnit->GenModeS);
-        }
-        else if (pname==GL_OBJECT_PLANE) {
-            COPY_4V( params, texUnit->ObjectPlaneS );
-        }
-        else if (pname==GL_EYE_PLANE) {
-            COPY_4V( params, texUnit->EyePlaneS );
-        }
-        else {
-           _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
-           return;
-        }
-        break;
-      case GL_T:
-         if (pname==GL_TEXTURE_GEN_MODE) {
-            params[0] = ENUM_TO_FLOAT(texUnit->GenModeT);
-        }
-        else if (pname==GL_OBJECT_PLANE) {
-            COPY_4V( params, texUnit->ObjectPlaneT );
-        }
-        else if (pname==GL_EYE_PLANE) {
-            COPY_4V( params, texUnit->EyePlaneT );
-        }
-        else {
-           _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
-           return;
-        }
-        break;
-      case GL_R:
-         if (pname==GL_TEXTURE_GEN_MODE) {
-            params[0] = ENUM_TO_FLOAT(texUnit->GenModeR);
-        }
-        else if (pname==GL_OBJECT_PLANE) {
-            COPY_4V( params, texUnit->ObjectPlaneR );
-        }
-        else if (pname==GL_EYE_PLANE) {
-            COPY_4V( params, texUnit->EyePlaneR );
-        }
-        else {
-           _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
-           return;
-        }
-        break;
-      case GL_Q:
-         if (pname==GL_TEXTURE_GEN_MODE) {
-            params[0] = ENUM_TO_FLOAT(texUnit->GenModeQ);
-        }
-        else if (pname==GL_OBJECT_PLANE) {
-            COPY_4V( params, texUnit->ObjectPlaneQ );
-        }
-        else if (pname==GL_EYE_PLANE) {
-            COPY_4V( params, texUnit->EyePlaneQ );
-        }
-        else {
-           _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
-           return;
-        }
-        break;
-      default:
-         _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(coord)" );
-        return;
-   }
-}
-
-
-
-void GLAPIENTRY
-_mesa_GetTexGeniv( GLenum coord, GLenum pname, GLint *params )
-{
-   const struct gl_texture_unit *texUnit;
-   GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END(ctx);
-
-   if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexGeniv(current unit)");
-      return;
-   }
-
-   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
-
-   switch (coord) {
-      case GL_S:
-         if (pname==GL_TEXTURE_GEN_MODE) {
-            params[0] = texUnit->GenModeS;
-        }
-        else if (pname==GL_OBJECT_PLANE) {
-            params[0] = (GLint) texUnit->ObjectPlaneS[0];
-            params[1] = (GLint) texUnit->ObjectPlaneS[1];
-            params[2] = (GLint) texUnit->ObjectPlaneS[2];
-            params[3] = (GLint) texUnit->ObjectPlaneS[3];
-        }
-        else if (pname==GL_EYE_PLANE) {
-            params[0] = (GLint) texUnit->EyePlaneS[0];
-            params[1] = (GLint) texUnit->EyePlaneS[1];
-            params[2] = (GLint) texUnit->EyePlaneS[2];
-            params[3] = (GLint) texUnit->EyePlaneS[3];
-        }
-        else {
-           _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
-           return;
-        }
-        break;
-      case GL_T:
-         if (pname==GL_TEXTURE_GEN_MODE) {
-            params[0] = texUnit->GenModeT;
-        }
-        else if (pname==GL_OBJECT_PLANE) {
-            params[0] = (GLint) texUnit->ObjectPlaneT[0];
-            params[1] = (GLint) texUnit->ObjectPlaneT[1];
-            params[2] = (GLint) texUnit->ObjectPlaneT[2];
-            params[3] = (GLint) texUnit->ObjectPlaneT[3];
-        }
-        else if (pname==GL_EYE_PLANE) {
-            params[0] = (GLint) texUnit->EyePlaneT[0];
-            params[1] = (GLint) texUnit->EyePlaneT[1];
-            params[2] = (GLint) texUnit->EyePlaneT[2];
-            params[3] = (GLint) texUnit->EyePlaneT[3];
-        }
-        else {
-           _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
-           return;
-        }
-        break;
-      case GL_R:
-         if (pname==GL_TEXTURE_GEN_MODE) {
-            params[0] = texUnit->GenModeR;
-        }
-        else if (pname==GL_OBJECT_PLANE) {
-            params[0] = (GLint) texUnit->ObjectPlaneR[0];
-            params[1] = (GLint) texUnit->ObjectPlaneR[1];
-            params[2] = (GLint) texUnit->ObjectPlaneR[2];
-            params[3] = (GLint) texUnit->ObjectPlaneR[3];
-        }
-        else if (pname==GL_EYE_PLANE) {
-            params[0] = (GLint) texUnit->EyePlaneR[0];
-            params[1] = (GLint) texUnit->EyePlaneR[1];
-            params[2] = (GLint) texUnit->EyePlaneR[2];
-            params[3] = (GLint) texUnit->EyePlaneR[3];
-        }
-        else {
-           _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
-           return;
-        }
-        break;
-      case GL_Q:
-         if (pname==GL_TEXTURE_GEN_MODE) {
-            params[0] = texUnit->GenModeQ;
-        }
-        else if (pname==GL_OBJECT_PLANE) {
-            params[0] = (GLint) texUnit->ObjectPlaneQ[0];
-            params[1] = (GLint) texUnit->ObjectPlaneQ[1];
-            params[2] = (GLint) texUnit->ObjectPlaneQ[2];
-            params[3] = (GLint) texUnit->ObjectPlaneQ[3];
-        }
-        else if (pname==GL_EYE_PLANE) {
-            params[0] = (GLint) texUnit->EyePlaneQ[0];
-            params[1] = (GLint) texUnit->EyePlaneQ[1];
-            params[2] = (GLint) texUnit->EyePlaneQ[2];
-            params[3] = (GLint) texUnit->EyePlaneQ[3];
-         }
-        else {
-           _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
-           return;
-        }
-        break;
-      default:
-         _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(coord)" );
-        return;
-   }
-}
-#endif
-
-
 /* GL_ARB_multitexture */
 void GLAPIENTRY
 _mesa_ActiveTextureARB(GLenum texture)
@@ -2768,6 +1411,47 @@ update_texture_matrices( GLcontext *ctx )
 }
 
 
+/**
+ * Update texture object's _Function field.  We need to do this
+ * whenever any of the texture object's shadow-related fields change
+ * or when we start/stop using a fragment program.
+ *
+ * This function could be expanded someday to update additional per-object
+ * fields that depend on assorted state changes.
+ */
+static void
+update_texture_compare_function(GLcontext *ctx,
+                                struct gl_texture_object *tObj)
+{
+   /* XXX temporarily disable this test since it breaks the GLSL
+    * shadow2D(), etc. functions.
+    */
+   if (0 /*ctx->FragmentProgram._Current*/) {
+      /* Texel/coordinate comparison is ignored for programs.
+       * See GL_ARB_fragment_program/shader spec for details.
+       */
+      tObj->_Function = GL_NONE;
+   }
+   else if (tObj->CompareFlag) {
+      /* GL_SGIX_shadow */
+      if (tObj->CompareOperator == GL_TEXTURE_LEQUAL_R_SGIX) {
+         tObj->_Function = GL_LEQUAL;
+      }
+      else {
+         ASSERT(tObj->CompareOperator == GL_TEXTURE_GEQUAL_R_SGIX);
+         tObj->_Function = GL_GEQUAL;
+      }
+   }
+   else if (tObj->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB) {
+      /* GL_ARB_shadow */
+      tObj->_Function = tObj->CompareFunc;
+   }
+   else {
+      tObj->_Function = GL_NONE;  /* pass depth through as grayscale */
+   }
+}
+
+
 /**
  * Helper function for determining which texture object (1D, 2D, cube, etc)
  * should actually be used.
@@ -2778,12 +1462,13 @@ texture_override(GLcontext *ctx,
                  struct gl_texture_object *texObj, GLuint textureBit)
 {
    if (!texUnit->_ReallyEnabled && (enableBits & textureBit)) {
-      if (!texObj->Complete) {
+      if (!texObj->_Complete) {
          _mesa_test_texobj_completeness(ctx, texObj);
       }
-      if (texObj->Complete) {
+      if (texObj->_Complete) {
          texUnit->_ReallyEnabled = textureBit;
          texUnit->_Current = texObj;
+         update_texture_compare_function(ctx, texObj);
       }
    }
 }
@@ -2864,6 +1549,10 @@ update_texture_state( GLcontext *ctx )
        * complete.  That's the one we'll use for texturing.  If we're using
        * a fragment program we're guaranteed that bitcount(enabledBits) <= 1.
        */
+      texture_override(ctx, texUnit, enableBits,
+                       texUnit->Current2DArray, TEXTURE_2D_ARRAY_BIT);
+      texture_override(ctx, texUnit, enableBits,
+                       texUnit->Current1DArray, TEXTURE_1D_ARRAY_BIT);
       texture_override(ctx, texUnit, enableBits,
                        texUnit->CurrentCubeMap, TEXTURE_CUBE_BIT);
       texture_override(ctx, texUnit, enableBits,
@@ -3032,6 +1721,14 @@ alloc_proxy_textures( GLcontext *ctx )
    if (!ctx->Texture.ProxyRect)
       goto cleanup;
 
+   ctx->Texture.Proxy1DArray = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_1D_ARRAY_EXT);
+   if (!ctx->Texture.Proxy1DArray)
+      goto cleanup;
+
+   ctx->Texture.Proxy2DArray = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_2D_ARRAY_EXT);
+   if (!ctx->Texture.Proxy2DArray)
+      goto cleanup;
+
    return GL_TRUE;
 
  cleanup:
@@ -3045,6 +1742,10 @@ alloc_proxy_textures( GLcontext *ctx )
       (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyCubeMap);
    if (ctx->Texture.ProxyRect)
       (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyRect);
+   if (ctx->Texture.Proxy1DArray)
+      (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy1DArray);
+   if (ctx->Texture.Proxy2DArray)
+      (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy2DArray);
    return GL_FALSE;
 }
 
@@ -3092,6 +1793,8 @@ init_texture_unit( GLcontext *ctx, GLuint unit )
    texUnit->Current3D = ctx->Shared->Default3D;
    texUnit->CurrentCubeMap = ctx->Shared->DefaultCubeMap;
    texUnit->CurrentRect = ctx->Shared->DefaultRect;
+   texUnit->Current1DArray = ctx->Shared->Default1DArray;
+   texUnit->Current2DArray = ctx->Shared->Default2DArray;
 }
 
 
@@ -3112,6 +1815,8 @@ _mesa_init_texture(GLcontext *ctx)
    ctx->Shared->Default3D->RefCount += MAX_TEXTURE_UNITS;
    ctx->Shared->DefaultCubeMap->RefCount += MAX_TEXTURE_UNITS;
    ctx->Shared->DefaultRect->RefCount += MAX_TEXTURE_UNITS;
+   ctx->Shared->Default1DArray->RefCount += MAX_TEXTURE_UNITS;
+   ctx->Shared->Default2DArray->RefCount += MAX_TEXTURE_UNITS;
 
    /* Texture group */
    ctx->Texture.CurrentUnit = 0;      /* multitexture */
@@ -3119,9 +1824,9 @@ _mesa_init_texture(GLcontext *ctx)
    for (i=0; i<MAX_TEXTURE_UNITS; i++)
       init_texture_unit( ctx, i );
    ctx->Texture.SharedPalette = GL_FALSE;
+#if FEATURE_colortable
    _mesa_init_colortable(&ctx->Texture.Palette);
-
-   _mesa_TexEnvProgramCacheInit( ctx );
+#endif
 
    /* Allocate proxy textures */
    if (!alloc_proxy_textures( ctx ))
@@ -3137,17 +1842,20 @@ _mesa_init_texture(GLcontext *ctx)
 void
 _mesa_free_texture_data(GLcontext *ctx)
 {
-   GLuint i;
-
    /* Free proxy texture objects */
    (ctx->Driver.DeleteTexture)(ctx,  ctx->Texture.Proxy1D );
    (ctx->Driver.DeleteTexture)(ctx,  ctx->Texture.Proxy2D );
    (ctx->Driver.DeleteTexture)(ctx,  ctx->Texture.Proxy3D );
    (ctx->Driver.DeleteTexture)(ctx,  ctx->Texture.ProxyCubeMap );
    (ctx->Driver.DeleteTexture)(ctx,  ctx->Texture.ProxyRect );
+   (ctx->Driver.DeleteTexture)(ctx,  ctx->Texture.Proxy1DArray );
+   (ctx->Driver.DeleteTexture)(ctx,  ctx->Texture.Proxy2DArray );
 
-   for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++)
-      _mesa_free_colortable_data( &ctx->Texture.Unit[i].ColorTable );
-
-   _mesa_TexEnvProgramCacheDestroy( ctx );
+#if FEATURE_colortable
+   {
+      GLuint i;
+      for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++)
+         _mesa_free_colortable_data( &ctx->Texture.Unit[i].ColorTable );
+   }
+#endif
 }