mesa: consolidate sub-texture error checking code
authorBrian Paul <brianp@vmware.com>
Sat, 22 Sep 2012 15:30:24 +0000 (09:30 -0600)
committerBrian Paul <brianp@vmware.com>
Wed, 26 Sep 2012 13:43:49 +0000 (07:43 -0600)
Do all error checking of glTexSubImage, glCopyTexSubImage and
glCompressedTexSubImage's xoffset, yoffset, zoffset, width, height, and
depth params in one place.

src/mesa/main/teximage.c

index 81ca753b7d34153d9d692155ac360a1929ef0f68..501d33d747a48edf09fda0f100124320f3882509 100644 (file)
@@ -1343,23 +1343,82 @@ _mesa_legal_texture_dimensions(struct gl_context *ctx, GLenum target,
 
 
 /**
- * Do error checking of xoffset, yoffset, width, height for glTexSubImage,
- * glCopyTexSubImage and glCompressedTexSubImage.
- * Basically, check that the subregion is aligned to the compressed format's
- * block size.  See comments in function for more info.
+ * Do error checking of xoffset, yoffset, zoffset, width, height and depth
+ * for glTexSubImage, glCopyTexSubImage and glCompressedTexSubImage.
+ * \param destImage  the destination texture image.
  * \return GL_TRUE if error found, GL_FALSE otherwise.
  */
 static GLboolean
 error_check_subtexture_dimensions(struct gl_context *ctx,
-                                  const char *function,
-                                  GLuint dims,
-                                  gl_format texFormat,
-                                  GLint xoffset, GLint yoffset,
+                                  const char *function, GLuint dims,
+                                  const struct gl_texture_image *destImage,
+                                  GLint xoffset, GLint yoffset, GLint zoffset,
                                   GLsizei subWidth, GLsizei subHeight,
-                                  GLsizei texWidth, GLsizei texHeight)
+                                  GLsizei subDepth)
 {
+   const GLenum target = destImage->TexObject->Target;
    GLuint bw, bh;
 
+   /* Check size */
+   if (subWidth < 0) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "%s%dD(width=%d)", function, dims, subWidth);
+      return GL_TRUE;
+   }
+
+   if (dims > 1 && subHeight < 0) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "%s%dD(height=%d)", function, dims, subHeight);
+      return GL_TRUE;
+   }
+
+   if (dims > 2 && subDepth < 0) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "%s%dD(depth=%d)", function, dims, subDepth);
+      return GL_TRUE;
+   }
+
+   /* check xoffset and width */
+   if (xoffset < -destImage->Border) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "%s%dD(xoffset)",
+                  function, dims);
+      return GL_TRUE;
+   }
+
+   if (xoffset + subWidth > destImage->Width) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "%s%dD(xoffset+width)",
+                  function, dims);
+      return GL_TRUE;
+   }
+
+   /* check yoffset and height */
+   if (dims > 1) {
+      GLint yBorder = (target == GL_TEXTURE_1D_ARRAY) ? 0 : destImage->Border;
+      if (yoffset < -yBorder) {
+         _mesa_error(ctx, GL_INVALID_VALUE, "%s%dD(yoffset)",
+                     function, dims);
+         return GL_TRUE;
+      }
+      if (yoffset + subHeight > destImage->Height) {
+         _mesa_error(ctx, GL_INVALID_VALUE, "%s%dD(yoffset+height)",
+                     function, dims);
+         return GL_TRUE;
+      }
+   }
+
+   /* check zoffset and depth */
+   if (dims > 2) {
+      GLint zBorder = (target == GL_TEXTURE_2D_ARRAY) ? 0 : destImage->Border;
+      if (zoffset < -zBorder) {
+         _mesa_error(ctx, GL_INVALID_VALUE, "%s3D(zoffset)", function);
+         return GL_TRUE;
+      }
+      if (zoffset + subDepth  > (GLint) destImage->Depth) {
+         _mesa_error(ctx, GL_INVALID_VALUE, "%s3D(zoffset+depth)", function);
+         return GL_TRUE;
+      }
+   }
+
    /*
     * The OpenGL spec (and GL_ARB_texture_compression) says only whole
     * compressed texture images can be updated.  But, that restriction may be
@@ -1367,28 +1426,30 @@ error_check_subtexture_dimensions(struct gl_context *ctx,
     * compressed formats supported by Mesa allow sub-textures to be updated
     * along compressed block boundaries.
     */
-   _mesa_get_format_block_size(texFormat, &bw, &bh);
+   _mesa_get_format_block_size(destImage->TexFormat, &bw, &bh);
 
-   /* offset must be multiple of block size */
-   if ((xoffset % bw != 0) || (yoffset % bh != 0)) {
-      _mesa_error(ctx, GL_INVALID_OPERATION,
-                  "%s%dD(xoffset = %d, yoffset = %d)",
-                  function, dims, xoffset, yoffset);
-      return GL_TRUE;
-   }
+   if (bw != 1 || bh != 1) {
+      /* offset must be multiple of block size */
+      if ((xoffset % bw != 0) || (yoffset % bh != 0)) {
+         _mesa_error(ctx, GL_INVALID_OPERATION,
+                     "%s%dD(xoffset = %d, yoffset = %d)",
+                     function, dims, xoffset, yoffset);
+         return GL_TRUE;
+      }
 
-   /* size must be multiple of bw by bh or equal to whole texture size */
-   if ((subWidth % bw != 0) && subWidth != texWidth) {
-      _mesa_error(ctx, GL_INVALID_OPERATION,
-                  "%s%dD(width = %d)", function, dims, subWidth);
-      return GL_TRUE;
-   }
+      /* size must be multiple of bw by bh or equal to whole texture size */
+      if ((subWidth % bw != 0) && subWidth != destImage->Width) {
+         _mesa_error(ctx, GL_INVALID_OPERATION,
+                     "%s%dD(width = %d)", function, dims, subWidth);
+         return GL_TRUE;
+      }
 
-   if ((subHeight % bh != 0) && subHeight != texHeight) {
-      _mesa_error(ctx, GL_INVALID_OPERATION,
-                  "%s%dD(height = %d)", function, dims, subHeight);
-      return GL_TRUE;
-   }         
+      if ((subHeight % bh != 0) && subHeight != destImage->Height) {
+         _mesa_error(ctx, GL_INVALID_OPERATION,
+                     "%s%dD(height = %d)", function, dims, subHeight);
+         return GL_TRUE;
+      }         
+   }
 
    return GL_FALSE;
 }
@@ -2147,23 +2208,6 @@ texsubimage_error_check(struct gl_context *ctx, GLuint dimensions,
       return GL_TRUE;
    }
 
-   /* Check for negative sizes */
-   if (width < 0) {
-      _mesa_error(ctx, GL_INVALID_VALUE,
-                  "glTexSubImage%dD(width=%d)", dimensions, width);
-      return GL_TRUE;
-   }
-   if (height < 0 && dimensions > 1) {
-      _mesa_error(ctx, GL_INVALID_VALUE,
-                  "glTexSubImage%dD(height=%d)", dimensions, height);
-      return GL_TRUE;
-   }
-   if (depth < 0 && dimensions > 2) {
-      _mesa_error(ctx, GL_INVALID_VALUE,
-                  "glTexSubImage%dD(depth=%d)", dimensions, depth);
-      return GL_TRUE;
-   }
-
    /* OpenGL ES 1.x and OpenGL ES 2.0 impose additional restrictions on the
     * combinations of format and type that can be used.  Formats and types
     * that require additional extensions (e.g., GL_FLOAT requires
@@ -2205,40 +2249,11 @@ texsubimage_error_check(struct gl_context *ctx, GLuint dimensions,
       return GL_TRUE;
    }
 
-   if (xoffset < -((GLint)texImage->Border)) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(xoffset)",
-                  dimensions);
-      return GL_TRUE;
-   }
-   if (xoffset + width > (GLint) (texImage->Width + texImage->Border)) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(xoffset+width)",
-                  dimensions);
+   if (error_check_subtexture_dimensions(ctx, "glTexSubImage", dimensions,
+                                         texImage, xoffset, yoffset, 0,
+                                         width, height, 1)) {
       return GL_TRUE;
    }
-   if (dimensions > 1) {
-      GLint yBorder = (target == GL_TEXTURE_1D_ARRAY) ? 0 : texImage->Border;
-      if (yoffset < -yBorder) {
-         _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(yoffset)",
-                     dimensions);
-         return GL_TRUE;
-      }
-      if (yoffset + height > (GLint) texImage->Height + yBorder) {
-         _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(yoffset+height)",
-                     dimensions);
-         return GL_TRUE;
-      }
-   }
-   if (dimensions > 2) {
-      GLint zBorder = (target == GL_TEXTURE_2D_ARRAY) ? 0 : texImage->Border;
-      if (zoffset < -zBorder) {
-         _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage3D(zoffset)");
-         return GL_TRUE;
-      }
-      if (zoffset + depth  > (GLint) texImage->Depth + zBorder) {
-         _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage3D(zoffset+depth)");
-         return GL_TRUE;
-      }
-   }
 
    if (_mesa_is_format_compressed(texImage->TexFormat)) {
       if (compressedteximage_only_format(ctx, texImage->InternalFormat)) {
@@ -2246,14 +2261,6 @@ texsubimage_error_check(struct gl_context *ctx, GLuint dimensions,
                "glTexSubImage%dD(no compression for format)", dimensions);
          return GL_TRUE;
       }
-
-      if (error_check_subtexture_dimensions(ctx, "glTexSubImage", dimensions,
-                                            texImage->TexFormat,
-                                            xoffset, yoffset,
-                                            width, height,
-                                            texImage->Width, texImage->Height)) {
-         return GL_TRUE;
-      }
    }
 
    if (ctx->Version >= 30 || ctx->Extensions.EXT_texture_integer) {
@@ -2491,52 +2498,6 @@ copytexsubimage_error_check(struct gl_context *ctx, GLuint dimensions,
                                          width, height, 1)) {
       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);
-      return GL_TRUE;
-   }
-   if (xoffset + width > (GLint) (texImage->Width + texImage->Border)) {
-      _mesa_error(ctx, GL_INVALID_VALUE,
-                  "glCopyTexSubImage%dD(xoffset+width)", dimensions);
-      return GL_TRUE;
-   }
-   if (dimensions > 1) {
-      GLint yBorder = (target == GL_TEXTURE_1D_ARRAY) ? 0 : texImage->Border;
-      if (yoffset < -yBorder) {
-         _mesa_error(ctx, GL_INVALID_VALUE,
-                     "glCopyTexSubImage%dD(yoffset=%d)", dimensions, yoffset);
-         return GL_TRUE;
-      }
-      /* NOTE: we're adding the border here, not subtracting! */
-      if (yoffset + height > (GLint) texImage->Height + yBorder) {
-         _mesa_error(ctx, GL_INVALID_VALUE,
-                     "glCopyTexSubImage%dD(yoffset+height)", dimensions);
-         return GL_TRUE;
-      }
-   }
-
-   /* check z offset */
-   if (dimensions > 2) {
-      GLint zBorder = (target == GL_TEXTURE_2D_ARRAY) ? 0 : texImage->Border;
-      if (zoffset < -zBorder) {
-         _mesa_error(ctx, GL_INVALID_VALUE,
-                     "glCopyTexSubImage%dD(zoffset)", dimensions);
-         return GL_TRUE;
-      }
-      if (zoffset > (GLint) texImage->Depth + zBorder) {
-         _mesa_error(ctx, GL_INVALID_VALUE,
-                     "glCopyTexSubImage%dD(zoffset+depth)", dimensions);
-         return GL_TRUE;
-      }
-   }
 
    if (_mesa_is_format_compressed(texImage->TexFormat)) {
       if (compressedteximage_only_format(ctx, texImage->InternalFormat)) {
@@ -2544,14 +2505,6 @@ copytexsubimage_error_check(struct gl_context *ctx, GLuint dimensions,
                "glCopyTexSubImage%dD(no compression for format)", dimensions);
          return GL_TRUE;
       }
-
-      if (error_check_subtexture_dimensions(ctx, "glCopyTexSubImage",
-                                            dimensions, texImage->TexFormat,
-                                            xoffset, yoffset, width, height,
-                                            texImage->Width,
-                                            texImage->Height)) {
-         return GL_TRUE;
-      }
    }
 
    if (texImage->InternalFormat == GL_YCBCR_MESA) {
@@ -3584,32 +3537,6 @@ compressed_subtexture_error_check(struct gl_context *ctx, GLint 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)"
@@ -3618,9 +3545,8 @@ compressed_subtexture_error_check(struct gl_context *ctx, GLint dims,
    }
 
    if (error_check_subtexture_dimensions(ctx, "glCompressedTexSubImage", dims,
-                                         texImage->TexFormat,
-                                         xoffset, yoffset, width, height,
-                                         texImage->Width, texImage->Height)) {
+                                         texImage, xoffset, yoffset, zoffset,
+                                         width, height, depth)) {
       return GL_TRUE;
    }