From 289d47eee5342bd7ec1c25a29d9bdc8d6f9dc4ed Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 29 Aug 2000 23:31:23 +0000 Subject: [PATCH] finished compressed texture support (Bill White) --- src/mesa/main/dd.h | 49 ++++- src/mesa/main/extensions.c | 6 +- src/mesa/main/teximage.c | 425 ++++++++++++++++++++++++++----------- src/mesa/main/teximage.h | 8 +- 4 files changed, 357 insertions(+), 131 deletions(-) diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h index 08bdf4b03cf..fce30099d35 100644 --- a/src/mesa/main/dd.h +++ b/src/mesa/main/dd.h @@ -1,4 +1,4 @@ -/* $Id: dd.h,v 1.27 2000/08/08 16:15:14 brianp Exp $ */ +/* $Id: dd.h,v 1.28 2000/08/29 23:31:23 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..e61b7e3b164 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.33 2000/08/29 23:31:23 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 14f9c60315c..db4b51f7316 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -1,8 +1,8 @@ -/* $Id: teximage.c,v 1.40 2000/08/21 14:22:24 brianp Exp $ */ +/* $Id: teximage.c,v 1.41 2000/08/29 23:31:23 brianp Exp $ */ /* * Mesa 3-D graphics library - * Version: 3.5 + * Version: 3.4 * * Copyright (C) 1999-2000 Brian Paul All Rights Reserved. * @@ -141,21 +141,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: @@ -163,10 +165,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: @@ -176,31 +174,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: @@ -211,23 +190,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: @@ -330,25 +292,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; } @@ -513,13 +462,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; @@ -539,7 +489,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); } @@ -558,13 +508,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; + } } @@ -690,7 +653,7 @@ _mesa_select_tex_image(GLcontext *ctx, const struct gl_texture_unit *texUnit, * NOTE: All texture image parameters should have already been error checked. */ static void -make_texture_image( GLcontext *ctx, GLint dimensions, +make_texture_image( GLcontext *ctx, struct gl_texture_image *texImage, GLenum srcFormat, GLenum srcType, const GLvoid *pixels, const struct gl_pixelstore_attrib *unpacking) @@ -1005,7 +968,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. @@ -1131,7 +1094,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); @@ -1349,6 +1312,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. */ @@ -1364,6 +1425,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)) { @@ -1388,7 +1462,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); if (ctx->ImageTransferState == UPDATE_IMAGE_TRANSFER_STATE) _mesa_update_image_transfer_state(ctx); @@ -1405,7 +1479,7 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat, } if (retain || !success) { /* make internal copy of the texture image */ - make_texture_image(ctx, 1, texImage, format, type, + make_texture_image(ctx, texImage, format, type, pixels, &ctx->Unpack); if (!success && ctx->Driver.TexImage1D) { /* let device driver try to use unpacked image */ @@ -1447,7 +1521,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); } } @@ -1474,6 +1548,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)) { @@ -1499,7 +1586,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); if (ctx->ImageTransferState == UPDATE_IMAGE_TRANSFER_STATE) _mesa_update_image_transfer_state(ctx); @@ -1516,7 +1604,7 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat, } if (retain || !success) { /* make internal copy of the texture image */ - make_texture_image(ctx, 2, texImage, format, type, + make_texture_image(ctx, texImage, format, type, pixels, &ctx->Unpack); if (!success && ctx->Driver.TexImage2D) { /* let device driver try to use unpacked image */ @@ -1567,7 +1655,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); } } @@ -1596,6 +1685,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 */ @@ -1619,7 +1722,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); if (ctx->ImageTransferState == UPDATE_IMAGE_TRANSFER_STATE) @@ -1637,7 +1740,7 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat, } if (retain || !success) { /* make internal copy of the texture image */ - make_texture_image(ctx, 3, texImage, format, type, + make_texture_image(ctx, texImage, format, type, pixels, &ctx->Unpack); if (!success && ctx->Driver.TexImage3D) { /* let device driver try to use unpacked image */ @@ -1679,7 +1782,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); } } @@ -1767,7 +1870,7 @@ _mesa_get_teximage_from_driver( GLcontext *ctx, GLenum target, GLint level, for (img = 0; img < depth; img++) { for (row = 0; row < height; row++) { _mesa_unpack_index_span(ctx, width, dstType, destPtr, - imgType, srcPtr, &_mesa_native_packing, 0); + imgType, srcPtr, &_mesa_native_packing, GL_FALSE); destPtr += destBytesPerRow; srcPtr += srcBytesPerRow; } @@ -1779,7 +1882,7 @@ _mesa_get_teximage_from_driver( GLcontext *ctx, GLenum target, GLint level, for (img = 0; img < depth; img++) { for (row = 0; row < height; row++) { _mesa_unpack_ubyte_color_span(ctx, width, dstFormat, destPtr, - imgFormat, imgType, srcPtr, &_mesa_native_packing, 0); + imgFormat, imgType, srcPtr, &_mesa_native_packing, GL_FALSE); destPtr += destBytesPerRow; srcPtr += srcBytesPerRow; } @@ -2247,6 +2350,7 @@ _mesa_TexSubImage3D( GLenum target, GLint level, else { /* color texture */ GLint img, row; + /* XXX convolution */ for (img = 0; img < depth; img++) { const GLubyte *src = _mesa_image_address(&ctx->Unpack, pixels, width, height, format, type, img, 0, 0); @@ -2554,10 +2658,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)) { @@ -2582,23 +2701,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) { @@ -2610,8 +2738,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); } } @@ -2631,7 +2760,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); } } @@ -2651,6 +2780,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 && @@ -2658,6 +2801,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)) { @@ -2682,23 +2826,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) { @@ -2710,8 +2868,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); } } @@ -2731,7 +2890,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); } } @@ -2751,10 +2910,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)) { @@ -2779,23 +2953,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) { @@ -2807,8 +2992,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); } } @@ -2828,7 +3014,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); } } @@ -2872,7 +3058,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..9789bd55419 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.12 2000/08/29 23:31:23 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); -- 2.30.2