mesa: replace gl_texture_format with gl_format
[mesa.git] / src / mesa / main / teximage.c
index 8228303040932feb47acb4b76a45c7481d5ca6d0..c4e5ce2682480a5d9fdf580908e26357d1103453 100644 (file)
@@ -33,9 +33,8 @@
 #include "glheader.h"
 #include "bufferobj.h"
 #include "context.h"
-#if FEATURE_convolve
 #include "convolve.h"
-#endif
+#include "enums.h"
 #include "fbobject.h"
 #include "framebuffer.h"
 #include "hash.h"
@@ -901,7 +900,7 @@ clear_teximage_fields(struct gl_texture_image *img)
    img->HeightLog2 = 0;
    img->DepthLog2 = 0;
    img->Data = NULL;
-   img->TexFormat = &_mesa_null_texformat;
+   img->TexFormat = MESA_FORMAT_NONE;
    img->FetchTexelc = NULL;
    img->FetchTexelf = NULL;
    img->IsCompressed = 0;
@@ -2075,6 +2074,23 @@ update_fbo_texture(GLcontext *ctx, struct gl_texture_object *texObj,
 }
 
 
+/**
+ * If the texture object's GenerateMipmap flag is set and we've
+ * changed the texture base level image, regenerate the rest of the
+ * mipmap levels now.
+ */
+static INLINE void
+check_gen_mipmap(GLcontext *ctx, GLenum target,
+                 struct gl_texture_object *texObj, GLint level)
+{
+   ASSERT(target != GL_TEXTURE_CUBE_MAP);
+   if (texObj->GenerateMipmap && level == texObj->BaseLevel) {
+      ASSERT(ctx->Driver.GenerateMipmap);
+      ctx->Driver.GenerateMipmap(ctx, target, texObj);
+   }
+}
+
+
 /** Debug helper: override the user-requested internal format */
 static GLenum
 override_internal_format(GLenum internalFormat, GLint width, GLint height)
@@ -2131,6 +2147,13 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
+   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+      _mesa_debug(ctx, "glTexImage1D %s %d %s %d %d %s %s %p\n",
+                  _mesa_lookup_enum_by_nr(target), level,
+                  _mesa_lookup_enum_by_nr(internalFormat), width, border,
+                  _mesa_lookup_enum_by_nr(format),
+                  _mesa_lookup_enum_by_nr(type), pixels);
+
    internalFormat = override_internal_format(internalFormat, width, 1);
 
 #if FEATURE_convolve
@@ -2161,36 +2184,36 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
         texImage = _mesa_get_tex_image(ctx, texObj, target, level);
         if (!texImage) {
            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
-           goto out;
-        }
-      
-        if (texImage->Data) {
-           ctx->Driver.FreeTexImageData( ctx, texImage );
         }
+         else {
+            if (texImage->Data) {
+               ctx->Driver.FreeTexImageData( ctx, texImage );
+            }
+
+            ASSERT(texImage->Data == NULL);
+
+            clear_teximage_fields(texImage); /* not really needed, but helpful */
+            _mesa_init_teximage_fields(ctx, target, texImage,
+                                       postConvWidth, 1, 1,
+                                       border, internalFormat);
+
+            /* Give the texture to the driver.  <pixels> may be null. */
+            ASSERT(ctx->Driver.TexImage1D);
+            ctx->Driver.TexImage1D(ctx, target, level, internalFormat,
+                                   width, border, format, type, pixels,
+                                   &ctx->Unpack, texObj, texImage);
+
+            ASSERT(texImage->TexFormat);
 
-        ASSERT(texImage->Data == NULL);
-
-        clear_teximage_fields(texImage); /* not really needed, but helpful */
-        _mesa_init_teximage_fields(ctx, target, texImage,
-                                   postConvWidth, 1, 1,
-                                   border, internalFormat);
-        
-        ASSERT(ctx->Driver.TexImage1D);
-
-        /* Give the texture to the driver!  <pixels> may be null! */
-        (*ctx->Driver.TexImage1D)(ctx, target, level, internalFormat,
-                                  width, border, format, type, pixels,
-                                  &ctx->Unpack, texObj, texImage);
-        
-        ASSERT(texImage->TexFormat);
-
-        update_fbo_texture(ctx, texObj, face, level);
-        
-        /* state update */
-        texObj->_Complete = GL_FALSE;
-        ctx->NewState |= _NEW_TEXTURE;
-      }
-   out:
+            check_gen_mipmap(ctx, target, texObj, level);
+
+            update_fbo_texture(ctx, texObj, face, level);
+
+            /* state update */
+            texObj->_Complete = GL_FALSE;
+            ctx->NewState |= _NEW_TEXTURE;
+         }
+      }
       _mesa_unlock_texture(ctx, texObj);
    }
    else if (target == GL_PROXY_TEXTURE_1D) {
@@ -2209,8 +2232,8 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
          _mesa_init_teximage_fields(ctx, target, texImage,
                                     postConvWidth, 1, 1,
                                     border, internalFormat);
-         texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
-                                          internalFormat, format, type);
+         texImage->TexFormat =
+            ctx->Driver.ChooseTextureFormat(ctx, internalFormat, format, type);
       }
    }
    else {
@@ -2230,6 +2253,13 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
+   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+      _mesa_debug(ctx, "glTexImage2D %s %d %s %d %d %d %s %s %p\n",
+                  _mesa_lookup_enum_by_nr(target), level,
+                  _mesa_lookup_enum_by_nr(internalFormat), width, height,
+                  border, _mesa_lookup_enum_by_nr(format),
+                  _mesa_lookup_enum_by_nr(type), pixels);
+
    internalFormat = override_internal_format(internalFormat, width, height);
 
 #if FEATURE_convolve
@@ -2269,35 +2299,35 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
         texImage = _mesa_get_tex_image(ctx, texObj, target, level);
         if (!texImage) {
            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
-           goto out;
-        }
-        
-        if (texImage->Data) {
-           ctx->Driver.FreeTexImageData( ctx, texImage );
         }
-        
-        ASSERT(texImage->Data == NULL);
-        clear_teximage_fields(texImage); /* not really needed, but helpful */
-        _mesa_init_teximage_fields(ctx, target, texImage,
-                                   postConvWidth, postConvHeight, 1,
-                                   border, internalFormat);
-        
-        ASSERT(ctx->Driver.TexImage2D);
-
-        /* Give the texture to the driver!  <pixels> may be null! */
-        (*ctx->Driver.TexImage2D)(ctx, target, level, internalFormat,
-                                  width, height, border, format, type, pixels,
-                                  &ctx->Unpack, texObj, texImage);
-        
-        ASSERT(texImage->TexFormat);
-
-        update_fbo_texture(ctx, texObj, face, level);
-
-        /* state update */
-        texObj->_Complete = GL_FALSE;
-        ctx->NewState |= _NEW_TEXTURE;
-      }
-   out:
+         else {
+            if (texImage->Data) {
+               ctx->Driver.FreeTexImageData( ctx, texImage );
+            }
+
+            ASSERT(texImage->Data == NULL);
+            clear_teximage_fields(texImage); /* not really needed, but helpful */
+            _mesa_init_teximage_fields(ctx, target, texImage,
+                                       postConvWidth, postConvHeight, 1,
+                                       border, internalFormat);
+
+            /* Give the texture to the driver.  <pixels> may be null. */
+            ASSERT(ctx->Driver.TexImage2D);
+            ctx->Driver.TexImage2D(ctx, target, level, internalFormat,
+                                   width, height, border, format, type,
+                                   pixels, &ctx->Unpack, texObj, texImage);
+
+            ASSERT(texImage->TexFormat);
+
+            check_gen_mipmap(ctx, target, texObj, level);
+
+            update_fbo_texture(ctx, texObj, face, level);
+
+            /* state update */
+            texObj->_Complete = GL_FALSE;
+            ctx->NewState |= _NEW_TEXTURE;
+         }
+      }
       _mesa_unlock_texture(ctx, texObj);
    }
    else if (target == GL_PROXY_TEXTURE_2D ||
@@ -2322,8 +2352,8 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
          _mesa_init_teximage_fields(ctx, target, texImage,
                                     postConvWidth, postConvHeight, 1,
                                     border, internalFormat);
-         texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
-                                          internalFormat, format, type);
+         texImage->TexFormat =
+            ctx->Driver.ChooseTextureFormat(ctx, internalFormat, format, type);
       }
    }
    else {
@@ -2346,6 +2376,13 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
+   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+      _mesa_debug(ctx, "glTexImage3D %s %d %s %d %d %d %d %s %s %p\n",
+                  _mesa_lookup_enum_by_nr(target), level,
+                  _mesa_lookup_enum_by_nr(internalFormat), width, height,
+                  depth, border, _mesa_lookup_enum_by_nr(format),
+                  _mesa_lookup_enum_by_nr(type), pixels);
+
    internalFormat = override_internal_format(internalFormat, width, height);
 
    if (target == GL_TEXTURE_3D ||
@@ -2372,35 +2409,35 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
         texImage = _mesa_get_tex_image(ctx, texObj, target, level);
         if (!texImage) {
            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
-           goto out;
-        }
-        
-        if (texImage->Data) {
-           ctx->Driver.FreeTexImageData( ctx, texImage );
         }
-        
-        ASSERT(texImage->Data == NULL);
-        clear_teximage_fields(texImage); /* not really needed, but helpful */
-        _mesa_init_teximage_fields(ctx, target, texImage,
-                                   width, height, depth,
-                                   border, internalFormat);
+         else {
+            if (texImage->Data) {
+               ctx->Driver.FreeTexImageData( ctx, texImage );
+            }
+
+            ASSERT(texImage->Data == NULL);
+            clear_teximage_fields(texImage); /* not really needed, but helpful */
+            _mesa_init_teximage_fields(ctx, target, texImage,
+                                       width, height, depth,
+                                       border, internalFormat);
 
-        ASSERT(ctx->Driver.TexImage3D);
+            /* Give the texture to the driver.  <pixels> may be null. */
+            ASSERT(ctx->Driver.TexImage3D);
+            ctx->Driver.TexImage3D(ctx, target, level, internalFormat,
+                                   width, height, depth, border, format, type,
+                                   pixels, &ctx->Unpack, texObj, texImage);
 
-        /* Give the texture to the driver!  <pixels> may be null! */
-        (*ctx->Driver.TexImage3D)(ctx, target, level, internalFormat,
-                                  width, height, depth, border, format, type,
-                                  pixels, &ctx->Unpack, texObj, texImage);
+            ASSERT(texImage->TexFormat);
 
-        ASSERT(texImage->TexFormat);
+            check_gen_mipmap(ctx, target, texObj, level);
 
-        update_fbo_texture(ctx, texObj, face, level);
+            update_fbo_texture(ctx, texObj, face, level);
 
-        /* state update */
-        texObj->_Complete = GL_FALSE;
-        ctx->NewState |= _NEW_TEXTURE;
+            /* state update */
+            texObj->_Complete = GL_FALSE;
+            ctx->NewState |= _NEW_TEXTURE;
+         }
       }
-   out:
       _mesa_unlock_texture(ctx, texObj);
    }
    else if (target == GL_PROXY_TEXTURE_3D ||
@@ -2419,8 +2456,8 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
          /* no error, set the tex image parameters */
          _mesa_init_teximage_fields(ctx, target, texImage, width, height,
                                     depth, border, internalFormat);
-         texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
-                                          internalFormat, format, type);
+         texImage->TexFormat =
+            ctx->Driver.ChooseTextureFormat(ctx, internalFormat, format, type);
       }
    }
    else {
@@ -2455,6 +2492,12 @@ _mesa_TexSubImage1D( GLenum target, GLint level,
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
+   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+      _mesa_debug(ctx, "glTexSubImage1D %s %d %d %d %s %s %p\n",
+                  _mesa_lookup_enum_by_nr(target), level,
+                  xoffset, width, _mesa_lookup_enum_by_nr(format),
+                  _mesa_lookup_enum_by_nr(type), pixels);
+
    if (ctx->NewState & _MESA_NEW_TRANSFER_STATE)
       _mesa_update_state(ctx);
 
@@ -2480,23 +2523,24 @@ _mesa_TexSubImage1D( GLenum target, GLint level,
       texImage = _mesa_select_tex_image(ctx, texObj, target, level);
 
       if (subtexture_error_check2(ctx, 1, target, level, xoffset, 0, 0,
-                                 postConvWidth, 1, 1, format, type, texImage)) {
-        goto out;   /* error was detected */
+                                 postConvWidth, 1, 1,
+                                  format, type, texImage)) {
+         /* error was recorded */
       }
+      else if (width > 0) {
+         /* If we have a border, xoffset=-1 is legal.  Bias by border width */
+         xoffset += texImage->Border;
 
-      if (width == 0)
-        goto out;  /* no-op, not an error */
+         ASSERT(ctx->Driver.TexSubImage1D);
+         ctx->Driver.TexSubImage1D(ctx, target, level, xoffset, width,
+                                   format, type, pixels, &ctx->Unpack,
+                                   texObj, texImage);
 
-      /* If we have a border, xoffset=-1 is legal.  Bias by border width */
-      xoffset += texImage->Border;
+         check_gen_mipmap(ctx, target, texObj, level);
 
-      ASSERT(ctx->Driver.TexSubImage1D);
-      (*ctx->Driver.TexSubImage1D)(ctx, target, level, xoffset, width,
-                                  format, type, pixels, &ctx->Unpack,
-                                  texObj, texImage);
-      ctx->NewState |= _NEW_TEXTURE;
+         ctx->NewState |= _NEW_TEXTURE;
+      }
    }
- out:
    _mesa_unlock_texture(ctx, texObj);
 }
 
@@ -2515,6 +2559,13 @@ _mesa_TexSubImage2D( GLenum target, GLint level,
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
+   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+      _mesa_debug(ctx, "glTexSubImage2D %s %d %d %d %d %d %s %s %p\n",
+                  _mesa_lookup_enum_by_nr(target), level,
+                  xoffset, yoffset, width, height,
+                  _mesa_lookup_enum_by_nr(format),
+                  _mesa_lookup_enum_by_nr(type), pixels);
+
    if (ctx->NewState & _MESA_NEW_TRANSFER_STATE)
       _mesa_update_state(ctx);
 
@@ -2533,30 +2584,31 @@ _mesa_TexSubImage2D( GLenum target, GLint level,
 
    texUnit = _mesa_get_current_tex_unit(ctx);
    texObj = _mesa_select_tex_object(ctx, texUnit, target);
+
    _mesa_lock_texture(ctx, texObj);
    {
       texImage = _mesa_select_tex_image(ctx, texObj, target, level);
 
       if (subtexture_error_check2(ctx, 2, target, level, xoffset, yoffset, 0,
-                                 postConvWidth, postConvHeight, 1, format, type, 
-                                 texImage)) {
-        goto out;   /* error was detected */
+                                 postConvWidth, postConvHeight, 1,
+                                  format, type, texImage)) {
+        /* error was recorded */
       }
+      else if (width > 0 && height >= 0) {
+         /* If we have a border, xoffset=-1 is legal.  Bias by border width */
+         xoffset += texImage->Border;
+         yoffset += texImage->Border;
+
+         ASSERT(ctx->Driver.TexSubImage2D);
+         ctx->Driver.TexSubImage2D(ctx, target, level, xoffset, yoffset,
+                                   width, height, format, type, pixels,
+                                   &ctx->Unpack, texObj, texImage);
 
-      if (width == 0 || height == 0)
-        goto out;  /* no-op, not an error */
+         check_gen_mipmap(ctx, target, texObj, level);
 
-      /* If we have a border, xoffset=-1 is legal.  Bias by border width */
-      xoffset += texImage->Border;
-      yoffset += texImage->Border;
-      
-      ASSERT(ctx->Driver.TexSubImage2D);
-      (*ctx->Driver.TexSubImage2D)(ctx, target, level, xoffset, yoffset,
-                                  width, height, format, type, pixels,
-                                  &ctx->Unpack, texObj, texImage);
-      ctx->NewState |= _NEW_TEXTURE;
+         ctx->NewState |= _NEW_TEXTURE;
+      }
    }
- out:
    _mesa_unlock_texture(ctx, texObj);
 }
 
@@ -2575,6 +2627,13 @@ _mesa_TexSubImage3D( GLenum target, GLint level,
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
+   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+      _mesa_debug(ctx, "glTexSubImage3D %s %d %d %d %d %d %d %d %s %s %p\n",
+                  _mesa_lookup_enum_by_nr(target), level,
+                  xoffset, yoffset, zoffset, width, height, depth,
+                  _mesa_lookup_enum_by_nr(format),
+                  _mesa_lookup_enum_by_nr(type), pixels);
+
    if (ctx->NewState & _MESA_NEW_TRANSFER_STATE)
       _mesa_update_state(ctx);
 
@@ -2590,28 +2649,30 @@ _mesa_TexSubImage3D( GLenum target, GLint level,
    {
       texImage = _mesa_select_tex_image(ctx, texObj, target, level);
 
-      if (subtexture_error_check2(ctx, 3, target, level, xoffset, yoffset, zoffset,
-                                 width, height, depth, format, type, texImage)) {
-        goto out;   /* error was detected */
+      if (subtexture_error_check2(ctx, 3, target, level,
+                                  xoffset, yoffset, zoffset,
+                                 width, height, depth,
+                                  format, type, texImage)) {
+         /* error was recorded */
       }
+      else if (width > 0 && height > 0 && height > 0) {
+         /* If we have a border, xoffset=-1 is legal.  Bias by border width */
+         xoffset += texImage->Border;
+         yoffset += texImage->Border;
+         zoffset += texImage->Border;
 
-      if (width == 0 || height == 0 || height == 0)
-        goto out;  /* no-op, not an error */
+         ASSERT(ctx->Driver.TexSubImage3D);
+         ctx->Driver.TexSubImage3D(ctx, target, level,
+                                   xoffset, yoffset, zoffset,
+                                   width, height, depth,
+                                   format, type, pixels,
+                                   &ctx->Unpack, texObj, texImage );
 
-      /* If we have a border, xoffset=-1 is legal.  Bias by border width */
-      xoffset += texImage->Border;
-      yoffset += texImage->Border;
-      zoffset += texImage->Border;
+         check_gen_mipmap(ctx, target, texObj, level);
 
-      ASSERT(ctx->Driver.TexSubImage3D);
-      (*ctx->Driver.TexSubImage3D)(ctx, target, level,
-                                  xoffset, yoffset, zoffset,
-                                  width, height, depth,
-                                  format, type, pixels,
-                                  &ctx->Unpack, texObj, texImage );
-      ctx->NewState |= _NEW_TEXTURE;
+         ctx->NewState |= _NEW_TEXTURE;
+      }
    }
- out:
    _mesa_unlock_texture(ctx, texObj);
 }
 
@@ -2631,6 +2692,12 @@ _mesa_CopyTexImage1D( GLenum target, GLint level,
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
+   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+      _mesa_debug(ctx, "glCopyTexImage1D %s %d %s %d %d %d %d\n",
+                  _mesa_lookup_enum_by_nr(target), level,
+                  _mesa_lookup_enum_by_nr(internalFormat),
+                  x, y, width, border);
+
    if (ctx->NewState & NEW_COPY_TEX_STATE)
       _mesa_update_state(ctx);
 
@@ -2646,38 +2713,39 @@ _mesa_CopyTexImage1D( GLenum target, GLint level,
 
    texUnit = _mesa_get_current_tex_unit(ctx);
    texObj = _mesa_select_tex_object(ctx, texUnit, target);
+
    _mesa_lock_texture(ctx, texObj);
    {
       texImage = _mesa_get_tex_image(ctx, texObj, target, level);
       if (!texImage) {
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D");
-        goto out;
       }
+      else {
+         if (texImage->Data) {
+            ctx->Driver.FreeTexImageData( ctx, texImage );
+         }
 
-      if (texImage->Data) {
-        ctx->Driver.FreeTexImageData( ctx, texImage );
-      }
-      
-      ASSERT(texImage->Data == NULL);
+         ASSERT(texImage->Data == NULL);
 
-      clear_teximage_fields(texImage); /* not really needed, but helpful */
-      _mesa_init_teximage_fields(ctx, target, texImage, postConvWidth, 1, 1,
-                                border, internalFormat);
+         clear_teximage_fields(texImage); /* not really needed, but helpful */
+         _mesa_init_teximage_fields(ctx, target, texImage, postConvWidth, 1, 1,
+                                    border, internalFormat);
 
+         ASSERT(ctx->Driver.CopyTexImage1D);
+         ctx->Driver.CopyTexImage1D(ctx, target, level, internalFormat,
+                                    x, y, width, border);
 
-      ASSERT(ctx->Driver.CopyTexImage1D);
-      (*ctx->Driver.CopyTexImage1D)(ctx, target, level, internalFormat,
-                                   x, y, width, border);
+         ASSERT(texImage->TexFormat);
 
-      ASSERT(texImage->TexFormat);
+         check_gen_mipmap(ctx, target, texObj, level);
 
-      update_fbo_texture(ctx, texObj, face, level);
+         update_fbo_texture(ctx, texObj, face, level);
 
-      /* state update */
-      texObj->_Complete = GL_FALSE;
-      ctx->NewState |= _NEW_TEXTURE;
+         /* state update */
+         texObj->_Complete = GL_FALSE;
+         ctx->NewState |= _NEW_TEXTURE;
+      }
    }
- out:
    _mesa_unlock_texture(ctx, texObj);
 }
 
@@ -2696,6 +2764,12 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
+   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+      _mesa_debug(ctx, "glCopyTexImage2D %s %d %s %d %d %d %d %d\n",
+                  _mesa_lookup_enum_by_nr(target), level,
+                  _mesa_lookup_enum_by_nr(internalFormat),
+                  x, y, width, height, border);
+
    if (ctx->NewState & NEW_COPY_TEX_STATE)
       _mesa_update_state(ctx);
 
@@ -2719,33 +2793,34 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
 
       if (!texImage) {
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D");
-        goto out;
       }
-      
-      if (texImage->Data) {
-        ctx->Driver.FreeTexImageData( ctx, texImage );
-      }
-      
-      ASSERT(texImage->Data == NULL);
+      else {
+         if (texImage->Data) {
+            ctx->Driver.FreeTexImageData( ctx, texImage );
+         }
+
+         ASSERT(texImage->Data == NULL);
+
+         clear_teximage_fields(texImage); /* not really needed, but helpful */
+         _mesa_init_teximage_fields(ctx, target, texImage,
+                                    postConvWidth, postConvHeight, 1,
+                                    border, internalFormat);
+
+         ASSERT(ctx->Driver.CopyTexImage2D);
+         ctx->Driver.CopyTexImage2D(ctx, target, level, internalFormat,
+                                    x, y, width, height, border);
 
-      clear_teximage_fields(texImage); /* not really needed, but helpful */
-      _mesa_init_teximage_fields(ctx, target, texImage,
-                                postConvWidth, postConvHeight, 1,
-                                border, internalFormat);
-      
-      ASSERT(ctx->Driver.CopyTexImage2D);
-      (*ctx->Driver.CopyTexImage2D)(ctx, target, level, internalFormat,
-                                   x, y, width, height, border);
-      
-      ASSERT(texImage->TexFormat);
+         ASSERT(texImage->TexFormat);
 
-      update_fbo_texture(ctx, texObj, face, level);
+         check_gen_mipmap(ctx, target, texObj, level);
 
-      /* state update */
-      texObj->_Complete = GL_FALSE;
-      ctx->NewState |= _NEW_TEXTURE;
+         update_fbo_texture(ctx, texObj, face, level);
+
+         /* state update */
+         texObj->_Complete = GL_FALSE;
+         ctx->NewState |= _NEW_TEXTURE;
+      }
    }
- out:
    _mesa_unlock_texture(ctx, texObj);
 }
 
@@ -2764,6 +2839,11 @@ _mesa_CopyTexSubImage1D( GLenum target, GLint level,
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
+   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+      _mesa_debug(ctx, "glCopyTexSubImage1D %s %d %d %d %d %d\n",
+                  _mesa_lookup_enum_by_nr(target),
+                  level, xoffset, x, y, width);
+
    if (ctx->NewState & NEW_COPY_TEX_STATE)
       _mesa_update_state(ctx);
 
@@ -2785,23 +2865,25 @@ _mesa_CopyTexSubImage1D( GLenum target, GLint level,
 
       if (copytexsubimage_error_check2(ctx, 1, target, level,
                                       xoffset, 0, 0, postConvWidth, 1,
-                                      texImage))
-        goto out;
-      
+                                      texImage)) {
+         /* error was recorded */
+      }
+      else {
+         /* If we have a border, xoffset=-1 is legal.  Bias by border width */
+         xoffset += texImage->Border;
 
-      /* If we have a border, xoffset=-1 is legal.  Bias by border width */
-      xoffset += texImage->Border;
+         if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y,
+                                        &width, &height)) {
+            ASSERT(ctx->Driver.CopyTexSubImage1D);
+            ctx->Driver.CopyTexSubImage1D(ctx, target, level,
+                                          xoffset, x, y, width);
 
-      if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y,
-                                     &width, &height)) {
-         ASSERT(ctx->Driver.CopyTexSubImage1D);
-         ctx->Driver.CopyTexSubImage1D(ctx, target, level,
-                                       xoffset, x, y, width);
-      }
+            check_gen_mipmap(ctx, target, texObj, level);
 
-      ctx->NewState |= _NEW_TEXTURE;
+            ctx->NewState |= _NEW_TEXTURE;
+         }
+      }
    }
- out:
    _mesa_unlock_texture(ctx, texObj);
 }
 
@@ -2819,6 +2901,11 @@ _mesa_CopyTexSubImage2D( GLenum target, GLint level,
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
+   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+      _mesa_debug(ctx, "glCopyTexSubImage2D %s %d %d %d %d %d %d %d\n",
+                  _mesa_lookup_enum_by_nr(target),
+                  level, xoffset, yoffset, x, y, width, height);
+
    if (ctx->NewState & NEW_COPY_TEX_STATE)
       _mesa_update_state(ctx);
 
@@ -2839,24 +2926,29 @@ _mesa_CopyTexSubImage2D( GLenum target, GLint level,
       }
 #endif
 
-      if (copytexsubimage_error_check2(ctx, 2, target, level, xoffset, yoffset, 0,
-                                      postConvWidth, postConvHeight, texImage))
-        goto out;
+      if (copytexsubimage_error_check2(ctx, 2, target, level,
+                                       xoffset, yoffset, 0,
+                                      postConvWidth, postConvHeight,
+                                       texImage)) {
+         /* error was recorded */
+      }
+      else {
+         /* If we have a border, xoffset=-1 is legal.  Bias by border width */
+         xoffset += texImage->Border;
+         yoffset += texImage->Border;
 
-      /* If we have a border, xoffset=-1 is legal.  Bias by border width */
-      xoffset += texImage->Border;
-      yoffset += texImage->Border;
+         if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y,
+                                        &width, &height)) {
+            ASSERT(ctx->Driver.CopyTexSubImage2D);
+            ctx->Driver.CopyTexSubImage2D(ctx, target, level, xoffset, yoffset,
+                                          x, y, width, height);
 
-      if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y,
-                                     &width, &height)) {
-         ASSERT(ctx->Driver.CopyTexSubImage2D);
-         ctx->Driver.CopyTexSubImage2D(ctx, target, level,
-                                      xoffset, yoffset, x, y, width, height);
-      }
+            check_gen_mipmap(ctx, target, texObj, level);
 
-      ctx->NewState |= _NEW_TEXTURE;
+            ctx->NewState |= _NEW_TEXTURE;
+         }
+      }
    }
- out:
    _mesa_unlock_texture(ctx, texObj);
 }
 
@@ -2874,6 +2966,11 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level,
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
+   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+      _mesa_debug(ctx, "glCopyTexSubImage3D %s %d %d %d %d %d %d %d %d\n",
+                  _mesa_lookup_enum_by_nr(target),
+                  level, xoffset, yoffset, zoffset, x, y, width, height);
+
    if (ctx->NewState & NEW_COPY_TEX_STATE)
       _mesa_update_state(ctx);
 
@@ -2896,25 +2993,28 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level,
 
       if (copytexsubimage_error_check2(ctx, 3, target, level, xoffset, yoffset,
                                       zoffset, postConvWidth, postConvHeight,
-                                      texImage))
-        goto out;
-
-      /* If we have a border, xoffset=-1 is legal.  Bias by border width */
-      xoffset += texImage->Border;
-      yoffset += texImage->Border;
-      zoffset += texImage->Border;
-      
-      if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y,
-                                     &width, &height)) {
-         ASSERT(ctx->Driver.CopyTexSubImage3D);
-         ctx->Driver.CopyTexSubImage3D(ctx, target, level,
-                                      xoffset, yoffset, zoffset,
-                                      x, y, width, height);
+                                      texImage)) {
+         /* error was recored */
       }
+      else {
+         /* If we have a border, xoffset=-1 is legal.  Bias by border width */
+         xoffset += texImage->Border;
+         yoffset += texImage->Border;
+         zoffset += texImage->Border;
+
+         if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y,
+                                        &width, &height)) {
+            ASSERT(ctx->Driver.CopyTexSubImage3D);
+            ctx->Driver.CopyTexSubImage3D(ctx, target, level,
+                                          xoffset, yoffset, zoffset,
+                                          x, y, width, height);
 
-      ctx->NewState |= _NEW_TEXTURE;
+            check_gen_mipmap(ctx, target, texObj, level);
+
+            ctx->NewState |= _NEW_TEXTURE;
+         }
+      }
    }
- out:
    _mesa_unlock_texture(ctx, texObj);
 }
 
@@ -3122,6 +3222,12 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level,
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
+   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+      _mesa_debug(ctx, "glCompressedTexImage1DARB %s %d %s %d %d %d %p\n",
+                  _mesa_lookup_enum_by_nr(target), level,
+                  _mesa_lookup_enum_by_nr(internalFormat),
+                  width, border, imageSize, data);
+
    if (target == GL_TEXTURE_1D) {
       /* non-proxy target */
       struct gl_texture_unit *texUnit;
@@ -3142,28 +3248,29 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level,
         texImage = _mesa_get_tex_image(ctx, texObj, target, level);
         if (!texImage) {
            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage1D");
-           goto out;
         }
-        
-        if (texImage->Data) {
-           ctx->Driver.FreeTexImageData( ctx, texImage );
-        }
-        ASSERT(texImage->Data == NULL);
+         else {
+            if (texImage->Data) {
+               ctx->Driver.FreeTexImageData( ctx, texImage );
+            }
+            ASSERT(texImage->Data == NULL);
 
-        _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1,
-                                   border, internalFormat);
+            _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1,
+                                       border, internalFormat);
 
-        ASSERT(ctx->Driver.CompressedTexImage1D);
-        (*ctx->Driver.CompressedTexImage1D)(ctx, target, level,
-                                            internalFormat, width, border,
-                                            imageSize, data,
-                                            texObj, texImage);
+            ASSERT(ctx->Driver.CompressedTexImage1D);
+            ctx->Driver.CompressedTexImage1D(ctx, target, level,
+                                             internalFormat, width, border,
+                                             imageSize, data,
+                                             texObj, texImage);
 
-        /* state update */
-        texObj->_Complete = GL_FALSE;
-        ctx->NewState |= _NEW_TEXTURE;
+            check_gen_mipmap(ctx, target, texObj, level);
+
+            /* state update */
+            texObj->_Complete = GL_FALSE;
+            ctx->NewState |= _NEW_TEXTURE;
+         }
       }
-   out:
       _mesa_unlock_texture(ctx, texObj);
    }
    else if (target == GL_PROXY_TEXTURE_1D) {
@@ -3216,6 +3323,12 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level,
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
+   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+      _mesa_debug(ctx, "glCompressedTexImage2DARB %s %d %s %d %d %d %d %p\n",
+                  _mesa_lookup_enum_by_nr(target), level,
+                  _mesa_lookup_enum_by_nr(internalFormat),
+                  width, height, border, imageSize, data);
+
    if (target == GL_TEXTURE_2D ||
        (ctx->Extensions.ARB_texture_cube_map &&
         target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
@@ -3239,28 +3352,29 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level,
         texImage = _mesa_get_tex_image(ctx, texObj, target, level);
         if (!texImage) {
            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D");
-           goto out;
-        }
-        
-        if (texImage->Data) {
-           ctx->Driver.FreeTexImageData( ctx, texImage );
         }
-        ASSERT(texImage->Data == NULL);
-
-        _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1,
-                                   border, internalFormat);
-
-        ASSERT(ctx->Driver.CompressedTexImage2D);
-        (*ctx->Driver.CompressedTexImage2D)(ctx, target, level,
-                                            internalFormat, width, height,
-                                            border, imageSize, data,
-                                            texObj, texImage);
-        
-        /* state update */
-        texObj->_Complete = GL_FALSE;
-        ctx->NewState |= _NEW_TEXTURE;
-      }
-   out:
+         else {
+            if (texImage->Data) {
+               ctx->Driver.FreeTexImageData( ctx, texImage );
+            }
+            ASSERT(texImage->Data == NULL);
+
+            _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1,
+                                       border, internalFormat);
+
+            ASSERT(ctx->Driver.CompressedTexImage2D);
+            ctx->Driver.CompressedTexImage2D(ctx, target, level,
+                                             internalFormat, width, height,
+                                             border, imageSize, data,
+                                             texObj, texImage);
+
+            check_gen_mipmap(ctx, target, texObj, level);
+
+            /* state update */
+            texObj->_Complete = GL_FALSE;
+            ctx->NewState |= _NEW_TEXTURE;
+         }
+      }
       _mesa_unlock_texture(ctx, texObj);
    }
    else if (target == GL_PROXY_TEXTURE_2D ||
@@ -3315,6 +3429,12 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level,
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
+   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+      _mesa_debug(ctx, "glCompressedTexImage3DARB %s %d %s %d %d %d %d %d %p\n",
+                  _mesa_lookup_enum_by_nr(target), level,
+                  _mesa_lookup_enum_by_nr(internalFormat),
+                  width, height, depth, border, imageSize, data);
+
    if (target == GL_TEXTURE_3D) {
       /* non-proxy target */
       struct gl_texture_unit *texUnit;
@@ -3334,29 +3454,31 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level,
         texImage = _mesa_get_tex_image(ctx, texObj, target, level);
         if (!texImage) {
            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage3D");
-           goto out;
-        }
-        
-        if (texImage->Data) {
-           ctx->Driver.FreeTexImageData( ctx, texImage );
         }
-        ASSERT(texImage->Data == NULL);
-
-        _mesa_init_teximage_fields(ctx, target, texImage, width, height, depth,
-                                   border, internalFormat);
-
-        ASSERT(ctx->Driver.CompressedTexImage3D);
-        (*ctx->Driver.CompressedTexImage3D)(ctx, target, level,
-                                            internalFormat,
-                                            width, height, depth,
-                                            border, imageSize, data,
-                                            texObj, texImage);
-        
-        /* state update */
-        texObj->_Complete = GL_FALSE;
-        ctx->NewState |= _NEW_TEXTURE;
-      }
-   out:
+         else {
+            if (texImage->Data) {
+               ctx->Driver.FreeTexImageData( ctx, texImage );
+            }
+            ASSERT(texImage->Data == NULL);
+
+            _mesa_init_teximage_fields(ctx, target, texImage,
+                                       width, height, depth,
+                                       border, internalFormat);
+
+            ASSERT(ctx->Driver.CompressedTexImage3D);
+            ctx->Driver.CompressedTexImage3D(ctx, target, level,
+                                             internalFormat,
+                                             width, height, depth,
+                                             border, imageSize, data,
+                                             texObj, texImage);
+
+            check_gen_mipmap(ctx, target, texObj, level);
+
+            /* state update */
+            texObj->_Complete = GL_FALSE;
+            ctx->NewState |= _NEW_TEXTURE;
+         }
+      }
       _mesa_unlock_texture(ctx, texObj);
    }
    else if (target == GL_PROXY_TEXTURE_3D) {
@@ -3422,6 +3544,7 @@ _mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset,
 
    texUnit = _mesa_get_current_tex_unit(ctx);
    texObj = _mesa_select_tex_object(ctx, texUnit, target);
+
    _mesa_lock_texture(ctx, texObj);
    {
       texImage = _mesa_select_tex_image(ctx, texObj, target, level);
@@ -3430,26 +3553,25 @@ _mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset,
       if ((GLint) format != texImage->InternalFormat) {
         _mesa_error(ctx, GL_INVALID_OPERATION,
                     "glCompressedTexSubImage1D(format)");
-        goto out;
       }
+      else if ((width == 1 || width == 2) &&
+               (GLuint) width != texImage->Width) {
+        _mesa_error(ctx, GL_INVALID_VALUE,
+                     "glCompressedTexSubImage1D(width)");
+      }
+      else if (width > 0) {
+         if (ctx->Driver.CompressedTexSubImage1D) {
+            ctx->Driver.CompressedTexSubImage1D(ctx, target, level,
+                                                xoffset, width,
+                                                format, imageSize, data,
+                                                texObj, texImage);
+         }
 
-      if ((width == 1 || width == 2) && (GLuint) width != texImage->Width) {
-        _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage1D(width)");
-        goto out;
-      }
-      
-      if (width == 0)
-        goto out;  /* no-op, not an error */
+         check_gen_mipmap(ctx, target, texObj, level);
 
-      if (ctx->Driver.CompressedTexSubImage1D) {
-        (*ctx->Driver.CompressedTexSubImage1D)(ctx, target, level,
-                                               xoffset, width,
-                                               format, imageSize, data,
-                                               texObj, texImage);
+         ctx->NewState |= _NEW_TEXTURE;
       }
-      ctx->NewState |= _NEW_TEXTURE;
    }
- out:
    _mesa_unlock_texture(ctx, texObj);
 }
 
@@ -3479,6 +3601,7 @@ _mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset,
 
    texUnit = _mesa_get_current_tex_unit(ctx);
    texObj = _mesa_select_tex_object(ctx, texUnit, target);
+
    _mesa_lock_texture(ctx, texObj);
    {
       texImage = _mesa_select_tex_image(ctx, texObj, target, level);
@@ -3487,27 +3610,26 @@ _mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset,
       if ((GLint) format != texImage->InternalFormat) {
         _mesa_error(ctx, GL_INVALID_OPERATION,
                     "glCompressedTexSubImage2D(format)");
-        goto out;
       }
-
-      if (((width == 1 || width == 2) && (GLuint) width != texImage->Width) ||
-         ((height == 1 || height == 2) && (GLuint) height != texImage->Height)) {
+      else if (((width == 1 || width == 2)
+                && (GLuint) width != texImage->Width) ||
+               ((height == 1 || height == 2)
+                && (GLuint) height != texImage->Height)) {
         _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage2D(size)");
-        goto out;
       }
-      
-      if (width == 0 || height == 0)
-        goto out;  /* no-op, not an error */
-
-      if (ctx->Driver.CompressedTexSubImage2D) {
-        (*ctx->Driver.CompressedTexSubImage2D)(ctx, target, level,
+      else if (width > 0 && height > 0) {
+         if (ctx->Driver.CompressedTexSubImage2D) {
+            ctx->Driver.CompressedTexSubImage2D(ctx, target, level,
                                                xoffset, yoffset, width, height,
                                                format, imageSize, data,
                                                texObj, texImage);
+         }
+
+         check_gen_mipmap(ctx, target, texObj, level);
+
+         ctx->NewState |= _NEW_TEXTURE;
       }
-      ctx->NewState |= _NEW_TEXTURE;
    }
- out:
    _mesa_unlock_texture(ctx, texObj);
 }
 
@@ -3536,6 +3658,7 @@ _mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset,
 
    texUnit = _mesa_get_current_tex_unit(ctx);
    texObj = _mesa_select_tex_object(ctx, texUnit, target);
+
    _mesa_lock_texture(ctx, texObj);
    {
       texImage = _mesa_select_tex_image(ctx, texObj, target, level);
@@ -3544,29 +3667,29 @@ _mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset,
       if ((GLint) format != texImage->InternalFormat) {
         _mesa_error(ctx, GL_INVALID_OPERATION,
                     "glCompressedTexSubImage3D(format)");
-        goto out;
       }
-
-      if (((width == 1 || width == 2) && (GLuint) width != texImage->Width) ||
-         ((height == 1 || height == 2) && (GLuint) height != texImage->Height) ||
-         ((depth == 1 || depth == 2) && (GLuint) depth != texImage->Depth)) {
+      else if (((width == 1 || width == 2)
+                && (GLuint) width != texImage->Width) ||
+               ((height == 1 || height == 2)
+                && (GLuint) height != texImage->Height) ||
+               ((depth == 1 || depth == 2)
+                && (GLuint) depth != texImage->Depth)) {
         _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage3D(size)");
-        goto out;
       }
-      
-      if (width == 0 || height == 0 || depth == 0)
-        goto out;  /* no-op, not an error */
-
-      if (ctx->Driver.CompressedTexSubImage3D) {
-        (*ctx->Driver.CompressedTexSubImage3D)(ctx, target, level,
+      else if (width > 0 && height > 0 && depth > 0) {
+         if (ctx->Driver.CompressedTexSubImage3D) {
+            ctx->Driver.CompressedTexSubImage3D(ctx, target, level,
                                                xoffset, yoffset, zoffset,
                                                width, height, depth,
                                                format, imageSize, data,
                                                texObj, texImage);
+         }
+
+         check_gen_mipmap(ctx, target, texObj, level);
+
+         ctx->NewState |= _NEW_TEXTURE;
       }
-      ctx->NewState |= _NEW_TEXTURE;
    }
- out:
    _mesa_unlock_texture(ctx, texObj);
 }