From c3c19be8e0d0b13916cc128cf3c8e839935c912a Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 8 May 2006 23:52:32 +0000 Subject: More updates for texture compression. 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 | 47 ++++++++++++++++++++++++++++++++++++++++ src/mesa/main/texcompress.h | 17 +++++++++++---- src/mesa/main/teximage.c | 53 ++++++++++++++++++++++++--------------------- src/mesa/main/texstore.c | 5 +++-- 4 files changed, 91 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/mesa/main/texcompress.c b/src/mesa/main/texcompress.c index c6c7c8adca..0a92c92683 100644 --- a/src/mesa/main/texcompress.c +++ b/src/mesa/main/texcompress.c @@ -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 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. diff --git a/src/mesa/main/texcompress.h b/src/mesa/main/texcompress.h index 637c6a80c3..5b5e64e15d 100644 --- a/src/mesa/main/texcompress.h +++ b/src/mesa/main/texcompress.h @@ -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 */ diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index 4b9b1b8728..f993e21958 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -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; diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c index c373d2f95e..b9a1925be0 100644 --- a/src/mesa/main/texstore.c +++ b/src/mesa/main/texstore.c @@ -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); -- cgit v1.2.3