mesa: remove _mesa_compressed_texture_size()
[mesa.git] / src / mesa / main / texparam.c
index 865aae86276a7a7954b8ef07713c1d23d034a7f4..afa66f149ce249817bfd684c72773f70799a26a8 100644 (file)
 
 
 #include "main/glheader.h"
+#include "main/colormac.h"
 #include "main/context.h"
 #include "main/enums.h"
-#include "main/colormac.h"
+#include "main/formats.h"
 #include "main/macros.h"
 #include "main/texcompress.h"
 #include "main/texparam.h"
 #include "main/teximage.h"
+#include "main/texstate.h"
 #include "shader/prog_instruction.h"
 
 
@@ -69,7 +71,7 @@ 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_ENUM, "glTexParameter(param=0x%x)", wrap );
    return GL_FALSE;
 }
 
@@ -88,33 +90,33 @@ get_texobj(GLcontext *ctx, GLenum target)
       return NULL;
    }
 
-   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+   texUnit = _mesa_get_current_tex_unit(ctx);
 
    switch (target) {
    case GL_TEXTURE_1D:
-      return texUnit->Current1D;
+      return texUnit->CurrentTex[TEXTURE_1D_INDEX];
    case GL_TEXTURE_2D:
-      return texUnit->Current2D;
+      return texUnit->CurrentTex[TEXTURE_2D_INDEX];
    case GL_TEXTURE_3D:
-      return texUnit->Current3D;
+      return texUnit->CurrentTex[TEXTURE_3D_INDEX];
    case GL_TEXTURE_CUBE_MAP:
       if (ctx->Extensions.ARB_texture_cube_map) {
-         return texUnit->CurrentCubeMap;
+         return texUnit->CurrentTex[TEXTURE_CUBE_INDEX];
       }
       break;
    case GL_TEXTURE_RECTANGLE_NV:
       if (ctx->Extensions.NV_texture_rectangle) {
-         return texUnit->CurrentRect;
+         return texUnit->CurrentTex[TEXTURE_RECT_INDEX];
       }
       break;
    case GL_TEXTURE_1D_ARRAY_EXT:
       if (ctx->Extensions.MESA_texture_array) {
-         return texUnit->Current1DArray;
+         return texUnit->CurrentTex[TEXTURE_1D_ARRAY_INDEX];
       }
       break;
    case GL_TEXTURE_2D_ARRAY_EXT:
       if (ctx->Extensions.MESA_texture_array) {
-         return texUnit->Current2DArray;
+         return texUnit->CurrentTex[TEXTURE_2D_ARRAY_INDEX];
       }
       break;
    default:
@@ -179,8 +181,11 @@ flush(GLcontext *ctx, struct gl_texture_object *texObj)
 }
 
 
-/** Set an integer-valued texture parameter */
-static void
+/**
+ * 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)
@@ -188,13 +193,13 @@ set_tex_parameteri(GLcontext *ctx,
    switch (pname) {
    case GL_TEXTURE_MIN_FILTER:
       if (texObj->MinFilter == params[0])
-         return;
+         return GL_FALSE;
       switch (params[0]) {
       case GL_NEAREST:
       case GL_LINEAR:
          flush(ctx, texObj);
          texObj->MinFilter = params[0];
-         return;
+         return GL_TRUE;
       case GL_NEAREST_MIPMAP_NEAREST:
       case GL_LINEAR_MIPMAP_NEAREST:
       case GL_NEAREST_MIPMAP_LINEAR:
@@ -202,90 +207,99 @@ set_tex_parameteri(GLcontext *ctx,
          if (texObj->Target != GL_TEXTURE_RECTANGLE_NV) {
             flush(ctx, texObj);
             texObj->MinFilter = params[0];
-            return;
+            return GL_TRUE;
          }
          /* fall-through */
       default:
-         _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
+         _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(param=0x%x)",
+                      params[0] );
       }
-      return;
+      return GL_FALSE;
 
    case GL_TEXTURE_MAG_FILTER:
       if (texObj->MagFilter == params[0])
-         return;
+         return GL_FALSE;
       switch (params[0]) {
       case GL_NEAREST:
       case GL_LINEAR:
          flush(ctx, texObj);
          texObj->MagFilter = params[0];
-         return;
+         return GL_TRUE;
       default:
-         _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
+         _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(param=0x%x)",
+                      params[0]);
       }
-      return;
+      return GL_FALSE;
 
    case GL_TEXTURE_WRAP_S:
       if (texObj->WrapS == params[0])
-         return;
+         return GL_FALSE;
       if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
          flush(ctx, texObj);
          texObj->WrapS = params[0];
+         return GL_TRUE;
       }
-      return;
+      return GL_FALSE;
 
    case GL_TEXTURE_WRAP_T:
       if (texObj->WrapT == params[0])
-         return;
+         return GL_FALSE;
       if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
          flush(ctx, texObj);
          texObj->WrapT = params[0];
+         return GL_TRUE;
       }
-      return;
+      return GL_FALSE;
 
    case GL_TEXTURE_WRAP_R:
       if (texObj->WrapR == params[0])
-         return;
+         return GL_FALSE;
       if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
          flush(ctx, texObj);
          texObj->WrapR = params[0];
+         return GL_TRUE;
       }
-      return;
+      return GL_FALSE;
 
    case GL_TEXTURE_BASE_LEVEL:
       if (texObj->BaseLevel == params[0])
-         return;
+         return GL_FALSE;
       if (params[0] < 0 ||
           (texObj->Target == GL_TEXTURE_RECTANGLE_ARB && params[0] != 0)) {
-         _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)");
-         return;
+         _mesa_error(ctx, GL_INVALID_VALUE,
+                     "glTexParameter(param=%d)", params[0]);
+         return GL_FALSE;
       }
       flush(ctx, texObj);
       texObj->BaseLevel = params[0];
-      return;
+      return GL_TRUE;
 
    case GL_TEXTURE_MAX_LEVEL:
       if (texObj->MaxLevel == params[0])
-         return;
+         return GL_FALSE;
       if (params[0] < 0 || texObj->Target == GL_TEXTURE_RECTANGLE_ARB) {
-         _mesa_error(ctx, GL_INVALID_OPERATION, "glTexParameter(param)");
-         return;
+         _mesa_error(ctx, GL_INVALID_OPERATION,
+                     "glTexParameter(param=%d)", params[0]);
+         return GL_FALSE;
       }
       flush(ctx, texObj);
       texObj->MaxLevel = params[0];
-      return;
+      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;
          }
+         return GL_FALSE;
       }
       else {
          _mesa_error(ctx, GL_INVALID_ENUM,
                      "glTexParameter(pname=GL_GENERATE_MIPMAP_SGIS)");
       }
-      return;
+      return GL_FALSE;
 
    case GL_TEXTURE_COMPARE_MODE_ARB:
       if (ctx->Extensions.ARB_shadow &&
@@ -294,24 +308,26 @@ set_tex_parameteri(GLcontext *ctx,
          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;
+      return GL_FALSE;
 
    case GL_TEXTURE_COMPARE_FUNC_ARB:
       if (ctx->Extensions.ARB_shadow) {
          if (texObj->CompareFunc == params[0])
-            return;
+            return GL_FALSE;
          switch (params[0]) {
          case GL_LEQUAL:
          case GL_GEQUAL:
             flush(ctx, texObj);
             texObj->CompareFunc = params[0];
-            return;
+            return GL_TRUE;
          case GL_EQUAL:
          case GL_NOTEQUAL:
          case GL_LESS:
@@ -321,7 +337,7 @@ set_tex_parameteri(GLcontext *ctx,
             if (ctx->Extensions.EXT_shadow_funcs) {
                flush(ctx, texObj);
                texObj->CompareFunc = params[0];
-               return;
+               return GL_TRUE;
             }
             /* fall-through */
          default:
@@ -330,9 +346,9 @@ set_tex_parameteri(GLcontext *ctx,
          }
       }
       else {
-         _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(param)");
+         _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname);
       }
-      return;
+      return GL_FALSE;
 
    case GL_DEPTH_TEXTURE_MODE_ARB:
       if (ctx->Extensions.ARB_depth_texture &&
@@ -342,13 +358,14 @@ set_tex_parameteri(GLcontext *ctx,
          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;
+      return GL_FALSE;
 
 #ifdef FEATURE_OES_draw_texture
    case GL_TEXTURE_CROP_RECT_OES:
@@ -356,7 +373,7 @@ set_tex_parameteri(GLcontext *ctx,
       texObj->CropRect[1] = params[1];
       texObj->CropRect[2] = params[2];
       texObj->CropRect[3] = params[3];
-      return;
+      return GL_TRUE;
 #endif
 
    case GL_TEXTURE_SWIZZLE_R_EXT:
@@ -369,18 +386,18 @@ set_tex_parameteri(GLcontext *ctx,
          if (swz < 0) {
             _mesa_error(ctx, GL_INVALID_OPERATION,
                         "glTexParameter(swizzle 0x%x)", params[0]);
-            return;
+            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;
+            return GL_TRUE;
          }
       }
       _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname);
-      return;
+      return GL_FALSE;
 
    case GL_TEXTURE_SWIZZLE_RGBA_EXT:
       if (ctx->Extensions.EXT_texture_swizzle) {
@@ -395,22 +412,26 @@ set_tex_parameteri(GLcontext *ctx,
             else {
                _mesa_error(ctx, GL_INVALID_OPERATION,
                            "glTexParameter(swizzle 0x%x)", params[comp]);
-               return;
+               return GL_FALSE;
             }
          }
-         return;
+         return GL_TRUE;
       }
       _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname);
-      return;
+      return GL_FALSE;
 
    default:
       _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname);
    }
+   return GL_FALSE;
 }
 
 
-/** Set a float-valued texture parameter */
-static void
+/**
+ * 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)
@@ -418,54 +439,58 @@ set_tex_parameterf(GLcontext *ctx,
    switch (pname) {
    case GL_TEXTURE_MIN_LOD:
       if (texObj->MinLod == params[0])
-         return;
+         return GL_FALSE;
       flush(ctx, texObj);
       texObj->MinLod = params[0];
-      return;
+      return GL_TRUE;
 
    case GL_TEXTURE_MAX_LOD:
       if (texObj->MaxLod == params[0])
-         return;
+         return GL_FALSE;
       flush(ctx, texObj);
       texObj->MaxLod = params[0];
-      return;
+      return GL_TRUE;
 
    case GL_TEXTURE_PRIORITY:
       flush(ctx, texObj);
       texObj->Priority = CLAMP(params[0], 0.0F, 1.0F);
-      return;
+      return GL_TRUE;
 
    case GL_TEXTURE_MAX_ANISOTROPY_EXT:
       if (ctx->Extensions.EXT_texture_filter_anisotropic) {
          if (texObj->MaxAnisotropy == params[0])
-            return;
+            return GL_FALSE;
          if (params[0] < 1.0) {
             _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
-            return;
+            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 {
-         _mesa_error(ctx, GL_INVALID_ENUM,
-                     "glTexParameter(pname=GL_TEXTURE_MAX_ANISOTROPY_EXT)");
+         static GLuint count = 0;
+         if (count++ < 10)
+            _mesa_error(ctx, GL_INVALID_ENUM,
+                        "glTexParameter(pname=GL_TEXTURE_MAX_ANISOTROPY_EXT)");
       }
-      return;
+      return GL_FALSE;
 
    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=GL_TEXTURE_COMPARE_FAIL_VALUE_ARB)");
       }
-      return;
+      return GL_FALSE;
 
    case GL_TEXTURE_LOD_BIAS:
       /* NOTE: this is really part of OpenGL 1.4, not EXT_texture_lod_bias */
@@ -473,7 +498,9 @@ set_tex_parameterf(GLcontext *ctx,
          if (texObj->LodBias != params[0]) {
             flush(ctx, texObj);
             texObj->LodBias = params[0];
+            return GL_TRUE;
          }
+         return GL_FALSE;
       }
       break;
 
@@ -483,21 +510,19 @@ set_tex_parameterf(GLcontext *ctx,
       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]);
-      return;
+      return GL_TRUE;
 
    default:
       _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname);
    }
+   return GL_FALSE;
 }
 
 
 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);
@@ -521,15 +546,15 @@ _mesa_TexParameterf(GLenum target, GLenum pname, GLfloat param)
       {
          /* convert float param to int */
          GLint p = (GLint) param;
-         set_tex_parameteri(ctx, texObj, pname, &p);
+         need_update = set_tex_parameteri(ctx, texObj, pname, &p);
       }
-      return;
+      break;
    default:
       /* this will generate an error if pname is illegal */
-      set_tex_parameterf(ctx, texObj, pname, &param);
+      need_update = set_tex_parameterf(ctx, texObj, pname, &param);
    }
 
-   if (ctx->Driver.TexParameter && ctx->ErrorValue == GL_NO_ERROR) {
+   if (ctx->Driver.TexParameter && need_update) {
       ctx->Driver.TexParameter(ctx, target, texObj, pname, &param);
    }
 }
@@ -538,6 +563,7 @@ _mesa_TexParameterf(GLenum target, GLenum pname, GLfloat param)
 void GLAPIENTRY
 _mesa_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params)
 {
+   GLboolean need_update;
    struct gl_texture_object *texObj;
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END(ctx);
@@ -561,7 +587,7 @@ _mesa_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params)
       {
          /* convert float param to int */
          GLint p = (GLint) params[0];
-         set_tex_parameteri(ctx, texObj, pname, &p);
+         need_update = set_tex_parameteri(ctx, texObj, pname, &p);
       }
       break;
 
@@ -574,17 +600,17 @@ _mesa_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params)
          iparams[1] = (GLint) params[1];
          iparams[2] = (GLint) params[2];
          iparams[3] = (GLint) params[3];
-         set_tex_parameteri(ctx, target, iparams);
+         need_update = set_tex_parameteri(ctx, target, iparams);
       }
       break;
 #endif
 
    default:
       /* this will generate an error if pname is illegal */
-      set_tex_parameterf(ctx, texObj, pname, params);
+      need_update = set_tex_parameterf(ctx, texObj, pname, params);
    }
 
-   if (ctx->Driver.TexParameter && ctx->ErrorValue == GL_NO_ERROR) {
+   if (ctx->Driver.TexParameter && need_update) {
       ctx->Driver.TexParameter(ctx, target, texObj, pname, params);
    }
 }
@@ -593,6 +619,7 @@ _mesa_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params)
 void GLAPIENTRY
 _mesa_TexParameteri(GLenum target, GLenum pname, GLint param)
 {
+   GLboolean need_update;
    struct gl_texture_object *texObj;
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END(ctx);
@@ -611,15 +638,15 @@ _mesa_TexParameteri(GLenum target, GLenum pname, GLint param)
       {
          GLfloat fparam = (GLfloat) param;
          /* convert int param to float */
-         set_tex_parameterf(ctx, texObj, pname, &fparam);
+         need_update = set_tex_parameterf(ctx, texObj, pname, &fparam);
       }
       break;
    default:
       /* this will generate an error if pname is illegal */
-      set_tex_parameteri(ctx, texObj, pname, &param);
+      need_update = set_tex_parameteri(ctx, texObj, pname, &param);
    }
 
-   if (ctx->Driver.TexParameter && ctx->ErrorValue == GL_NO_ERROR) {
+   if (ctx->Driver.TexParameter && need_update) {
       GLfloat fparam = (GLfloat) param;
       ctx->Driver.TexParameter(ctx, target, texObj, pname, &fparam);
    }
@@ -629,6 +656,7 @@ _mesa_TexParameteri(GLenum target, GLenum pname, GLint param)
 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);
@@ -646,7 +674,7 @@ _mesa_TexParameteriv(GLenum target, GLenum pname, const GLint *params)
          fparams[1] = INT_TO_FLOAT(params[1]);
          fparams[2] = INT_TO_FLOAT(params[2]);
          fparams[3] = INT_TO_FLOAT(params[3]);
-         set_tex_parameterf(ctx, texObj, pname, fparams);
+         need_update = set_tex_parameterf(ctx, texObj, pname, fparams);
       }
       break;
    case GL_TEXTURE_MIN_LOD:
@@ -658,15 +686,15 @@ _mesa_TexParameteriv(GLenum target, GLenum pname, const GLint *params)
       {
          /* convert int param to float */
          GLfloat fparam = (GLfloat) params[0];
-         set_tex_parameterf(ctx, texObj, pname, &fparam);
+         need_update = set_tex_parameterf(ctx, texObj, pname, &fparam);
       }
       break;
    default:
       /* this will generate an error if pname is illegal */
-      set_tex_parameteri(ctx, texObj, pname, params);
+      need_update = set_tex_parameteri(ctx, texObj, pname, params);
    }
 
-   if (ctx->Driver.TexParameter && ctx->ErrorValue == GL_NO_ERROR) {
+   if (ctx->Driver.TexParameter && need_update) {
       GLfloat fparams[4];
       fparams[0] = INT_TO_FLOAT(params[0]);
       if (pname == GL_TEXTURE_BORDER_COLOR ||
@@ -690,44 +718,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 )
@@ -735,9 +725,9 @@ _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;
+   gl_format texFormat;
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END(ctx);
 
@@ -747,19 +737,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;
    }
 
@@ -781,6 +765,8 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level,
       goto out;
    }
 
+   texFormat = img->TexFormat;
+
    isProxy = _mesa_is_proxy_texture(target);
 
    switch (pname) {
@@ -800,20 +786,10 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level,
          *params = img->Border;
          break;
       case GL_TEXTURE_RED_SIZE:
-         if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA)
-            *params = img->TexFormat->RedBits;
-         else
-            *params = 0;
-         break;
       case GL_TEXTURE_GREEN_SIZE:
-         if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA)
-            *params = img->TexFormat->GreenBits;
-         else
-            *params = 0;
-         break;
       case GL_TEXTURE_BLUE_SIZE:
          if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA)
-            *params = img->TexFormat->BlueBits;
+            *params = _mesa_get_format_bits(texFormat, pname);
          else
             *params = 0;
          break;
@@ -821,43 +797,52 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level,
          if (img->_BaseFormat == GL_ALPHA ||
              img->_BaseFormat == GL_LUMINANCE_ALPHA ||
              img->_BaseFormat == GL_RGBA)
-            *params = img->TexFormat->AlphaBits;
+            *params = _mesa_get_format_bits(texFormat, pname);
          else
             *params = 0;
          break;
       case GL_TEXTURE_INTENSITY_SIZE:
          if (img->_BaseFormat != GL_INTENSITY)
             *params = 0;
-         else if (img->TexFormat->IntensityBits > 0)
-            *params = img->TexFormat->IntensityBits;
-         else /* intensity probably stored as rgb texture */
-            *params = MIN2(img->TexFormat->RedBits, img->TexFormat->GreenBits);
+         else {
+            *params = _mesa_get_format_bits(texFormat, pname);
+            if (*params == 0) {
+               /* intensity probably stored as rgb texture */
+               *params = MIN2(_mesa_get_format_bits(texFormat, GL_TEXTURE_RED_SIZE),
+                              _mesa_get_format_bits(texFormat, GL_TEXTURE_GREEN_SIZE));
+            }
+         }
          break;
       case GL_TEXTURE_LUMINANCE_SIZE:
          if (img->_BaseFormat != GL_LUMINANCE &&
              img->_BaseFormat != GL_LUMINANCE_ALPHA)
             *params = 0;
-         else if (img->TexFormat->LuminanceBits > 0)
-            *params = img->TexFormat->LuminanceBits;
-         else /* luminance probably stored as rgb texture */
-            *params = MIN2(img->TexFormat->RedBits, img->TexFormat->GreenBits);
+         else {
+            *params = _mesa_get_format_bits(texFormat, pname);
+            if (*params == 0) {
+               /* luminance probably stored as rgb texture */
+               *params = MIN2(_mesa_get_format_bits(texFormat, GL_TEXTURE_RED_SIZE),
+                              _mesa_get_format_bits(texFormat, GL_TEXTURE_GREEN_SIZE));
+            }
+         }
          break;
       case GL_TEXTURE_INDEX_SIZE_EXT:
          if (img->_BaseFormat == GL_COLOR_INDEX)
-            *params = img->TexFormat->IndexBits;
+            *params = _mesa_get_format_bits(texFormat, pname);
          else
             *params = 0;
          break;
       case GL_TEXTURE_DEPTH_SIZE_ARB:
          if (ctx->Extensions.ARB_depth_texture)
-            *params = img->TexFormat->DepthBits;
+            *params = _mesa_get_format_bits(texFormat, pname);
          else
             _mesa_error(ctx, GL_INVALID_ENUM,
                         "glGetTexLevelParameter[if]v(pname)");
          break;
       case GL_TEXTURE_STENCIL_SIZE_EXT:
-         if (ctx->Extensions.EXT_packed_depth_stencil) {
-            *params = img->TexFormat->StencilBits;
+         if (ctx->Extensions.EXT_packed_depth_stencil ||
+             ctx->Extensions.ARB_framebuffer_object) {
+            *params = _mesa_get_format_bits(texFormat, pname);
          }
          else {
             _mesa_error(ctx, GL_INVALID_ENUM,
@@ -867,13 +852,9 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level,
 
       /* GL_ARB_texture_compression */
       case GL_TEXTURE_COMPRESSED_IMAGE_SIZE:
-        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);
+        if (_mesa_is_format_compressed(img->TexFormat) && !isProxy) {
+            *params = _mesa_format_image_size(texFormat, img->Width,
+                                              img->Height, img->Depth);
         }
         else {
            _mesa_error(ctx, GL_INVALID_OPERATION,
@@ -881,13 +862,14 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level,
         }
          break;
       case GL_TEXTURE_COMPRESSED:
-         *params = (GLint) img->IsCompressed;
+         *params = (GLint) _mesa_is_format_compressed(img->TexFormat);
          break;
 
       /* GL_ARB_texture_float */
       case GL_TEXTURE_RED_TYPE_ARB:
          if (ctx->Extensions.ARB_texture_float) {
-            *params = img->TexFormat->RedBits ? img->TexFormat->DataType : GL_NONE;
+            *params = _mesa_get_format_bits(texFormat, GL_TEXTURE_RED_SIZE) ?
+               _mesa_get_format_datatype(texFormat) : GL_NONE;
          }
          else {
             _mesa_error(ctx, GL_INVALID_ENUM,
@@ -896,7 +878,8 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level,
          break;
       case GL_TEXTURE_GREEN_TYPE_ARB:
          if (ctx->Extensions.ARB_texture_float) {
-            *params = img->TexFormat->GreenBits ? img->TexFormat->DataType : GL_NONE;
+            *params = _mesa_get_format_bits(texFormat, GL_TEXTURE_GREEN_SIZE) ?
+               _mesa_get_format_datatype(texFormat) : GL_NONE;
          }
          else {
             _mesa_error(ctx, GL_INVALID_ENUM,
@@ -905,7 +888,8 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level,
          break;
       case GL_TEXTURE_BLUE_TYPE_ARB:
          if (ctx->Extensions.ARB_texture_float) {
-            *params = img->TexFormat->BlueBits ? img->TexFormat->DataType : GL_NONE;
+            *params = _mesa_get_format_bits(texFormat, GL_TEXTURE_BLUE_SIZE) ?
+               _mesa_get_format_datatype(texFormat) : GL_NONE;
          }
          else {
             _mesa_error(ctx, GL_INVALID_ENUM,
@@ -914,7 +898,8 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level,
          break;
       case GL_TEXTURE_ALPHA_TYPE_ARB:
          if (ctx->Extensions.ARB_texture_float) {
-            *params = img->TexFormat->AlphaBits ? img->TexFormat->DataType : GL_NONE;
+            *params = _mesa_get_format_bits(texFormat, GL_TEXTURE_ALPHA_SIZE) ?
+               _mesa_get_format_datatype(texFormat) : GL_NONE;
          }
          else {
             _mesa_error(ctx, GL_INVALID_ENUM,
@@ -923,7 +908,8 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level,
          break;
       case GL_TEXTURE_LUMINANCE_TYPE_ARB:
          if (ctx->Extensions.ARB_texture_float) {
-            *params = img->TexFormat->LuminanceBits ? img->TexFormat->DataType : GL_NONE;
+            *params = _mesa_get_format_bits(texFormat, GL_TEXTURE_LUMINANCE_SIZE) ?
+               _mesa_get_format_datatype(texFormat) : GL_NONE;
          }
          else {
             _mesa_error(ctx, GL_INVALID_ENUM,
@@ -932,7 +918,8 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level,
          break;
       case GL_TEXTURE_INTENSITY_TYPE_ARB:
          if (ctx->Extensions.ARB_texture_float) {
-            *params = img->TexFormat->IntensityBits ? img->TexFormat->DataType : GL_NONE;
+            *params = _mesa_get_format_bits(texFormat, GL_TEXTURE_INTENSITY_SIZE) ?
+               _mesa_get_format_datatype(texFormat) : GL_NONE;
          }
          else {
             _mesa_error(ctx, GL_INVALID_ENUM,
@@ -941,7 +928,8 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level,
          break;
       case GL_TEXTURE_DEPTH_TYPE_ARB:
          if (ctx->Extensions.ARB_texture_float) {
-            *params = img->TexFormat->DepthBits ? img->TexFormat->DataType : GL_NONE;
+            *params = _mesa_get_format_bits(texFormat, GL_TEXTURE_DEPTH_SIZE) ?
+               _mesa_get_format_datatype(texFormat) : GL_NONE;
          }
          else {
             _mesa_error(ctx, GL_INVALID_ENUM,
@@ -975,7 +963,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) {
@@ -1142,7 +1130,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) {