Mesa (master): mesa: clean-up and fix glCompressedTexSubImage error checking

Brian Paul brianp at kemper.freedesktop.org
Wed Sep 19 16:01:35 UTC 2012


Module: Mesa
Branch: master
Commit: 0c67fe5d2dc6d8066fc23c39184d9614abf63992
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=0c67fe5d2dc6d8066fc23c39184d9614abf63992

Author: Brian Paul <brianp at vmware.com>
Date:   Tue Sep 18 15:51:33 2012 -0600

mesa: clean-up and fix glCompressedTexSubImage error checking

---

 src/mesa/main/teximage.c |  145 ++++++++++++++++++++++++++--------------------
 1 files changed, 81 insertions(+), 64 deletions(-)

diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c
index 0f50160..8885a14 100644
--- a/src/mesa/main/teximage.c
+++ b/src/mesa/main/teximage.c
@@ -3525,74 +3525,68 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level,
 /**
  * First-part of error checking for glCompressedTexSubImage[123]D().
  * These are the checks which are independent of the destination image.
- * \return error code or GL_NO_ERROR.
+ * \return GL_TRUE if error, GL_FALSE otherwise
  */
-static GLenum
-compressed_subtexture_error_check(struct gl_context *ctx, GLint dimensions,
-                                  GLenum target, GLint level,
-                                  GLint xoffset, GLint yoffset, GLint zoffset,
-                                  GLsizei width, GLsizei height, GLsizei depth,
-                                  GLenum format, GLsizei imageSize)
+static GLboolean
+compressed_subtexture_error_check1(struct gl_context *ctx, GLint dims,
+                                   GLenum target, GLint level,
+                                   GLint xoffset, GLint yoffset,
+                                   GLsizei width, GLsizei height,
+                                   GLsizei depth,
+                                   GLenum format, GLsizei imageSize)
 {
-   GLint expectedSize, maxLevels = 0, maxTextureSize;
-
-   (void) zoffset;
+   GLint expectedSize;
+   GLboolean targetOK = GL_TRUE;
 
-   if (dimensions == 1) {
-      /* 1D compressed textures not allowed */
-      return GL_INVALID_ENUM;
+   /* check the target */
+   if (dims == 1 || dims == 3) {
+      /* No 1D/3D compressed textures at this time */
+      targetOK = GL_FALSE;
    }
-   else if (dimensions == 2) {
-      if (target == GL_PROXY_TEXTURE_2D) {
-         maxLevels = ctx->Const.MaxTextureLevels;
-      }
-      else if (target == GL_TEXTURE_2D) {
-         maxLevels = ctx->Const.MaxTextureLevels;
-      }
-      else if (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB) {
-         if (!ctx->Extensions.ARB_texture_cube_map)
-            return GL_INVALID_ENUM; /*target*/
-         maxLevels = ctx->Const.MaxCubeTextureLevels;
-      }
-      else if (_mesa_is_cube_face(target)) {
-         if (!ctx->Extensions.ARB_texture_cube_map)
-            return GL_INVALID_ENUM; /*target*/
-         maxLevels = ctx->Const.MaxCubeTextureLevels;
-      }
-      else {
-         return GL_INVALID_ENUM; /*target*/
+   else {
+      assert(dims == 2);
+      switch (target) {
+      case GL_PROXY_TEXTURE_2D:
+      case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+      case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+      case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+      case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+      /* XXX texture rectangle? */
+         /* OK */
+      default:
+         targetOK = GL_FALSE;
       }
    }
-   else if (dimensions == 3) {
-      /* 3D compressed textures not allowed */
-      return GL_INVALID_ENUM;
-   }
 
-   maxTextureSize = 1 << (maxLevels - 1);
+   if (!targetOK) {
+      _mesa_error(ctx, GL_INVALID_ENUM,
+                  "glCompressedTexSubImage%uD(target=0x%x)", dims, target);
+      return GL_TRUE;
+   }
 
    /* this will catch any invalid compressed format token */
-   if (!_mesa_is_compressed_format(ctx, format))
-      return GL_INVALID_ENUM;
-
-   if (width < 1 || width > maxTextureSize)
-      return GL_INVALID_VALUE;
-
-   if ((height < 1 || height > maxTextureSize)
-       && dimensions > 1)
-      return GL_INVALID_VALUE;
-
-   if (level < 0 || level >= maxLevels)
-      return GL_INVALID_VALUE;
+   if (!_mesa_is_compressed_format(ctx, format)) {
+      _mesa_error(ctx, GL_INVALID_ENUM,
+                  "glCompressedTexSubImage%uD(format)", dims);
+      return GL_TRUE;
+   }
 
-   /*
-    * do checks which depend on compression block size
-    */
+   if (level < 0 || level >= _mesa_max_texture_levels(ctx, target)) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "glCompressedTexSubImage%uD(level=%d)", dims, level);
+      return GL_TRUE;
+   }
 
    expectedSize = compressed_tex_size(width, height, depth, format);
-   if (expectedSize != imageSize)
-      return GL_INVALID_VALUE;
+   if (expectedSize != imageSize) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "glCompressedTexSubImage%uD(imageSize=%d)", dims, imageSize);
+      return GL_TRUE;
+   }
 
-   return GL_NO_ERROR;
+   return GL_FALSE;
 }
 
 
@@ -3602,7 +3596,7 @@ compressed_subtexture_error_check(struct gl_context *ctx, GLint dimensions,
  */
 static GLboolean
 compressed_subtexture_error_check2(struct gl_context *ctx, GLuint dims,
-                                   GLint xoffset, GLint yoffset,
+                                   GLint xoffset, GLint yoffset, GLint zoffset,
                                    GLsizei width, GLsizei height,
                                    GLsizei depth, GLenum format,
                                    struct gl_texture_image *texImage)
@@ -3614,6 +3608,32 @@ compressed_subtexture_error_check2(struct gl_context *ctx, GLuint dims,
       return GL_TRUE;
    }
 
+   /* check for negative offsets */
+   if (xoffset < 0 || yoffset < 0 || zoffset < 0) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "glCompressedTexSubImage%uD(xoffset=%d yoffset=%d "
+                  "zoffset=%d)", dims, xoffset, yoffset, zoffset);
+      return GL_TRUE;
+   }
+
+   /* check for bad width, height, depth */
+   if (width < 0 || height < 0 || depth < 0) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "glCompressedTexSubImage%uD(width=%d height=%d depth=%d)",
+                  dims, width, height, depth);
+      return GL_TRUE;
+   }
+
+   /* check offset + size */
+   if (xoffset + width > texImage->Width ||
+       yoffset + height > texImage->Height ||
+       zoffset + depth > texImage->Depth) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "glCompressedTexSubImage%uD(x+width, y+height, z+depth)",
+                  dims);
+      return GL_TRUE;
+   }
+
    if (compressedteximage_only_format(ctx, format)) {
       _mesa_error(ctx, GL_INVALID_OPERATION,
                   "glCompressedTexSubImage%uD(format=0x%x cannot be updated)"
@@ -3679,16 +3699,13 @@ compressed_tex_sub_image(GLuint dims, GLenum target, GLint level,
 {
    struct gl_texture_object *texObj;
    struct gl_texture_image *texImage;
-   GLenum error;
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
-   error = compressed_subtexture_error_check(ctx, dims, target, level,
-                                             xoffset, 0, 0, /* pos */
-                                             width, height, depth,   /* size */
-                                             format, imageSize);
-   if (error) {
-      _mesa_error(ctx, error, "glCompressedTexSubImage%uD", dims);
+   if (compressed_subtexture_error_check1(ctx, dims, target, level,
+                                          xoffset, yoffset,
+                                          width, height, depth,   /* size */
+                                          format, imageSize)) {
       return;
    }
 
@@ -3700,7 +3717,7 @@ compressed_tex_sub_image(GLuint dims, GLenum target, GLint level,
       assert(texImage);
 
       if (compressed_subtexture_error_check2(ctx, dims, xoffset, yoffset,
-                                             width, height, depth,
+                                             zoffset, width, height, depth,
                                              format, texImage)) {
          /* error was recorded */
       }




More information about the mesa-commit mailing list