From 3ebbfc8372d410801c799b3eb7821075dae73b17 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Mon, 12 Sep 2011 11:46:09 -0500 Subject: [PATCH] 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 Reviewed-by: Brian Paul Tested-by: Jin Yang --- src/mesa/main/teximage.c | 81 ++++++++++++++++++++++++++++++++++------ 1 file changed, 70 insertions(+), 11 deletions(-) diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index 76dcd9c514d..fa00183ac65 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -3031,15 +3031,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; @@ -3051,6 +3048,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"; @@ -3073,8 +3132,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); @@ -3092,15 +3151,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 is not consistent with the format, dimensions, and -- 2.30.2