Mesa (7.11): mesa: Refactor compressed texture error checks to work with paletted textures

Ian Romanick idr at kemper.freedesktop.org
Wed Oct 26 01:42:10 UTC 2011


Module: Mesa
Branch: 7.11
Commit: 30b199f86791194210224807127dd3a56871aab5
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=30b199f86791194210224807127dd3a56871aab5

Author: Ian Romanick <ian.d.romanick at intel.com>
Date:   Mon Sep 12 11:46:09 2011 -0500

mesa: Refactor compressed texture error checks to work with paletted textures

This code was really broken before.  A lot of the error checks were
done much later (too late), and some of the error checks would fail.
The underlying problem is that Mesa doesn't ever keep compressed paletted
textures in their original format.  The textures are immediately
converted to some RGB or RGBA format.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=39991
Signed-off-by: Ian Romanick <ian.d.romanick at intel.com>
Reviewed-by: Brian Paul <brianp at vmware.com>
Tested-by: Jin Yang <jin.a.yang at intel.com>
(cherry picked from commit 3ebbfc8372d410801c799b3eb7821075dae73b17)

---

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

diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c
index 0339fd4..55f90a9 100644
--- a/src/mesa/main/teximage.c
+++ b/src/mesa/main/teximage.c
@@ -3039,15 +3039,12 @@ compressed_texture_error_check(struct gl_context *ctx, GLint dimensions,
    const GLenum proxyTarget = get_proxy_target(target);
    const GLint maxLevels = _mesa_max_texture_levels(ctx, target);
    GLint expectedSize;
+   GLenum choose_format;
+   GLenum choose_type;
+   GLenum proxy_format;
 
    *reason = ""; /* no error */
 
-   /* check level */
-   if (level < 0 || level >= maxLevels) {
-      *reason = "level";
-      return GL_INVALID_VALUE;
-   }
-
    if (!target_can_be_compressed(ctx, target, internalFormat)) {
       *reason = "target";
       return GL_INVALID_ENUM;
@@ -3059,6 +3056,68 @@ compressed_texture_error_check(struct gl_context *ctx, GLint dimensions,
       return GL_INVALID_ENUM;
    }
 
+   switch (internalFormat) {
+#if FEATURE_ES
+   case GL_PALETTE4_RGB8_OES:
+   case GL_PALETTE4_RGBA8_OES:
+   case GL_PALETTE4_R5_G6_B5_OES:
+   case GL_PALETTE4_RGBA4_OES:
+   case GL_PALETTE4_RGB5_A1_OES:
+   case GL_PALETTE8_RGB8_OES:
+   case GL_PALETTE8_RGBA8_OES:
+   case GL_PALETTE8_R5_G6_B5_OES:
+   case GL_PALETTE8_RGBA4_OES:
+   case GL_PALETTE8_RGB5_A1_OES:
+      _mesa_cpal_compressed_format_type(internalFormat, &choose_format,
+					&choose_type);
+      proxy_format = choose_format;
+
+      /* check level */
+      if (level > 0 || level < -maxLevels) {
+	 *reason = "level";
+	 return GL_INVALID_VALUE;
+      }
+
+      if (dimensions != 2) {
+	 *reason = "compressed paletted textures must be 2D";
+	 return GL_INVALID_OPERATION;
+      }
+
+      /* Figure out the expected texture size (in bytes).  This will be
+       * checked against the actual size later.
+       */
+      expectedSize = _mesa_cpal_compressed_size(level, internalFormat,
+						width, height);
+
+      /* This is for the benefit of the TestProxyTexImage below.  It expects
+       * level to be non-negative.  OES_compressed_paletted_texture uses a
+       * weird mechanism where the level specified to glCompressedTexImage2D
+       * is -(n-1) number of levels in the texture, and the data specifies the
+       * complete mipmap stack.  This is done to ensure the palette is the
+       * same for all levels.
+       */
+      level = -level;
+      break;
+#endif
+
+   default:
+      choose_format = GL_NONE;
+      choose_type = GL_NONE;
+      proxy_format = internalFormat;
+
+      /* check level */
+      if (level < 0 || level >= maxLevels) {
+	 *reason = "level";
+	 return GL_INVALID_VALUE;
+      }
+
+      /* Figure out the expected texture size (in bytes).  This will be
+       * checked against the actual size later.
+       */
+      expectedSize = compressed_tex_size(width, height, depth, internalFormat);
+      break;
+   }
+
    /* This should really never fail */
    if (_mesa_base_tex_format(ctx, internalFormat) < 0) {
       *reason = "internalFormat";
@@ -3081,8 +3140,8 @@ compressed_texture_error_check(struct gl_context *ctx, GLint dimensions,
    /* check image size against compression block size */
    {
       gl_format texFormat =
-         ctx->Driver.ChooseTextureFormat(ctx, internalFormat,
-                                         GL_NONE, GL_NONE);
+         ctx->Driver.ChooseTextureFormat(ctx, proxy_format,
+					 choose_format, choose_type);
       GLuint bw, bh;
 
       _mesa_get_format_block_size(texFormat, &bw, &bh);
@@ -3100,15 +3159,15 @@ compressed_texture_error_check(struct gl_context *ctx, GLint dimensions,
 
    /* check image sizes */
    if (!ctx->Driver.TestProxyTexImage(ctx, proxyTarget, level,
-                                      internalFormat, GL_NONE, GL_NONE,
-                                      width, height, depth, border)) {
+				      proxy_format, choose_format,
+				      choose_type,
+				      width, height, depth, border)) {
       /* See error comment above */
       *reason = "invalid width, height or format";
       return GL_INVALID_OPERATION;
    }
 
    /* check image size in bytes */
-   expectedSize = compressed_tex_size(width, height, depth, internalFormat);
    if (expectedSize != imageSize) {
       /* Per GL_ARB_texture_compression:  GL_INVALID_VALUE is generated [...]
        * if <imageSize> is not consistent with the format, dimensions, and




More information about the mesa-commit mailing list