Merge commit 'origin/master' into gallium-0.2
[mesa.git] / src / mesa / main / teximage.c
index 4c48370d9de993107643fdb6e2d3a4634b2f2457..a5e0db736ed7c82729225dde4de223244731d1a4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Mesa 3-D graphics library
+ * mesa 3-D graphics library
  * Version:  7.1
  *
  * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
@@ -1217,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;
@@ -1306,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;
@@ -1316,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;
@@ -1329,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;
@@ -1353,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;
@@ -1366,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;
@@ -1380,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;
@@ -2991,6 +3002,7 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
                                          &postConvHeight);
    }
 #endif
+
    if (copytexture_error_check(ctx, 2, target, level, internalFormat,
                                postConvWidth, postConvHeight, border))
       return;
@@ -3052,11 +3064,6 @@ _mesa_CopyTexSubImage1D( GLenum target, GLint level,
    if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
       _mesa_update_state(ctx);
 
-#if FEATURE_convolve
-   /* XXX should test internal format */
-   _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL);
-#endif
-
    if (copytexsubimage_error_check1(ctx, 1, target, level))
       return;
 
@@ -3067,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))
@@ -3106,11 +3119,6 @@ _mesa_CopyTexSubImage2D( GLenum target, GLint level,
    if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
       _mesa_update_state(ctx);
 
-#if FEATURE_convolve
-   /* XXX should test internal format */
-   _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth, &postConvHeight);
-#endif
-
    if (copytexsubimage_error_check1(ctx, 2, target, level))
       return;
 
@@ -3121,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;
@@ -3159,11 +3174,6 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level,
    if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
       _mesa_update_state(ctx);
 
-#if FEATURE_convolve
-   /* XXX should test internal format */
-   _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth, &postConvHeight);
-#endif
-
    if (copytexsubimage_error_check1(ctx, 3, target, level))
       return;
 
@@ -3174,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))
@@ -3267,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;