mesa: more comments, clean-ups
[mesa.git] / src / mesa / main / texparam.c
index a9e752a6371096cff5869de2924403843c604cc5..05d144270ecdcd4219cf154874676b7d2d685c02 100644 (file)
@@ -1,8 +1,9 @@
 /*
  * Mesa 3-D graphics library
- * Version:  7.1
+ * Version:  7.5
  *
  * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
+ * Copyright (C) 2009  VMware, Inc.  All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -37,6 +38,8 @@
 #include "main/texcompress.h"
 #include "main/texparam.h"
 #include "main/teximage.h"
+#include "main/texstate.h"
+#include "shader/prog_instruction.h"
 
 
 /**
@@ -67,409 +70,640 @@ validate_texture_wrap_mode(GLcontext * ctx, GLenum target, GLenum wrap)
       return GL_TRUE;
    }
 
-   _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
+   _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param=0x%x)", wrap );
    return GL_FALSE;
 }
 
 
-void GLAPIENTRY
-_mesa_TexParameterf( GLenum target, GLenum pname, GLfloat param )
+/**
+ * Get current texture object for given target.
+ * Return NULL if any error.
+ */
+static struct gl_texture_object *
+get_texobj(GLcontext *ctx, GLenum target)
 {
-   _mesa_TexParameterfv(target, pname, &param);
+   struct gl_texture_unit *texUnit;
+
+   if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureImageUnits) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glTexParameter(current unit)");
+      return NULL;
+   }
+
+   texUnit = _mesa_get_current_tex_unit(ctx);
+
+   switch (target) {
+   case GL_TEXTURE_1D:
+      return texUnit->CurrentTex[TEXTURE_1D_INDEX];
+   case GL_TEXTURE_2D:
+      return texUnit->CurrentTex[TEXTURE_2D_INDEX];
+   case GL_TEXTURE_3D:
+      return texUnit->CurrentTex[TEXTURE_3D_INDEX];
+   case GL_TEXTURE_CUBE_MAP:
+      if (ctx->Extensions.ARB_texture_cube_map) {
+         return texUnit->CurrentTex[TEXTURE_CUBE_INDEX];
+      }
+      break;
+   case GL_TEXTURE_RECTANGLE_NV:
+      if (ctx->Extensions.NV_texture_rectangle) {
+         return texUnit->CurrentTex[TEXTURE_RECT_INDEX];
+      }
+      break;
+   case GL_TEXTURE_1D_ARRAY_EXT:
+      if (ctx->Extensions.MESA_texture_array) {
+         return texUnit->CurrentTex[TEXTURE_1D_ARRAY_INDEX];
+      }
+      break;
+   case GL_TEXTURE_2D_ARRAY_EXT:
+      if (ctx->Extensions.MESA_texture_array) {
+         return texUnit->CurrentTex[TEXTURE_2D_ARRAY_INDEX];
+      }
+      break;
+   default:
+      ;
+   }
+
+   _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(target)");
+   return NULL;
 }
 
 
-void GLAPIENTRY
-_mesa_TexParameterfv( GLenum target, GLenum pname, const GLfloat *params )
+/**
+ * Convert GL_RED/GREEN/BLUE/ALPHA/ZERO/ONE to SWIZZLE_X/Y/Z/W/ZERO/ONE.
+ * \return -1 if error.
+ */
+static GLint
+comp_to_swizzle(GLenum comp)
 {
-   const GLenum eparam = (GLenum) (GLint) params[0];
-   struct gl_texture_unit *texUnit;
-   struct gl_texture_object *texObj;
-   GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END(ctx);
+   switch (comp) {
+   case GL_RED:
+      return SWIZZLE_X;
+   case GL_GREEN:
+      return SWIZZLE_Y;
+   case GL_BLUE:
+      return SWIZZLE_Z;
+   case GL_ALPHA:
+      return SWIZZLE_W;
+   case GL_ZERO:
+      return SWIZZLE_ZERO;
+   case GL_ONE:
+      return SWIZZLE_ONE;
+   default:
+      return -1;
+   }
+}
 
-   if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE))
-      _mesa_debug(ctx, "glTexParameter %s %s %.1f(%s)...\n",
-                  _mesa_lookup_enum_by_nr(target),
-                  _mesa_lookup_enum_by_nr(pname),
-                  *params,
-                 _mesa_lookup_enum_by_nr(eparam));
 
-   if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureImageUnits) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glTexParameterfv(current unit)");
-      return;
+static void
+set_swizzle_component(GLuint *swizzle, GLuint comp, GLuint swz)
+{
+   ASSERT(comp < 4);
+   ASSERT(swz <= SWIZZLE_NIL);
+   {
+      GLuint mask = 0x7 << (3 * comp);
+      GLuint s = (*swizzle & ~mask) | (swz << (3 * comp));
+      *swizzle = s;
    }
+}
 
-   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
 
-   switch (target) {
-      case GL_TEXTURE_1D:
-         texObj = texUnit->Current1D;
-         break;
-      case GL_TEXTURE_2D:
-         texObj = texUnit->Current2D;
-         break;
-      case GL_TEXTURE_3D:
-         texObj = texUnit->Current3D;
-         break;
-      case GL_TEXTURE_CUBE_MAP:
-         if (!ctx->Extensions.ARB_texture_cube_map) {
-            _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(target)" );
-            return;
-         }
-         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_2D_ARRAY_EXT:
-         if (!ctx->Extensions.MESA_texture_array) {
-            _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(target)" );
-            return;
-         }
-         texObj = texUnit->Current2DArray;
-         break;
-      default:
-         _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(target)" );
-         return;
-   }
+/**
+ * This is called just prior to changing any texture object state.
+ * Any pending rendering will be flushed out, we'll set the _NEW_TEXTURE
+ * state flag and then mark the texture object as 'incomplete' so that any
+ * per-texture derived state gets recomputed.
+ */
+static INLINE void
+flush(GLcontext *ctx, struct gl_texture_object *texObj)
+{
+   FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+   texObj->_Complete = GL_FALSE;
+}
 
+
+/**
+ * Set an integer-valued texture parameter
+ * \return GL_TRUE if legal AND the value changed, GL_FALSE otherwise
+ */
+static GLboolean
+set_tex_parameteri(GLcontext *ctx,
+                   struct gl_texture_object *texObj,
+                   GLenum pname, const GLint *params)
+{
    switch (pname) {
-      case GL_TEXTURE_MIN_FILTER:
-         /* A small optimization */
-         if (texObj->MinFilter == eparam)
-            return;
-         if (eparam==GL_NEAREST || eparam==GL_LINEAR) {
-            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-            texObj->MinFilter = eparam;
-         }
-         else if ((eparam==GL_NEAREST_MIPMAP_NEAREST ||
-                   eparam==GL_LINEAR_MIPMAP_NEAREST ||
-                   eparam==GL_NEAREST_MIPMAP_LINEAR ||
-                   eparam==GL_LINEAR_MIPMAP_LINEAR) &&
-                  texObj->Target != GL_TEXTURE_RECTANGLE_NV) {
-            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-            texObj->MinFilter = eparam;
-         }
-         else {
-            _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
-            return;
-         }
-         break;
-      case GL_TEXTURE_MAG_FILTER:
-         /* A small optimization */
-         if (texObj->MagFilter == eparam)
-            return;
+   case GL_TEXTURE_MIN_FILTER:
+      if (texObj->MinFilter == params[0])
+         return GL_FALSE;
+      switch (params[0]) {
+      case GL_NEAREST:
+      case GL_LINEAR:
+         flush(ctx, texObj);
+         texObj->MinFilter = params[0];
+         return GL_TRUE;
+      case GL_NEAREST_MIPMAP_NEAREST:
+      case GL_LINEAR_MIPMAP_NEAREST:
+      case GL_NEAREST_MIPMAP_LINEAR:
+      case GL_LINEAR_MIPMAP_LINEAR:
+         if (texObj->Target != GL_TEXTURE_RECTANGLE_NV) {
+            flush(ctx, texObj);
+            texObj->MinFilter = params[0];
+            return GL_TRUE;
+         }
+         /* fall-through */
+      default:
+         _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param=0x%x)",
+                      params[0] );
+      }
+      return GL_FALSE;
 
-         if (eparam==GL_NEAREST || eparam==GL_LINEAR) {
-            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-            texObj->MagFilter = eparam;
-         }
-         else {
-            _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
-            return;
-         }
-         break;
-      case GL_TEXTURE_WRAP_S:
-         if (texObj->WrapS == eparam)
-            return;
-         if (validate_texture_wrap_mode(ctx, texObj->Target, eparam)) {
-            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-            texObj->WrapS = eparam;
-         }
-         else {
-            return;
-         }
-         break;
-      case GL_TEXTURE_WRAP_T:
-         if (texObj->WrapT == eparam)
-            return;
-         if (validate_texture_wrap_mode(ctx, texObj->Target, eparam)) {
-            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-            texObj->WrapT = eparam;
-         }
-         else {
-            return;
-         }
-         break;
-      case GL_TEXTURE_WRAP_R:
-         if (texObj->WrapR == eparam)
-            return;
-         if (validate_texture_wrap_mode(ctx, texObj->Target, eparam)) {
-            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-            texObj->WrapR = eparam;
-         }
-         else {
-           return;
-         }
-         break;
-      case GL_TEXTURE_BORDER_COLOR:
-         FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-         texObj->BorderColor[RCOMP] = params[0];
-         texObj->BorderColor[GCOMP] = params[1];
-         texObj->BorderColor[BCOMP] = params[2];
-         texObj->BorderColor[ACOMP] = params[3];
-         UNCLAMPED_FLOAT_TO_CHAN(texObj->_BorderChan[RCOMP], params[0]);
-         UNCLAMPED_FLOAT_TO_CHAN(texObj->_BorderChan[GCOMP], params[1]);
-         UNCLAMPED_FLOAT_TO_CHAN(texObj->_BorderChan[BCOMP], params[2]);
-         UNCLAMPED_FLOAT_TO_CHAN(texObj->_BorderChan[ACOMP], params[3]);
-         break;
-      case GL_TEXTURE_MIN_LOD:
-         if (texObj->MinLod == params[0])
-            return;
-         FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-         texObj->MinLod = params[0];
-         break;
-      case GL_TEXTURE_MAX_LOD:
-         if (texObj->MaxLod == params[0])
-            return;
-         FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-         texObj->MaxLod = params[0];
-         break;
-      case GL_TEXTURE_BASE_LEVEL:
-         if (params[0] < 0.0) {
-            _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)");
-            return;
-         }
-         if (target == GL_TEXTURE_RECTANGLE_ARB && params[0] != 0.0) {
-            _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)");
-            return;
-         }
-         FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-         texObj->BaseLevel = (GLint) params[0];
-         break;
-      case GL_TEXTURE_MAX_LEVEL:
-         if (params[0] < 0.0) {
-            _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)");
-            return;
-         }
-         if (target == GL_TEXTURE_RECTANGLE_ARB) {
-            _mesa_error(ctx, GL_INVALID_OPERATION, "glTexParameter(param)");
-            return;
-         }
-         FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-         texObj->MaxLevel = (GLint) params[0];
-         break;
-      case GL_TEXTURE_PRIORITY:
-         FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-         texObj->Priority = CLAMP( params[0], 0.0F, 1.0F );
-         break;
-      case GL_TEXTURE_MAX_ANISOTROPY_EXT:
-         if (ctx->Extensions.EXT_texture_filter_anisotropic) {
-           if (params[0] < 1.0) {
-              _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
-              return;
-           }
-            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-            /* clamp to max, that's what NVIDIA does */
-            texObj->MaxAnisotropy = MIN2(params[0],
-                                         ctx->Const.MaxTextureMaxAnisotropy);
-         }
-         else {
-            _mesa_error(ctx, GL_INVALID_ENUM,
-                        "glTexParameter(pname=GL_TEXTURE_MAX_ANISOTROPY_EXT)");
-            return;
-         }
-         break;
-      case GL_TEXTURE_COMPARE_SGIX:
-         if (ctx->Extensions.SGIX_shadow) {
-            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-            texObj->CompareFlag = params[0] ? GL_TRUE : GL_FALSE;
-         }
-         else {
-            _mesa_error(ctx, GL_INVALID_ENUM,
-                        "glTexParameter(pname=GL_TEXTURE_COMPARE_SGIX)");
-            return;
-         }
-         break;
-      case GL_TEXTURE_COMPARE_OPERATOR_SGIX:
-         if (ctx->Extensions.SGIX_shadow) {
-            GLenum op = (GLenum) params[0];
-            if (op == GL_TEXTURE_LEQUAL_R_SGIX ||
-                op == GL_TEXTURE_GEQUAL_R_SGIX) {
-               FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-               texObj->CompareOperator = op;
-            }
-            else {
-               _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(param)");
-            }
-         }
-         else {
-            _mesa_error(ctx, GL_INVALID_ENUM,
-                    "glTexParameter(pname=GL_TEXTURE_COMPARE_OPERATOR_SGIX)");
-            return;
-         }
-         break;
-      case GL_SHADOW_AMBIENT_SGIX: /* aka GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
-         if (ctx->Extensions.SGIX_shadow_ambient) {
-            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-            texObj->ShadowAmbient = CLAMP(params[0], 0.0F, 1.0F);
-         }
-         else {
-            _mesa_error(ctx, GL_INVALID_ENUM,
-                        "glTexParameter(pname=GL_SHADOW_AMBIENT_SGIX)");
-            return;
-         }
-         break;
-      case GL_GENERATE_MIPMAP_SGIS:
-         if (ctx->Extensions.SGIS_generate_mipmap) {
-            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+   case GL_TEXTURE_MAG_FILTER:
+      if (texObj->MagFilter == params[0])
+         return GL_FALSE;
+      switch (params[0]) {
+      case GL_NEAREST:
+      case GL_LINEAR:
+         flush(ctx, texObj);
+         texObj->MagFilter = params[0];
+         return GL_TRUE;
+      default:
+         _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param=0x%x)",
+                      params[0]);
+      }
+      return GL_FALSE;
+
+   case GL_TEXTURE_WRAP_S:
+      if (texObj->WrapS == params[0])
+         return GL_FALSE;
+      if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
+         flush(ctx, texObj);
+         texObj->WrapS = params[0];
+         return GL_TRUE;
+      }
+      return GL_FALSE;
+
+   case GL_TEXTURE_WRAP_T:
+      if (texObj->WrapT == params[0])
+         return GL_FALSE;
+      if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
+         flush(ctx, texObj);
+         texObj->WrapT = params[0];
+         return GL_TRUE;
+      }
+      return GL_FALSE;
+
+   case GL_TEXTURE_WRAP_R:
+      if (texObj->WrapR == params[0])
+         return GL_FALSE;
+      if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
+         flush(ctx, texObj);
+         texObj->WrapR = params[0];
+         return GL_TRUE;
+      }
+      return GL_FALSE;
+
+   case GL_TEXTURE_BASE_LEVEL:
+      if (texObj->BaseLevel == params[0])
+         return GL_FALSE;
+      if (params[0] < 0 ||
+          (texObj->Target == GL_TEXTURE_RECTANGLE_ARB && params[0] != 0)) {
+         _mesa_error(ctx, GL_INVALID_VALUE,
+                     "glTexParameter(param=%d)", params[0]);
+         return GL_FALSE;
+      }
+      flush(ctx, texObj);
+      texObj->BaseLevel = params[0];
+      return GL_TRUE;
+
+   case GL_TEXTURE_MAX_LEVEL:
+      if (texObj->MaxLevel == params[0])
+         return GL_FALSE;
+      if (params[0] < 0 || texObj->Target == GL_TEXTURE_RECTANGLE_ARB) {
+         _mesa_error(ctx, GL_INVALID_OPERATION,
+                     "glTexParameter(param=%d)", params[0]);
+         return GL_FALSE;
+      }
+      flush(ctx, texObj);
+      texObj->MaxLevel = params[0];
+      return GL_TRUE;
+
+   case GL_GENERATE_MIPMAP_SGIS:
+      if (ctx->Extensions.SGIS_generate_mipmap) {
+         if (texObj->GenerateMipmap != params[0]) {
+            flush(ctx, texObj);
             texObj->GenerateMipmap = params[0] ? GL_TRUE : GL_FALSE;
+            return GL_TRUE;
          }
-         else {
-            _mesa_error(ctx, GL_INVALID_ENUM,
-                        "glTexParameter(pname=GL_GENERATE_MIPMAP_SGIS)");
-            return;
-         }
-         break;
-      case GL_TEXTURE_COMPARE_MODE_ARB:
-         if (ctx->Extensions.ARB_shadow) {
-            const GLenum mode = (GLenum) params[0];
-            if (mode == GL_NONE || mode == GL_COMPARE_R_TO_TEXTURE_ARB) {
-               FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-               texObj->CompareMode = mode;
-            }
-            else {
-               _mesa_error(ctx, GL_INVALID_ENUM,
-                           "glTexParameter(bad GL_TEXTURE_COMPARE_MODE_ARB: 0x%x)", mode);
-               return;
-            }
-         }
-         else {
-            _mesa_error(ctx, GL_INVALID_ENUM,
-                        "glTexParameter(pname=GL_TEXTURE_COMPARE_MODE_ARB)");
-            return;
-         }
-         break;
-      case GL_TEXTURE_COMPARE_FUNC_ARB:
-         if (ctx->Extensions.ARB_shadow) {
-            const GLenum func = (GLenum) params[0];
-            if (func == GL_LEQUAL || func == GL_GEQUAL) {
-               FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-               texObj->CompareFunc = func;
-            }
-            else if (ctx->Extensions.EXT_shadow_funcs &&
-                     (func == GL_EQUAL ||
-                      func == GL_NOTEQUAL ||
-                      func == GL_LESS ||
-                      func == GL_GREATER ||
-                      func == GL_ALWAYS ||
-                      func == GL_NEVER)) {
-               FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-               texObj->CompareFunc = func;
-            }
-            else {
-               _mesa_error(ctx, GL_INVALID_ENUM,
-                           "glTexParameter(bad GL_TEXTURE_COMPARE_FUNC_ARB)");
-               return;
+         return GL_FALSE;
+      }
+      else {
+         _mesa_error(ctx, GL_INVALID_ENUM,
+                     "glTexParameter(pname=GL_GENERATE_MIPMAP_SGIS)");
+      }
+      return GL_FALSE;
+
+   case GL_TEXTURE_COMPARE_MODE_ARB:
+      if (ctx->Extensions.ARB_shadow &&
+          (params[0] == GL_NONE ||
+           params[0] == GL_COMPARE_R_TO_TEXTURE_ARB)) {
+         if (texObj->CompareMode != params[0]) {
+            flush(ctx, texObj);
+            texObj->CompareMode = params[0];
+            return GL_TRUE;
+         }
+         return GL_FALSE;
+      }
+      else {
+         _mesa_error(ctx, GL_INVALID_ENUM,
+                     "glTexParameter(GL_TEXTURE_COMPARE_MODE_ARB)");
+      }
+      return GL_FALSE;
+
+   case GL_TEXTURE_COMPARE_FUNC_ARB:
+      if (ctx->Extensions.ARB_shadow) {
+         if (texObj->CompareFunc == params[0])
+            return GL_FALSE;
+         switch (params[0]) {
+         case GL_LEQUAL:
+         case GL_GEQUAL:
+            flush(ctx, texObj);
+            texObj->CompareFunc = params[0];
+            return GL_TRUE;
+         case GL_EQUAL:
+         case GL_NOTEQUAL:
+         case GL_LESS:
+         case GL_GREATER:
+         case GL_ALWAYS:
+         case GL_NEVER:
+            if (ctx->Extensions.EXT_shadow_funcs) {
+               flush(ctx, texObj);
+               texObj->CompareFunc = params[0];
+               return GL_TRUE;
             }
-         }
-         else {
+            /* fall-through */
+         default:
             _mesa_error(ctx, GL_INVALID_ENUM,
-                        "glTexParameter(pname=GL_TEXTURE_COMPARE_FUNC_ARB)");
-            return;
+                        "glTexParameter(GL_TEXTURE_COMPARE_FUNC_ARB)");
          }
-         break;
-      case GL_DEPTH_TEXTURE_MODE_ARB:
-         if (ctx->Extensions.ARB_depth_texture) {
-            const GLenum result = (GLenum) params[0];
-            if (result == GL_LUMINANCE || result == GL_INTENSITY
-                || result == GL_ALPHA) {
-               FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-               texObj->DepthMode = result;
+      }
+      else {
+         _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname);
+      }
+      return GL_FALSE;
+
+   case GL_DEPTH_TEXTURE_MODE_ARB:
+      if (ctx->Extensions.ARB_depth_texture &&
+          (params[0] == GL_LUMINANCE ||
+           params[0] == GL_INTENSITY ||
+           params[0] == GL_ALPHA)) {
+         if (texObj->DepthMode != params[0]) {
+            flush(ctx, texObj);
+            texObj->DepthMode = params[0];
+            return GL_TRUE;
+         }
+      }
+      else {
+         _mesa_error(ctx, GL_INVALID_ENUM,
+                     "glTexParameter(GL_DEPTH_TEXTURE_MODE_ARB)");
+      }
+      return GL_FALSE;
+
+#ifdef FEATURE_OES_draw_texture
+   case GL_TEXTURE_CROP_RECT_OES:
+      texObj->CropRect[0] = params[0];
+      texObj->CropRect[1] = params[1];
+      texObj->CropRect[2] = params[2];
+      texObj->CropRect[3] = params[3];
+      return GL_TRUE;
+#endif
+
+   case GL_TEXTURE_SWIZZLE_R_EXT:
+   case GL_TEXTURE_SWIZZLE_G_EXT:
+   case GL_TEXTURE_SWIZZLE_B_EXT:
+   case GL_TEXTURE_SWIZZLE_A_EXT:
+      if (ctx->Extensions.EXT_texture_swizzle) {
+         const GLuint comp = pname - GL_TEXTURE_SWIZZLE_R_EXT;
+         const GLint swz = comp_to_swizzle(params[0]);
+         if (swz < 0) {
+            _mesa_error(ctx, GL_INVALID_OPERATION,
+                        "glTexParameter(swizzle 0x%x)", params[0]);
+            return GL_FALSE;
+         }
+         ASSERT(comp < 4);
+         if (swz >= 0) {
+            flush(ctx, texObj);
+            texObj->Swizzle[comp] = params[0];
+            set_swizzle_component(&texObj->_Swizzle, comp, swz);
+            return GL_TRUE;
+         }
+      }
+      _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname);
+      return GL_FALSE;
+
+   case GL_TEXTURE_SWIZZLE_RGBA_EXT:
+      if (ctx->Extensions.EXT_texture_swizzle) {
+         GLuint comp;
+         flush(ctx, texObj);
+         for (comp = 0; comp < 4; comp++) {
+            const GLint swz = comp_to_swizzle(params[comp]);
+            if (swz >= 0) {
+               texObj->Swizzle[comp] = params[comp];
+               set_swizzle_component(&texObj->_Swizzle, comp, swz);
             }
             else {
-               _mesa_error(ctx, GL_INVALID_ENUM,
-                          "glTexParameter(bad GL_DEPTH_TEXTURE_MODE_ARB)");
-               return;
+               _mesa_error(ctx, GL_INVALID_OPERATION,
+                           "glTexParameter(swizzle 0x%x)", params[comp]);
+               return GL_FALSE;
             }
          }
-         else {
+         return GL_TRUE;
+      }
+      _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname);
+      return GL_FALSE;
+
+   default:
+      _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname);
+   }
+   return GL_FALSE;
+}
+
+
+/**
+ * Set a float-valued texture parameter
+ * \return GL_TRUE if legal AND the value changed, GL_FALSE otherwise
+ */
+static GLboolean
+set_tex_parameterf(GLcontext *ctx,
+                   struct gl_texture_object *texObj,
+                   GLenum pname, const GLfloat *params)
+{
+   switch (pname) {
+   case GL_TEXTURE_MIN_LOD:
+      if (texObj->MinLod == params[0])
+         return GL_FALSE;
+      flush(ctx, texObj);
+      texObj->MinLod = params[0];
+      return GL_TRUE;
+
+   case GL_TEXTURE_MAX_LOD:
+      if (texObj->MaxLod == params[0])
+         return GL_FALSE;
+      flush(ctx, texObj);
+      texObj->MaxLod = params[0];
+      return GL_TRUE;
+
+   case GL_TEXTURE_PRIORITY:
+      flush(ctx, texObj);
+      texObj->Priority = CLAMP(params[0], 0.0F, 1.0F);
+      return GL_TRUE;
+
+   case GL_TEXTURE_MAX_ANISOTROPY_EXT:
+      if (ctx->Extensions.EXT_texture_filter_anisotropic) {
+         if (texObj->MaxAnisotropy == params[0])
+            return GL_FALSE;
+         if (params[0] < 1.0) {
+            _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
+            return GL_FALSE;
+         }
+         flush(ctx, texObj);
+         /* clamp to max, that's what NVIDIA does */
+         texObj->MaxAnisotropy = MIN2(params[0],
+                                      ctx->Const.MaxTextureMaxAnisotropy);
+         return GL_TRUE;
+      }
+      else {
+         static GLuint count = 0;
+         if (count++ < 10)
             _mesa_error(ctx, GL_INVALID_ENUM,
-                        "glTexParameter(pname=GL_DEPTH_TEXTURE_MODE_ARB)");
-            return;
-         }
-         break;
-      case GL_TEXTURE_LOD_BIAS:
-         /* NOTE: this is really part of OpenGL 1.4, not EXT_texture_lod_bias*/
-         if (ctx->Extensions.EXT_texture_lod_bias) {
-            if (texObj->LodBias != params[0]) {
-               FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-               texObj->LodBias = params[0];
-            }
-         }
-         break;
-#ifdef FEATURE_OES_draw_texture
-      case GL_TEXTURE_CROP_RECT_OES:
-         texObj->CropRect[0] = (GLint) params[0];
-         texObj->CropRect[1] = (GLint) params[1];
-         texObj->CropRect[2] = (GLint) params[2];
-         texObj->CropRect[3] = (GLint) params[3];
-         break;
-#endif
+                        "glTexParameter(pname=GL_TEXTURE_MAX_ANISOTROPY_EXT)");
+      }
+      return GL_FALSE;
 
-      default:
+   case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
+      if (ctx->Extensions.ARB_shadow_ambient) {
+         if (texObj->CompareFailValue != params[0]) {
+            flush(ctx, texObj);
+            texObj->CompareFailValue = CLAMP(params[0], 0.0F, 1.0F);
+            return GL_TRUE;
+         }
+      }
+      else {
          _mesa_error(ctx, GL_INVALID_ENUM,
-                     "glTexParameter(pname=0x%x)", pname);
-         return;
+                    "glTexParameter(pname=GL_TEXTURE_COMPARE_FAIL_VALUE_ARB)");
+      }
+      return GL_FALSE;
+
+   case GL_TEXTURE_LOD_BIAS:
+      /* NOTE: this is really part of OpenGL 1.4, not EXT_texture_lod_bias */
+      if (ctx->Extensions.EXT_texture_lod_bias) {
+         if (texObj->LodBias != params[0]) {
+            flush(ctx, texObj);
+            texObj->LodBias = params[0];
+            return GL_TRUE;
+         }
+         return GL_FALSE;
+      }
+      break;
+
+   case GL_TEXTURE_BORDER_COLOR:
+      flush(ctx, texObj);
+      texObj->BorderColor[RCOMP] = params[0];
+      texObj->BorderColor[GCOMP] = params[1];
+      texObj->BorderColor[BCOMP] = params[2];
+      texObj->BorderColor[ACOMP] = params[3];
+      return GL_TRUE;
+
+   default:
+      _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname);
    }
+   return GL_FALSE;
+}
 
-   texObj->_Complete = GL_FALSE;
 
-   if (ctx->Driver.TexParameter) {
-      (*ctx->Driver.TexParameter)( ctx, target, texObj, pname, params );
+void GLAPIENTRY
+_mesa_TexParameterf(GLenum target, GLenum pname, GLfloat param)
+{
+   GLboolean need_update;
+   struct gl_texture_object *texObj;
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   texObj = get_texobj(ctx, target);
+   if (!texObj)
+      return;
+
+   switch (pname) {
+   case GL_TEXTURE_MIN_FILTER:
+   case GL_TEXTURE_MAG_FILTER:
+   case GL_TEXTURE_WRAP_S:
+   case GL_TEXTURE_WRAP_T:
+   case GL_TEXTURE_WRAP_R:
+   case GL_TEXTURE_BASE_LEVEL:
+   case GL_TEXTURE_MAX_LEVEL:
+   case GL_GENERATE_MIPMAP_SGIS:
+   case GL_TEXTURE_COMPARE_MODE_ARB:
+   case GL_TEXTURE_COMPARE_FUNC_ARB:
+   case GL_DEPTH_TEXTURE_MODE_ARB:
+      {
+         /* convert float param to int */
+         GLint p = (GLint) param;
+         need_update = set_tex_parameteri(ctx, texObj, pname, &p);
+      }
+      break;
+   default:
+      /* this will generate an error if pname is illegal */
+      need_update = set_tex_parameterf(ctx, texObj, pname, &param);
+   }
+
+   if (ctx->Driver.TexParameter && need_update) {
+      ctx->Driver.TexParameter(ctx, target, texObj, pname, &param);
    }
 }
 
 
 void GLAPIENTRY
-_mesa_TexParameteri( GLenum target, GLenum pname, GLint param )
+_mesa_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params)
 {
-   GLfloat fparam[4];
-   if (pname == GL_TEXTURE_PRIORITY)
-      fparam[0] = INT_TO_FLOAT(param);
-   else
-      fparam[0] = (GLfloat) param;
-   fparam[1] = fparam[2] = fparam[3] = 0.0;
-   _mesa_TexParameterfv(target, pname, fparam);
+   GLboolean need_update;
+   struct gl_texture_object *texObj;
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   texObj = get_texobj(ctx, target);
+   if (!texObj)
+      return;
+
+   switch (pname) {
+   case GL_TEXTURE_MIN_FILTER:
+   case GL_TEXTURE_MAG_FILTER:
+   case GL_TEXTURE_WRAP_S:
+   case GL_TEXTURE_WRAP_T:
+   case GL_TEXTURE_WRAP_R:
+   case GL_TEXTURE_BASE_LEVEL:
+   case GL_TEXTURE_MAX_LEVEL:
+   case GL_GENERATE_MIPMAP_SGIS:
+   case GL_TEXTURE_COMPARE_MODE_ARB:
+   case GL_TEXTURE_COMPARE_FUNC_ARB:
+   case GL_DEPTH_TEXTURE_MODE_ARB:
+      {
+         /* convert float param to int */
+         GLint p = (GLint) params[0];
+         need_update = set_tex_parameteri(ctx, texObj, pname, &p);
+      }
+      break;
+
+#ifdef FEATURE_OES_draw_texture
+   case GL_TEXTURE_CROP_RECT_OES:
+      {
+         /* convert float params to int */
+         GLint iparams[4];
+         iparams[0] = (GLint) params[0];
+         iparams[1] = (GLint) params[1];
+         iparams[2] = (GLint) params[2];
+         iparams[3] = (GLint) params[3];
+         need_update = set_tex_parameteri(ctx, target, iparams);
+      }
+      break;
+#endif
+
+   default:
+      /* this will generate an error if pname is illegal */
+      need_update = set_tex_parameterf(ctx, texObj, pname, params);
+   }
+
+   if (ctx->Driver.TexParameter && need_update) {
+      ctx->Driver.TexParameter(ctx, target, texObj, pname, params);
+   }
 }
 
 
 void GLAPIENTRY
-_mesa_TexParameteriv( GLenum target, GLenum pname, const GLint *params )
+_mesa_TexParameteri(GLenum target, GLenum pname, GLint param)
 {
-   GLfloat fparam[4];
-   if (pname == GL_TEXTURE_BORDER_COLOR) {
-      fparam[0] = INT_TO_FLOAT(params[0]);
-      fparam[1] = INT_TO_FLOAT(params[1]);
-      fparam[2] = INT_TO_FLOAT(params[2]);
-      fparam[3] = INT_TO_FLOAT(params[3]);
+   GLboolean need_update;
+   struct gl_texture_object *texObj;
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   texObj = get_texobj(ctx, target);
+   if (!texObj)
+      return;
+
+   switch (pname) {
+   case GL_TEXTURE_MIN_LOD:
+   case GL_TEXTURE_MAX_LOD:
+   case GL_TEXTURE_PRIORITY:
+   case GL_TEXTURE_MAX_ANISOTROPY_EXT:
+   case GL_TEXTURE_LOD_BIAS:
+   case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
+      {
+         GLfloat fparam = (GLfloat) param;
+         /* convert int param to float */
+         need_update = set_tex_parameterf(ctx, texObj, pname, &fparam);
+      }
+      break;
+   default:
+      /* this will generate an error if pname is illegal */
+      need_update = set_tex_parameteri(ctx, texObj, pname, &param);
    }
-   else if (pname == GL_TEXTURE_CROP_RECT_OES) {
-      fparam[0] = (GLfloat) params[0];
-      fparam[1] = (GLfloat) params[1];
-      fparam[2] = (GLfloat) params[2];
-      fparam[3] = (GLfloat) params[3];
+
+   if (ctx->Driver.TexParameter && need_update) {
+      GLfloat fparam = (GLfloat) param;
+      ctx->Driver.TexParameter(ctx, target, texObj, pname, &fparam);
    }
-   else {
-      if (pname == GL_TEXTURE_PRIORITY)
-         fparam[0] = INT_TO_FLOAT(params[0]);
-      else
-         fparam[0] = (GLfloat) params[0];
-      fparam[1] = fparam[2] = fparam[3] = 0.0F;
+}
+
+
+void GLAPIENTRY
+_mesa_TexParameteriv(GLenum target, GLenum pname, const GLint *params)
+{
+   GLboolean need_update;
+   struct gl_texture_object *texObj;
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   texObj = get_texobj(ctx, target);
+   if (!texObj)
+      return;
+
+   switch (pname) {
+   case GL_TEXTURE_BORDER_COLOR:
+      {
+         /* convert int params to float */
+         GLfloat fparams[4];
+         fparams[0] = INT_TO_FLOAT(params[0]);
+         fparams[1] = INT_TO_FLOAT(params[1]);
+         fparams[2] = INT_TO_FLOAT(params[2]);
+         fparams[3] = INT_TO_FLOAT(params[3]);
+         need_update = set_tex_parameterf(ctx, texObj, pname, fparams);
+      }
+      break;
+   case GL_TEXTURE_MIN_LOD:
+   case GL_TEXTURE_MAX_LOD:
+   case GL_TEXTURE_PRIORITY:
+   case GL_TEXTURE_MAX_ANISOTROPY_EXT:
+   case GL_TEXTURE_LOD_BIAS:
+   case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
+      {
+         /* convert int param to float */
+         GLfloat fparam = (GLfloat) params[0];
+         need_update = set_tex_parameterf(ctx, texObj, pname, &fparam);
+      }
+      break;
+   default:
+      /* this will generate an error if pname is illegal */
+      need_update = set_tex_parameteri(ctx, texObj, pname, params);
+   }
+
+   if (ctx->Driver.TexParameter && need_update) {
+      GLfloat fparams[4];
+      fparams[0] = INT_TO_FLOAT(params[0]);
+      if (pname == GL_TEXTURE_BORDER_COLOR ||
+          pname == GL_TEXTURE_CROP_RECT_OES) {
+         fparams[1] = INT_TO_FLOAT(params[1]);
+         fparams[2] = INT_TO_FLOAT(params[2]);
+         fparams[3] = INT_TO_FLOAT(params[3]);
+      }
+      ctx->Driver.TexParameter(ctx, target, texObj, pname, fparams);
    }
-   _mesa_TexParameterfv(target, pname, fparam);
 }
 
 
@@ -483,44 +717,6 @@ _mesa_GetTexLevelParameterfv( GLenum target, GLint level,
 }
 
 
-static GLuint
-tex_image_dimensions(GLcontext *ctx, GLenum target)
-{
-   switch (target) {
-      case GL_TEXTURE_1D:
-      case GL_PROXY_TEXTURE_1D:
-         return 1;
-      case GL_TEXTURE_2D:
-      case GL_PROXY_TEXTURE_2D:
-         return 2;
-      case GL_TEXTURE_3D:
-      case GL_PROXY_TEXTURE_3D:
-         return 3;
-      case GL_TEXTURE_CUBE_MAP:
-      case GL_PROXY_TEXTURE_CUBE_MAP:
-      case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
-      case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
-      case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
-      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
-      case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
-      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
-         return ctx->Extensions.ARB_texture_cube_map ? 2 : 0;
-      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;
-   }
-}
-
-
 void GLAPIENTRY
 _mesa_GetTexLevelParameteriv( GLenum target, GLint level,
                               GLenum pname, GLint *params )
@@ -528,7 +724,6 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level,
    const struct gl_texture_unit *texUnit;
    struct gl_texture_object *texObj;
    const struct gl_texture_image *img = NULL;
-   GLuint dimensions;
    GLboolean isProxy;
    GLint maxLevels;
    GET_CURRENT_CONTEXT(ctx);
@@ -540,19 +735,13 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level,
       return;
    }
 
-   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+   texUnit = _mesa_get_current_tex_unit(ctx);
 
    /* this will catch bad target values */
-   dimensions = tex_image_dimensions(ctx, target);  /* 1, 2 or 3 */
-   if (dimensions == 0) {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(target)");
-      return;
-   }
-
    maxLevels = _mesa_max_texture_levels(ctx, target);
    if (maxLevels == 0) {
-      /* should not happen since <target> was just checked above */
-      _mesa_problem(ctx, "maxLevels=0 in _mesa_GetTexLevelParameter");
+      _mesa_error(ctx, GL_INVALID_ENUM,
+                  "glGetTexLevelParameter[if]v(target=0x%x)", target);
       return;
    }
 
@@ -649,7 +838,8 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level,
                         "glGetTexLevelParameter[if]v(pname)");
          break;
       case GL_TEXTURE_STENCIL_SIZE_EXT:
-         if (ctx->Extensions.EXT_packed_depth_stencil) {
+         if (ctx->Extensions.EXT_packed_depth_stencil ||
+             ctx->Extensions.ARB_framebuffer_object) {
             *params = img->TexFormat->StencilBits;
          }
          else {
@@ -660,33 +850,21 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level,
 
       /* GL_ARB_texture_compression */
       case GL_TEXTURE_COMPRESSED_IMAGE_SIZE:
-         if (ctx->Extensions.ARB_texture_compression) {
-            if (img->IsCompressed && !isProxy) {
-               /* Don't use ctx->Driver.CompressedTextureSize() since that
-                * may returned a padded hardware size.
-                */
-               *params = _mesa_compressed_texture_size(ctx, img->Width,
-                                                   img->Height, img->Depth,
-                                                   img->TexFormat->MesaFormat);
-            }
-            else {
-               _mesa_error(ctx, GL_INVALID_OPERATION,
-                           "glGetTexLevelParameter[if]v(pname)");
-            }
-         }
-         else {
-            _mesa_error(ctx, GL_INVALID_ENUM,
-                        "glGetTexLevelParameter[if]v(pname)");
-         }
+        if (img->IsCompressed && !isProxy) {
+           /* Don't use ctx->Driver.CompressedTextureSize() since that
+            * may returned a padded hardware size.
+            */
+           *params = _mesa_compressed_texture_size(ctx, img->Width,
+                                                   img->Height, img->Depth,
+                                                   img->TexFormat->MesaFormat);
+        }
+        else {
+           _mesa_error(ctx, GL_INVALID_OPERATION,
+                       "glGetTexLevelParameter[if]v(pname)");
+        }
          break;
       case GL_TEXTURE_COMPRESSED:
-         if (ctx->Extensions.ARB_texture_compression) {
-            *params = (GLint) img->IsCompressed;
-         }
-         else {
-            _mesa_error(ctx, GL_INVALID_ENUM,
-                        "glGetTexLevelParameter[if]v(pname)");
-         }
+         *params = (GLint) img->IsCompressed;
          break;
 
       /* GL_ARB_texture_float */
@@ -780,7 +958,7 @@ _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params )
       return;
    }
 
-   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+   texUnit = _mesa_get_current_tex_unit(ctx);
 
    obj = _mesa_select_tex_object(ctx, texUnit, target);
    if (!obj) {
@@ -841,63 +1019,49 @@ _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params )
             *params = obj->MaxAnisotropy;
          }
         else
-           error = 1;
-         break;
-      case GL_TEXTURE_COMPARE_SGIX:
-         if (ctx->Extensions.SGIX_shadow) {
-            *params = (GLfloat) obj->CompareFlag;
-         }
-        else 
-           error = 1;
-         break;
-      case GL_TEXTURE_COMPARE_OPERATOR_SGIX:
-         if (ctx->Extensions.SGIX_shadow) {
-            *params = (GLfloat) obj->CompareOperator;
-         }
-        else 
-           error = 1;
+           error = GL_TRUE;
          break;
-      case GL_SHADOW_AMBIENT_SGIX: /* aka GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
-         if (ctx->Extensions.SGIX_shadow_ambient) {
-            *params = obj->ShadowAmbient;
+      case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
+         if (ctx->Extensions.ARB_shadow_ambient) {
+            *params = obj->CompareFailValue;
          }
         else 
-           error = 1;
+           error = GL_TRUE;
          break;
       case GL_GENERATE_MIPMAP_SGIS:
          if (ctx->Extensions.SGIS_generate_mipmap) {
             *params = (GLfloat) obj->GenerateMipmap;
          }
         else 
-           error = 1;
+           error = GL_TRUE;
          break;
       case GL_TEXTURE_COMPARE_MODE_ARB:
          if (ctx->Extensions.ARB_shadow) {
             *params = (GLfloat) obj->CompareMode;
          }
         else 
-           error = 1;
+           error = GL_TRUE;
          break;
       case GL_TEXTURE_COMPARE_FUNC_ARB:
          if (ctx->Extensions.ARB_shadow) {
             *params = (GLfloat) obj->CompareFunc;
          }
         else 
-           error = 1;
+           error = GL_TRUE;
          break;
       case GL_DEPTH_TEXTURE_MODE_ARB:
          if (ctx->Extensions.ARB_depth_texture) {
             *params = (GLfloat) obj->DepthMode;
          }
         else 
-           error = 1;
+           error = GL_TRUE;
          break;
       case GL_TEXTURE_LOD_BIAS:
          if (ctx->Extensions.EXT_texture_lod_bias) {
             *params = obj->LodBias;
          }
         else 
-           error = 1;
+           error = GL_TRUE;
          break;
 #ifdef FEATURE_OES_draw_texture
       case GL_TEXTURE_CROP_RECT_OES:
@@ -907,10 +1071,37 @@ _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params )
          params[3] = obj->CropRect[3];
          break;
 #endif
+
+      case GL_TEXTURE_SWIZZLE_R_EXT:
+      case GL_TEXTURE_SWIZZLE_G_EXT:
+      case GL_TEXTURE_SWIZZLE_B_EXT:
+      case GL_TEXTURE_SWIZZLE_A_EXT:
+         if (ctx->Extensions.EXT_texture_swizzle) {
+            GLuint comp = pname - GL_TEXTURE_SWIZZLE_R_EXT;
+            *params = (GLfloat) obj->Swizzle[comp];
+         }
+         else {
+            error = GL_TRUE;
+         }
+         break;
+
+      case GL_TEXTURE_SWIZZLE_RGBA_EXT:
+         if (ctx->Extensions.EXT_texture_swizzle) {
+            GLuint comp;
+            for (comp = 0; comp < 4; comp++) {
+               params[comp] = (GLfloat) obj->Swizzle[comp];
+            }
+         }
+         else {
+            error = GL_TRUE;
+         }
+         break;
+
       default:
-        error = 1;
+        error = GL_TRUE;
         break;
    }
+
    if (error)
       _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname=0x%x)",
                  pname);
@@ -924,6 +1115,7 @@ _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params )
 {
    struct gl_texture_unit *texUnit;
    struct gl_texture_object *obj;
+   GLboolean error = GL_FALSE;
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END(ctx);
 
@@ -933,7 +1125,7 @@ _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params )
       return;
    }
 
-   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+   texUnit = _mesa_get_current_tex_unit(ctx);
 
    obj = _mesa_select_tex_object(ctx, texUnit, target);
    if (!obj) {
@@ -944,19 +1136,19 @@ _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params )
    switch (pname) {
       case GL_TEXTURE_MAG_FILTER:
          *params = (GLint) obj->MagFilter;
-         return;
+         break;;
       case GL_TEXTURE_MIN_FILTER:
          *params = (GLint) obj->MinFilter;
-         return;
+         break;;
       case GL_TEXTURE_WRAP_S:
          *params = (GLint) obj->WrapS;
-         return;
+         break;;
       case GL_TEXTURE_WRAP_T:
          *params = (GLint) obj->WrapT;
-         return;
+         break;;
       case GL_TEXTURE_WRAP_R:
          *params = (GLint) obj->WrapR;
-         return;
+         break;;
       case GL_TEXTURE_BORDER_COLOR:
          {
             GLfloat b[4];
@@ -969,7 +1161,7 @@ _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params )
             params[2] = FLOAT_TO_INT(b[2]);
             params[3] = FLOAT_TO_INT(b[3]);
          }
-         return;
+         break;;
       case GL_TEXTURE_RESIDENT:
          {
             GLboolean resident;
@@ -979,74 +1171,76 @@ _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params )
                resident = GL_TRUE;
             *params = (GLint) resident;
          }
-         return;
+         break;;
       case GL_TEXTURE_PRIORITY:
          *params = FLOAT_TO_INT(obj->Priority);
-         return;
+         break;;
       case GL_TEXTURE_MIN_LOD:
          *params = (GLint) obj->MinLod;
-         return;
+         break;;
       case GL_TEXTURE_MAX_LOD:
          *params = (GLint) obj->MaxLod;
-         return;
+         break;;
       case GL_TEXTURE_BASE_LEVEL:
          *params = obj->BaseLevel;
-         return;
+         break;;
       case GL_TEXTURE_MAX_LEVEL:
          *params = obj->MaxLevel;
-         return;
+         break;;
       case GL_TEXTURE_MAX_ANISOTROPY_EXT:
          if (ctx->Extensions.EXT_texture_filter_anisotropic) {
             *params = (GLint) obj->MaxAnisotropy;
-            return;
          }
-         break;
-      case GL_TEXTURE_COMPARE_SGIX:
-         if (ctx->Extensions.SGIX_shadow) {
-            *params = (GLint) obj->CompareFlag;
-            return;
+         else {
+            error = GL_TRUE;
          }
          break;
-      case GL_TEXTURE_COMPARE_OPERATOR_SGIX:
-         if (ctx->Extensions.SGIX_shadow) {
-            *params = (GLint) obj->CompareOperator;
-            return;
+      case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
+         if (ctx->Extensions.ARB_shadow_ambient) {
+            *params = (GLint) FLOAT_TO_INT(obj->CompareFailValue);
          }
-         break;
-      case GL_SHADOW_AMBIENT_SGIX: /* aka GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
-         if (ctx->Extensions.SGIX_shadow_ambient) {
-            *params = (GLint) FLOAT_TO_INT(obj->ShadowAmbient);
-            return;
+         else {
+            error = GL_TRUE;
          }
          break;
       case GL_GENERATE_MIPMAP_SGIS:
          if (ctx->Extensions.SGIS_generate_mipmap) {
             *params = (GLint) obj->GenerateMipmap;
-            return;
+         }
+         else {
+            error = GL_TRUE;
          }
          break;
       case GL_TEXTURE_COMPARE_MODE_ARB:
          if (ctx->Extensions.ARB_shadow) {
             *params = (GLint) obj->CompareMode;
-            return;
+         }
+         else {
+            error = GL_TRUE;
          }
          break;
       case GL_TEXTURE_COMPARE_FUNC_ARB:
          if (ctx->Extensions.ARB_shadow) {
             *params = (GLint) obj->CompareFunc;
-            return;
+         }
+         else {
+            error = GL_TRUE;
          }
          break;
       case GL_DEPTH_TEXTURE_MODE_ARB:
          if (ctx->Extensions.ARB_depth_texture) {
             *params = (GLint) obj->DepthMode;
-            return;
+         }
+         else {
+            error = GL_TRUE;
          }
          break;
       case GL_TEXTURE_LOD_BIAS:
          if (ctx->Extensions.EXT_texture_lod_bias) {
             *params = (GLint) obj->LodBias;
-            return;
+         }
+         else {
+            error = GL_TRUE;
          }
          break;
 #ifdef FEATURE_OES_draw_texture
@@ -1057,9 +1251,35 @@ _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params )
          params[3] = obj->CropRect[3];
          break;
 #endif
+      case GL_TEXTURE_SWIZZLE_R_EXT:
+      case GL_TEXTURE_SWIZZLE_G_EXT:
+      case GL_TEXTURE_SWIZZLE_B_EXT:
+      case GL_TEXTURE_SWIZZLE_A_EXT:
+         if (ctx->Extensions.EXT_texture_swizzle) {
+            GLuint comp = pname - GL_TEXTURE_SWIZZLE_R_EXT;
+            *params = obj->Swizzle[comp];
+         }
+         else {
+            error = GL_TRUE;
+         }
+         break;
+
+      case GL_TEXTURE_SWIZZLE_RGBA_EXT:
+         if (ctx->Extensions.EXT_texture_swizzle) {
+            COPY_4V(params, obj->Swizzle);
+         }
+         else {
+            error = GL_TRUE;
+         }
+         break;
+
       default:
          ; /* silence warnings */
    }
-   /* If we get here, pname was an unrecognized enum */
-   _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname=0x%x)", pname);
+
+   if (error)
+      _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname=0x%x)",
+                 pname);
+
+   _mesa_unlock_texture(ctx, obj);
 }