ARB sync: Add infrastructure for glGetInteger64v
[mesa.git] / src / mesa / main / teximage.c
index 109fe0e0521a60a33d7d3b23161d4e71fa6b31bb..8228303040932feb47acb4b76a45c7481d5ca6d0 100644 (file)
@@ -182,6 +182,8 @@ logbase2( int n )
  *
  * This is the format which is used during texture application (i.e. the
  * texture format and env mode determine the arithmetic used.
+ *
+ * XXX this could be static
  */
 GLint
 _mesa_base_tex_format( GLcontext *ctx, GLint internalFormat )
@@ -414,211 +416,6 @@ _mesa_base_tex_format( GLcontext *ctx, GLint internalFormat )
 }
 
 
-/**
- * Test if the given image format is a color/RGBA format (i.e., not color
- * index, depth, stencil, etc).
- * \param format  the image format value (may by an internal texture format)
- * \return GL_TRUE if its a color/RGBA format, GL_FALSE otherwise.
- * XXX maybe move this func to image.c
- */
-GLboolean
-_mesa_is_color_format(GLenum format)
-{
-   switch (format) {
-      case GL_RED:
-      case GL_GREEN:
-      case GL_BLUE:
-      case GL_ALPHA:
-      case GL_ALPHA4:
-      case GL_ALPHA8:
-      case GL_ALPHA12:
-      case GL_ALPHA16:
-      case 1:
-      case GL_LUMINANCE:
-      case GL_LUMINANCE4:
-      case GL_LUMINANCE8:
-      case GL_LUMINANCE12:
-      case GL_LUMINANCE16:
-      case 2:
-      case GL_LUMINANCE_ALPHA:
-      case GL_LUMINANCE4_ALPHA4:
-      case GL_LUMINANCE6_ALPHA2:
-      case GL_LUMINANCE8_ALPHA8:
-      case GL_LUMINANCE12_ALPHA4:
-      case GL_LUMINANCE12_ALPHA12:
-      case GL_LUMINANCE16_ALPHA16:
-      case GL_INTENSITY:
-      case GL_INTENSITY4:
-      case GL_INTENSITY8:
-      case GL_INTENSITY12:
-      case GL_INTENSITY16:
-      case 3:
-      case GL_RGB:
-      case GL_BGR:
-      case GL_R3_G3_B2:
-      case GL_RGB4:
-      case GL_RGB5:
-      case GL_RGB8:
-      case GL_RGB10:
-      case GL_RGB12:
-      case GL_RGB16:
-      case 4:
-      case GL_ABGR_EXT:
-      case GL_RGBA:
-      case GL_BGRA:
-      case GL_RGBA2:
-      case GL_RGBA4:
-      case GL_RGB5_A1:
-      case GL_RGBA8:
-      case GL_RGB10_A2:
-      case GL_RGBA12:
-      case GL_RGBA16:
-      /* float texture formats */
-      case GL_ALPHA16F_ARB:
-      case GL_ALPHA32F_ARB:
-      case GL_LUMINANCE16F_ARB:
-      case GL_LUMINANCE32F_ARB:
-      case GL_LUMINANCE_ALPHA16F_ARB:
-      case GL_LUMINANCE_ALPHA32F_ARB:
-      case GL_INTENSITY16F_ARB:
-      case GL_INTENSITY32F_ARB:
-      case GL_RGB16F_ARB:
-      case GL_RGB32F_ARB:
-      case GL_RGBA16F_ARB:
-      case GL_RGBA32F_ARB:
-      /* compressed formats */
-      case GL_COMPRESSED_ALPHA:
-      case GL_COMPRESSED_LUMINANCE:
-      case GL_COMPRESSED_LUMINANCE_ALPHA:
-      case GL_COMPRESSED_INTENSITY:
-      case GL_COMPRESSED_RGB:
-      case GL_COMPRESSED_RGBA:
-      case GL_RGB_S3TC:
-      case GL_RGB4_S3TC:
-      case GL_RGBA_S3TC:
-      case GL_RGBA4_S3TC:
-      case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
-      case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
-      case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
-      case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
-      case GL_COMPRESSED_RGB_FXT1_3DFX:
-      case GL_COMPRESSED_RGBA_FXT1_3DFX:
-#if FEATURE_EXT_texture_sRGB
-      case GL_SRGB_EXT:
-      case GL_SRGB8_EXT:
-      case GL_SRGB_ALPHA_EXT:
-      case GL_SRGB8_ALPHA8_EXT:
-      case GL_SLUMINANCE_ALPHA_EXT:
-      case GL_SLUMINANCE8_ALPHA8_EXT:
-      case GL_SLUMINANCE_EXT:
-      case GL_SLUMINANCE8_EXT:
-      case GL_COMPRESSED_SRGB_EXT:
-      case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
-      case GL_COMPRESSED_SRGB_ALPHA_EXT:
-      case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
-      case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
-      case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
-      case GL_COMPRESSED_SLUMINANCE_EXT:
-      case GL_COMPRESSED_SLUMINANCE_ALPHA_EXT:
-#endif /* FEATURE_EXT_texture_sRGB */
-         return GL_TRUE;
-      /* signed texture formats */
-      case GL_RGBA_SNORM:
-      case GL_RGBA8_SNORM:
-         return GL_TRUE;
-      case GL_YCBCR_MESA:  /* not considered to be RGB */
-         /* fall-through */
-      default:
-         return GL_FALSE;
-   }
-}
-
-
-/**
- * Test if the given image format is a color index format.
- */
-static GLboolean
-is_index_format(GLenum format)
-{
-   switch (format) {
-      case GL_COLOR_INDEX:
-      case GL_COLOR_INDEX1_EXT:
-      case GL_COLOR_INDEX2_EXT:
-      case GL_COLOR_INDEX4_EXT:
-      case GL_COLOR_INDEX8_EXT:
-      case GL_COLOR_INDEX12_EXT:
-      case GL_COLOR_INDEX16_EXT:
-         return GL_TRUE;
-      default:
-         return GL_FALSE;
-   }
-}
-
-
-/**
- * Test if the given image format is a depth component format.
- */
-static GLboolean
-is_depth_format(GLenum format)
-{
-   switch (format) {
-      case GL_DEPTH_COMPONENT16:
-      case GL_DEPTH_COMPONENT24:
-      case GL_DEPTH_COMPONENT32:
-      case GL_DEPTH_COMPONENT:
-         return GL_TRUE;
-      default:
-         return GL_FALSE;
-   }
-}
-
-
-/**
- * Test if the given image format is a YCbCr format.
- */
-static GLboolean
-is_ycbcr_format(GLenum format)
-{
-   switch (format) {
-      case GL_YCBCR_MESA:
-         return GL_TRUE;
-      default:
-         return GL_FALSE;
-   }
-}
-
-
-/**
- * Test if the given image format is a Depth/Stencil format.
- */
-static GLboolean
-is_depthstencil_format(GLenum format)
-{
-   switch (format) {
-      case GL_DEPTH24_STENCIL8_EXT:
-      case GL_DEPTH_STENCIL_EXT:
-         return GL_TRUE;
-      default:
-         return GL_FALSE;
-   }
-}
-
-/**
- * Test if the given image format is a dudv format.
- */
-static GLboolean
-is_dudv_format(GLenum format)
-{
-   switch (format) {
-      case GL_DUDV_ATI:
-      case GL_DU8DV8_ATI:
-         return GL_TRUE;
-      default:
-         return GL_FALSE;
-   }
-}
-
-
 /**
  * Test if it is a supported compressed format.
  * 
@@ -765,6 +562,9 @@ _mesa_delete_texture_image( GLcontext *ctx, struct gl_texture_image *texImage )
 GLboolean
 _mesa_is_proxy_texture(GLenum target)
 {
+   /* NUM_TEXTURE_TARGETS should match number of terms below */
+   assert(NUM_TEXTURE_TARGETS == 7);
+
    return (target == GL_PROXY_TEXTURE_1D ||
            target == GL_PROXY_TEXTURE_2D ||
            target == GL_PROXY_TEXTURE_3D ||
@@ -984,10 +784,6 @@ _mesa_max_texture_levels(GLcontext *ctx, GLenum target)
    case GL_PROXY_TEXTURE_1D:
    case GL_TEXTURE_2D:
    case GL_PROXY_TEXTURE_2D:
-   case GL_TEXTURE_1D_ARRAY_EXT:
-   case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
-   case GL_TEXTURE_2D_ARRAY_EXT:
-   case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
       return ctx->Const.MaxTextureLevels;
    case GL_TEXTURE_3D:
    case GL_PROXY_TEXTURE_3D:
@@ -1000,10 +796,17 @@ _mesa_max_texture_levels(GLcontext *ctx, GLenum target)
    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
    case GL_TEXTURE_CUBE_MAP_ARB:
    case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
-      return ctx->Const.MaxCubeTextureLevels;
+      return ctx->Extensions.ARB_texture_cube_map
+         ? ctx->Const.MaxCubeTextureLevels : 0;
    case GL_TEXTURE_RECTANGLE_NV:
    case GL_PROXY_TEXTURE_RECTANGLE_NV:
-      return 1;
+      return ctx->Extensions.NV_texture_rectangle ? 1 : 0;
+   case GL_TEXTURE_1D_ARRAY_EXT:
+   case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
+   case GL_TEXTURE_2D_ARRAY_EXT:
+   case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
+      return ctx->Extensions.MESA_texture_array
+         ? ctx->Const.MaxTextureLevels : 0;
    default:
       return 0; /* bad target */
    }
@@ -1203,6 +1006,23 @@ _mesa_init_teximage_fields(GLcontext *ctx, GLenum target,
 }
 
 
+/**
+ * Free and clear fields of the gl_texture_image struct.
+ *
+ * \param ctx GL context.
+ * \param texImage texture image structure to be cleared.
+ *
+ * After the call, \p texImage will have no data associated with it.  Its
+ * fields are cleared so that its parent object will test incomplete.
+ */
+void
+_mesa_clear_texture_image(GLcontext *ctx, struct gl_texture_image *texImage)
+{
+   ctx->Driver.FreeTexImageData(ctx, texImage);
+   clear_teximage_fields(texImage);
+}
+
+
 /**
  * This is the fallback for Driver.TestProxyTexImage().  Test the texture
  * level, width, height and depth against the ctx->Const limits for textures.
@@ -1517,13 +1337,13 @@ texture_error_check( GLcontext *ctx, GLenum target,
 
    /* make sure internal format and format basically agree */
    colorFormat = _mesa_is_color_format(format);
-   indexFormat = is_index_format(format);
+   indexFormat = _mesa_is_index_format(format);
    if ((_mesa_is_color_format(internalFormat) && !colorFormat && !indexFormat) ||
-       (is_index_format(internalFormat) && !indexFormat) ||
-       (is_depth_format(internalFormat) != is_depth_format(format)) ||
-       (is_ycbcr_format(internalFormat) != is_ycbcr_format(format)) ||
-       (is_depthstencil_format(internalFormat) != is_depthstencil_format(format)) ||
-       (is_dudv_format(internalFormat) != is_dudv_format(format))) {
+       (_mesa_is_index_format(internalFormat) && !indexFormat) ||
+       (_mesa_is_depth_format(internalFormat) != _mesa_is_depth_format(format)) ||
+       (_mesa_is_ycbcr_format(internalFormat) != _mesa_is_ycbcr_format(format)) ||
+       (_mesa_is_depthstencil_format(internalFormat) != _mesa_is_depthstencil_format(format)) ||
+       (_mesa_is_dudv_format(internalFormat) != _mesa_is_dudv_format(format))) {
       if (!isProxy)
          _mesa_error(ctx, GL_INVALID_OPERATION,
                      "glTexImage%dD(incompatible internalFormat 0x%x, format 0x%x)",
@@ -1857,14 +1677,14 @@ copytexture_error_check( GLcontext *ctx, GLuint dimensions,
       return GL_TRUE;
    }
 
-   /* NOTE: the format and type aren't really significant for
-    * TestProxyTexImage().  Only the internalformat really matters.
    if (!_mesa_source_buffer_exists(ctx, format)) {
       _mesa_error(ctx, GL_INVALID_OPERATION,
                   "glCopyTexImage%dD(missing readbuffer)", dimensions);
       return GL_TRUE;
    }
 
+   /* NOTE: the format and type aren't really significant for
+    * TestProxyTexImage().  Only the internalformat really matters.
     */
    type = GL_FLOAT;
 
@@ -1958,7 +1778,7 @@ copytexture_error_check( GLcontext *ctx, GLuint dimensions,
          return GL_TRUE;
       }
    }
-   else if (is_depth_format(internalFormat)) {
+   else if (_mesa_is_depth_format(internalFormat)) {
       /* make sure we have depth/stencil buffers */
       if (!ctx->ReadBuffer->_DepthBuffer) {
          _mesa_error(ctx, GL_INVALID_OPERATION,
@@ -1966,7 +1786,7 @@ copytexture_error_check( GLcontext *ctx, GLuint dimensions,
          return GL_TRUE;
       }
    }
-   else if (is_depthstencil_format(internalFormat)) {
+   else if (_mesa_is_depthstencil_format(internalFormat)) {
       /* make sure we have depth/stencil buffers */
       if (!ctx->ReadBuffer->_DepthBuffer || !ctx->ReadBuffer->_StencilBuffer) {
          _mesa_error(ctx, GL_INVALID_OPERATION,
@@ -2191,169 +2011,6 @@ copytexsubimage_error_check2( GLcontext *ctx, GLuint dimensions,
 }
 
 
-/**
- * Do error checking for a glGetTexImage() call.
- * \return GL_TRUE if any error, GL_FALSE if no errors.
- */
-static GLboolean
-getteximage_error_check(GLcontext *ctx, GLenum target, GLint level,
-                        GLenum format, GLenum type, GLvoid *pixels )
-{
-   const struct gl_texture_unit *texUnit;
-   struct gl_texture_object *texObj;
-   struct gl_texture_image *texImage;
-   const GLuint maxLevels = _mesa_max_texture_levels(ctx, target);
-
-   ASSERT(maxLevels > 0);  /* 0 indicates bad target, caught above */
-
-   if (level < 0 || level >= maxLevels) {
-      _mesa_error( ctx, GL_INVALID_VALUE, "glGetTexImage(level)" );
-      return GL_TRUE;
-   }
-
-   if (_mesa_sizeof_packed_type(type) <= 0) {
-      _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexImage(type)" );
-      return GL_TRUE;
-   }
-
-   if (_mesa_components_in_format(format) <= 0 ||
-       format == GL_STENCIL_INDEX) {
-      _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexImage(format)" );
-      return GL_TRUE;
-   }
-
-   if (!ctx->Extensions.EXT_paletted_texture && is_index_format(format)) {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
-      return GL_TRUE;
-   }
-
-   if (!ctx->Extensions.ARB_depth_texture && is_depth_format(format)) {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
-      return GL_TRUE;
-   }
-
-   if (!ctx->Extensions.MESA_ycbcr_texture && is_ycbcr_format(format)) {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
-      return GL_TRUE;
-   }
-
-   if (!ctx->Extensions.EXT_packed_depth_stencil
-       && is_depthstencil_format(format)) {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
-      return GL_TRUE;
-   }
-
-   if (!ctx->Extensions.ATI_envmap_bumpmap
-       && is_dudv_format(format)) {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
-      return GL_TRUE;
-   }
-
-
-   texUnit = &(ctx->Texture.Unit[ctx->Texture.CurrentUnit]);
-   texObj = _mesa_select_tex_object(ctx, texUnit, target);
-   texImage = _mesa_select_tex_image(ctx, texObj, target, level);
-   if (!texImage) {
-      /* out of memory */
-      return GL_TRUE;
-   }
-      
-   /* Make sure the requested image format is compatible with the
-    * texture's format.  Note that a color index texture can be converted
-    * to RGBA so that combo is allowed.
-    */
-   if (_mesa_is_color_format(format)
-       && !_mesa_is_color_format(texImage->TexFormat->BaseFormat)
-       && !is_index_format(texImage->TexFormat->BaseFormat)) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
-      return GL_TRUE;
-   }
-   else if (is_index_format(format)
-            && !is_index_format(texImage->TexFormat->BaseFormat)) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
-      return GL_TRUE;
-   }
-   else if (is_depth_format(format)
-            && !is_depth_format(texImage->TexFormat->BaseFormat)
-            && !is_depthstencil_format(texImage->TexFormat->BaseFormat)) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
-      return GL_TRUE;
-   }
-   else if (is_ycbcr_format(format)
-            && !is_ycbcr_format(texImage->TexFormat->BaseFormat)) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
-      return GL_TRUE;
-   }
-   else if (is_depthstencil_format(format)
-            && !is_depthstencil_format(texImage->TexFormat->BaseFormat)) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
-      return GL_TRUE;
-   }
-   else if (is_dudv_format(format)
-            && !is_dudv_format(texImage->TexFormat->BaseFormat)) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
-      return GL_TRUE;
-   }
-
-   if (ctx->Pack.BufferObj->Name) {
-      /* packing texture image into a PBO */
-      const GLuint dimensions = (target == GL_TEXTURE_3D) ? 3 : 2;
-      if (!_mesa_validate_pbo_access(dimensions, &ctx->Pack, texImage->Width,
-                                     texImage->Height, texImage->Depth,
-                                     format, type, pixels)) {
-         _mesa_error(ctx, GL_INVALID_OPERATION,
-                     "glGetTexImage(invalid PBO access)");
-         return GL_TRUE;
-      }
-   }
-
-   return GL_FALSE;
-}
-
-
-
-/**
- * Get texture image.  Called by glGetTexImage.
- *
- * \param target texture target.
- * \param level image level.
- * \param format pixel data format for returned image.
- * \param type pixel data type for returned image.
- * \param pixels returned pixel data.
- */
-void GLAPIENTRY
-_mesa_GetTexImage( GLenum target, GLint level, GLenum format,
-                   GLenum type, GLvoid *pixels )
-{
-   const struct gl_texture_unit *texUnit;
-   struct gl_texture_object *texObj;
-   GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-
-   texUnit = &(ctx->Texture.Unit[ctx->Texture.CurrentUnit]);
-   texObj = _mesa_select_tex_object(ctx, texUnit, target);
-   if (!texObj || _mesa_is_proxy_texture(target)) {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(target)");
-      return;
-   }
-
-   if (getteximage_error_check(ctx, target, level, format, type, pixels)) {
-      return;
-   }
-
-   _mesa_lock_texture(ctx, texObj);
-   {
-      struct gl_texture_image *texImage =
-         _mesa_select_tex_image(ctx, texObj, target, level);
-
-      /* typically, this will call _mesa_get_teximage() */
-      ctx->Driver.GetTexImage(ctx, target, level, format, type, pixels,
-                              texObj, texImage);
-   }
-   _mesa_unlock_texture(ctx, texObj);
-}
-
-
 /** Callback info for walking over FBO hash table */
 struct cb_info
 {
@@ -2497,7 +2154,7 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
       if (ctx->NewState & _MESA_NEW_TRANSFER_STATE)
         _mesa_update_state(ctx);
 
-      texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+      texUnit = _mesa_get_current_tex_unit(ctx);
       texObj = _mesa_select_tex_object(ctx, texUnit, target);
       _mesa_lock_texture(ctx, texObj);
       {
@@ -2605,7 +2262,7 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
       if (ctx->NewState & _MESA_NEW_TRANSFER_STATE)
         _mesa_update_state(ctx);
 
-      texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+      texUnit = _mesa_get_current_tex_unit(ctx);
       texObj = _mesa_select_tex_object(ctx, texUnit, target);
       _mesa_lock_texture(ctx, texObj);
       {
@@ -2708,7 +2365,7 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
       if (ctx->NewState & _MESA_NEW_TRANSFER_STATE)
         _mesa_update_state(ctx);
 
-      texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+      texUnit = _mesa_get_current_tex_unit(ctx);
       texObj = _mesa_select_tex_object(ctx, texUnit, target);
       _mesa_lock_texture(ctx, texObj);
       {
@@ -2814,7 +2471,7 @@ _mesa_TexSubImage1D( GLenum target, GLint level,
    }
 
 
-   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+   texUnit = _mesa_get_current_tex_unit(ctx);
    texObj = _mesa_select_tex_object(ctx, texUnit, target);
    assert(texObj);
 
@@ -2874,7 +2531,7 @@ _mesa_TexSubImage2D( GLenum target, GLint level,
       return;   /* error was detected */
    }
 
-   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+   texUnit = _mesa_get_current_tex_unit(ctx);
    texObj = _mesa_select_tex_object(ctx, texUnit, target);
    _mesa_lock_texture(ctx, texObj);
    {
@@ -2926,7 +2583,7 @@ _mesa_TexSubImage3D( GLenum target, GLint level,
       return;   /* error was detected */
    }
 
-   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+   texUnit = _mesa_get_current_tex_unit(ctx);
    texObj = _mesa_select_tex_object(ctx, texUnit, target);
 
    _mesa_lock_texture(ctx, texObj);
@@ -2987,7 +2644,7 @@ _mesa_CopyTexImage1D( GLenum target, GLint level,
                                postConvWidth, 1, border))
       return;
 
-   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+   texUnit = _mesa_get_current_tex_unit(ctx);
    texObj = _mesa_select_tex_object(ctx, texUnit, target);
    _mesa_lock_texture(ctx, texObj);
    {
@@ -3053,7 +2710,7 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
                                postConvWidth, postConvHeight, border))
       return;
 
-   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+   texUnit = _mesa_get_current_tex_unit(ctx);
    texObj = _mesa_select_tex_object(ctx, texUnit, target);
 
    _mesa_lock_texture(ctx, texObj);
@@ -3113,7 +2770,7 @@ _mesa_CopyTexSubImage1D( GLenum target, GLint level,
    if (copytexsubimage_error_check1(ctx, 1, target, level))
       return;
 
-   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+   texUnit = _mesa_get_current_tex_unit(ctx);
    texObj = _mesa_select_tex_object(ctx, texUnit, target);
 
    _mesa_lock_texture(ctx, texObj);
@@ -3168,7 +2825,7 @@ _mesa_CopyTexSubImage2D( GLenum target, GLint level,
    if (copytexsubimage_error_check1(ctx, 2, target, level))
       return;
 
-   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+   texUnit = _mesa_get_current_tex_unit(ctx);
    texObj = _mesa_select_tex_object(ctx, texUnit, target);
 
    _mesa_lock_texture(ctx, texObj);
@@ -3223,7 +2880,7 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level,
    if (copytexsubimage_error_check1(ctx, 3, target, level))
       return;
 
-   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+   texUnit = _mesa_get_current_tex_unit(ctx);
    texObj = _mesa_select_tex_object(ctx, texUnit, target);
 
    _mesa_lock_texture(ctx, texObj);
@@ -3477,7 +3134,7 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level,
          return;
       }
 
-      texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+      texUnit = _mesa_get_current_tex_unit(ctx);
       texObj = _mesa_select_tex_object(ctx, texUnit, target);
 
       _mesa_lock_texture(ctx, texObj);
@@ -3531,7 +3188,7 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level,
          struct gl_texture_unit *texUnit;
          struct gl_texture_object *texObj;
          struct gl_texture_image *texImage;
-         texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+         texUnit = _mesa_get_current_tex_unit(ctx);
         texObj = _mesa_select_tex_object(ctx, texUnit, target);
 
         _mesa_lock_texture(ctx, texObj);
@@ -3574,7 +3231,7 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level,
          return;
       }
 
-      texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+      texUnit = _mesa_get_current_tex_unit(ctx);
       texObj = _mesa_select_tex_object(ctx, texUnit, target);
 
       _mesa_lock_texture(ctx, texObj);
@@ -3630,7 +3287,7 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level,
          struct gl_texture_unit *texUnit;
          struct gl_texture_object *texObj;
          struct gl_texture_image *texImage;
-         texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+         texUnit = _mesa_get_current_tex_unit(ctx);
         texObj = _mesa_select_tex_object(ctx, texUnit, target);
 
         _mesa_lock_texture(ctx, texObj);
@@ -3670,7 +3327,7 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level,
          return;
       }
 
-      texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+      texUnit = _mesa_get_current_tex_unit(ctx);
       texObj = _mesa_select_tex_object(ctx, texUnit, target);
       _mesa_lock_texture(ctx, texObj);
       {
@@ -3724,7 +3381,7 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level,
          struct gl_texture_unit *texUnit;
          struct gl_texture_object *texObj;
          struct gl_texture_image *texImage;
-         texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+         texUnit = _mesa_get_current_tex_unit(ctx);
         texObj = _mesa_select_tex_object(ctx, texUnit, target);
         _mesa_lock_texture(ctx, texObj);
         {
@@ -3763,7 +3420,7 @@ _mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset,
       return;
    }
 
-   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+   texUnit = _mesa_get_current_tex_unit(ctx);
    texObj = _mesa_select_tex_object(ctx, texUnit, target);
    _mesa_lock_texture(ctx, texObj);
    {
@@ -3820,7 +3477,7 @@ _mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset,
       return;
    }
 
-   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+   texUnit = _mesa_get_current_tex_unit(ctx);
    texObj = _mesa_select_tex_object(ctx, texUnit, target);
    _mesa_lock_texture(ctx, texObj);
    {
@@ -3877,7 +3534,7 @@ _mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset,
       return;
    }
 
-   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+   texUnit = _mesa_get_current_tex_unit(ctx);
    texObj = _mesa_select_tex_object(ctx, texUnit, target);
    _mesa_lock_texture(ctx, texObj);
    {
@@ -3914,55 +3571,3 @@ _mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset,
 }
 
 
-void GLAPIENTRY
-_mesa_GetCompressedTexImageARB(GLenum target, GLint level, GLvoid *img)
-{
-   const struct gl_texture_unit *texUnit;
-   struct gl_texture_object *texObj;
-   struct gl_texture_image *texImage;
-   GLint maxLevels;
-   GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-
-   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
-   texObj = _mesa_select_tex_object(ctx, texUnit, target);
-   if (!texObj) {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImageARB");
-      return;
-   }
-
-   maxLevels = _mesa_max_texture_levels(ctx, target);
-   ASSERT(maxLevels > 0); /* 0 indicates bad target, caught above */
-
-   if (level < 0 || level >= maxLevels) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glGetCompressedTexImageARB(level)");
-      return;
-   }
-
-   if (_mesa_is_proxy_texture(target)) {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImageARB(target)");
-      return;
-   }
-
-   _mesa_lock_texture(ctx, texObj);
-   {
-      texImage = _mesa_select_tex_image(ctx, texObj, target, level);
-      if (texImage) {
-         if (texImage->IsCompressed) {
-            /* this typically calls _mesa_get_compressed_teximage() */
-            ctx->Driver.GetCompressedTexImage(ctx, target, level, img,
-                                              texObj, texImage);
-         }
-         else {
-            _mesa_error(ctx, GL_INVALID_OPERATION,
-                        "glGetCompressedTexImageARB");
-         }
-      }
-      else {
-         /* probably invalid mipmap level */
-         _mesa_error(ctx, GL_INVALID_VALUE,
-                     "glGetCompressedTexImageARB(level)");
-      }
-   }
-   _mesa_unlock_texture(ctx, texObj);
-}