More updates for texture compression.
authorBrian Paul <brian.paul@tungstengraphics.com>
Mon, 8 May 2006 23:52:32 +0000 (23:52 +0000)
committerBrian Paul <brian.paul@tungstengraphics.com>
Mon, 8 May 2006 23:52:32 +0000 (23:52 +0000)
Added _mesa_compressed_texture_size_glenum() for validating the imageSize
parameter to glCompressedTex[Sub]Image1/2/3() which does _not_ call
ctx->Driver.CompressedTextureSize() - since that could return a padded size.

src/mesa/main/texcompress.c
src/mesa/main/texcompress.h
src/mesa/main/teximage.c
src/mesa/main/texstore.c

index c6c7c8adca0eaef84fd4d3fe07a61f7389243ffd..0a92c9268361cd15654716910836c6a5d91f5d86 100644 (file)
@@ -162,6 +162,53 @@ _mesa_compressed_texture_size( GLcontext *ctx,
 }
 
 
+/**
+ * As above, but format is specified by a GLenum (GL_COMPRESSED_*) token.
+ *
+ * Note: This function CAN NOT return a padded hardware texture size.
+ * That's why we don't call the ctx->Driver.CompressedTextureSize() function.
+ *
+ * We use this function to validate the <imageSize> parameter
+ * of glCompressedTex[Sub]Image1/2/3D(), which must be an exact match.
+ */
+GLuint
+_mesa_compressed_texture_size_glenum(GLcontext *ctx,
+                                     GLsizei width, GLsizei height,
+                                     GLsizei depth, GLenum glformat)
+{
+   GLuint mesaFormat;
+
+   switch (glformat) {
+   case GL_COMPRESSED_RGB_FXT1_3DFX:
+      mesaFormat = MESA_FORMAT_RGB_FXT1;
+      break;
+   case GL_COMPRESSED_RGBA_FXT1_3DFX:
+      mesaFormat = MESA_FORMAT_RGBA_FXT1;
+      break;
+   case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+   case GL_RGB_S3TC:
+      mesaFormat = MESA_FORMAT_RGB_DXT1;
+      break;
+   case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+   case GL_RGB4_S3TC:
+      mesaFormat = MESA_FORMAT_RGBA_DXT1;
+      break;
+   case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+   case GL_RGBA_S3TC:
+      mesaFormat = MESA_FORMAT_RGBA_DXT3;
+      break;
+   case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+   case GL_RGBA4_S3TC:
+      mesaFormat = MESA_FORMAT_RGBA_DXT5;
+      break;
+   default:
+      return 0;
+   }
+
+   return _mesa_compressed_texture_size(ctx, width, height, depth, mesaFormat);
+}
+
+
 /*
  * Compute the bytes per row in a compressed texture image.
  * We use this for computing the destination address for sub-texture updates.
index 637c6a80c3e62125742c1e0a2280a4d35955a647..5b5e64e15dd945154f97f6709df2d9a688adb811 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * Mesa 3-D graphics library
- * Version:  6.1
+ * Version:  6.5.1
  *
- * Copyright (C) 1999-2004  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2006  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"),
@@ -28,6 +28,7 @@
 #include "mtypes.h"
 
 #if _HAVE_FULL_GL
+
 extern GLuint
 _mesa_get_compressed_formats( GLcontext *ctx, GLint *formats );
 
@@ -36,6 +37,11 @@ _mesa_compressed_texture_size( GLcontext *ctx,
                                GLsizei width, GLsizei height, GLsizei depth,
                                GLuint mesaFormat );
 
+extern GLuint
+_mesa_compressed_texture_size_glenum(GLcontext *ctx,
+                                     GLsizei width, GLsizei height,
+                                     GLsizei depth, GLenum glformat);
+
 extern GLint
 _mesa_compressed_row_stride(GLuint mesaFormat, GLsizei width);
 
@@ -53,13 +59,16 @@ extern void
 _mesa_init_texture_fxt1( GLcontext *ctx );
 
 
+#else /* _HAVE_FULL_GL */
 
-#else
+/* no-op macros */
 #define _mesa_get_compressed_formats( c, f ) 0
 #define _mesa_compressed_texture_size( c, w, h, d, f ) 0
+#define _mesa_compressed_texture_size_glenum( c, w, h, d, f ) 0
 #define _mesa_compressed_row_stride( f, w) 0
 #define _mesa_compressed_image_address(c, r, i, f, w, i2 ) 0
 #define _mesa_compress_teximage( c, w, h, sF, s, sRS, dF, d, drs ) ((void)0)
-#endif
+
+#endif /* _HAVE_FULL_GL */
 
 #endif /* TEXCOMPRESS_H */
index 4b9b1b8728d27a3e7dd5debd941b1d4f0a51c251..f993e2195817e1ef84ffd08ff63ffee237a40321 100644 (file)
@@ -533,22 +533,17 @@ is_depthstencil_format(GLenum format)
 static GLboolean
 is_compressed_format(GLcontext *ctx, GLenum internalFormat)
 {
-   (void) ctx;
-   switch (internalFormat) {
-      case GL_COMPRESSED_RGB_FXT1_3DFX:
-      case GL_COMPRESSED_RGBA_FXT1_3DFX:
-      case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
-      case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
-      case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
-      case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
-      case GL_RGB_S3TC:
-      case GL_RGB4_S3TC:
-      case GL_RGBA_S3TC:
-      case GL_RGBA4_S3TC:
+   GLint supported[100]; /* 100 should be plenty */
+   GLuint i, n;
+
+   n = _mesa_get_compressed_formats(ctx, supported);
+   ASSERT(n < 100);
+   for (i = 0; i < n; i++) {
+      if ((GLint) internalFormat == supported[i]) {
          return GL_TRUE;
-      default:
-         return GL_FALSE;
+      }
    }
+   return GL_FALSE;
 }
 
 
@@ -642,6 +637,8 @@ void
 _mesa_free_texture_image_data(GLcontext *ctx,
                               struct gl_texture_image *texImage)
 {
+   (void) ctx;
+
    if (texImage->Data && !texImage->IsClientData) {
       /* free the old texture data */
       _mesa_free_texmemory(texImage->Data);
@@ -2840,7 +2837,7 @@ compressed_texture_error_check(GLcontext *ctx, GLint dimensions,
                                GLsizei height, GLsizei depth, GLint border,
                                GLsizei imageSize)
 {
-   GLint /**expectedSize,**/ maxLevels = 0, maxTextureSize;
+   GLint expectedSize, maxLevels = 0, maxTextureSize;
 
    if (dimensions == 1) {
       /* 1D compressed textures not allowed */
@@ -2875,9 +2872,11 @@ compressed_texture_error_check(GLcontext *ctx, GLint dimensions,
 
    maxTextureSize = 1 << (maxLevels - 1);
 
+   /* This will detect any invalid internalFormat value */
    if (!is_compressed_format(ctx, internalFormat))
       return GL_INVALID_ENUM;
 
+   /* This should really never fail */
    if (_mesa_base_tex_format(ctx, internalFormat) < 0)
       return GL_INVALID_ENUM;
 
@@ -2909,13 +2908,10 @@ compressed_texture_error_check(GLcontext *ctx, GLint dimensions,
    if (level < 0 || level >= maxLevels)
       return GL_INVALID_VALUE;
 
-#if 0
-   /* XXX need to renable this code someday! */
-   expectedSize = ctx->Driver.CompressedTextureSize(ctx, width, height, depth,
-                                                    internalFormat);
+   expectedSize = _mesa_compressed_texture_size_glenum(ctx, width, height,
+                                                       depth, internalFormat);
    if (expectedSize != imageSize)
       return GL_INVALID_VALUE;
-#endif
 
    return GL_NO_ERROR;
 }
@@ -2971,6 +2967,7 @@ compressed_subtexture_error_check(GLcontext *ctx, GLint dimensions,
 
    maxTextureSize = 1 << (maxLevels - 1);
 
+   /* this will catch any invalid compressed format token */
    if (!is_compressed_format(ctx, format))
       return GL_INVALID_ENUM;
 
@@ -2996,8 +2993,8 @@ compressed_subtexture_error_check(GLcontext *ctx, GLint dimensions,
    if ((height & 3) != 0 && height != 2 && height != 1)
       return GL_INVALID_VALUE;
 
-   expectedSize = ctx->Driver.CompressedTextureSize(ctx, width, height, depth,
-                                                    format);
+   expectedSize = _mesa_compressed_texture_size_glenum(ctx, width, height,
+                                                       depth, format);
    if (expectedSize != imageSize)
       return GL_INVALID_VALUE;
 
@@ -3265,7 +3262,9 @@ _mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset,
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
    error = compressed_subtexture_error_check(ctx, 1, target, level,
-                                xoffset, 0, 0, width, 1, 1, format, imageSize);
+                                             xoffset, 0, 0, /* pos */
+                                             width, 1, 1,   /* size */
+                                             format, imageSize);
    if (error) {
       _mesa_error(ctx, error, "glCompressedTexSubImage1D");
       return;
@@ -3314,7 +3313,9 @@ _mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset,
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
    error = compressed_subtexture_error_check(ctx, 2, target, level,
-                     xoffset, yoffset, 0, width, height, 1, format, imageSize);
+                                             xoffset, yoffset, 0, /* pos */
+                                             width, height, 1,    /* size */
+                                             format, imageSize);
    if (error) {
       /* XXX proxy target? */
       _mesa_error(ctx, error, "glCompressedTexSubImage2D");
@@ -3365,7 +3366,9 @@ _mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset,
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
    error = compressed_subtexture_error_check(ctx, 3, target, level,
-           xoffset, yoffset, zoffset, width, height, depth, format, imageSize);
+                                             xoffset, yoffset, zoffset,/*pos*/
+                                             width, height, depth, /*size*/
+                                             format, imageSize);
    if (error) {
       _mesa_error(ctx, error, "glCompressedTexSubImage2D");
       return;
index c373d2f95eac927024eef4bb3aa6c60103825d32..b9a1925be024cbe773207eac5d847ccbdfeaa418 100644 (file)
@@ -2383,12 +2383,13 @@ choose_texture_format(GLcontext *ctx, struct gl_texture_image *texImage,
                       GLuint dims,
                       GLenum format, GLenum type, GLint internalFormat)
 {
-   assert(ctx->Driver.ChooseTextureFormat);
+   ASSERT(dims == 1 || dims == 2 || dims == 3);
+   ASSERT(ctx->Driver.ChooseTextureFormat);
 
    texImage->TexFormat
       = ctx->Driver.ChooseTextureFormat(ctx, internalFormat, format, type);
 
-   assert(texImage->TexFormat);
+   ASSERT(texImage->TexFormat);
 
    set_fetch_functions(texImage, dims);