Merge commit 'origin/master' into gallium-0.2
[mesa.git] / src / mesa / main / teximage.c
index 5c96be921657b4c587e53668faf59e5f318b3184..a5e0db736ed7c82729225dde4de223244731d1a4 100644 (file)
@@ -1,8 +1,8 @@
 /*
- * Mesa 3-D graphics library
+ * mesa 3-D graphics library
  * Version:  7.1
  *
- * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2008  Brian Paul   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"),
@@ -32,7 +32,9 @@
 #include "glheader.h"
 #include "bufferobj.h"
 #include "context.h"
+#if FEATURE_convolve
 #include "convolve.h"
+#endif
 #include "fbobject.h"
 #include "framebuffer.h"
 #include "image.h"
@@ -239,13 +241,12 @@ _mesa_base_tex_format( GLcontext *ctx, GLint internalFormat )
       }
    }
 
-   if (ctx->Extensions.SGIX_depth_texture ||
-       ctx->Extensions.ARB_depth_texture) {
+   if (ctx->Extensions.ARB_depth_texture) {
       switch (internalFormat) {
          case GL_DEPTH_COMPONENT:
-         case GL_DEPTH_COMPONENT16_SGIX:
-         case GL_DEPTH_COMPONENT24_SGIX:
-         case GL_DEPTH_COMPONENT32_SGIX:
+         case GL_DEPTH_COMPONENT16:
+         case GL_DEPTH_COMPONENT24:
+         case GL_DEPTH_COMPONENT32:
             return GL_DEPTH_COMPONENT;
          default:
             ; /* fallthrough */
@@ -387,9 +388,10 @@ _mesa_base_tex_format( GLcontext *ctx, GLint internalFormat )
  * 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
  */
-static GLboolean
-is_color_format(GLenum format)
+GLboolean
+_mesa_is_color_format(GLenum format)
 {
    switch (format) {
       case GL_RED:
@@ -490,6 +492,7 @@ is_color_format(GLenum format)
 #endif /* FEATURE_EXT_texture_sRGB */
          return GL_TRUE;
       case GL_YCBCR_MESA:  /* not considered to be RGB */
+         /* fall-through */
       default:
          return GL_FALSE;
    }
@@ -524,9 +527,9 @@ static GLboolean
 is_depth_format(GLenum format)
 {
    switch (format) {
-      case GL_DEPTH_COMPONENT16_ARB:
-      case GL_DEPTH_COMPONENT24_ARB:
-      case GL_DEPTH_COMPONENT32_ARB:
+      case GL_DEPTH_COMPONENT16:
+      case GL_DEPTH_COMPONENT24:
+      case GL_DEPTH_COMPONENT32:
       case GL_DEPTH_COMPONENT:
          return GL_TRUE;
       default:
@@ -765,15 +768,15 @@ _mesa_select_tex_object(GLcontext *ctx, const struct gl_texture_unit *texUnit,
       case GL_TEXTURE_1D:
          return texUnit->Current1D;
       case GL_PROXY_TEXTURE_1D:
-         return ctx->Texture.Proxy1D;
+         return ctx->Texture.ProxyTex[TEXTURE_1D_INDEX];
       case GL_TEXTURE_2D:
          return texUnit->Current2D;
       case GL_PROXY_TEXTURE_2D:
-         return ctx->Texture.Proxy2D;
+         return ctx->Texture.ProxyTex[TEXTURE_2D_INDEX];
       case GL_TEXTURE_3D:
          return texUnit->Current3D;
       case GL_PROXY_TEXTURE_3D:
-         return ctx->Texture.Proxy3D;
+         return ctx->Texture.ProxyTex[TEXTURE_3D_INDEX];
       case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
       case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
       case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
@@ -785,25 +788,25 @@ _mesa_select_tex_object(GLcontext *ctx, const struct gl_texture_unit *texUnit,
                 ? texUnit->CurrentCubeMap : NULL;
       case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
          return ctx->Extensions.ARB_texture_cube_map
-                ? ctx->Texture.ProxyCubeMap : NULL;
+                ? ctx->Texture.ProxyTex[TEXTURE_CUBE_INDEX] : NULL;
       case GL_TEXTURE_RECTANGLE_NV:
          return ctx->Extensions.NV_texture_rectangle
                 ? texUnit->CurrentRect : NULL;
       case GL_PROXY_TEXTURE_RECTANGLE_NV:
          return ctx->Extensions.NV_texture_rectangle
-                ? ctx->Texture.ProxyRect : NULL;
+                ? ctx->Texture.ProxyTex[TEXTURE_RECT_INDEX] : NULL;
       case GL_TEXTURE_1D_ARRAY_EXT:
          return ctx->Extensions.MESA_texture_array
                 ? texUnit->Current1DArray : NULL;
       case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
          return ctx->Extensions.MESA_texture_array
-                ? ctx->Texture.Proxy1DArray : NULL;
+                ? ctx->Texture.ProxyTex[TEXTURE_1D_ARRAY_INDEX] : NULL;
       case GL_TEXTURE_2D_ARRAY_EXT:
          return ctx->Extensions.MESA_texture_array
                 ? texUnit->Current2DArray : NULL;
       case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
          return ctx->Extensions.MESA_texture_array
-                ? ctx->Texture.Proxy2DArray : NULL;
+                ? ctx->Texture.ProxyTex[TEXTURE_2D_ARRAY_INDEX] : NULL;
       default:
          _mesa_problem(NULL, "bad target in _mesa_select_tex_object()");
          return NULL;
@@ -930,106 +933,106 @@ _mesa_get_proxy_tex_image(GLcontext *ctx, GLenum target, GLint level)
    case GL_PROXY_TEXTURE_1D:
       if (level >= ctx->Const.MaxTextureLevels)
          return NULL;
-      texImage = ctx->Texture.Proxy1D->Image[0][level];
+      texImage = ctx->Texture.ProxyTex[TEXTURE_1D_INDEX]->Image[0][level];
       if (!texImage) {
          texImage = ctx->Driver.NewTextureImage(ctx);
          if (!texImage) {
             _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
             return NULL;
          }
-         ctx->Texture.Proxy1D->Image[0][level] = texImage;
+         ctx->Texture.ProxyTex[TEXTURE_1D_INDEX]->Image[0][level] = texImage;
          /* Set the 'back' pointer */
-         texImage->TexObject = ctx->Texture.Proxy1D;
+         texImage->TexObject = ctx->Texture.ProxyTex[TEXTURE_1D_INDEX];
       }
       return texImage;
    case GL_PROXY_TEXTURE_2D:
       if (level >= ctx->Const.MaxTextureLevels)
          return NULL;
-      texImage = ctx->Texture.Proxy2D->Image[0][level];
+      texImage = ctx->Texture.ProxyTex[TEXTURE_2D_INDEX]->Image[0][level];
       if (!texImage) {
          texImage = ctx->Driver.NewTextureImage(ctx);
          if (!texImage) {
             _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
             return NULL;
          }
-         ctx->Texture.Proxy2D->Image[0][level] = texImage;
+         ctx->Texture.ProxyTex[TEXTURE_2D_INDEX]->Image[0][level] = texImage;
          /* Set the 'back' pointer */
-         texImage->TexObject = ctx->Texture.Proxy2D;
+         texImage->TexObject = ctx->Texture.ProxyTex[TEXTURE_2D_INDEX];
       }
       return texImage;
    case GL_PROXY_TEXTURE_3D:
       if (level >= ctx->Const.Max3DTextureLevels)
          return NULL;
-      texImage = ctx->Texture.Proxy3D->Image[0][level];
+      texImage = ctx->Texture.ProxyTex[TEXTURE_3D_INDEX]->Image[0][level];
       if (!texImage) {
          texImage = ctx->Driver.NewTextureImage(ctx);
          if (!texImage) {
             _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
             return NULL;
          }
-         ctx->Texture.Proxy3D->Image[0][level] = texImage;
+         ctx->Texture.ProxyTex[TEXTURE_3D_INDEX]->Image[0][level] = texImage;
          /* Set the 'back' pointer */
-         texImage->TexObject = ctx->Texture.Proxy3D;
+         texImage->TexObject = ctx->Texture.ProxyTex[TEXTURE_3D_INDEX];
       }
       return texImage;
    case GL_PROXY_TEXTURE_CUBE_MAP:
       if (level >= ctx->Const.MaxCubeTextureLevels)
          return NULL;
-      texImage = ctx->Texture.ProxyCubeMap->Image[0][level];
+      texImage = ctx->Texture.ProxyTex[TEXTURE_CUBE_INDEX]->Image[0][level];
       if (!texImage) {
          texImage = ctx->Driver.NewTextureImage(ctx);
          if (!texImage) {
             _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
             return NULL;
          }
-         ctx->Texture.ProxyCubeMap->Image[0][level] = texImage;
+         ctx->Texture.ProxyTex[TEXTURE_CUBE_INDEX]->Image[0][level] = texImage;
          /* Set the 'back' pointer */
-         texImage->TexObject = ctx->Texture.ProxyCubeMap;
+         texImage->TexObject = ctx->Texture.ProxyTex[TEXTURE_CUBE_INDEX];
       }
       return texImage;
    case GL_PROXY_TEXTURE_RECTANGLE_NV:
       if (level > 0)
          return NULL;
-      texImage = ctx->Texture.ProxyRect->Image[0][level];
+      texImage = ctx->Texture.ProxyTex[TEXTURE_RECT_INDEX]->Image[0][level];
       if (!texImage) {
          texImage = ctx->Driver.NewTextureImage(ctx);
          if (!texImage) {
             _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
             return NULL;
          }
-         ctx->Texture.ProxyRect->Image[0][level] = texImage;
+         ctx->Texture.ProxyTex[TEXTURE_RECT_INDEX]->Image[0][level] = texImage;
          /* Set the 'back' pointer */
-         texImage->TexObject = ctx->Texture.ProxyRect;
+         texImage->TexObject = ctx->Texture.ProxyTex[TEXTURE_RECT_INDEX];
       }
       return texImage;
    case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
       if (level >= ctx->Const.MaxTextureLevels)
          return NULL;
-      texImage = ctx->Texture.Proxy1DArray->Image[0][level];
+      texImage = ctx->Texture.ProxyTex[TEXTURE_1D_ARRAY_INDEX]->Image[0][level];
       if (!texImage) {
          texImage = ctx->Driver.NewTextureImage(ctx);
          if (!texImage) {
             _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
             return NULL;
          }
-         ctx->Texture.Proxy1DArray->Image[0][level] = texImage;
+         ctx->Texture.ProxyTex[TEXTURE_1D_ARRAY_INDEX]->Image[0][level] = texImage;
          /* Set the 'back' pointer */
-         texImage->TexObject = ctx->Texture.Proxy1DArray;
+         texImage->TexObject = ctx->Texture.ProxyTex[TEXTURE_1D_ARRAY_INDEX];
       }
       return texImage;
    case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
       if (level >= ctx->Const.MaxTextureLevels)
          return NULL;
-      texImage = ctx->Texture.Proxy2DArray->Image[0][level];
+      texImage = ctx->Texture.ProxyTex[TEXTURE_2D_ARRAY_INDEX]->Image[0][level];
       if (!texImage) {
          texImage = ctx->Driver.NewTextureImage(ctx);
          if (!texImage) {
             _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
             return NULL;
          }
-         ctx->Texture.Proxy2DArray->Image[0][level] = texImage;
+         ctx->Texture.ProxyTex[TEXTURE_2D_ARRAY_INDEX]->Image[0][level] = texImage;
          /* Set the 'back' pointer */
-         texImage->TexObject = ctx->Texture.Proxy2DArray;
+         texImage->TexObject = ctx->Texture.ProxyTex[TEXTURE_2D_ARRAY_INDEX];
       }
       return texImage;
    default:
@@ -1214,25 +1217,36 @@ _mesa_init_teximage_fields(GLcontext *ctx, GLenum target,
    img->Width = width;
    img->Height = height;
    img->Depth = depth;
+
    img->Width2 = width - 2 * border;   /* == 1 << img->WidthLog2; */
-   img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */
-   img->Depth2 = depth - 2 * border;   /* == 1 << img->DepthLog2; */
    img->WidthLog2 = logbase2(img->Width2);
-   if (height == 1)  /* 1-D texture */
+
+   if (height == 1) { /* 1-D texture */
+      img->Height2 = 1;
       img->HeightLog2 = 0;
-   else
+   }
+   else {
+      img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */
       img->HeightLog2 = logbase2(img->Height2);
-   if (depth == 1)   /* 2-D texture */
+   }
+
+   if (depth == 1) {  /* 2-D texture */
+      img->Depth2 = 1;
       img->DepthLog2 = 0;
-   else
+   }
+   else {
+      img->Depth2 = depth - 2 * border;   /* == 1 << img->DepthLog2; */
       img->DepthLog2 = logbase2(img->Depth2);
+   }
+
    img->MaxLog2 = MAX2(img->WidthLog2, img->HeightLog2);
+
    img->IsCompressed = GL_FALSE;
    img->CompressedSize = 0;
 
-   if ((width == 1 || _mesa_bitcount(img->Width2) == 1) &&
-       (height == 1 || _mesa_bitcount(img->Height2) == 1) &&
-       (depth == 1 || _mesa_bitcount(img->Depth2) == 1))
+   if ((width == 1 || _mesa_is_pow_two(img->Width2)) &&
+       (height == 1 || _mesa_is_pow_two(img->Height2)) &&
+       (depth == 1 || _mesa_is_pow_two(img->Depth2)))
       img->_IsPowerOfTwo = GL_TRUE;
    else
       img->_IsPowerOfTwo = GL_FALSE;
@@ -1303,7 +1317,7 @@ _mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level,
       maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
       if (width < 2 * border || width > 2 + maxSize ||
           (!ctx->Extensions.ARB_texture_non_power_of_two &&
-           width >0 && _mesa_bitcount(width - 2 * border) != 1) ||
+           width >0 && !_mesa_is_pow_two(width - 2 * border)) ||
           level >= ctx->Const.MaxTextureLevels) {
          /* bad width or level */
          return GL_FALSE;
@@ -1313,10 +1327,10 @@ _mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level,
       maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
       if (width < 2 * border || width > 2 + maxSize ||
           (!ctx->Extensions.ARB_texture_non_power_of_two &&
-           width > 0 && _mesa_bitcount(width - 2 * border) != 1) ||
+           width > 0 && !_mesa_is_pow_two(width - 2 * border)) ||
           height < 2 * border || height > 2 + maxSize ||
           (!ctx->Extensions.ARB_texture_non_power_of_two &&
-           height > 0 && _mesa_bitcount(height - 2 * border) != 1) ||
+           height > 0 && !_mesa_is_pow_two(height - 2 * border)) ||
           level >= ctx->Const.MaxTextureLevels) {
          /* bad width or height or level */
          return GL_FALSE;
@@ -1326,13 +1340,13 @@ _mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level,
       maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1);
       if (width < 2 * border || width > 2 + maxSize ||
           (!ctx->Extensions.ARB_texture_non_power_of_two &&
-           width > 0 && _mesa_bitcount(width - 2 * border) != 1) ||
+           width > 0 && !_mesa_is_pow_two(width - 2 * border)) ||
           height < 2 * border || height > 2 + maxSize ||
           (!ctx->Extensions.ARB_texture_non_power_of_two &&
-           height > 0 && _mesa_bitcount(height - 2 * border) != 1) ||
+           height > 0 && !_mesa_is_pow_two(height - 2 * border)) ||
           depth < 2 * border || depth > 2 + maxSize ||
           (!ctx->Extensions.ARB_texture_non_power_of_two &&
-           depth > 0 && _mesa_bitcount(depth - 2 * border) != 1) ||
+           depth > 0 && !_mesa_is_pow_two(depth - 2 * border)) ||
           level >= ctx->Const.Max3DTextureLevels) {
          /* bad width or height or depth or level */
          return GL_FALSE;
@@ -1350,10 +1364,10 @@ _mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level,
       maxSize = 1 << (ctx->Const.MaxCubeTextureLevels - 1);
       if (width < 2 * border || width > 2 + maxSize ||
           (!ctx->Extensions.ARB_texture_non_power_of_two &&
-           width > 0 && _mesa_bitcount(width - 2 * border) != 1) ||
+           width > 0 && !_mesa_is_pow_two(width - 2 * border)) ||
           height < 2 * border || height > 2 + maxSize ||
           (!ctx->Extensions.ARB_texture_non_power_of_two &&
-           height > 0 && _mesa_bitcount(height - 2 * border) != 1) ||
+           height > 0 && !_mesa_is_pow_two(height - 2 * border)) ||
           level >= ctx->Const.MaxCubeTextureLevels) {
          /* bad width or height */
          return GL_FALSE;
@@ -1363,7 +1377,7 @@ _mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level,
       maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
       if (width < 2 * border || width > 2 + maxSize ||
           (!ctx->Extensions.ARB_texture_non_power_of_two &&
-           width > 0 && _mesa_bitcount(width - 2 * border) != 1) ||
+           width > 0 && !_mesa_is_pow_two(width - 2 * border)) ||
           level >= ctx->Const.MaxTextureLevels) {
          /* bad width or level */
          return GL_FALSE;
@@ -1377,10 +1391,10 @@ _mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level,
       maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
       if (width < 2 * border || width > 2 + maxSize ||
           (!ctx->Extensions.ARB_texture_non_power_of_two &&
-           width > 0 && _mesa_bitcount(width - 2 * border) != 1) ||
+           width > 0 && !_mesa_is_pow_two(width - 2 * border)) ||
           height < 2 * border || height > 2 + maxSize ||
           (!ctx->Extensions.ARB_texture_non_power_of_two &&
-           height > 0 && _mesa_bitcount(height - 2 * border) != 1) ||
+           height > 0 && !_mesa_is_pow_two(height - 2 * border)) ||
           level >= ctx->Const.MaxTextureLevels) {
          /* bad width or height or level */
          return GL_FALSE;
@@ -1575,9 +1589,9 @@ texture_error_check( GLcontext *ctx, GLenum target,
    }
 
    /* make sure internal format and format basically agree */
-   colorFormat = is_color_format(format);
+   colorFormat = _mesa_is_color_format(format);
    indexFormat = is_index_format(format);
-   if ((is_color_format(internalFormat) && !colorFormat && !indexFormat) ||
+   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)) ||
@@ -2004,7 +2018,7 @@ copytexture_error_check( GLcontext *ctx, GLuint dimensions,
    }
 
    if (is_compressed_format(ctx, internalFormat)) {
-      if (target != GL_TEXTURE_2D) {
+      if (!target_can_be_compressed(ctx, target)) {
          _mesa_error(ctx, GL_INVALID_ENUM,
                      "glCopyTexImage%d(target)", dimensions);
          return GL_TRUE;
@@ -2039,30 +2053,20 @@ copytexture_error_check( GLcontext *ctx, GLuint dimensions,
 
 /**
  * Test glCopyTexSubImage[12]D() parameters for errors.
+ * Note that this is the first part of error checking.
+ * See also copytexsubimage_error_check2() below for the second part.
  * 
  * \param ctx GL context.
  * \param dimensions texture image dimensions (must be 1, 2 or 3).
  * \param target texture target given by the user.
  * \param level image level given by the user.
- * \param xoffset sub-image x offset given by the user.
- * \param yoffset sub-image y offset given by the user.
- * \param zoffset sub-image z offset given by the user.
- * \param width image width given by the user.
- * \param height image height given by the user.
  * 
  * \return GL_TRUE if an error was detected, or GL_FALSE if no errors.
- * 
- * Verifies each of the parameters against the constants specified in
- * __GLcontextRec::Const and the supported extensions, and according to the
- * OpenGL specification.
  */
 static GLboolean
-copytexsubimage_error_check( GLcontext *ctx, GLuint dimensions,
-                             GLenum target, GLint level,
-                             GLint xoffset, GLint yoffset, GLint zoffset,
-                             GLsizei width, GLsizei height)
+copytexsubimage_error_check1( GLcontext *ctx, GLuint dimensions,
+                              GLenum target, GLint level)
 {
-   /* Check target */
    /* Check that the source buffer is complete */
    if (ctx->ReadBuffer->Name) {
       _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer);
@@ -2073,6 +2077,7 @@ copytexsubimage_error_check( GLcontext *ctx, GLuint dimensions,
       }
    }
 
+   /* Check target */
    if (dimensions == 1) {
       if (target != GL_TEXTURE_1D) {
          _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage1D(target)" );
@@ -2120,21 +2125,18 @@ copytexsubimage_error_check( GLcontext *ctx, GLuint dimensions,
       return GL_TRUE;
    }
 
-   /* Check size */
-   if (width < 0) {
-      _mesa_error(ctx, GL_INVALID_VALUE,
-                  "glCopyTexSubImage%dD(width=%d)", dimensions, width);
-      return GL_TRUE;
-   }
-   if (dimensions > 1 && height < 0) {
-      _mesa_error(ctx, GL_INVALID_VALUE,
-                  "glCopyTexSubImage%dD(height=%d)", dimensions, height);
-      return GL_TRUE;
-   }
-
    return GL_FALSE;
 }
 
+
+/**
+ * Second part of error checking for glCopyTexSubImage[12]D().
+ * \param xoffset sub-image x offset given by the user.
+ * \param yoffset sub-image y offset given by the user.
+ * \param zoffset sub-image z offset given by the user.
+ * \param width image width given by the user.
+ * \param height image height given by the user.
+ */
 static GLboolean
 copytexsubimage_error_check2( GLcontext *ctx, GLuint dimensions,
                              GLenum target, GLint level,
@@ -2142,6 +2144,7 @@ copytexsubimage_error_check2( GLcontext *ctx, GLuint dimensions,
                              GLsizei width, GLsizei height,
                              const struct gl_texture_image *teximage )
 {
+   /* check that dest tex image exists */
    if (!teximage) {
       _mesa_error(ctx, GL_INVALID_OPERATION,
                   "glCopyTexSubImage%dD(undefined texture level: %d)",
@@ -2149,6 +2152,19 @@ copytexsubimage_error_check2( GLcontext *ctx, GLuint dimensions,
       return GL_TRUE;
    }
 
+   /* Check size */
+   if (width < 0) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "glCopyTexSubImage%dD(width=%d)", dimensions, width);
+      return GL_TRUE;
+   }
+   if (dimensions > 1 && height < 0) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "glCopyTexSubImage%dD(height=%d)", dimensions, height);
+      return GL_TRUE;
+   }
+
+   /* check x/y offsets */
    if (xoffset < -((GLint)teximage->Border)) {
       _mesa_error(ctx, GL_INVALID_VALUE,
                   "glCopyTexSubImage%dD(xoffset=%d)", dimensions, xoffset);
@@ -2173,6 +2189,7 @@ copytexsubimage_error_check2( GLcontext *ctx, GLuint dimensions,
       }
    }
 
+   /* check z offset */
    if (dimensions > 2) {
       if (zoffset < -((GLint)teximage->Border)) {
          _mesa_error(ctx, GL_INVALID_VALUE,
@@ -2187,7 +2204,7 @@ copytexsubimage_error_check2( GLcontext *ctx, GLuint dimensions,
    }
 
    if (teximage->IsCompressed) {
-      if (target != GL_TEXTURE_2D) {
+      if (!target_can_be_compressed(ctx, target)) {
          _mesa_error(ctx, GL_INVALID_ENUM,
                      "glCopyTexSubImage%d(target)", dimensions);
          return GL_TRUE;
@@ -2295,8 +2312,7 @@ _mesa_GetTexImage( GLenum target, GLint level, GLenum format,
       return;
    }
 
-   if (!ctx->Extensions.SGIX_depth_texture &&
-       !ctx->Extensions.ARB_depth_texture && is_depth_format(format)) {
+   if (!ctx->Extensions.ARB_depth_texture && is_depth_format(format)) {
       _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
       return;
    }
@@ -2312,9 +2328,6 @@ _mesa_GetTexImage( GLenum target, GLint level, GLenum format,
       return;
    }
 
-   if (!pixels)
-      return;
-
    _mesa_lock_texture(ctx, texObj);
    {
       texImage = _mesa_select_tex_image(ctx, texObj, target, level);
@@ -2328,8 +2341,8 @@ _mesa_GetTexImage( GLenum target, GLint level, GLenum format,
        * texture's format.  Note that a color index texture can be converted
        * to RGBA so that combo is allowed.
        */
-      if (is_color_format(format)
-         && !is_color_format(texImage->TexFormat->BaseFormat)
+      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)");
         goto out;
@@ -2421,9 +2434,11 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
-   if (is_color_format(internalFormat)) {
+#if FEATURE_convolve
+   if (_mesa_is_color_format(internalFormat)) {
       _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL);
    }
+#endif
 
    if (target == GL_TEXTURE_1D) {
       /* non-proxy target */
@@ -2516,10 +2531,12 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
-   if (is_color_format(internalFormat)) {
+#if FEATURE_convolve
+   if (_mesa_is_color_format(internalFormat)) {
       _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth,
                                         &postConvHeight);
    }
+#endif
 
    if (target == GL_TEXTURE_2D ||
        (ctx->Extensions.ARB_texture_cube_map &&
@@ -2597,7 +2614,7 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
                               1, border)) {
          /* when error, clear all proxy texture image parameters */
          if (texImage)
-            clear_teximage_fields(ctx->Texture.Proxy2D->Image[0][level]);
+            clear_teximage_fields(ctx->Texture.ProxyTex[TEXTURE_2D_INDEX]->Image[0][level]);
       }
       else {
          /* no error, set the tex image parameters */
@@ -2697,8 +2714,8 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
       }
       else {
          /* no error, set the tex image parameters */
-         _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1,
-                                    border, internalFormat);
+         _mesa_init_teximage_fields(ctx, target, texImage, width, height,
+                                    depth, border, internalFormat);
          texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
                                           internalFormat, format, type);
       }
@@ -2738,10 +2755,12 @@ _mesa_TexSubImage1D( GLenum target, GLint level,
    if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
       _mesa_update_state(ctx);
 
+#if FEATURE_convolve
    /* XXX should test internal format */
-   if (is_color_format(format)) {
+   if (_mesa_is_color_format(format)) {
       _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL);
    }
+#endif
 
    if (subtexture_error_check(ctx, 1, target, level, xoffset, 0, 0,
                               postConvWidth, 1, 1, format, type)) {
@@ -2796,11 +2815,13 @@ _mesa_TexSubImage2D( GLenum target, GLint level,
    if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
       _mesa_update_state(ctx);
 
+#if FEATURE_convolve
    /* XXX should test internal format */
-   if (is_color_format(format)) {
+   if (_mesa_is_color_format(format)) {
       _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth,
                                          &postConvHeight);
    }
+#endif
 
    if (subtexture_error_check(ctx, 2, target, level, xoffset, yoffset, 0,
                              postConvWidth, postConvHeight, 1, format, type)) {
@@ -2910,9 +2931,11 @@ _mesa_CopyTexImage1D( GLenum target, GLint level,
    if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
       _mesa_update_state(ctx);
 
-   if (is_color_format(internalFormat)) {
+#if FEATURE_convolve
+   if (_mesa_is_color_format(internalFormat)) {
       _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL);
    }
+#endif
 
    if (copytexture_error_check(ctx, 1, target, level, internalFormat,
                                postConvWidth, 1, border))
@@ -2973,10 +2996,12 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
    if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
       _mesa_update_state(ctx);
 
-   if (is_color_format(internalFormat)) {
+#if FEATURE_convolve
+   if (_mesa_is_color_format(internalFormat)) {
       _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth,
                                          &postConvHeight);
    }
+#endif
 
    if (copytexture_error_check(ctx, 2, target, level, internalFormat,
                                postConvWidth, postConvHeight, border))
@@ -3039,11 +3064,7 @@ _mesa_CopyTexSubImage1D( GLenum target, GLint level,
    if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
       _mesa_update_state(ctx);
 
-   /* XXX should test internal format */
-   _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL);
-
-   if (copytexsubimage_error_check(ctx, 1, target, level,
-                                   xoffset, 0, 0, postConvWidth, 1))
+   if (copytexsubimage_error_check1(ctx, 1, target, level))
       return;
 
    texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
@@ -3053,6 +3074,12 @@ _mesa_CopyTexSubImage1D( GLenum target, GLint level,
    {
       texImage = _mesa_select_tex_image(ctx, texObj, target, level);
 
+#if FEATURE_convolve
+      if (texImage && _mesa_is_color_format(texImage->InternalFormat)) {
+         _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL);
+      }
+#endif
+
       if (copytexsubimage_error_check2(ctx, 1, target, level,
                                       xoffset, 0, 0, postConvWidth, 1,
                                       texImage))
@@ -3092,11 +3119,7 @@ _mesa_CopyTexSubImage2D( GLenum target, GLint level,
    if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
       _mesa_update_state(ctx);
 
-   /* XXX should test internal format */
-   _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth, &postConvHeight);
-
-   if (copytexsubimage_error_check(ctx, 2, target, level, xoffset, yoffset, 0,
-                                   postConvWidth, postConvHeight))
+   if (copytexsubimage_error_check1(ctx, 2, target, level))
       return;
 
    texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
@@ -3106,6 +3129,13 @@ _mesa_CopyTexSubImage2D( GLenum target, GLint level,
    {
       texImage = _mesa_select_tex_image(ctx, texObj, target, level);
 
+#if FEATURE_convolve
+      if (texImage && _mesa_is_color_format(texImage->InternalFormat)) {
+         _mesa_adjust_image_for_convolution(ctx, 2,
+                                            &postConvWidth, &postConvHeight);
+      }
+#endif
+
       if (copytexsubimage_error_check2(ctx, 2, target, level, xoffset, yoffset, 0,
                                       postConvWidth, postConvHeight, texImage))
         goto out;
@@ -3144,11 +3174,7 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level,
    if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
       _mesa_update_state(ctx);
 
-   /* XXX should test internal format */
-   _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth, &postConvHeight);
-
-   if (copytexsubimage_error_check(ctx, 3, target, level, xoffset, yoffset,
-                                   zoffset, postConvWidth, postConvHeight))
+   if (copytexsubimage_error_check1(ctx, 3, target, level))
       return;
 
    texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
@@ -3158,6 +3184,13 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level,
    {
       texImage = _mesa_select_tex_image(ctx, texObj, target, level);
 
+#if FEATURE_convolve
+      if (texImage && _mesa_is_color_format(texImage->InternalFormat)) {
+         _mesa_adjust_image_for_convolution(ctx, 2,
+                                            &postConvWidth, &postConvHeight);
+      }
+#endif
+
       if (copytexsubimage_error_check2(ctx, 3, target, level, xoffset, yoffset,
                                       zoffset, postConvWidth, postConvHeight,
                                       texImage))
@@ -3251,16 +3284,16 @@ compressed_texture_error_check(GLcontext *ctx, GLint dimensions,
     * XXX We should probably use the proxy texture error check function here.
     */
    if (width < 1 || width > maxTextureSize ||
-       (!ctx->Extensions.ARB_texture_non_power_of_two && _mesa_bitcount(width) != 1))
+       (!ctx->Extensions.ARB_texture_non_power_of_two && !_mesa_is_pow_two(width)))
       return GL_INVALID_VALUE;
 
    if ((height < 1 || height > maxTextureSize ||
-       (!ctx->Extensions.ARB_texture_non_power_of_two && _mesa_bitcount(height) != 1))
+       (!ctx->Extensions.ARB_texture_non_power_of_two && !_mesa_is_pow_two(height)))
        && dimensions > 1)
       return GL_INVALID_VALUE;
 
    if ((depth < 1 || depth > maxTextureSize ||
-       (!ctx->Extensions.ARB_texture_non_power_of_two && _mesa_bitcount(depth) != 1))
+       (!ctx->Extensions.ARB_texture_non_power_of_two && !_mesa_is_pow_two(depth)))
        && dimensions > 2)
       return GL_INVALID_VALUE;