summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBrian Paul <brian.paul@tungstengraphics.com>2000-08-29 22:58:57 +0000
committerBrian Paul <brian.paul@tungstengraphics.com>2000-08-29 22:58:57 +0000
commit846101fe60e3aee0bcc7f474353c50342d6c17e5 (patch)
tree4d21cf840ef661030a3d107446bad922da266859 /src
parent9af68b12220bc3d8ef47248ef23b760785b260cc (diff)
finished compressed texture support (Bill White)
Diffstat (limited to 'src')
-rw-r--r--src/mesa/main/dd.h49
-rw-r--r--src/mesa/main/extensions.c6
-rw-r--r--src/mesa/main/teximage.c423
-rw-r--r--src/mesa/main/teximage.h8
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);