diff options
author | Brian Paul <brian.paul@tungstengraphics.com> | 2000-08-29 22:58:57 +0000 |
---|---|---|
committer | Brian Paul <brian.paul@tungstengraphics.com> | 2000-08-29 22:58:57 +0000 |
commit | 846101fe60e3aee0bcc7f474353c50342d6c17e5 (patch) | |
tree | 4d21cf840ef661030a3d107446bad922da266859 /src | |
parent | 9af68b12220bc3d8ef47248ef23b760785b260cc (diff) |
finished compressed texture support (Bill White)
Diffstat (limited to 'src')
-rw-r--r-- | src/mesa/main/dd.h | 49 | ||||
-rw-r--r-- | src/mesa/main/extensions.c | 6 | ||||
-rw-r--r-- | src/mesa/main/teximage.c | 423 | ||||
-rw-r--r-- | src/mesa/main/teximage.h | 8 |
4 files changed, 362 insertions, 124 deletions
diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h index 900bc88567e..318f1e18554 100644 --- a/src/mesa/main/dd.h +++ b/src/mesa/main/dd.h @@ -1,4 +1,4 @@ -/* $Id: dd.h,v 1.26.4.1 2000/08/08 16:02:09 brianp Exp $ */ +/* $Id: dd.h,v 1.26.4.2 2000/08/29 22:58:57 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -642,17 +642,20 @@ struct dd_function_table { */ GLboolean (*CompressedTexImage1D)( GLcontext *ctx, GLenum target, - GLint level, const GLvoid *data, + GLint level, GLsizei imageSize, + const GLvoid *data, struct gl_texture_object *texObj, struct gl_texture_image *texImage, GLboolean *retainInternalCopy); GLboolean (*CompressedTexImage2D)( GLcontext *ctx, GLenum target, - GLint level, const GLvoid *data, + GLint level, GLsizei imageSize, + const GLvoid *data, struct gl_texture_object *texObj, struct gl_texture_image *texImage, GLboolean *retainInternalCopy); GLboolean (*CompressedTexImage3D)( GLcontext *ctx, GLenum target, - GLint level, const GLvoid *data, + GLint level, GLsizei imageSize, + const GLvoid *data, struct gl_texture_object *texObj, struct gl_texture_image *texImage, GLboolean *retainInternalCopy); @@ -700,6 +703,42 @@ struct dd_function_table { * should do the job. */ + GLint (*BaseCompressedTexFormat)(GLcontext *ctx, + GLint internalFormat); + /* Called to compute the base format for a specific compressed + * format. Return -1 if the internalFormat is not a specific + * compressed format that the driver recognizes. Note the + * return value differences between this function and + * SpecificCompressedTexFormat below. + */ + + GLint (*SpecificCompressedTexFormat)(GLcontext *ctx, + GLint internalFormat, + GLint numDimensions); + /* Called to turn a generic texture format into a specific + * texture format. For example, if a driver implements + * GL_3DFX_texture_compression_FXT1, this would map + * GL_COMPRESSED_RGBA_ARB to GL_COMPRESSED_RGBA_FXT1_3DFX. + * + * If the driver does not know how to handle the compressed + * format, then just return the generic format, and Mesa will + * do the right thing with it. + */ + + GLboolean (*IsCompressedFormat)(GLcontext *ctx, GLint internalFormat); + /* Called to tell if a format is a compressed format. + */ + + GLsizei (*CompressedImageSize)(GLcontext *ctx, + GLenum internalFormat, + GLuint numDimensions, + GLuint width, + GLuint height, + GLuint depth); + /* Calculate the size of a compressed image, given the image's + * format and dimensions. + */ + void (*GetCompressedTexImage)( GLcontext *ctx, GLenum target, GLint lod, void *image, const struct gl_texture_object *texObj, @@ -760,7 +799,7 @@ struct dd_function_table { /*** - *** Accelerated point, line, polygon, glDrawPixels and glBitmap functions: + *** Accelerated point, line, polygon, quad and rect functions: ***/ points_func PointsFunc; diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c index 5d4ad1bb9e4..818ea161829 100644 --- a/src/mesa/main/extensions.c +++ b/src/mesa/main/extensions.c @@ -1,8 +1,8 @@ -/* $Id: extensions.c,v 1.32 2000/06/27 21:42:13 brianp Exp $ */ +/* $Id: extensions.c,v 1.32.4.1 2000/08/29 22:58:57 brianp Exp $ */ /* * Mesa 3-D graphics library - * Version: 3.3 + * Version: 3.4 * * Copyright (C) 1999-2000 Brian Paul All Rights Reserved. * @@ -51,7 +51,7 @@ struct extension { static struct { int enabled; const char *name; } default_extensions[] = { { DEFAULT_OFF, "GL_ARB_imaging" }, /* in progress */ { DEFAULT_ON, "GL_ARB_multitexture" }, - { DEFAULT_OFF, "GL_ARB_texture_compression" }, /* in progress */ + { DEFAULT_OFF, "GL_ARB_texture_compression" }, { DEFAULT_OFF, "GL_ARB_texture_cube_map" }, /* in progress */ { ALWAYS_ENABLED, "GL_ARB_tranpose_matrix" }, { ALWAYS_ENABLED, "GL_EXT_abgr" }, diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index 98f62c8162c..0ebac85991d 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -1,7 +1,8 @@ +/* $Id: teximage.c,v 1.39.4.1 2000/08/29 22:58:57 brianp Exp $ */ /* * Mesa 3-D graphics library - * Version: 3.3 + * Version: 3.4 * * Copyright (C) 1999-2000 Brian Paul All Rights Reserved. * @@ -139,21 +140,23 @@ logbase2( int n ) GLint _mesa_base_tex_format( GLcontext *ctx, GLint format ) { + /* + * Ask the driver for the base format, if it doesn't + * know, it will return -1; + */ + if (ctx->Driver.BaseCompressedTexFormat) { + GLint ifmt = (*ctx->Driver.BaseCompressedTexFormat)(ctx, format); + if (ifmt >= 0) { + return ifmt; + } + } switch (format) { - case GL_COMPRESSED_ALPHA_ARB: - if (ctx && !ctx->Extensions.HaveTextureCompression) - return -1; - /* fall-through */ case GL_ALPHA: case GL_ALPHA4: case GL_ALPHA8: case GL_ALPHA12: case GL_ALPHA16: return GL_ALPHA; - case GL_COMPRESSED_LUMINANCE_ARB: - if (ctx && !ctx->Extensions.HaveTextureCompression) - return -1; - /* fall-through */ case 1: case GL_LUMINANCE: case GL_LUMINANCE4: @@ -161,10 +164,6 @@ _mesa_base_tex_format( GLcontext *ctx, GLint format ) case GL_LUMINANCE12: case GL_LUMINANCE16: return GL_LUMINANCE; - case GL_COMPRESSED_LUMINANCE_ALPHA_ARB: - if (ctx && !ctx->Extensions.HaveTextureCompression) - return -1; - /* fall-through */ case 2: case GL_LUMINANCE_ALPHA: case GL_LUMINANCE4_ALPHA4: @@ -174,31 +173,12 @@ _mesa_base_tex_format( GLcontext *ctx, GLint format ) case GL_LUMINANCE12_ALPHA12: case GL_LUMINANCE16_ALPHA16: return GL_LUMINANCE_ALPHA; - case GL_COMPRESSED_INTENSITY_ARB: - if (ctx && !ctx->Extensions.HaveTextureCompression) - return -1; - /* fall-through */ case GL_INTENSITY: case GL_INTENSITY4: case GL_INTENSITY8: case GL_INTENSITY12: case GL_INTENSITY16: return GL_INTENSITY; - case GL_COMPRESSED_RGB_ARB: - if (ctx && ctx->Extensions.HaveTextureCompression) - return GL_RGB; - else - return -1; - case GL_COMPRESSED_RGB_FXT1_3DFX: - if (ctx && ctx->Extensions.HaveTextureCompressionFXT1) - return GL_RGB; - else - return -1; - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - if (ctx && ctx->Extensions.HaveTextureCompressionS3TC) - return GL_RGB; - else - return -1; case 3: case GL_RGB: case GL_R3_G3_B2: @@ -209,23 +189,6 @@ _mesa_base_tex_format( GLcontext *ctx, GLint format ) case GL_RGB12: case GL_RGB16: return GL_RGB; - case GL_COMPRESSED_RGBA_ARB: - if (ctx && ctx->Extensions.HaveTextureCompression) - return GL_RGBA; - else - return -1; - case GL_COMPRESSED_RGBA_FXT1_3DFX: - if (ctx && ctx->Extensions.HaveTextureCompressionFXT1) - return GL_RGBA; - else - return -1; - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: - if (ctx && ctx->Extensions.HaveTextureCompressionS3TC) - return GL_RGBA; - else - return -1; case 4: case GL_RGBA: case GL_RGBA2: @@ -328,25 +291,12 @@ components_in_intformat( GLint format ) * otherwise. */ static GLboolean -is_compressed_format(GLenum internalFormat) +is_compressed_format(GLcontext *ctx, GLenum internalFormat) { - switch (internalFormat) { - case GL_COMPRESSED_ALPHA_ARB: - case GL_COMPRESSED_LUMINANCE_ARB: - case GL_COMPRESSED_LUMINANCE_ALPHA_ARB: - case GL_COMPRESSED_INTENSITY_ARB: - case GL_COMPRESSED_RGB_ARB: - case GL_COMPRESSED_RGBA_ARB: - 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_COMPRESSED_RGB_FXT1_3DFX: - case GL_COMPRESSED_RGBA_FXT1_3DFX: - return GL_TRUE; - default: - return GL_FALSE; - } + if (ctx->Driver.IsCompressedFormat) { + return (*ctx->Driver.IsCompressedFormat)(ctx, internalFormat); + } + return GL_FALSE; } @@ -511,13 +461,14 @@ _mesa_alloc_texture_image( void ) * Initialize most fields of a gl_texture_image struct. */ static void -init_texture_image( struct gl_texture_image *img, +init_texture_image( GLcontext *ctx, + struct gl_texture_image *img, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum internalFormat ) { ASSERT(img); ASSERT(!img->Data); - img->Format = (GLenum) _mesa_base_tex_format(NULL, internalFormat); + img->Format = (GLenum) _mesa_base_tex_format(ctx, internalFormat); set_teximage_component_sizes( img ); img->IntFormat = (GLenum) internalFormat; img->Border = border; @@ -537,7 +488,7 @@ init_texture_image( struct gl_texture_image *img, img->Height2 = 1 << img->HeightLog2; img->Depth2 = 1 << img->DepthLog2; img->MaxLog2 = MAX2(img->WidthLog2, img->HeightLog2); - img->IsCompressed = is_compressed_format(internalFormat); + img->IsCompressed = is_compressed_format(ctx, internalFormat); } @@ -556,13 +507,26 @@ _mesa_free_texture_image( struct gl_texture_image *teximage ) /* * Return number of bytes of storage needed to store a compressed texture - * image. + * image. Only the driver knows for sure. If the driver can't help us, + * we must return 0. */ GLuint -_mesa_compressed_image_size(GLenum internalFormat, - GLint width, GLint height, GLint depth) +_mesa_compressed_image_size(GLcontext *ctx, + GLenum internalFormat, + GLint numDimensions, + GLint width, + GLint height, + GLint depth) { - return 0; + if (ctx->Driver.CompressedImageSize) { + return (*ctx->Driver.CompressedImageSize)(ctx, internalFormat, + numDimensions, + width, height, depth); + } + else { + /* Shouldn't this be an internal error of some sort? */ + return 0; + } } @@ -999,7 +963,7 @@ texture_error_check( GLcontext *ctx, GLenum target, return GL_TRUE; } - if (!is_compressed_format(internalFormat)) { + if (!is_compressed_format(ctx, internalFormat)) { if (!_mesa_is_legal_format_and_type( format, type )) { /* Yes, generate GL_INVALID_OPERATION, not GL_INVALID_ENUM, if there * is a type/format mismatch. See 1.2 spec page 94, sec 3.6.4. @@ -1125,7 +1089,7 @@ subtexture_error_check( GLcontext *ctx, GLuint dimensions, } } - if (!is_compressed_format(destTex->IntFormat)) { + if (!is_compressed_format(ctx, destTex->IntFormat)) { if (!_mesa_is_legal_format_and_type(format, type)) { char message[100]; sprintf(message, "glTexSubImage%dD(format or type)", dimensions); @@ -1344,6 +1308,104 @@ copytexsubimage_error_check( GLcontext *ctx, GLuint dimensions, /* + * Turn generic compressed formats into specific compressed format. + * Some of the compressed formats we don't support, so we + * fall back to the uncompressed format. (See issue 15 of + * the GL_ARB_texture_compression specification.) + */ +static GLint +get_specific_compressed_tex_format(GLcontext *ctx, + GLint ifmt, GLint numDimensions) +{ + char message[100]; + GLint internalFormat = ifmt; + + if (ctx->Extensions.HaveTextureCompression + && ctx->Driver.SpecificCompressedTexFormat) { + /* + * First, ask the driver for the specific format. + */ + switch (internalFormat) { + case GL_COMPRESSED_ALPHA_ARB: + case GL_COMPRESSED_LUMINANCE_ARB: + case GL_COMPRESSED_LUMINANCE_ALPHA_ARB: + case GL_COMPRESSED_INTENSITY_ARB: + case GL_COMPRESSED_RGB_ARB: + case GL_COMPRESSED_RGBA_ARB: + internalFormat = (*ctx->Driver.SpecificCompressedTexFormat) + (ctx, internalFormat, numDimensions); + /* XXX shouldn't we return now? */ + break; + default: + /* silence compiler warnings */ + ; + } + } + + /* + * Now, convert any generic format left to an uncompressed + * specific format. If the driver does not support compression + * of the format, we must drop back to the uncompressed format. + * See issue 15 of the GL_ARB_texture_compression specification. + */ + switch (internalFormat) { + case GL_COMPRESSED_ALPHA_ARB: + if (ctx && !ctx->Extensions.HaveTextureCompression) { + sprintf(message, "glTexImage%dD(internalFormat)", numDimensions); + gl_error(ctx, GL_INVALID_VALUE, message); + return -1; + } + internalFormat = GL_ALPHA; + break; + case GL_COMPRESSED_LUMINANCE_ARB: + if (ctx && !ctx->Extensions.HaveTextureCompression) { + sprintf(message, "glTexImage%dD(internalFormat)", numDimensions); + gl_error(ctx, GL_INVALID_VALUE, message); + return -1; + } + internalFormat = GL_LUMINANCE; + break; + case GL_COMPRESSED_LUMINANCE_ALPHA_ARB: + if (ctx && !ctx->Extensions.HaveTextureCompression) { + sprintf(message, "glTexImage%dD(internalFormat)", numDimensions); + gl_error(ctx, GL_INVALID_VALUE, message); + return -1; + } + internalFormat = GL_LUMINANCE_ALPHA; + break; + case GL_COMPRESSED_INTENSITY_ARB: + if (ctx && !ctx->Extensions.HaveTextureCompression) { + sprintf(message, "glTexImage%dD(internalFormat)", numDimensions); + gl_error(ctx, GL_INVALID_VALUE, message); + return -1; + } + internalFormat = GL_INTENSITY; + break; + case GL_COMPRESSED_RGB_ARB: + if (ctx && !ctx->Extensions.HaveTextureCompression) { + sprintf(message, "glTexImage%dD(internalFormat)", numDimensions); + gl_error(ctx, GL_INVALID_VALUE, message); + return -1; + } + internalFormat = GL_RGB; + break; + case GL_COMPRESSED_RGBA_ARB: + if (ctx && !ctx->Extensions.HaveTextureCompression) { + sprintf(message, "glTexImage%dD(internalFormat)", numDimensions); + gl_error(ctx, GL_INVALID_VALUE, message); + return -1; + } + internalFormat = GL_RGBA; + break; + default: + gl_problem(ctx, "unexpected format in get_specific_compressed_tex_format"); + } + return internalFormat; +} + + + +/* * Called from the API. Note that width includes the border. */ void @@ -1358,6 +1420,19 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat, struct gl_texture_unit *texUnit; struct gl_texture_object *texObj; struct gl_texture_image *texImage; + GLint ifmt; + + ifmt = get_specific_compressed_tex_format(ctx, internalFormat, 1); + if (ifmt < 0) { + /* + * The error here is that we were sent a generic compressed + * format, but the extension is not supported. + */ + return; + } + else { + internalFormat = ifmt; + } if (texture_error_check(ctx, target, level, internalFormat, format, type, 1, width, 1, 1, border)) { @@ -1382,7 +1457,7 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat, } /* setup the teximage struct's fields */ - init_texture_image(texImage, width, 1, 1, border, internalFormat); + init_texture_image(ctx, texImage, width, 1, 1, border, internalFormat); /* process the texture image */ if (pixels) { @@ -1439,7 +1514,7 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat, } else { /* if no error, update proxy texture image parameters */ - init_texture_image(ctx->Texture.Proxy1D->Image[level], + init_texture_image(ctx, ctx->Texture.Proxy1D->Image[level], width, 1, 1, border, internalFormat); } } @@ -1466,6 +1541,19 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat, struct gl_texture_unit *texUnit; struct gl_texture_object *texObj; struct gl_texture_image *texImage; + GLint ifmt; + + ifmt = get_specific_compressed_tex_format(ctx, internalFormat, 2); + if (ifmt < 0) { + /* + * The error here is that we were sent a generic compressed + * format, but the extension is not supported. + */ + return; + } + else { + internalFormat = ifmt; + } if (texture_error_check(ctx, target, level, internalFormat, format, type, 2, width, height, 1, border)) { @@ -1491,7 +1579,8 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat, } /* setup the teximage struct's fields */ - init_texture_image(texImage, width, height, 1, border, internalFormat); + init_texture_image(ctx, texImage, width, height, + 1, border, internalFormat); /* process the texture image */ if (pixels) { @@ -1557,7 +1646,8 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat, } else { /* if no error, update proxy texture image parameters */ - init_texture_image(ctx->Texture.Proxy2D->Image[level], + init_texture_image(ctx, + ctx->Texture.Proxy2D->Image[level], width, height, 1, border, internalFormat); } } @@ -1586,6 +1676,20 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat, struct gl_texture_unit *texUnit; struct gl_texture_object *texObj; struct gl_texture_image *texImage; + GLint ifmt; + + ifmt = get_specific_compressed_tex_format(ctx, internalFormat, 3); + if (ifmt < 0) { + /* + * The error here is that we were sent a generic compressed + * format, but the extension is not supported. + */ + return; + } + else { + internalFormat = ifmt; + } + if (texture_error_check(ctx, target, level, internalFormat, format, type, 3, width, height, depth, border)) { return; /* error in texture image was detected */ @@ -1609,7 +1713,7 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat, } /* setup the teximage struct's fields */ - init_texture_image(texImage, width, height, depth, + init_texture_image(ctx, texImage, width, height, depth, border, internalFormat); /* process the texture image */ @@ -1667,7 +1771,7 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat, } else { /* if no error, update proxy texture image parameters */ - init_texture_image(ctx->Texture.Proxy3D->Image[level], + init_texture_image(ctx, ctx->Texture.Proxy3D->Image[level], width, height, depth, border, internalFormat); } } @@ -2053,6 +2157,18 @@ _mesa_TexSubImage2D( GLenum target, GLint level, struct gl_texture_image *texImage; GLboolean success = GL_FALSE; + printf("TexSubImage2D %d x %d @ %d, %d f=0x%x t=0x%x %g %g\n", + width, height, xoffset, yoffset, format, type, + ctx->Pixel.AlphaScale, ctx->Pixel.AlphaBias); + { + int i; + GLubyte *p = (GLubyte *) pixels; + for (i = 0; i < 10; i++) { + printf("%02x ", p[i*4+3]); + } + printf("\n"); + } + if (subtexture_error_check(ctx, 2, target, level, xoffset, yoffset, 0, width, height, 1, format, type)) { return; /* error was detected */ @@ -2511,10 +2627,25 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level, GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glCompressedTexImage1DARB"); + switch (internalFormat) { + case GL_COMPRESSED_ALPHA_ARB: + case GL_COMPRESSED_LUMINANCE_ARB: + case GL_COMPRESSED_LUMINANCE_ALPHA_ARB: + case GL_COMPRESSED_INTENSITY_ARB: + case GL_COMPRESSED_RGB_ARB: + case GL_COMPRESSED_RGBA_ARB: + gl_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage1DARB"); + return; + default: + /* silence compiler warning */ + ; + } + if (target == GL_TEXTURE_1D) { struct gl_texture_unit *texUnit; struct gl_texture_object *texObj; struct gl_texture_image *texImage; + GLsizei computedImageSize; if (texture_error_check(ctx, target, level, internalFormat, GL_NONE, GL_NONE, 1, width, 1, 1, border)) { @@ -2539,23 +2670,32 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level, } /* setup the teximage struct's fields */ - init_texture_image(texImage, width, 1, 1, border, internalFormat); + init_texture_image(ctx, texImage, width, 1, 1, + border, internalFormat); /* process the texture image */ if (data) { GLboolean retain = GL_TRUE; GLboolean success = GL_FALSE; if (ctx->Driver.CompressedTexImage1D) { - success = (*ctx->Driver.CompressedTexImage1D)( ctx, target, level, - data, texObj, texImage, &retain); + success = (*ctx->Driver.CompressedTexImage1D)(ctx, target, level, + imageSize, data, texObj, texImage, &retain); } if (retain || !success) { /* make internal copy of the texture image */ - GLuint imageSize = _mesa_compressed_image_size(internalFormat, - width, 1, 1); - texImage->Data = MALLOC(imageSize); + computedImageSize = _mesa_compressed_image_size(ctx, + internalFormat, + 1, /* num dims */ + width, + 1, /* height */ + 1); /* depth */ + if (computedImageSize != imageSize) { + gl_error(ctx, GL_INVALID_VALUE, "glCompressedTexImage1DARB(imageSize)"); + return; + } + texImage->Data = MALLOC(computedImageSize); if (texImage->Data) { - MEMCPY(texImage->Data, data, imageSize); + MEMCPY(texImage->Data, data, computedImageSize); } } if (!retain && texImage->Data) { @@ -2567,8 +2707,9 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level, make_null_texture(texImage); if (ctx->Driver.CompressedTexImage1D) { GLboolean retain; - (*ctx->Driver.CompressedTexImage1D)( ctx, target, level, - texImage->Data, texObj, texImage, &retain); + (*ctx->Driver.CompressedTexImage1D)(ctx, target, level, 0, + texImage->Data, texObj, + texImage, &retain); } } @@ -2588,7 +2729,7 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level, } else { /* if no error, update proxy texture image parameters */ - init_texture_image(ctx->Texture.Proxy1D->Image[level], + init_texture_image(ctx, ctx->Texture.Proxy1D->Image[level], width, 1, 1, border, internalFormat); } } @@ -2608,6 +2749,20 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level, GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glCompressedTexImage2DARB"); + switch (internalFormat) { + case GL_COMPRESSED_ALPHA_ARB: + case GL_COMPRESSED_LUMINANCE_ARB: + case GL_COMPRESSED_LUMINANCE_ALPHA_ARB: + case GL_COMPRESSED_INTENSITY_ARB: + case GL_COMPRESSED_RGB_ARB: + case GL_COMPRESSED_RGBA_ARB: + gl_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage2DARB"); + return; + default: + /* silence compiler warning */ + ; + } + if (target==GL_TEXTURE_2D || (ctx->Extensions.HaveTextureCubeMap && target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && @@ -2615,6 +2770,7 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level, struct gl_texture_unit *texUnit; struct gl_texture_object *texObj; struct gl_texture_image *texImage; + GLsizei computedImageSize; if (texture_error_check(ctx, target, level, internalFormat, GL_NONE, GL_NONE, 1, width, height, 1, border)) { @@ -2639,23 +2795,37 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level, } /* setup the teximage struct's fields */ - init_texture_image(texImage, width, height, 1, border, internalFormat); + init_texture_image(ctx, texImage, width, height, 1, border, internalFormat); /* process the texture image */ if (data) { GLboolean retain = GL_TRUE; GLboolean success = GL_FALSE; if (ctx->Driver.CompressedTexImage2D) { - success = (*ctx->Driver.CompressedTexImage2D)( ctx, target, level, - data, texObj, texImage, &retain); + success = (*ctx->Driver.CompressedTexImage2D)( ctx, + target, + level, + imageSize, + data, + texObj, + texImage, + &retain); } if (retain || !success) { /* make internal copy of the texture image */ - GLuint imageSize = _mesa_compressed_image_size(internalFormat, - width, height, 1); - texImage->Data = MALLOC(imageSize); + computedImageSize = _mesa_compressed_image_size(ctx, + internalFormat, + 2, /* num dims */ + width, + height, + 1); /* depth */ + if (computedImageSize != imageSize) { + gl_error(ctx, GL_INVALID_VALUE, "glCompressedTexImage2DARB(imageSize)"); + return; + } + texImage->Data = MALLOC(computedImageSize); if (texImage->Data) { - MEMCPY(texImage->Data, data, imageSize); + MEMCPY(texImage->Data, data, computedImageSize); } } if (!retain && texImage->Data) { @@ -2667,8 +2837,9 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level, make_null_texture(texImage); if (ctx->Driver.CompressedTexImage2D) { GLboolean retain; - (*ctx->Driver.CompressedTexImage2D)( ctx, target, level, - texImage->Data, texObj, texImage, &retain); + (*ctx->Driver.CompressedTexImage2D)( ctx, target, level, 0, + texImage->Data, texObj, + texImage, &retain); } } @@ -2688,7 +2859,7 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level, } else { /* if no error, update proxy texture image parameters */ - init_texture_image(ctx->Texture.Proxy2D->Image[level], + init_texture_image(ctx, ctx->Texture.Proxy2D->Image[level], width, 1, 1, border, internalFormat); } } @@ -2708,10 +2879,25 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level, GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glCompressedTexImage3DARB"); + switch (internalFormat) { + case GL_COMPRESSED_ALPHA_ARB: + case GL_COMPRESSED_LUMINANCE_ARB: + case GL_COMPRESSED_LUMINANCE_ALPHA_ARB: + case GL_COMPRESSED_INTENSITY_ARB: + case GL_COMPRESSED_RGB_ARB: + case GL_COMPRESSED_RGBA_ARB: + gl_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage3DARB"); + return; + default: + /* silence compiler warning */ + ; + } + if (target == GL_TEXTURE_3D) { struct gl_texture_unit *texUnit; struct gl_texture_object *texObj; struct gl_texture_image *texImage; + GLsizei computedImageSize; if (texture_error_check(ctx, target, level, internalFormat, GL_NONE, GL_NONE, 1, width, height, depth, border)) { @@ -2736,23 +2922,34 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level, } /* setup the teximage struct's fields */ - init_texture_image(texImage, width, height, depth, border, internalFormat); + init_texture_image(ctx, texImage, width, height, depth, + border, internalFormat); /* process the texture image */ if (data) { GLboolean retain = GL_TRUE; GLboolean success = GL_FALSE; if (ctx->Driver.CompressedTexImage3D) { - success = (*ctx->Driver.CompressedTexImage3D)( ctx, target, level, - data, texObj, texImage, &retain); + success = (*ctx->Driver.CompressedTexImage3D)(ctx, target, level, + imageSize, data, + texObj, texImage, + &retain); } if (retain || !success) { /* make internal copy of the texture image */ - GLuint imageSize = _mesa_compressed_image_size(internalFormat, - width, height, depth); - texImage->Data = MALLOC(imageSize); + computedImageSize = _mesa_compressed_image_size(ctx, + internalFormat, + 3, /* num dims */ + width, + height, + depth); + if (computedImageSize != imageSize) { + gl_error(ctx, GL_INVALID_VALUE, "glCompressedTexImage3DARB(imageSize)"); + return; + } + texImage->Data = MALLOC(computedImageSize); if (texImage->Data) { - MEMCPY(texImage->Data, data, imageSize); + MEMCPY(texImage->Data, data, computedImageSize); } } if (!retain && texImage->Data) { @@ -2764,8 +2961,9 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level, make_null_texture(texImage); if (ctx->Driver.CompressedTexImage3D) { GLboolean retain; - (*ctx->Driver.CompressedTexImage3D)( ctx, target, level, - texImage->Data, texObj, texImage, &retain); + (*ctx->Driver.CompressedTexImage3D)( ctx, target, level, 0, + texImage->Data, texObj, + texImage, &retain); } } @@ -2785,7 +2983,7 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level, } else { /* if no error, update proxy texture image parameters */ - init_texture_image(ctx->Texture.Proxy3D->Image[level], + init_texture_image(ctx, ctx->Texture.Proxy3D->Image[level], width, 1, 1, border, internalFormat); } } @@ -2829,7 +3027,6 @@ _mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset, gl_problem(ctx, "glCompressedTexSubImage1DARB failed!"); return; } - } diff --git a/src/mesa/main/teximage.h b/src/mesa/main/teximage.h index 6bef66ad0f4..0a900339f6d 100644 --- a/src/mesa/main/teximage.h +++ b/src/mesa/main/teximage.h @@ -1,8 +1,8 @@ -/* $Id: teximage.h,v 1.11 2000/06/05 07:28:49 joukj Exp $ */ +/* $Id: teximage.h,v 1.11.4.1 2000/08/29 22:58:57 brianp Exp $ */ /* * Mesa 3-D graphics library - * Version: 3.3 + * Version: 3.4 * * Copyright (C) 1999-2000 Brian Paul All Rights Reserved. * @@ -48,7 +48,9 @@ _mesa_free_texture_image( struct gl_texture_image *teximage ); extern GLuint -_mesa_compressed_image_size(GLenum internalFormat, +_mesa_compressed_image_size(GLcontext *ctx, + GLenum internalFormat, + GLint numDimensions, GLint width, GLint height, GLint depth); |