From 89fb06fcc11cbe3f23521312155d6c55d869f526 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 27 Sep 2002 02:45:37 +0000 Subject: new texture compression infrastructure --- src/mesa/Makefile.X11 | 3 +- src/mesa/drivers/dos/dmesa.c | 11 +- src/mesa/drivers/ggi/ggimesa.c | 11 +- src/mesa/drivers/glide/fxdd.c | 8 +- src/mesa/drivers/osmesa/osmesa.c | 13 +- src/mesa/drivers/windows/wmesa.c | 30 +- src/mesa/drivers/x11/xm_dd.c | 11 +- src/mesa/main/Makefile.BeOS-R5 | 1 + src/mesa/main/Makefile.DJ | 5 +- src/mesa/main/Makefile.OSMesa16 | 3 +- src/mesa/main/Makefile.X11 | 3 +- src/mesa/main/Makefile.ugl | 1 + src/mesa/main/Makefile.win | 1 + src/mesa/main/context.c | 3 +- src/mesa/main/dd.h | 51 +-- src/mesa/main/extensions.c | 5 +- src/mesa/main/get.c | 42 ++- src/mesa/main/mtypes.h | 15 +- src/mesa/main/state.c | 5 +- src/mesa/main/texcompress.c | 159 ++++++++ src/mesa/main/texcompress.h | 58 +++ src/mesa/main/texformat.c | 51 +-- src/mesa/main/texformat.h | 7 +- src/mesa/main/texformat_tmp.h | 13 +- src/mesa/main/teximage.c | 784 +++++++++++++++++++++++++-------------- src/mesa/main/texstate.c | 18 +- src/mesa/main/texstore.c | 634 +++++++++++++++++++++++-------- src/mesa/main/texstore.h | 33 +- src/mesa/main/texutil.c | 4 +- src/mesa/swrast/s_texstore.c | 146 +++----- 30 files changed, 1391 insertions(+), 738 deletions(-) create mode 100644 src/mesa/main/texcompress.c create mode 100644 src/mesa/main/texcompress.h (limited to 'src') diff --git a/src/mesa/Makefile.X11 b/src/mesa/Makefile.X11 index 19a90b03b2..378df24eb8 100644 --- a/src/mesa/Makefile.X11 +++ b/src/mesa/Makefile.X11 @@ -1,4 +1,4 @@ -# $Id: Makefile.X11,v 1.68 2002/06/13 04:28:29 brianp Exp $ +# $Id: Makefile.X11,v 1.69 2002/09/27 02:45:37 brianp Exp $ # Mesa 3-D graphics library # Version: 4.1 @@ -63,6 +63,7 @@ CORE_SOURCES = \ rastpos.c \ state.c \ stencil.c \ + texcompress.c \ texformat.c \ teximage.c \ texobj.c \ diff --git a/src/mesa/drivers/dos/dmesa.c b/src/mesa/drivers/dos/dmesa.c index 148d7402e2..1d430354f6 100644 --- a/src/mesa/drivers/dos/dmesa.c +++ b/src/mesa/drivers/dos/dmesa.c @@ -649,16 +649,19 @@ void dmesa_init_pointers (GLcontext *ctx) ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d; ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage; + ctx->Driver.CompressedTexImage1D = _mesa_store_compressed_teximage1d; + ctx->Driver.CompressedTexImage2D = _mesa_store_compressed_teximage2d; + ctx->Driver.CompressedTexImage3D = _mesa_store_compressed_teximage3d; + ctx->Driver.CompressedTexSubImage1D = _mesa_store_compressed_texsubimage1d; + ctx->Driver.CompressedTexSubImage2D = _mesa_store_compressed_texsubimage2d; + ctx->Driver.CompressedTexSubImage3D = _mesa_store_compressed_texsubimage3d; + ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d; ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d; ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d; ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d; ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d; - ctx->Driver.BaseCompressedTexFormat = _mesa_base_compressed_texformat; - ctx->Driver.CompressedTextureSize = _mesa_compressed_texture_size; - ctx->Driver.GetCompressedTexImage = _mesa_get_compressed_teximage; - /* Swrast hooks for imaging extensions: */ ctx->Driver.CopyColorTable = _swrast_CopyColorTable; diff --git a/src/mesa/drivers/ggi/ggimesa.c b/src/mesa/drivers/ggi/ggimesa.c index 86de850e91..6fff79648c 100644 --- a/src/mesa/drivers/ggi/ggimesa.c +++ b/src/mesa/drivers/ggi/ggimesa.c @@ -241,16 +241,19 @@ static void gl_ggiSetupPointers(GLcontext *ctx) ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d; ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage; + ctx->Driver.CompressedTexImage1D = _mesa_store_compressed_teximage1d; + ctx->Driver.CompressedTexImage2D = _mesa_store_compressed_teximage2d; + ctx->Driver.CompressedTexImage3D = _mesa_store_compressed_teximage3d; + ctx->Driver.CompressedTexSubImage1D = _mesa_store_compressed_texsubimage1d; + ctx->Driver.CompressedTexSubImage2D = _mesa_store_compressed_texsubimage2d; + ctx->Driver.CompressedTexSubImage3D = _mesa_store_compressed_texsubimage3d; + ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d; ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d; ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d; ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d; ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d; - ctx->Driver.BaseCompressedTexFormat = _mesa_base_compressed_texformat; - ctx->Driver.CompressedTextureSize = _mesa_compressed_texture_size; - ctx->Driver.GetCompressedTexImage = _mesa_get_compressed_teximage; - /* Imaging extensions */ ctx->Driver.CopyColorTable = _swrast_CopyColorTable; ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable; diff --git a/src/mesa/drivers/glide/fxdd.c b/src/mesa/drivers/glide/fxdd.c index 8f81033b15..d4ef05be14 100644 --- a/src/mesa/drivers/glide/fxdd.c +++ b/src/mesa/drivers/glide/fxdd.c @@ -1,4 +1,4 @@ -/* $Id: fxdd.c,v 1.90 2002/08/21 02:59:31 brianp Exp $ */ +/* $Id: fxdd.c,v 1.91 2002/09/27 02:45:38 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -1014,6 +1014,12 @@ fxSetupDDPointers(GLcontext * ctx) ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d; ctx->Driver.TexSubImage2D = fxDDTexSubImage2D; ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d; + ctx->Driver.CompressedTexImage1D = _mesa_store_compressed_teximage1d; + ctx->Driver.CompressedTexImage2D = _mesa_store_compressed_teximage2d; + ctx->Driver.CompressedTexImage3D = _mesa_store_compressed_teximage3d; + ctx->Driver.CompressedTexSubImage1D = _mesa_store_compressed_texsubimage1d; + ctx->Driver.CompressedTexSubImage2D = _mesa_store_compressed_texsubimage2d; + ctx->Driver.CompressedTexSubImage3D = _mesa_store_compressed_texsubimage3d; ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d; ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d; ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d; diff --git a/src/mesa/drivers/osmesa/osmesa.c b/src/mesa/drivers/osmesa/osmesa.c index 51d6508283..ae497dd173 100644 --- a/src/mesa/drivers/osmesa/osmesa.c +++ b/src/mesa/drivers/osmesa/osmesa.c @@ -1,4 +1,4 @@ -/* $Id: osmesa.c,v 1.87 2002/08/07 00:45:07 brianp Exp $ */ +/* $Id: osmesa.c,v 1.88 2002/09/27 02:45:39 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -2092,6 +2092,13 @@ static void osmesa_update_state( GLcontext *ctx, GLuint new_state ) ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d; ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage; + ctx->Driver.CompressedTexImage1D = _mesa_store_compressed_teximage1d; + ctx->Driver.CompressedTexImage2D = _mesa_store_compressed_teximage2d; + ctx->Driver.CompressedTexImage3D = _mesa_store_compressed_teximage3d; + ctx->Driver.CompressedTexSubImage1D = _mesa_store_compressed_texsubimage1d; + ctx->Driver.CompressedTexSubImage2D = _mesa_store_compressed_texsubimage2d; + ctx->Driver.CompressedTexSubImage3D = _mesa_store_compressed_texsubimage3d; + ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d; ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d; ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d; @@ -2102,10 +2109,6 @@ static void osmesa_update_state( GLcontext *ctx, GLuint new_state ) ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D; ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D; - ctx->Driver.BaseCompressedTexFormat = _mesa_base_compressed_texformat; - ctx->Driver.CompressedTextureSize = _mesa_compressed_texture_size; - ctx->Driver.GetCompressedTexImage = _mesa_get_compressed_teximage; - swdd->SetBuffer = set_buffer; /* RGB(A) span/pixel functions */ diff --git a/src/mesa/drivers/windows/wmesa.c b/src/mesa/drivers/windows/wmesa.c index 77c800f2b5..bd8d8c69d6 100644 --- a/src/mesa/drivers/windows/wmesa.c +++ b/src/mesa/drivers/windows/wmesa.c @@ -1,4 +1,4 @@ -/* $Id: wmesa.c,v 1.35 2002/09/12 17:05:55 kschultz Exp $ */ +/* $Id: wmesa.c,v 1.36 2002/09/27 02:45:39 brianp Exp $ */ /* * Windows (Win32) device driver for Mesa 3.4 @@ -1045,6 +1045,13 @@ static void SetFunctionPointers(GLcontext *ctx) ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d; ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage; + ctx->Driver.CompressedTexImage1D = _mesa_store_compressed_teximage1d; + ctx->Driver.CompressedTexImage2D = _mesa_store_compressed_teximage2d; + ctx->Driver.CompressedTexImage3D = _mesa_store_compressed_teximage3d; + ctx->Driver.CompressedTexSubImage1D = _mesa_store_compressed_texsubimage1d; + ctx->Driver.CompressedTexSubImage2D = _mesa_store_compressed_texsubimage2d; + ctx->Driver.CompressedTexSubImage3D = _mesa_store_compressed_texsubimage3d; + ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d; ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d; ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d; @@ -1054,15 +1061,9 @@ static void SetFunctionPointers(GLcontext *ctx) ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable; ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D; ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D; - - ctx->Driver.BaseCompressedTexFormat = _mesa_base_compressed_texformat; - ctx->Driver.CompressedTextureSize = _mesa_compressed_texture_size; - ctx->Driver.GetCompressedTexImage = _mesa_get_compressed_teximage; - - + swdd->SetBuffer = set_buffer; - - + /* Pixel/span writing functions: */ swdd->WriteRGBASpan = write_rgba_span; swdd->WriteRGBSpan = write_rgb_span; @@ -1123,6 +1124,13 @@ static void wmesa_update_state( GLcontext *ctx, GLuint new_state ) ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d; ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage; + ctx->Driver.CompressedTexImage1D = _mesa_store_compressed_teximage1d; + ctx->Driver.CompressedTexImage2D = _mesa_store_compressed_teximage2d; + ctx->Driver.CompressedTexImage3D = _mesa_store_compressed_teximage3d; + ctx->Driver.CompressedTexSubImage1D = _mesa_store_compressed_texsubimage1d; + ctx->Driver.CompressedTexSubImage2D = _mesa_store_compressed_texsubimage2d; + ctx->Driver.CompressedTexSubImage3D = _mesa_store_compressed_texsubimage3d; + ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d; ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d; ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d; @@ -1133,10 +1141,6 @@ static void wmesa_update_state( GLcontext *ctx, GLuint new_state ) ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D; ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D; - ctx->Driver.BaseCompressedTexFormat = _mesa_base_compressed_texformat; - ctx->Driver.CompressedTextureSize = _mesa_compressed_texture_size; - ctx->Driver.GetCompressedTexImage = _mesa_get_compressed_teximage; - swdd->SetBuffer = set_buffer; /* Pixel/span writing functions: */ diff --git a/src/mesa/drivers/x11/xm_dd.c b/src/mesa/drivers/x11/xm_dd.c index 81ca9e0044..3d4792737c 100644 --- a/src/mesa/drivers/x11/xm_dd.c +++ b/src/mesa/drivers/x11/xm_dd.c @@ -1,4 +1,4 @@ -/* $Id: xm_dd.c,v 1.35 2002/09/23 17:21:53 brianp Exp $ */ +/* $Id: xm_dd.c,v 1.36 2002/09/27 02:45:39 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -953,9 +953,12 @@ void xmesa_init_pointers( GLcontext *ctx ) ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d; ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d; - ctx->Driver.BaseCompressedTexFormat = _mesa_base_compressed_texformat; - ctx->Driver.CompressedTextureSize = _mesa_compressed_texture_size; - ctx->Driver.GetCompressedTexImage = _mesa_get_compressed_teximage; + ctx->Driver.CompressedTexImage1D = _mesa_store_compressed_teximage1d; + ctx->Driver.CompressedTexImage2D = _mesa_store_compressed_teximage2d; + ctx->Driver.CompressedTexImage3D = _mesa_store_compressed_teximage3d; + ctx->Driver.CompressedTexSubImage1D = _mesa_store_compressed_texsubimage1d; + ctx->Driver.CompressedTexSubImage2D = _mesa_store_compressed_texsubimage2d; + ctx->Driver.CompressedTexSubImage3D = _mesa_store_compressed_texsubimage3d; /* Swrast hooks for imaging extensions: */ diff --git a/src/mesa/main/Makefile.BeOS-R5 b/src/mesa/main/Makefile.BeOS-R5 index 65303863a2..00deb0e007 100644 --- a/src/mesa/main/Makefile.BeOS-R5 +++ b/src/mesa/main/Makefile.BeOS-R5 @@ -98,6 +98,7 @@ MESA_CORE_SRCS = \ rastpos.c \ state.c \ stencil.c \ + texcompress.c \ texformat.c \ teximage.c \ texobj.c \ diff --git a/src/mesa/main/Makefile.DJ b/src/mesa/main/Makefile.DJ index 57187420f5..92a9f09044 100644 --- a/src/mesa/main/Makefile.DJ +++ b/src/mesa/main/Makefile.DJ @@ -1,7 +1,7 @@ # Mesa 3-D graphics library -# Version: 4.0 +# Version: 4.1 # -# Copyright (C) 1999 Brian Paul All Rights Reserved. +# Copyright (C) 1999-2002 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"), @@ -129,6 +129,7 @@ CORE_SOURCES = \ rastpos.c \ state.c \ stencil.c \ + texcompress.c \ texformat.c \ teximage.c \ texobj.c \ diff --git a/src/mesa/main/Makefile.OSMesa16 b/src/mesa/main/Makefile.OSMesa16 index 4613f1a270..1f3b09206a 100644 --- a/src/mesa/main/Makefile.OSMesa16 +++ b/src/mesa/main/Makefile.OSMesa16 @@ -1,4 +1,4 @@ -# $Id: Makefile.OSMesa16,v 1.7 2002/06/13 04:28:29 brianp Exp $ +# $Id: Makefile.OSMesa16,v 1.8 2002/09/27 02:45:37 brianp Exp $ # Mesa 3-D graphics library # Version: 4.1 @@ -63,6 +63,7 @@ CORE_SOURCES = \ rastpos.c \ state.c \ stencil.c \ + texcompress.c \ texformat.c \ teximage.c \ texobj.c \ diff --git a/src/mesa/main/Makefile.X11 b/src/mesa/main/Makefile.X11 index 19a90b03b2..378df24eb8 100644 --- a/src/mesa/main/Makefile.X11 +++ b/src/mesa/main/Makefile.X11 @@ -1,4 +1,4 @@ -# $Id: Makefile.X11,v 1.68 2002/06/13 04:28:29 brianp Exp $ +# $Id: Makefile.X11,v 1.69 2002/09/27 02:45:37 brianp Exp $ # Mesa 3-D graphics library # Version: 4.1 @@ -63,6 +63,7 @@ CORE_SOURCES = \ rastpos.c \ state.c \ stencil.c \ + texcompress.c \ texformat.c \ teximage.c \ texobj.c \ diff --git a/src/mesa/main/Makefile.ugl b/src/mesa/main/Makefile.ugl index f8f00fa411..ae9ee7e541 100644 --- a/src/mesa/main/Makefile.ugl +++ b/src/mesa/main/Makefile.ugl @@ -93,6 +93,7 @@ GL_SOURCES = \ rastpos.c \ state.c \ stencil.c \ + texcompress.c \ texformat.c \ teximage.c \ texobj.c \ diff --git a/src/mesa/main/Makefile.win b/src/mesa/main/Makefile.win index 77814140a7..2b3f50e192 100644 --- a/src/mesa/main/Makefile.win +++ b/src/mesa/main/Makefile.win @@ -80,6 +80,7 @@ CORE_SRCS = \ rastpos.c \ state.c \ stencil.c \ + texcompress.c \ teximage.c \ texformat.c \ texobj.c \ diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 4a0b4ed23d..986dbc5aca 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -1,4 +1,4 @@ -/* $Id: context.c,v 1.176 2002/09/06 02:56:08 brianp Exp $ */ +/* $Id: context.c,v 1.177 2002/09/27 02:45:37 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -930,7 +930,6 @@ init_attrib_groups( GLcontext *ctx ) ctx->Const.MaxColorTableSize = MAX_COLOR_TABLE_SIZE; ctx->Const.MaxConvolutionWidth = MAX_CONVOLUTION_WIDTH; ctx->Const.MaxConvolutionHeight = MAX_CONVOLUTION_HEIGHT; - ctx->Const.NumCompressedTextureFormats = 0; ctx->Const.MaxClipPlanes = MAX_CLIP_PLANES; ctx->Const.MaxLights = MAX_LIGHTS; diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h index fcf0ceeb0d..8f40846975 100644 --- a/src/mesa/main/dd.h +++ b/src/mesa/main/dd.h @@ -1,4 +1,4 @@ -/* $Id: dd.h,v 1.71 2002/09/06 02:56:08 brianp Exp $ */ +/* $Id: dd.h,v 1.72 2002/09/27 02:45:37 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -341,55 +341,6 @@ struct dd_function_table { * should do the job. */ - void (*GetCompressedTexImage)( GLcontext *ctx, GLenum target, - GLint level, void *image, - const struct gl_texture_object *texObj, - struct gl_texture_image *texImage ); - /* Called by glGetCompressedTexImageARB. - * , , are specified by user. - * is the source texture object. - * is the source texture image. - */ - - 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. - * Example: if internalFormat==GL_COMPRESSED_RGB_FXT1_3DFX, return GL_RGB. - */ - - GLint (*CompressedTextureSize)(GLcontext *ctx, - const struct gl_texture_image *texImage); - -#if 000 - /* ... Note the - * return value differences between this function and - * SpecificCompressedTexFormat below. - */ - - GLint (*SpecificCompressedTexFormat)(GLcontext *ctx, - GLint internalFormat, - GLint numDimensions, - GLint *levelp, - GLsizei *widthp, - GLsizei *heightp, - GLsizei *depthp, - GLint *borderp, - GLenum *formatp, - GLenum *typep); - /* 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. - */ - -#endif - /*** *** Texture object functions: ***/ diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c index 0560397431..0129c8601a 100644 --- a/src/mesa/main/extensions.c +++ b/src/mesa/main/extensions.c @@ -1,4 +1,4 @@ -/* $Id: extensions.c,v 1.80 2002/09/21 17:34:56 brianp Exp $ */ +/* $Id: extensions.c,v 1.81 2002/09/27 02:45:37 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -132,9 +132,8 @@ static struct { { OFF, "GL_SGIX_pixel_texture", F(SGIX_pixel_texture) }, { OFF, "GL_SGIX_shadow", F(SGIX_shadow) }, { OFF, "GL_SGIX_shadow_ambient", F(SGIX_shadow_ambient) }, - { OFF, "GL_3DFX_texture_compression_FXT1", F(_3DFX_texture_compression_FXT1) }, + { OFF, "GL_3DFX_texture_compression_FXT1", F(TDFX_texture_compression_FXT1) }, { OFF, "GL_APPLE_client_storage", F(APPLE_client_storage) } - }; diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c index 4ccec6b9d8..4eee2c9fa7 100644 --- a/src/mesa/main/get.c +++ b/src/mesa/main/get.c @@ -1,4 +1,4 @@ -/* $Id: get.c,v 1.91 2002/09/21 17:34:56 brianp Exp $ */ +/* $Id: get.c,v 1.92 2002/09/27 02:45:37 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -38,7 +38,7 @@ #include "macros.h" #include "mmath.h" #include "mtypes.h" - +#include "texcompress.h" #include "math/m_matrix.h" #endif @@ -1034,14 +1034,16 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params ) break; case GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB: CHECK_EXTENSION_B(ARB_texture_compression, pname); - *params = INT_TO_BOOL(ctx->Const.NumCompressedTextureFormats); + *params = INT_TO_BOOL(_mesa_get_compressed_formats(ctx, NULL)); break; case GL_COMPRESSED_TEXTURE_FORMATS_ARB: CHECK_EXTENSION_B(ARB_texture_compression, pname); { - GLuint i; - for (i = 0; i < ctx->Const.NumCompressedTextureFormats; i++) - params[i] = INT_TO_BOOL(ctx->Const.CompressedTextureFormats[i]); + GLint formats[100]; + GLuint i, n; + n = _mesa_get_compressed_formats(ctx, formats); + for (i = 0; i < n; i++) + params[i] = INT_TO_BOOL(formats[i]); } break; @@ -2393,14 +2395,16 @@ _mesa_GetDoublev( GLenum pname, GLdouble *params ) break; case GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB: CHECK_EXTENSION_D(ARB_texture_compression, pname); - *params = (GLdouble) ctx->Const.NumCompressedTextureFormats; + *params = (GLdouble) _mesa_get_compressed_formats(ctx, NULL); break; case GL_COMPRESSED_TEXTURE_FORMATS_ARB: CHECK_EXTENSION_D(ARB_texture_compression, pname); { - GLuint i; - for (i = 0; i < ctx->Const.NumCompressedTextureFormats; i++) - params[i] = (GLdouble) ctx->Const.CompressedTextureFormats[i]; + GLint formats[100]; + GLuint i, n; + n = _mesa_get_compressed_formats(ctx, formats); + for (i = 0; i < n; i++) + params[i] = (GLdouble) formats[i]; } break; @@ -3754,14 +3758,16 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params ) break; case GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB: CHECK_EXTENSION_F(ARB_texture_compression, pname); - *params = (GLfloat) ctx->Const.NumCompressedTextureFormats; + *params = (GLfloat) _mesa_get_compressed_formats(ctx, NULL); break; case GL_COMPRESSED_TEXTURE_FORMATS_ARB: CHECK_EXTENSION_F(ARB_texture_compression, pname); { - GLuint i; - for (i = 0; i < ctx->Const.NumCompressedTextureFormats; i++) - params[i] = (GLfloat) ctx->Const.CompressedTextureFormats[i]; + GLint formats[100]; + GLuint i, n; + n = _mesa_get_compressed_formats(ctx, formats); + for (i = 0; i < n; i++) + params[i] = (GLfloat) formats[i]; } break; @@ -5088,15 +5094,11 @@ _mesa_GetIntegerv( GLenum pname, GLint *params ) break; case GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB: CHECK_EXTENSION_I(ARB_texture_compression, pname); - *params = (GLint) ctx->Const.NumCompressedTextureFormats; + *params = (GLint) _mesa_get_compressed_formats(ctx, NULL); break; case GL_COMPRESSED_TEXTURE_FORMATS_ARB: CHECK_EXTENSION_I(ARB_texture_compression, pname); - { - GLuint i; - for (i = 0; i < ctx->Const.NumCompressedTextureFormats; i++) - params[i] = (GLint) ctx->Const.CompressedTextureFormats[i]; - } + (void) _mesa_get_compressed_formats(ctx, params); break; /* GL_EXT_compiled_vertex_array */ diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index d3c6c6196d..3509be7987 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1,4 +1,4 @@ -/* $Id: mtypes.h,v 1.88 2002/09/23 16:37:13 brianp Exp $ */ +/* $Id: mtypes.h,v 1.89 2002/09/27 02:45:37 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -809,18 +809,16 @@ struct gl_texture_format { * GL_LUMINANCE_ALPHA, GL_RGB, GL_RGBA, * GL_COLOR_INDEX or GL_DEPTH_COMPONENT. */ - GLenum Type; /* Internal type as GL enum value - UNUSED?? */ - GLubyte RedBits; /* Bits per texel component */ - GLubyte GreenBits; - GLubyte BlueBits; + GLubyte GreenBits; /* These are just rough approximations for */ + GLubyte BlueBits; /* compressed texture formats. */ GLubyte AlphaBits; GLubyte LuminanceBits; GLubyte IntensityBits; GLubyte IndexBits; GLubyte DepthBits; - GLint TexelBytes; + GLint TexelBytes; /* Bytes per texel (0 for compressed formats */ FetchTexelFunc FetchTexel1D; /* Texel fetch function pointers */ FetchTexelFunc FetchTexel2D; @@ -833,6 +831,7 @@ struct gl_texture_image { GLenum Format; /* GL_ALPHA, GL_LUMINANCE, GL_LUMINANCE_ALPHA, * GL_INTENSITY, GL_RGB, GL_RGBA, * GL_COLOR_INDEX or GL_DEPTH_COMPONENT only. + * Used for choosing TexEnv arithmetic. */ GLint IntFormat; /* Internal format as given by the user */ GLuint Border; /* 0 or 1 */ @@ -1373,8 +1372,6 @@ struct gl_constants { GLuint MaxColorTableSize; GLuint MaxConvolutionWidth; GLuint MaxConvolutionHeight; - GLuint NumCompressedTextureFormats; /* GL_ARB_texture_compression */ - GLenum CompressedTextureFormats[MAX_COMPRESSED_TEXTURE_FORMATS]; GLuint MaxClipPlanes; GLuint MaxLights; }; @@ -1455,7 +1452,7 @@ struct gl_extensions { GLboolean SGIX_pixel_texture; GLboolean SGIX_shadow; GLboolean SGIX_shadow_ambient; /* or GL_ARB_shadow_ambient */ - GLboolean _3DFX_texture_compression_FXT1; + GLboolean TDFX_texture_compression_FXT1; GLboolean APPLE_client_storage; }; diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index d3d0baa934..24e127a93f 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -1,4 +1,4 @@ -/* $Id: state.c,v 1.91 2002/09/06 03:20:21 brianp Exp $ */ +/* $Id: state.c,v 1.92 2002/09/27 02:45:38 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -1041,9 +1041,6 @@ void _mesa_update_state( GLcontext *ctx ) ASSERT(ctx->Driver.CopyTexSubImage2D); ASSERT(ctx->Driver.CopyTexSubImage3D); if (ctx->Extensions.ARB_texture_compression) { - ASSERT(ctx->Driver.BaseCompressedTexFormat); - ASSERT(ctx->Driver.CompressedTextureSize); - ASSERT(ctx->Driver.GetCompressedTexImage); #if 0 /* HW drivers need these, but not SW rasterizers */ ASSERT(ctx->Driver.CompressedTexImage1D); ASSERT(ctx->Driver.CompressedTexImage2D); diff --git a/src/mesa/main/texcompress.c b/src/mesa/main/texcompress.c new file mode 100644 index 0000000000..0ba9aa9a4c --- /dev/null +++ b/src/mesa/main/texcompress.c @@ -0,0 +1,159 @@ +/* $Id: texcompress.c,v 1.1 2002/09/27 02:45:38 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 4.1 + * + * Copyright (C) 1999-2002 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"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +#include "glheader.h" +#include "context.h" +#include "image.h" +#include "mem.h" +#include "texcompress.h" +#include "texformat.h" + + +/** + * Get the list of supported internal compression formats. + * \param formats - the results list (may be NULL) + * \return number of formats. + */ +GLuint +_mesa_get_compressed_formats( GLcontext *ctx, GLint *formats ) +{ + GLuint n = 0; + if (ctx->Extensions.ARB_texture_compression) { + if (ctx->Extensions.TDFX_texture_compression_FXT1) { + if (formats) { + formats[n++] = GL_COMPRESSED_RGB_FXT1_3DFX; + formats[n++] = GL_COMPRESSED_RGBA_FXT1_3DFX; + } + else { + n += 4; + } + } + } + return n; +} + + + +/** + * Return bytes of storage needed for the given texture size and compressed + * format. + * \param width, height, depth - texture size in texels + * \param texFormat - one of the compressed format enums + * \return size in bytes, or zero if bad texFormat + */ +GLuint +_mesa_compressed_texture_size( GLcontext *ctx, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format ) +{ + GLuint size; + + switch (format) { + case GL_COMPRESSED_RGB_FXT1_3DFX: + case GL_COMPRESSED_RGBA_FXT1_3DFX: + /* round up to multiple of 4 */ + size = ((width + 7) / 8) * ((height + 3) / 4) * 16; + return size; + default: + _mesa_problem(ctx, "bad texformat in compressed_texture_size"); + return 0; + } +} + + +/* + * Compute the bytes per row in a compressed texture image. + */ +GLint +_mesa_compressed_row_stride(GLenum format, GLsizei width) +{ + GLint bytesPerTile, stride; + + switch (format) { + default: + return 0; + } + + stride = ((width + 3) / 4) * bytesPerTile; + return stride; +} + + +/* + * Return the address of the pixel at (col, row, img) in a + * compressed texture image. + * \param col, row, img - image position (3D) + * \param format - compressed image format + * \param width - image width + * \param image - the image address + * \return address of pixel at (row, col) + */ +GLubyte * +_mesa_compressed_image_address(GLint col, GLint row, GLint img, + GLenum format, + GLsizei width, const GLubyte *image) +{ + GLint bytesPerTile, stride; + GLubyte *addr; + + ASSERT((row & 3) == 0); + ASSERT((col & 3) == 0); + (void) img; + + switch (format) { + default: + return 0; + } + + stride = ((width + 3) / 4) * bytesPerTile; + + addr = (GLubyte *) image + (row / 4) * stride + (col / 4) * bytesPerTile; + return addr; +} + + + +/* + * \param srcRowStride - source stride, in pixels + */ +void +_mesa_compress_teximage( GLcontext *ctx, GLsizei width, GLsizei height, + GLenum srcFormat, const GLchan *source, GLint srcRowStride, + GLenum dstFormat, GLubyte *dest, GLint dstRowStride ) +{ + GLuint len = 0; + + switch (dstFormat) { + default: + _mesa_problem(ctx, "Bad dstFormat in _mesa_compress_teximage()"); + return; + } + + /* sanity check */ + ASSERT(len == _mesa_compressed_texture_size(ctx, width, height, + 1, dstFormat)); +} diff --git a/src/mesa/main/texcompress.h b/src/mesa/main/texcompress.h new file mode 100644 index 0000000000..53571673f0 --- /dev/null +++ b/src/mesa/main/texcompress.h @@ -0,0 +1,58 @@ +/* $Id: texcompress.h,v 1.1 2002/09/27 02:45:38 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 4.1 + * + * Copyright (C) 1999-2002 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"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef TEXCOMPRESS_H +#define TEXCOMPRESS_H + +#include "mtypes.h" + + +extern GLuint +_mesa_get_compressed_formats( GLcontext *ctx, GLint *formats ); + +extern GLuint +_mesa_compressed_texture_size( GLcontext *ctx, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format ); + +extern GLint +_mesa_compressed_row_stride(GLenum format, GLsizei width); + + +extern GLubyte * +_mesa_compressed_image_address(GLint col, GLint row, GLint img, + GLenum format, + GLsizei width, const GLubyte *image); + + +extern void +_mesa_compress_teximage( GLcontext *ctx, GLsizei width, GLsizei height, + GLenum srcFormat, + const GLchan *source, GLint srcRowStride, + GLenum dstformat, GLubyte *dest, GLint dstRowStride ); + + +#endif /* TEXCOMPRESS_H */ diff --git a/src/mesa/main/texformat.c b/src/mesa/main/texformat.c index 2c95b83859..1941c7a7b3 100644 --- a/src/mesa/main/texformat.c +++ b/src/mesa/main/texformat.c @@ -1,4 +1,4 @@ -/* $Id: texformat.c,v 1.15 2002/09/21 16:51:25 brianp Exp $ */ +/* $Id: texformat.c,v 1.16 2002/09/27 02:45:38 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -74,7 +74,6 @@ static void fetch_null_texel( const struct gl_texture_image *texImage, const struct gl_texture_format _mesa_texformat_rgba = { MESA_FORMAT_RGBA, /* MesaFormat */ GL_RGBA, /* BaseFormat */ - CHAN_TYPE, /* Type */ CHAN_BITS, /* RedBits */ CHAN_BITS, /* GreenBits */ CHAN_BITS, /* BlueBits */ @@ -92,7 +91,6 @@ const struct gl_texture_format _mesa_texformat_rgba = { const struct gl_texture_format _mesa_texformat_rgb = { MESA_FORMAT_RGB, /* MesaFormat */ GL_RGB, /* BaseFormat */ - CHAN_TYPE, /* Type */ CHAN_BITS, /* RedBits */ CHAN_BITS, /* GreenBits */ CHAN_BITS, /* BlueBits */ @@ -110,7 +108,6 @@ const struct gl_texture_format _mesa_texformat_rgb = { const struct gl_texture_format _mesa_texformat_alpha = { MESA_FORMAT_ALPHA, /* MesaFormat */ GL_ALPHA, /* BaseFormat */ - CHAN_TYPE, /* Type */ 0, /* RedBits */ 0, /* GreenBits */ 0, /* BlueBits */ @@ -128,7 +125,6 @@ const struct gl_texture_format _mesa_texformat_alpha = { const struct gl_texture_format _mesa_texformat_luminance = { MESA_FORMAT_LUMINANCE, /* MesaFormat */ GL_LUMINANCE, /* BaseFormat */ - CHAN_TYPE, /* Type */ 0, /* RedBits */ 0, /* GreenBits */ 0, /* BlueBits */ @@ -146,7 +142,6 @@ const struct gl_texture_format _mesa_texformat_luminance = { const struct gl_texture_format _mesa_texformat_luminance_alpha = { MESA_FORMAT_LUMINANCE_ALPHA, /* MesaFormat */ GL_LUMINANCE_ALPHA, /* BaseFormat */ - CHAN_TYPE, /* Type */ 0, /* RedBits */ 0, /* GreenBits */ 0, /* BlueBits */ @@ -164,7 +159,6 @@ const struct gl_texture_format _mesa_texformat_luminance_alpha = { const struct gl_texture_format _mesa_texformat_intensity = { MESA_FORMAT_INTENSITY, /* MesaFormat */ GL_INTENSITY, /* BaseFormat */ - CHAN_TYPE, /* Type */ 0, /* RedBits */ 0, /* GreenBits */ 0, /* BlueBits */ @@ -182,7 +176,6 @@ const struct gl_texture_format _mesa_texformat_intensity = { const struct gl_texture_format _mesa_texformat_color_index = { MESA_FORMAT_COLOR_INDEX, /* MesaFormat */ GL_COLOR_INDEX, /* BaseFormat */ - CHAN_TYPE, /* Type */ 0, /* RedBits */ 0, /* GreenBits */ 0, /* BlueBits */ @@ -200,7 +193,6 @@ const struct gl_texture_format _mesa_texformat_color_index = { const struct gl_texture_format _mesa_texformat_depth_component = { MESA_FORMAT_DEPTH_COMPONENT, /* MesaFormat */ GL_DEPTH_COMPONENT, /* BaseFormat */ - GL_FLOAT, /* Type */ 0, /* RedBits */ 0, /* GreenBits */ 0, /* BlueBits */ @@ -223,7 +215,6 @@ const struct gl_texture_format _mesa_texformat_depth_component = { const struct gl_texture_format _mesa_texformat_rgba8888 = { MESA_FORMAT_RGBA8888, /* MesaFormat */ GL_RGBA, /* BaseFormat */ - GL_UNSIGNED_INT_8_8_8_8, /* Type */ 8, /* RedBits */ 8, /* GreenBits */ 8, /* BlueBits */ @@ -241,7 +232,6 @@ const struct gl_texture_format _mesa_texformat_rgba8888 = { const struct gl_texture_format _mesa_texformat_argb8888 = { MESA_FORMAT_ARGB8888, /* MesaFormat */ GL_RGBA, /* BaseFormat */ - GL_UNSIGNED_INT_8_8_8_8_REV, /* Type */ 8, /* RedBits */ 8, /* GreenBits */ 8, /* BlueBits */ @@ -259,7 +249,6 @@ const struct gl_texture_format _mesa_texformat_argb8888 = { const struct gl_texture_format _mesa_texformat_rgb888 = { MESA_FORMAT_RGB888, /* MesaFormat */ GL_RGB, /* BaseFormat */ - GL_UNSIGNED_BYTE, /* Type */ 8, /* RedBits */ 8, /* GreenBits */ 8, /* BlueBits */ @@ -277,7 +266,6 @@ const struct gl_texture_format _mesa_texformat_rgb888 = { const struct gl_texture_format _mesa_texformat_rgb565 = { MESA_FORMAT_RGB565, /* MesaFormat */ GL_RGB, /* BaseFormat */ - GL_UNSIGNED_SHORT_5_6_5, /* Type */ 5, /* RedBits */ 6, /* GreenBits */ 5, /* BlueBits */ @@ -295,7 +283,6 @@ const struct gl_texture_format _mesa_texformat_rgb565 = { const struct gl_texture_format _mesa_texformat_argb4444 = { MESA_FORMAT_ARGB4444, /* MesaFormat */ GL_RGBA, /* BaseFormat */ - GL_UNSIGNED_SHORT_4_4_4_4_REV, /* Type */ 4, /* RedBits */ 4, /* GreenBits */ 4, /* BlueBits */ @@ -313,7 +300,6 @@ const struct gl_texture_format _mesa_texformat_argb4444 = { const struct gl_texture_format _mesa_texformat_argb1555 = { MESA_FORMAT_ARGB1555, /* MesaFormat */ GL_RGBA, /* BaseFormat */ - GL_UNSIGNED_SHORT_1_5_5_5_REV, /* Type */ 5, /* RedBits */ 5, /* GreenBits */ 5, /* BlueBits */ @@ -331,7 +317,6 @@ const struct gl_texture_format _mesa_texformat_argb1555 = { const struct gl_texture_format _mesa_texformat_al88 = { MESA_FORMAT_AL88, /* MesaFormat */ GL_LUMINANCE_ALPHA, /* BaseFormat */ - GL_UNSIGNED_BYTE, /* Type */ 0, /* RedBits */ 0, /* GreenBits */ 0, /* BlueBits */ @@ -349,7 +334,6 @@ const struct gl_texture_format _mesa_texformat_al88 = { const struct gl_texture_format _mesa_texformat_rgb332 = { MESA_FORMAT_RGB332, /* MesaFormat */ GL_RGB, /* BaseFormat */ - GL_UNSIGNED_BYTE_3_3_2, /* Type */ 3, /* RedBits */ 3, /* GreenBits */ 2, /* BlueBits */ @@ -367,7 +351,6 @@ const struct gl_texture_format _mesa_texformat_rgb332 = { const struct gl_texture_format _mesa_texformat_a8 = { MESA_FORMAT_A8, /* MesaFormat */ GL_ALPHA, /* BaseFormat */ - GL_UNSIGNED_BYTE, /* Type */ 0, /* RedBits */ 0, /* GreenBits */ 0, /* BlueBits */ @@ -385,7 +368,6 @@ const struct gl_texture_format _mesa_texformat_a8 = { const struct gl_texture_format _mesa_texformat_l8 = { MESA_FORMAT_L8, /* MesaFormat */ GL_LUMINANCE, /* BaseFormat */ - GL_UNSIGNED_BYTE, /* Type */ 0, /* RedBits */ 0, /* GreenBits */ 0, /* BlueBits */ @@ -403,7 +385,6 @@ const struct gl_texture_format _mesa_texformat_l8 = { const struct gl_texture_format _mesa_texformat_i8 = { MESA_FORMAT_I8, /* MesaFormat */ GL_INTENSITY, /* BaseFormat */ - GL_UNSIGNED_BYTE, /* Type */ 0, /* RedBits */ 0, /* GreenBits */ 0, /* BlueBits */ @@ -421,7 +402,6 @@ const struct gl_texture_format _mesa_texformat_i8 = { const struct gl_texture_format _mesa_texformat_ci8 = { MESA_FORMAT_CI8, /* MesaFormat */ GL_COLOR_INDEX, /* BaseFormat */ - GL_UNSIGNED_BYTE, /* Type */ 0, /* RedBits */ 0, /* GreenBits */ 0, /* BlueBits */ @@ -436,11 +416,9 @@ const struct gl_texture_format _mesa_texformat_ci8 = { fetch_3d_texel_ci8, /* FetchTexel3D */ }; - const struct gl_texture_format _mesa_texformat_ycbcr = { MESA_FORMAT_YCBCR, /* MesaFormat */ GL_YCBCR_MESA, /* BaseFormat */ - GL_UNSIGNED_SHORT_8_8_MESA, /* Type */ 0, /* RedBits */ 0, /* GreenBits */ 0, /* BlueBits */ @@ -459,7 +437,6 @@ const struct gl_texture_format _mesa_texformat_ycbcr = { const struct gl_texture_format _mesa_texformat_ycbcr_rev = { MESA_FORMAT_YCBCR_REV, /* MesaFormat */ GL_YCBCR_MESA, /* BaseFormat */ - GL_UNSIGNED_SHORT_8_8_REV_MESA, /* Type */ 0, /* RedBits */ 0, /* GreenBits */ 0, /* BlueBits */ @@ -623,13 +600,12 @@ const struct gl_texture_format _mesa_texformat_bgr233 = { #endif /* ============================================================= - * Null format: + * Null format (useful for proxy textures): */ const struct gl_texture_format _mesa_null_texformat = { -1, /* MesaFormat */ 0, /* BaseFormat */ - 0, /* Type */ 0, /* RedBits */ 0, /* GreenBits */ 0, /* BlueBits */ @@ -645,7 +621,6 @@ const struct gl_texture_format _mesa_null_texformat = { }; - GLboolean _mesa_is_hardware_tex_format( const struct gl_texture_format *format ) { @@ -774,6 +749,7 @@ _mesa_choose_tex_format( GLcontext *ctx, GLint internalFormat, _mesa_problem(ctx, "texture compression extension not enabled"); return &_mesa_texformat_rgba; + /* GL_MESA_ycrcr_texture */ case GL_YCBCR_MESA: if (type == GL_UNSIGNED_SHORT_8_8_MESA) return &_mesa_texformat_ycbcr; @@ -782,7 +758,6 @@ _mesa_choose_tex_format( GLcontext *ctx, GLint internalFormat, default: _mesa_problem(ctx, "unexpected format in _mesa_choose_tex_format()"); - _mesa_debug(ctx, "intformat = %d %x\n", internalFormat, internalFormat); return NULL; } } @@ -817,23 +792,3 @@ _mesa_base_compressed_texformat(GLcontext *ctx, GLint intFormat) return -1; /* not a recognized compressed format */ } } - - -/* - * Called via ctx->Driver.CompressedTextureSize(). - * This function is only used by software rasterizers. - * Hardware drivers will have to implement a specialized function. - */ -GLint -_mesa_compressed_texture_size(GLcontext *ctx, - const struct gl_texture_image *texImage) -{ - GLint b; - assert(texImage); - assert(texImage->TexFormat); - - b = texImage->Width * texImage->Height * texImage->Depth * - texImage->TexFormat->TexelBytes; - assert(b > 0); - return b; -} diff --git a/src/mesa/main/texformat.h b/src/mesa/main/texformat.h index d1e7544a42..09997820ea 100644 --- a/src/mesa/main/texformat.h +++ b/src/mesa/main/texformat.h @@ -1,4 +1,4 @@ -/* $Id: texformat.h,v 1.11 2002/09/23 16:37:14 brianp Exp $ */ +/* $Id: texformat.h,v 1.12 2002/09/27 02:45:38 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -67,7 +67,6 @@ enum _format { MESA_FORMAT_YCBCR, /* YYYY YYYY UorV UorV */ MESA_FORMAT_YCBCR_REV, /* UorV UorV YYYY YYYY */ - #if 0 /* upcoming little-endian formats: */ @@ -114,10 +113,6 @@ _mesa_choose_tex_format( GLcontext *ctx, GLint internalFormat, extern GLint _mesa_base_compressed_texformat(GLcontext *ctx, GLint intFormat); -extern GLint -_mesa_compressed_texture_size(GLcontext *ctx, - const struct gl_texture_image *texImage); - /* The default formats, GLchan per component: */ diff --git a/src/mesa/main/texformat_tmp.h b/src/mesa/main/texformat_tmp.h index f796928673..9f84c39b3c 100644 --- a/src/mesa/main/texformat_tmp.h +++ b/src/mesa/main/texformat_tmp.h @@ -1,4 +1,4 @@ -/* $Id: texformat_tmp.h,v 1.8 2002/09/23 16:37:14 brianp Exp $ */ +/* $Id: texformat_tmp.h,v 1.9 2002/09/27 02:45:38 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -23,10 +23,18 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * Author: + * Authors: * Gareth Hughes + * Brian Paul */ + +/* + * This template file generates texel fetch functions for 1-D, 2-D and 3-D + * texture images. + */ + + #if DIM == 1 #define CHAN_SRC( t, i, j, k, sz ) \ @@ -348,7 +356,6 @@ static void FETCH(ycbcr_rev)( const struct gl_texture_image *texImage, } - /* big-endian */ #if 0 diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index 769f74eda7..6ec00c0740 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -1,4 +1,4 @@ -/* $Id: teximage.c,v 1.116 2002/09/23 16:37:14 brianp Exp $ */ +/* $Id: teximage.c,v 1.117 2002/09/27 02:45:38 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -36,6 +36,7 @@ #include "mem.h" #include "mmath.h" #include "state.h" +#include "texcompress.h" #include "texformat.h" #include "teximage.h" #include "texstate.h" @@ -142,6 +143,10 @@ logbase2( int n ) * Given an internal texture format enum or 1, 2, 3, 4 return the * corresponding _base_ internal format: GL_ALPHA, GL_LUMINANCE, * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA. + * + * This is the format which is used during texture application (i.e. the + * texture format and env mode determine the arithmetic used. + * * Return -1 if invalid enum. */ GLint @@ -151,12 +156,6 @@ _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_ALPHA: case GL_ALPHA4: @@ -222,11 +221,55 @@ _mesa_base_tex_format( GLcontext *ctx, GLint format ) return GL_DEPTH_COMPONENT; else return -1; + + /* GL_ARB_texture_compression */ + case GL_COMPRESSED_ALPHA: + if (ctx->Extensions.ARB_texture_compression) + return GL_ALPHA; + else + return -1; + case GL_COMPRESSED_LUMINANCE: + if (ctx->Extensions.ARB_texture_compression) + return GL_LUMINANCE; + else + return -1; + case GL_COMPRESSED_LUMINANCE_ALPHA: + if (ctx->Extensions.ARB_texture_compression) + return GL_LUMINANCE_ALPHA; + else + return -1; + case GL_COMPRESSED_INTENSITY: + if (ctx->Extensions.ARB_texture_compression) + return GL_INTENSITY; + else + return -1; + case GL_COMPRESSED_RGB: + if (ctx->Extensions.ARB_texture_compression) + return GL_RGB; + else + return -1; + case GL_COMPRESSED_RGBA: + if (ctx->Extensions.ARB_texture_compression) + return GL_RGBA; + else + return -1; + case GL_COMPRESSED_RGB_FXT1_3DFX: + if (ctx->Extensions.TDFX_texture_compression_FXT1) + return GL_RGB; + else + return -1; + case GL_COMPRESSED_RGBA_FXT1_3DFX: + if (ctx->Extensions.TDFX_texture_compression_FXT1) + return GL_RGBA; + else + return -1; + case GL_YCBCR_MESA: if (ctx->Extensions.MESA_ycbcr_texture) return GL_YCBCR_MESA; else return -1; + default: return -1; /* error */ } @@ -309,25 +352,24 @@ is_index_format(GLenum format) } -/* - * Return GL_TRUE if internalFormat is a compressed format, return GL_FALSE - * otherwise. +/** + * Return GL_TRUE if internalFormat is a supported compressed format, + * return GL_FALSE otherwise. + * \param - internalFormat - the internal format token provided by the user */ static GLboolean -is_compressed_format(GLcontext *ctx, GLenum internalFormat) +is_compressed_format(GLenum internalFormat) { - if (ctx->Driver.BaseCompressedTexFormat) { - GLint b = (*ctx->Driver.BaseCompressedTexFormat)(ctx, internalFormat); - if (b > 0) + switch (internalFormat) { + case GL_COMPRESSED_RGB_FXT1_3DFX: + case GL_COMPRESSED_RGBA_FXT1_3DFX: return GL_TRUE; - else + default: return GL_FALSE; } - return GL_FALSE; } - /* * Store a gl_texture_image pointer in a gl_texture_object structure * according to the target and level parameters. @@ -657,7 +699,13 @@ _mesa_init_teximage_fields(GLcontext *ctx, GLenum target, img->Height2 = 1 << img->HeightLog2; img->Depth2 = 1 << img->DepthLog2; img->MaxLog2 = MAX2(img->WidthLog2, img->HeightLog2); - img->IsCompressed = is_compressed_format(ctx, internalFormat); + img->IsCompressed = is_compressed_format(internalFormat); + if (img->IsCompressed) + img->CompressedSize = _mesa_compressed_texture_size(ctx, width, height, + depth, internalFormat); + else + img->CompressedSize = 0; + /* Compute Width/Height/DepthScale for mipmap lod computation */ if (target == GL_TEXTURE_RECTANGLE_NV) { /* scale = 1.0 since texture coords directly map to texels */ @@ -689,7 +737,6 @@ texture_error_check( GLcontext *ctx, GLenum target, GLint depth, GLint border ) { GLboolean isProxy; - GLint iformat; GLint maxLevels = 0, maxTextureSize; if (dimensions == 1) { @@ -879,8 +926,7 @@ texture_error_check( GLcontext *ctx, GLenum target, } } - iformat = _mesa_base_tex_format( ctx, internalFormat ); - if (iformat < 0) { + if (_mesa_base_tex_format(ctx, internalFormat) < 0) { if (!isProxy) { _mesa_error(ctx, GL_INVALID_VALUE, "glTexImage%dD(internalFormat=0x%x)", @@ -889,24 +935,21 @@ texture_error_check( GLcontext *ctx, GLenum target, return GL_TRUE; } - ASSERT(iformat > 0); - - if (!is_compressed_format( ctx, internalFormat ) && - !_mesa_is_legal_format_and_type( format, type )) { + 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. */ if (!isProxy) { - _mesa_error(ctx, GL_INVALID_OPERATION, + _mesa_error(ctx, GL_INVALID_OPERATION, "glTexImage%dD(format or type)", dimensions); } return GL_TRUE; } - if (format == GL_YCBCR_MESA || iformat == GL_YCBCR_MESA) { + if (format == GL_YCBCR_MESA || internalFormat == GL_YCBCR_MESA) { ASSERT(ctx->Extensions.MESA_ycbcr_texture); if (format != GL_YCBCR_MESA || - iformat != GL_YCBCR_MESA || + internalFormat != GL_YCBCR_MESA || (type != GL_UNSIGNED_SHORT_8_8_MESA && type != GL_UNSIGNED_SHORT_8_8_REV_MESA)) { char message[100]; @@ -918,6 +961,32 @@ texture_error_check( GLcontext *ctx, GLenum target, } } + if (is_compressed_format(internalFormat)) { + if (target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D) { + /* OK */ + } + else if (ctx->Extensions.ARB_texture_cube_map && + (target == GL_PROXY_TEXTURE_CUBE_MAP || + (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && + target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z))) { + /* OK */ + } + else { + if (!isProxy) { + _mesa_error(ctx, GL_INVALID_ENUM, + "glTexImage%d(target)", dimensions); + return GL_TRUE; + } + } + if (border != 0) { + if (!isProxy) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glTexImage%D(border!=0)", dimensions); + } + return GL_TRUE; + } + } + /* if we get here, the parameters are OK */ return GL_FALSE; } @@ -940,7 +1009,6 @@ subtexture_error_check( GLcontext *ctx, GLuint dimensions, struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; struct gl_texture_image *destTex; GLint maxLevels = 0; - GLboolean compressed; if (dimensions == 1) { if (target != GL_TEXTURE_1D) { @@ -1037,30 +1105,51 @@ subtexture_error_check( GLcontext *ctx, GLuint dimensions, } } - compressed = is_compressed_format(ctx, destTex->IntFormat); - - if (!compressed && !_mesa_is_legal_format_and_type(format, type)) { + if (!_mesa_is_legal_format_and_type(format, type)) { _mesa_error(ctx, GL_INVALID_ENUM, "glTexSubImage%dD(format or type)", dimensions); return GL_TRUE; } - if (compressed) { - if (xoffset != -((GLint)destTex->Border)) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glTexSubImage1/2/3D(xoffset != -border"); + if (destTex->IsCompressed) { + const struct gl_texture_unit *texUnit; + const struct gl_texture_object *texObj; + const struct gl_texture_image *texImage; + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + texObj = _mesa_select_tex_object(ctx, texUnit, target); + texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + + if (target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D) { + /* OK */ + } + else if (ctx->Extensions.ARB_texture_cube_map && + (target == GL_PROXY_TEXTURE_CUBE_MAP || + (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && + target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z))) { + /* OK */ + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, + "glTexSubImage%D(target)", dimensions); return GL_TRUE; } - if (dimensions > 1 && yoffset != -((GLint)destTex->Border)) { + /* offset must be multiple of 4 */ + if ((xoffset & 3) || (yoffset & 3)) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glTexSubImage2/3D(yoffset != -border"); + "glTexSubImage%D(xoffset or yoffset)", dimensions); return GL_TRUE; } - if (dimensions > 2 && zoffset != -((GLint)destTex->Border)) { + /* size must be multiple of 4 or equal to whole texture size */ + if ((width & 3) && width != texImage->Width) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glTexSubImage3D(zoffset != -border"); + "glTexSubImage%D(width)", dimensions); return GL_TRUE; - } + } + if ((height & 3) && height != texImage->Height) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glTexSubImage%D(width)", dimensions); + return GL_TRUE; + } } return GL_FALSE; @@ -1077,7 +1166,6 @@ copytexture_error_check( GLcontext *ctx, GLuint dimensions, GLenum target, GLint level, GLint internalFormat, GLint width, GLint height, GLint border ) { - GLint iformat; GLint maxLevels = 0, maxTextureSize; if (dimensions == 1) { @@ -1157,13 +1245,25 @@ copytexture_error_check( GLcontext *ctx, GLuint dimensions, return GL_TRUE; } - iformat = _mesa_base_tex_format(ctx, internalFormat); - if (iformat < 0) { + if (_mesa_base_tex_format(ctx, internalFormat) < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glCopyTexImage%dD(internalFormat)", dimensions); return GL_TRUE; } + if (is_compressed_format(internalFormat)) { + if (target != GL_TEXTURE_2D) { + _mesa_error(ctx, GL_INVALID_ENUM, + "glCopyTexImage%d(target)", dimensions); + return GL_TRUE; + } + if (border != 0) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glCopyTexImage%D(border!=0)", dimensions); + return GL_TRUE; + } + } + /* if we get here, the parameters are OK */ return GL_FALSE; } @@ -1178,7 +1278,6 @@ copytexsubimage_error_check( GLcontext *ctx, GLuint dimensions, struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; struct gl_texture_image *teximage; GLint maxLevels = 0; - GLboolean compressed; if (dimensions == 1) { if (target != GL_TEXTURE_1D) { @@ -1277,23 +1376,29 @@ copytexsubimage_error_check( GLcontext *ctx, GLuint dimensions, } } - compressed = is_compressed_format(ctx, teximage->IntFormat); - if (compressed) { - if (xoffset != -((GLint)teximage->Border)) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glCopyTexSubImage1/2/3D(xoffset != -border"); + if (teximage->IsCompressed) { + if (target != GL_TEXTURE_2D) { + _mesa_error(ctx, GL_INVALID_ENUM, + "glCopyTexSubImage%d(target)", dimensions); return GL_TRUE; } - if (dimensions > 1 && yoffset != -((GLint)teximage->Border)) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glCopyTexSubImage2/3D(yoffset != -border"); + /* offset must be multiple of 4 */ + if ((xoffset & 3) || (yoffset & 3)) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glCopyTexSubImage%D(xoffset or yoffset)", dimensions); return GL_TRUE; } - if (dimensions > 2 && zoffset != -((GLint)teximage->Border)) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glCopyTexSubImage3D(zoffset != -border"); + /* size must be multiple of 4 */ + if ((width & 3) != 0 && width != teximage->Width) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glCopyTexSubImage%D(width)", dimensions); return GL_TRUE; - } + } + if ((height & 3) != 0 && height != teximage->Height) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glCopyTexSubImage%D(height)", dimensions); + return GL_TRUE; + } } /* if we get here, the parameters are OK */ @@ -1503,28 +1608,10 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat, ASSERT(ctx->Driver.TexImage1D); -#if 0 /* don't make default teximage anymore */ - if (pixels) { - (*ctx->Driver.TexImage1D)(ctx, target, level, internalFormat, - width, border, format, type, pixels, - &ctx->Unpack, texObj, texImage); - } - else { - GLubyte *dummy = make_null_texture(width, 1, 1, format); - if (dummy) { - (*ctx->Driver.TexImage1D)(ctx, target, level, internalFormat, - width, border, - format, GL_UNSIGNED_BYTE, dummy, - &_mesa_native_packing, texObj, texImage); - FREE(dummy); - } - } -#else - /* may be null! */ + /* Give the texture to the driver! may be null! */ (*ctx->Driver.TexImage1D)(ctx, target, level, internalFormat, width, border, format, type, pixels, &ctx->Unpack, texObj, texImage); -#endif ASSERT(texImage->TexFormat); if (!texImage->FetchTexel) { @@ -1533,27 +1620,15 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat, } ASSERT(texImage->FetchTexel); - if (texImage->IsCompressed) { - ASSERT(texImage->CompressedSize > 0); - } - /* state update */ texObj->Complete = GL_FALSE; ctx->NewState |= _NEW_TEXTURE; } else if (target == GL_PROXY_TEXTURE_1D) { /* Proxy texture: check for errors and update proxy state */ - GLenum error = texture_error_check(ctx, target, level, internalFormat, - format, type, 1, - postConvWidth, 1, 1, border); + GLboolean error = texture_error_check(ctx, target, level, internalFormat, + format, type, 1, postConvWidth, 1, 1, border); if (!error) { - struct gl_texture_unit *texUnit; - struct gl_texture_image *texImage; - texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - _mesa_init_teximage_fields(ctx, target, texImage, - postConvWidth, 1, 1, - border, internalFormat); ASSERT(ctx->Driver.TestProxyTexImage); error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level, internalFormat, format, type, @@ -1565,6 +1640,16 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat, clear_teximage_fields(ctx->Texture.Proxy1D->Image[level]); } } + else { + /* no error, set the tex image parameters */ + struct gl_texture_unit *texUnit; + struct gl_texture_image *texImage; + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + _mesa_init_teximage_fields(ctx, target, texImage, + postConvWidth, 1, 1, + border, internalFormat); + } } else { _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage1D(target)" ); @@ -1632,28 +1717,10 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat, ASSERT(ctx->Driver.TexImage2D); -#if 0 /* don't make default teximage anymore */ - if (pixels) { - (*ctx->Driver.TexImage2D)(ctx, target, level, internalFormat, - width, height, border, format, type, pixels, - &ctx->Unpack, texObj, texImage); - } - else { - GLubyte *dummy = make_null_texture(width, height, 1, format); - if (dummy) { - (*ctx->Driver.TexImage2D)(ctx, target, level, internalFormat, - width, height, border, - format, GL_UNSIGNED_BYTE, dummy, - &_mesa_native_packing, texObj, texImage); - FREE(dummy); - } - } -#else - /* may be null! */ + /* Give the texture to the driver! may be null! */ (*ctx->Driver.TexImage2D)(ctx, target, level, internalFormat, width, height, border, format, type, pixels, &ctx->Unpack, texObj, texImage); -#endif ASSERT(texImage->TexFormat); if (!texImage->FetchTexel) { @@ -1662,10 +1729,6 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat, } ASSERT(texImage->FetchTexel); - if (texImage->IsCompressed) { - ASSERT(texImage->CompressedSize > 0); - } - /* state update */ texObj->Complete = GL_FALSE; ctx->NewState |= _NEW_TEXTURE; @@ -1676,17 +1739,9 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat, (target == GL_PROXY_TEXTURE_RECTANGLE_NV && ctx->Extensions.NV_texture_rectangle)) { /* Proxy texture: check for errors and update proxy state */ - GLenum error = texture_error_check(ctx, target, level, internalFormat, - format, type, 2, - postConvWidth, postConvHeight, 1, border); + GLboolean error = texture_error_check(ctx, target, level, internalFormat, + format, type, 2, postConvWidth, postConvHeight, 1, border); if (!error) { - struct gl_texture_unit *texUnit; - struct gl_texture_image *texImage; - texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - _mesa_init_teximage_fields(ctx, target, texImage, - postConvWidth, postConvHeight, 1, - border, internalFormat); ASSERT(ctx->Driver.TestProxyTexImage); error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level, internalFormat, format, type, @@ -1700,6 +1755,16 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat, clear_teximage_fields(ctx->Texture.Proxy2D->Image[level]); } } + else { + /* no error, set the tex image parameters */ + struct gl_texture_unit *texUnit; + struct gl_texture_image *texImage; + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + _mesa_init_teximage_fields(ctx, target, texImage, + postConvWidth, postConvHeight, 1, + border, internalFormat); + } } else { _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage2D(target)" ); @@ -1757,30 +1822,10 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat, ASSERT(ctx->Driver.TexImage3D); -#if 0 /* don't make default teximage anymore */ - if (pixels) { - (*ctx->Driver.TexImage3D)(ctx, target, level, (GLint) internalFormat, - width, height, depth, border, - format, type, pixels, - &ctx->Unpack, texObj, texImage); - } - else { - GLubyte *dummy = make_null_texture(width, height, depth, format); - if (dummy) { - (*ctx->Driver.TexImage3D)(ctx, target, level, - (GLint) internalFormat, - width, height, depth, border, - format, GL_UNSIGNED_BYTE, dummy, - &_mesa_native_packing, texObj, texImage); - FREE(dummy); - } - } -#else - /* may be null! */ + /* Give the texture to the driver! may be null! */ (*ctx->Driver.TexImage3D)(ctx, target, level, internalFormat, width, height, depth, border, format, type, pixels, &ctx->Unpack, texObj, texImage); -#endif ASSERT(texImage->TexFormat); if (!texImage->FetchTexel) { @@ -1789,25 +1834,15 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat, } ASSERT(texImage->FetchTexel); - if (texImage->IsCompressed) { - ASSERT(texImage->CompressedSize > 0); - } - /* state update */ texObj->Complete = GL_FALSE; ctx->NewState |= _NEW_TEXTURE; } else if (target == GL_PROXY_TEXTURE_3D) { /* Proxy texture: check for errors and update proxy state */ - GLenum error = texture_error_check(ctx, target, level, internalFormat, + GLboolean error = texture_error_check(ctx, target, level, internalFormat, format, type, 3, width, height, depth, border); if (!error) { - struct gl_texture_unit *texUnit; - struct gl_texture_image *texImage; - texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1, - border, internalFormat); ASSERT(ctx->Driver.TestProxyTexImage); error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level, internalFormat, format, type, @@ -1819,6 +1854,15 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat, clear_teximage_fields(ctx->Texture.Proxy3D->Image[level]); } } + else { + /* no error, set the tex image parameters */ + struct gl_texture_unit *texUnit; + struct gl_texture_image *texImage; + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1, + border, internalFormat); + } } else { _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage3D(target)" ); @@ -1833,7 +1877,7 @@ _mesa_TexImage3DEXT( GLenum target, GLint level, GLenum internalFormat, GLint border, GLenum format, GLenum type, const GLvoid *pixels ) { - _mesa_TexImage3D(target, level, internalFormat, width, height, + _mesa_TexImage3D(target, level, (GLint) internalFormat, width, height, depth, border, format, type, pixels); } @@ -2219,6 +2263,176 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level, + +/**********************************************************************/ +/****** Compressed Textures ******/ +/**********************************************************************/ + + +/** + * Error checking for glCompressedTexImage[123]D(). + * \return error code or GL_NO_ERROR. + */ +static GLenum +compressed_texture_error_check(GLcontext *ctx, GLint dimensions, + GLenum target, GLint level, + GLenum internalFormat, GLsizei width, + GLsizei height, GLsizei depth, GLint border, + GLsizei imageSize) +{ + GLboolean isProxy = GL_FALSE; + GLint expectedSize, maxLevels = 0, maxTextureSize; + + if (dimensions == 1) { + /* 1D compressed textures not allowed */ + return GL_INVALID_ENUM; + } + else if (dimensions == 2) { + if (target == GL_PROXY_TEXTURE_2D) { + maxLevels = ctx->Const.MaxTextureLevels; + isProxy = GL_TRUE; + } + else if (target == GL_TEXTURE_2D) { + maxLevels = ctx->Const.MaxTextureLevels; + } + else if (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB) { + if (!ctx->Extensions.ARB_texture_cube_map) + return GL_INVALID_ENUM; /*target*/ + maxLevels = ctx->Const.MaxCubeTextureLevels; + isProxy = GL_TRUE; + } + else if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && + target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) { + if (!ctx->Extensions.ARB_texture_cube_map) + return GL_INVALID_ENUM; /*target*/ + maxLevels = ctx->Const.MaxCubeTextureLevels; + } + else { + return GL_INVALID_ENUM; /*target*/ + } + } + else if (dimensions == 3) { + /* 3D compressed textures not allowed */ + return GL_INVALID_ENUM; + } + + maxTextureSize = 1 << (maxLevels - 1); + + if (!is_compressed_format(internalFormat)) + return GL_INVALID_ENUM; + + if (border != 0) + return GL_INVALID_VALUE; + + if (width < 1 || width > maxTextureSize || logbase2(width) < 0) + return GL_INVALID_VALUE; + + if ((height < 1 || height > maxTextureSize || logbase2(height) < 0) + && dimensions > 1) + return GL_INVALID_VALUE; + + if ((depth < 1 || depth > maxTextureSize || logbase2(depth) < 0) + && dimensions > 2) + return GL_INVALID_VALUE; + + /* For cube map, width must equal height */ + if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && + target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB && width != height) + return GL_INVALID_VALUE; + + if (level < 0 || level >= maxLevels) + return GL_INVALID_VALUE; + + expectedSize = _mesa_compressed_texture_size(ctx, width, height, depth, + internalFormat); + if (expectedSize != imageSize) + return GL_INVALID_VALUE; + + return GL_NO_ERROR; +} + + +/** + * Error checking for glCompressedTexSubImage[123]D(). + * \return error code or GL_NO_ERROR. + */ +static GLenum +compressed_subtexture_error_check(GLcontext *ctx, GLint dimensions, + GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLsizei imageSize) +{ + GLboolean isProxy = GL_FALSE; + GLint expectedSize, maxLevels = 0, maxTextureSize; + + if (dimensions == 1) { + /* 1D compressed textures not allowed */ + return GL_INVALID_ENUM; + } + else if (dimensions == 2) { + if (target == GL_PROXY_TEXTURE_2D) { + maxLevels = ctx->Const.MaxTextureLevels; + isProxy = GL_TRUE; + } + else if (target == GL_TEXTURE_2D) { + maxLevels = ctx->Const.MaxTextureLevels; + } + else if (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB) { + if (!ctx->Extensions.ARB_texture_cube_map) + return GL_INVALID_ENUM; /*target*/ + maxLevels = ctx->Const.MaxCubeTextureLevels; + isProxy = GL_TRUE; + } + else if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && + target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) { + if (!ctx->Extensions.ARB_texture_cube_map) + return GL_INVALID_ENUM; /*target*/ + maxLevels = ctx->Const.MaxCubeTextureLevels; + } + else { + return GL_INVALID_ENUM; /*target*/ + } + } + else if (dimensions == 3) { + /* 3D compressed textures not allowed */ + return GL_INVALID_ENUM; + } + + maxTextureSize = 1 << (maxLevels - 1); + + if (!is_compressed_format(format)) + return GL_INVALID_ENUM; + + if (width < 1 || width > maxTextureSize || logbase2(width) < 0) + return GL_INVALID_VALUE; + + if ((height < 1 || height > maxTextureSize || logbase2(height) < 0) + && dimensions > 1) + return GL_INVALID_VALUE; + + if (level < 0 || level >= maxLevels) + return GL_INVALID_VALUE; + + if ((xoffset & 3) != 0 || (yoffset & 3) != 0) + return GL_INVALID_VALUE; + + if ((width & 3) != 0 && width != 2 && width != 1) + return GL_INVALID_VALUE; + + if ((height & 3) != 0 && height != 2 && height != 1) + return GL_INVALID_VALUE; + + expectedSize = _mesa_compressed_texture_size(ctx, width, height, depth, + format); + if (expectedSize != imageSize) + return GL_INVALID_VALUE; + + return GL_NO_ERROR; +} + + + void _mesa_CompressedTexImage1DARB(GLenum target, GLint level, GLenum internalFormat, GLsizei width, @@ -2228,28 +2442,15 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level, GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); - 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: - _mesa_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; - - if (texture_error_check(ctx, target, level, internalFormat, - GL_NONE, GL_NONE, 1, width, 1, 1, border)) { - return; /* error in texture image was detected */ + GLenum error = compressed_texture_error_check(ctx, 1, target, level, + internalFormat, width, 1, 1, border, imageSize); + if (error) { + _mesa_error(ctx, error, "glCompressedTexImage1D"); + return; } texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; @@ -2260,7 +2461,7 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level, texImage = _mesa_alloc_texture_image(); texObj->Image[level] = texImage; if (!texImage) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage1DARB"); + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage1D"); return; } } @@ -2272,14 +2473,11 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level, _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1, border, internalFormat); - if (ctx->Extensions.ARB_texture_compression) { - ASSERT(ctx->Driver.CompressedTexImage1D); - (*ctx->Driver.CompressedTexImage1D)(ctx, target, level, - internalFormat, width, border, - imageSize, data, - texObj, texImage); - ASSERT(texImage->CompressedSize > 0); /* sanity */ - } + ASSERT(ctx->Driver.CompressedTexImage1D); + (*ctx->Driver.CompressedTexImage1D)(ctx, target, level, + internalFormat, width, border, + imageSize, data, + texObj, texImage); /* state update */ texObj->Complete = GL_FALSE; @@ -2287,15 +2485,9 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level, } else if (target == GL_PROXY_TEXTURE_1D) { /* Proxy texture: check for errors and update proxy state */ - GLenum error = texture_error_check(ctx, target, level, internalFormat, - GL_NONE, GL_NONE, 1, width, 1, 1, border); + GLenum error = compressed_texture_error_check(ctx, 1, target, level, + internalFormat, width, 1, 1, border, imageSize); if (!error) { - struct gl_texture_unit *texUnit; - struct gl_texture_image *texImage; - texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1, - border, internalFormat); ASSERT(ctx->Driver.TestProxyTexImage); error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level, internalFormat, GL_NONE, GL_NONE, @@ -2307,9 +2499,18 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level, clear_teximage_fields(ctx->Texture.Proxy1D->Image[level]); } } + else { + /* store the teximage parameters */ + struct gl_texture_unit *texUnit; + struct gl_texture_image *texImage; + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1, + border, internalFormat); + } } else { - _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage1DARB(target)"); + _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage1D(target)"); return; } } @@ -2324,33 +2525,18 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level, GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); - 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: - _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage2DARB"); - return; - default: - /* silence compiler warning */ - ; - } - if (target == GL_TEXTURE_2D || (ctx->Extensions.ARB_texture_cube_map && target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && - target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) || - (ctx->Extensions.NV_texture_rectangle && - target == GL_TEXTURE_RECTANGLE_NV)) { + target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)) { struct gl_texture_unit *texUnit; struct gl_texture_object *texObj; struct gl_texture_image *texImage; - - if (texture_error_check(ctx, target, level, internalFormat, - GL_NONE, GL_NONE, 2, width, height, 1, border)) { - return; /* error in texture image was detected */ + GLenum error = compressed_texture_error_check(ctx, 2, target, level, + internalFormat, width, height, 1, border, imageSize); + if (error) { + _mesa_error(ctx, error, "glCompressedTexImage2D"); + return; } texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; @@ -2361,7 +2547,7 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level, texImage = _mesa_alloc_texture_image(); texObj->Image[level] = texImage; if (!texImage) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2DARB"); + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D"); return; } } @@ -2373,30 +2559,23 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level, _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1, border, internalFormat); - if (ctx->Extensions.ARB_texture_compression) { - ASSERT(ctx->Driver.CompressedTexImage2D); - (*ctx->Driver.CompressedTexImage2D)(ctx, target, level, - internalFormat, width, height, - border, imageSize, data, - texObj, texImage); - ASSERT(texImage->CompressedSize > 0); /* sanity */ - } + ASSERT(ctx->Driver.CompressedTexImage2D); + (*ctx->Driver.CompressedTexImage2D)(ctx, target, level, + internalFormat, width, height, + border, imageSize, data, + texObj, texImage); /* state update */ texObj->Complete = GL_FALSE; ctx->NewState |= _NEW_TEXTURE; } - else if (target == GL_PROXY_TEXTURE_2D) { + else if (target == GL_PROXY_TEXTURE_2D || + (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB && + ctx->Extensions.ARB_texture_cube_map)) { /* Proxy texture: check for errors and update proxy state */ - GLenum error = texture_error_check(ctx, target, level, internalFormat, - GL_NONE, GL_NONE, 2, width, height, 1, border); + GLenum error = compressed_texture_error_check(ctx, 2, target, level, + internalFormat, width, height, 1, border, imageSize); if (!error) { - struct gl_texture_unit *texUnit; - struct gl_texture_image *texImage; - texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1, - border, internalFormat); ASSERT(ctx->Driver.TestProxyTexImage); error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level, internalFormat, GL_NONE, GL_NONE, @@ -2410,9 +2589,18 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level, clear_teximage_fields(ctx->Texture.Proxy2D->Image[level]); } } + else { + /* store the teximage parameters */ + struct gl_texture_unit *texUnit; + struct gl_texture_image *texImage; + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1, + border, internalFormat); + } } else { - _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage2DARB(target)"); + _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage2D(target)"); return; } } @@ -2427,28 +2615,15 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level, GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); - 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: - _mesa_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; - - if (texture_error_check(ctx, target, level, internalFormat, - GL_NONE, GL_NONE, 3, width, height, depth, border)) { - return; /* error in texture image was detected */ + GLenum error = compressed_texture_error_check(ctx, 3, target, level, + internalFormat, width, height, depth, border, imageSize); + if (error) { + _mesa_error(ctx, error, "glCompressedTexImage3D"); + return; } texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; @@ -2459,7 +2634,7 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level, texImage = _mesa_alloc_texture_image(); texObj->Image[level] = texImage; if (!texImage) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage3DARB"); + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage3D"); return; } } @@ -2471,15 +2646,12 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level, _mesa_init_teximage_fields(ctx, target, texImage, width, height, depth, border, internalFormat); - if (ctx->Extensions.ARB_texture_compression) { - ASSERT(ctx->Driver.CompressedTexImage3D); - (*ctx->Driver.CompressedTexImage3D)(ctx, target, level, - internalFormat, - width, height, depth, - border, imageSize, data, - texObj, texImage); - ASSERT(texImage->CompressedSize > 0); /* sanity */ - } + ASSERT(ctx->Driver.CompressedTexImage3D); + (*ctx->Driver.CompressedTexImage3D)(ctx, target, level, + internalFormat, + width, height, depth, + border, imageSize, data, + texObj, texImage); /* state update */ texObj->Complete = GL_FALSE; @@ -2487,16 +2659,9 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level, } else if (target == GL_PROXY_TEXTURE_3D) { /* Proxy texture: check for errors and update proxy state */ - GLenum error = texture_error_check(ctx, target, level, internalFormat, - GL_NONE, GL_NONE, 3, width, height, depth, border); + GLenum error = compressed_texture_error_check(ctx, 3, target, level, + internalFormat, width, height, depth, border, imageSize); if (!error) { - struct gl_texture_unit *texUnit; - struct gl_texture_image *texImage; - texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - _mesa_init_teximage_fields(ctx, target, texImage, - width, height, depth, - border, internalFormat); ASSERT(ctx->Driver.TestProxyTexImage); error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level, internalFormat, GL_NONE, GL_NONE, @@ -2508,9 +2673,18 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level, clear_teximage_fields(ctx->Texture.Proxy3D->Image[level]); } } + else { + /* store the teximage parameters */ + struct gl_texture_unit *texUnit; + struct gl_texture_image *texImage; + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + _mesa_init_teximage_fields(ctx, target, texImage, width, height, + depth, border, internalFormat); + } } else { - _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage3DARB(target)"); + _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage3D(target)"); return; } } @@ -2524,12 +2698,15 @@ _mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset, struct gl_texture_unit *texUnit; struct gl_texture_object *texObj; struct gl_texture_image *texImage; + GLenum error; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); - if (subtexture_error_check(ctx, 1, target, level, xoffset, 0, 0, - width, 1, 1, format, GL_NONE)) { - return; /* error was detected */ + error = compressed_subtexture_error_check(ctx, 1, target, level, + xoffset, 0, 0, width, 1, 1, format, imageSize); + if (error) { + _mesa_error(ctx, error, "glCompressedTexSubImage1D"); + return; } texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; @@ -2537,6 +2714,17 @@ _mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset, texImage = _mesa_select_tex_image(ctx, texUnit, target, level); assert(texImage); + if (format != texImage->IntFormat) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glCompressedTexSubImage1D(format)"); + return; + } + + if ((width == 1 || width == 2) && width != texImage->Width) { + _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage1D(width)"); + return; + } + if (width == 0 || !data) return; /* no-op, not an error */ @@ -2559,12 +2747,15 @@ _mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset, struct gl_texture_unit *texUnit; struct gl_texture_object *texObj; struct gl_texture_image *texImage; + GLenum error; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); - if (subtexture_error_check(ctx, 2, target, level, xoffset, yoffset, 0, - width, height, 1, format, GL_NONE)) { - return; /* error was detected */ + error = compressed_subtexture_error_check(ctx, 2, target, level, + xoffset, yoffset, 0, width, height, 1, format, imageSize); + if (error) { + _mesa_error(ctx, error, "glCompressedTexSubImage2D"); + return; } texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; @@ -2572,6 +2763,18 @@ _mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset, texImage = _mesa_select_tex_image(ctx, texUnit, target, level); assert(texImage); + if (format != texImage->IntFormat) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glCompressedTexSubImage2D(format)"); + return; + } + + if (((width == 1 || width == 2) && width != texImage->Width) || + ((height == 1 || height == 2) && height != texImage->Height)) { + _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage2D(size)"); + return; + } + if (width == 0 || height == 0 || !data) return; /* no-op, not an error */ @@ -2594,12 +2797,15 @@ _mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset, struct gl_texture_unit *texUnit; struct gl_texture_object *texObj; struct gl_texture_image *texImage; + GLenum error; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); - if (subtexture_error_check(ctx, 3, target, level, xoffset, yoffset, zoffset, - width, height, depth, format, GL_NONE)) { - return; /* error was detected */ + error = compressed_subtexture_error_check(ctx, 3, target, level, + xoffset, yoffset, zoffset, width, height, depth, format, imageSize); + if (error) { + _mesa_error(ctx, error, "glCompressedTexSubImage2D"); + return; } texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; @@ -2607,6 +2813,19 @@ _mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset, texImage = _mesa_select_tex_image(ctx, texUnit, target, level); assert(texImage); + if (format != texImage->IntFormat) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glCompressedTexSubImage3D(format)"); + return; + } + + if (((width == 1 || width == 2) && width != texImage->Width) || + ((height == 1 || height == 2) && height != texImage->Height) || + ((depth == 1 || depth == 2) && depth != texImage->Depth)) { + _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage3D(size)"); + return; + } + if (width == 0 || height == 0 || depth == 0 || !data) return; /* no-op, not an error */ @@ -2675,9 +2894,6 @@ _mesa_GetCompressedTexImageARB(GLenum target, GLint level, GLvoid *img) if (!img) return; - if (ctx->Extensions.ARB_texture_compression) { - ASSERT(ctx->Driver.GetCompressedTexImage); - (*ctx->Driver.GetCompressedTexImage)(ctx, target, level, img, texObj, - texImage); - } + /* just memcpy, no pixelstore or pixel transfer */ + MEMCPY(img, texImage->Data, texImage->CompressedSize); } diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c index 302f071093..1287bdf2bf 100644 --- a/src/mesa/main/texstate.c +++ b/src/mesa/main/texstate.c @@ -1,4 +1,4 @@ -/* $Id: texstate.c,v 1.78 2002/09/08 17:29:16 brianp Exp $ */ +/* $Id: texstate.c,v 1.79 2002/09/27 02:45:38 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -1461,7 +1461,7 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, maxLevels = 1; break; default: - _mesa_printf(ctx, "bad target in _mesa_GetTexLevelParameter (0x%x)", target); + _mesa_problem(ctx, "switch in _mesa_GetTexLevelParameter"); return; } @@ -1557,7 +1557,8 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, if (ctx->Extensions.SGIX_depth_texture) *params = img->TexFormat->DepthBits; else - _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); + _mesa_error(ctx, GL_INVALID_ENUM, + "glGetTexLevelParameter[if]v(pname)"); return; /* GL_ARB_texture_compression */ @@ -1567,10 +1568,11 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, *params = img->CompressedSize; else _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetTexLevelParameter[if]v(pname)"); + "glGetTexLevelParameter[if]v(pname)"); } else { - _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); + _mesa_error(ctx, GL_INVALID_ENUM, + "glGetTexLevelParameter[if]v(pname)"); } return; case GL_TEXTURE_COMPRESSED_ARB: @@ -1578,12 +1580,14 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, *params = (GLint) img->IsCompressed; } else { - _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); + _mesa_error(ctx, GL_INVALID_ENUM, + "glGetTexLevelParameter[if]v(pname)"); } return; default: - _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); + _mesa_error(ctx, GL_INVALID_ENUM, + "glGetTexLevelParameter[if]v(pname)"); } } diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c index 07404a2609..899cf044fa 100644 --- a/src/mesa/main/texstore.c +++ b/src/mesa/main/texstore.c @@ -1,4 +1,4 @@ -/* $Id: texstore.c,v 1.41 2002/09/21 16:51:25 brianp Exp $ */ +/* $Id: texstore.c,v 1.42 2002/09/27 02:45:38 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -29,12 +29,38 @@ * Brian Paul */ +/* + * The GL texture image functions in teximage.c basically just do + * error checking and data structure allocation. They in turn call + * device driver functions which actually copy/convert/store the user's + * texture image data. + * + * However, most device drivers will be able to use the fallback functions + * in this file. That is, most drivers will have the following bit of + * code: + * ctx->Driver.TexImage1D = _mesa_store_teximage1d; + * ctx->Driver.TexImage2D = _mesa_store_teximage2d; + * ctx->Driver.TexImage3D = _mesa_store_teximage3d; + * etc... + * + * Texture image processing is actually kind of complicated. We have to do: + * Format/type conversions + * pixel unpacking + * pixel transfer (scale, bais, lookup, convolution!, etc) + * + * These functions can handle most everything, including processing full + * images and sub-images. + */ + + + #include "colormac.h" #include "context.h" #include "convolve.h" #include "image.h" #include "macros.h" #include "mem.h" +#include "texcompress.h" #include "texformat.h" #include "teximage.h" #include "texstore.h" @@ -46,9 +72,6 @@ * corresponding _base_ internal format: GL_ALPHA, GL_LUMINANCE, * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA. Return the * number of components for the format. Return -1 if invalid enum. - * - * GH: Do we really need this? We have the number of bytes per texel - * in the texture format structures, so why don't we just use that? */ static GLint components_in_intformat( GLint format ) @@ -129,7 +152,8 @@ components_in_intformat( GLint format ) * We also take care of all image transfer operations here, including * convolution, scale/bias, colortables, etc. * - * The destination texel channel type is always GLchan. + * The destination texel type is always GLchan. + * The destination texel format is one of the 6 basic types. * * A hardware driver may use this as a helper routine to unpack and * apply pixel transfer ops into a temporary image buffer. Then, @@ -137,8 +161,8 @@ components_in_intformat( GLint format ) * * Input: * dimensions - 1, 2, or 3 - * texFormat - GL_LUMINANCE, GL_INTENSITY, GL_LUMINANCE_ALPHA, GL_ALPHA, - * GL_RGB or GL_RGBA + * texDestFormat - GL_LUMINANCE, GL_INTENSITY, GL_LUMINANCE_ALPHA, GL_ALPHA, + * GL_RGB or GL_RGBA (the destination format) * texDestAddr - destination image address * srcWidth, srcHeight, srcDepth - size (in pixels) of src and dest images * dstXoffset, dstYoffset, dstZoffset - position to store the image within @@ -164,6 +188,12 @@ transfer_teximage(GLcontext *ctx, GLuint dimensions, ASSERT(ctx); ASSERT(dimensions >= 1 && dimensions <= 3); + ASSERT(texDestFormat == GL_LUMINANCE || + texDestFormat == GL_INTENSITY || + texDestFormat == GL_LUMINANCE_ALPHA || + texDestFormat == GL_ALPHA || + texDestFormat == GL_RGB || + texDestFormat == GL_RGBA); ASSERT(texDestAddr); ASSERT(srcWidth >= 1); ASSERT(srcHeight >= 1); @@ -445,6 +475,12 @@ _mesa_transfer_teximage(GLcontext *ctx, GLuint dimensions, GLint postConvWidth = srcWidth, postConvHeight = srcHeight; assert(baseInternalFormat > 0); + ASSERT(baseInternalFormat == GL_LUMINANCE || + baseInternalFormat == GL_INTENSITY || + baseInternalFormat == GL_LUMINANCE_ALPHA || + baseInternalFormat == GL_ALPHA || + baseInternalFormat == GL_RGB || + baseInternalFormat == GL_RGBA); if (transferOps & IMAGE_CONVOLUTION_BIT) { _mesa_adjust_image_for_convolution(ctx, dimensions, &postConvWidth, @@ -627,12 +663,83 @@ _mesa_transfer_teximage(GLcontext *ctx, GLuint dimensions, } + +/** + * Given a user's uncompressed texture image, this function takes care of + * pixel unpacking, pixel transfer, format conversion and compression. + */ +static void +transfer_compressed_teximage(GLcontext *ctx, GLuint dimensions, + GLsizei width, GLsizei height, GLsizei depth, + GLenum srcFormat, GLenum srcType, + const struct gl_pixelstore_attrib *unpacking, + const GLvoid *source, + GLenum dstFormat, GLubyte *dest, + GLint dstRowStride) +{ + GLchan *tempImage = NULL; + GLint srcRowStride; + GLenum baseFormat; + + ASSERT(dimensions == 2); + + baseFormat = _mesa_base_tex_format(ctx, dstFormat); + + if (srcFormat != baseFormat || srcType != CHAN_TYPE || + ctx->_ImageTransferState != 0 || unpacking->SwapBytes) { + /* need to convert user's image to texImage->Format, GLchan */ + GLint comps = components_in_intformat(baseFormat); + GLint postConvWidth = width, postConvHeight = height; + + /* XXX convolution untested */ + if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) { + _mesa_adjust_image_for_convolution(ctx, dimensions, &postConvWidth, + &postConvHeight); + } + + tempImage = (GLchan*) MALLOC(width * height * comps * sizeof(GLchan)); + if (!tempImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); + return; + } + transfer_teximage(ctx, dimensions, + baseFormat, /* dest format */ + tempImage, /* dst address */ + width, height, depth, /* src size */ + 0, 0, 0, /* x/y/zoffset */ + comps * width, /* dst row stride */ + comps * width * height, /* dst image stride */ + srcFormat, srcType, /* src format, type */ + source, unpacking, /* src and src packing */ + ctx->_ImageTransferState); + source = tempImage; + width = postConvWidth; + height = postConvHeight; + srcRowStride = width; + } + else { + if (unpacking->RowLength) + srcRowStride = unpacking->RowLength; + else + srcRowStride = width; + } + + _mesa_compress_teximage(ctx, width, height, baseFormat, + (const GLchan *) source, srcRowStride, + dstFormat, dest, dstRowStride); + if (tempImage) { + FREE(tempImage); + } +} + + + /* - * This is the software fallback for Driver.TexImage1D(). + * This is the software fallback for Driver.TexImage1D() + * and Driver.CopyTexImage2D(). * The texture image type will be GLchan. * The texture image format will be GL_COLOR_INDEX, GL_INTENSITY, * GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_ALPHA, GL_RGB or GL_RGBA. - * */ void _mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level, @@ -659,52 +766,55 @@ _mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level, texelBytes = texImage->TexFormat->TexelBytes; - /* Compute image size, in bytes */ - if (texImage->IsCompressed) { - assert(ctx->Driver.CompressedTextureSize); - sizeInBytes = ctx->Driver.CompressedTextureSize(ctx, texImage); - assert(sizeInBytes > 0); - texImage->CompressedSize = sizeInBytes; - } - else { - sizeInBytes = postConvWidth * texelBytes; - } - /* allocate memory */ + if (texImage->IsCompressed) + sizeInBytes = texImage->CompressedSize; + else + sizeInBytes = postConvWidth * texelBytes; texImage->Data = MESA_PBUFFER_ALLOC(sizeInBytes); if (!texImage->Data) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D"); return; } - if (pixels) { - /* unpack image, apply transfer ops and store in texImage->Data */ + if (!pixels) + return; + + /* unpack image, apply transfer ops and store in texImage->Data */ + if (texImage->IsCompressed) { + GLint dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat, + width); + transfer_compressed_teximage(ctx, 1, width, 1, 1, + format, type, packing, + pixels, texImage->IntFormat, + (GLubyte *) texImage->Data, dstRowStride); + } + else { _mesa_transfer_teximage(ctx, 1, - _mesa_base_tex_format(ctx, internalFormat), + texImage->Format, /* base format */ texImage->TexFormat, texImage->Data, - width, 1, 1, 0, 0, 0, + width, 1, 1, /* src size */ + 0, 0, 0, /* dstX/Y/Zoffset */ 0, /* dstRowStride */ 0, /* dstImageStride */ format, type, pixels, packing); + } - /* GL_SGIS_generate_mipmap */ - if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - _mesa_generate_mipmap(ctx, target, - &ctx->Texture.Unit[ctx->Texture.CurrentUnit], - texObj); - } + /* GL_SGIS_generate_mipmap */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + _mesa_generate_mipmap(ctx, target, + &ctx->Texture.Unit[ctx->Texture.CurrentUnit], + texObj); } } /* - * This is the software fallback for Driver.TexImage2D(). + * This is the software fallback for Driver.TexImage2D() + * and Driver.CopyTexImage2D(). * The texture image type will be GLchan. * The texture image format will be GL_COLOR_INDEX, GL_INTENSITY, * GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_ALPHA, GL_RGB or GL_RGBA. - * - * NOTE: if real texture compression is supported, this whole function - * will need to be overridden. */ void _mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level, @@ -732,51 +842,56 @@ _mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level, texelBytes = texImage->TexFormat->TexelBytes; - /* Compute image size, in bytes */ - if (texImage->IsCompressed) { - assert(ctx->Driver.CompressedTextureSize); - sizeInBytes = ctx->Driver.CompressedTextureSize(ctx, texImage); - assert(sizeInBytes > 0); - texImage->CompressedSize = sizeInBytes; - } - else { - sizeInBytes = postConvWidth * postConvHeight * texelBytes; - } - /* allocate memory */ + if (texImage->IsCompressed) + sizeInBytes = texImage->CompressedSize; + else + sizeInBytes = postConvWidth * postConvHeight * texelBytes; texImage->Data = MESA_PBUFFER_ALLOC(sizeInBytes); if (!texImage->Data) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); return; } - if (pixels) { - /* unpack image, apply transfer ops and store in texImage->Data */ + if (!pixels) + return; + + /* unpack image, apply transfer ops and store in texImage->Data */ + if (texImage->IsCompressed) { + GLint dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat, + width); + transfer_compressed_teximage(ctx, 2, width, height, 1, + format, type, packing, + pixels, texImage->IntFormat, + (GLubyte *) texImage->Data, dstRowStride); + } + else { _mesa_transfer_teximage(ctx, 2, - _mesa_base_tex_format(ctx, internalFormat), + texImage->Format, texImage->TexFormat, texImage->Data, - width, height, 1, 0, 0, 0, - texImage->Width * texelBytes, + width, height, 1, /* src size */ + 0, 0, 0, /* dstX/Y/Zoffset */ + texImage->Width * texelBytes, /* dstRowStride */ 0, /* dstImageStride */ format, type, pixels, packing); + } - /* GL_SGIS_generate_mipmap */ - if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - _mesa_generate_mipmap(ctx, target, - &ctx->Texture.Unit[ctx->Texture.CurrentUnit], - texObj); - } + /* GL_SGIS_generate_mipmap */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + _mesa_generate_mipmap(ctx, target, + &ctx->Texture.Unit[ctx->Texture.CurrentUnit], + texObj); } } /* - * This is the software fallback for Driver.TexImage3D(). + * This is the software fallback for Driver.TexImage3D() + * and Driver.CopyTexImage3D(). * The texture image type will be GLchan. * The texture image format will be GL_COLOR_INDEX, GL_INTENSITY, * GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_ALPHA, GL_RGB or GL_RGBA. - * */ void _mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level, @@ -798,40 +913,45 @@ _mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level, texelBytes = texImage->TexFormat->TexelBytes; - /* Compute image size, in bytes */ - if (texImage->IsCompressed) { - assert(ctx->Driver.CompressedTextureSize); - sizeInBytes = ctx->Driver.CompressedTextureSize(ctx, texImage); - assert(sizeInBytes > 0); - texImage->CompressedSize = sizeInBytes; - } - else { - sizeInBytes = width * height * depth * texelBytes; - } - /* allocate memory */ + if (texImage->IsCompressed) + sizeInBytes = texImage->CompressedSize; + else + sizeInBytes = width * height * depth * texelBytes; texImage->Data = MESA_PBUFFER_ALLOC(sizeInBytes); if (!texImage->Data) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D"); return; } - if (pixels) { - /* unpack image, apply transfer ops and store in texImage->Data */ + if (!pixels) + return; + + /* unpack image, apply transfer ops and store in texImage->Data */ + if (texImage->IsCompressed) { + GLint dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat, + width); + transfer_compressed_teximage(ctx, 3, width, height, depth, + format, type, packing, + pixels, texImage->IntFormat, + (GLubyte *) texImage->Data, dstRowStride); + } + else { _mesa_transfer_teximage(ctx, 3, - _mesa_base_tex_format(ctx, internalFormat), + texImage->Format, texImage->TexFormat, texImage->Data, - width, height, depth, 0, 0, 0, - texImage->Width * texelBytes, + width, height, depth, /* src size */ + 0, 0, 0, /* dstX/Y/Zoffset */ + texImage->Width * texelBytes, /* dstRowStride */ texImage->Width * texImage->Height * texelBytes, format, type, pixels, packing); + } - /* GL_SGIS_generate_mipmap */ - if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - _mesa_generate_mipmap(ctx, target, - &ctx->Texture.Unit[ctx->Texture.CurrentUnit], - texObj); - } + /* GL_SGIS_generate_mipmap */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + _mesa_generate_mipmap(ctx, target, + &ctx->Texture.Unit[ctx->Texture.CurrentUnit], + texObj); } } @@ -839,7 +959,8 @@ _mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level, /* - * This is the software fallback for Driver.TexSubImage1D(). + * This is the software fallback for Driver.TexSubImage1D() + * and Driver.CopyTexSubImage1D(). */ void _mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level, @@ -849,14 +970,31 @@ _mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { - _mesa_transfer_teximage(ctx, 1, - _mesa_base_tex_format(ctx, texImage->IntFormat), - texImage->TexFormat, texImage->Data, - width, 1, 1, /* src size */ - xoffset, 0, 0, /* dest offsets */ - 0, /* dstRowStride */ - 0, /* dstImageStride */ - format, type, pixels, packing); + if (texImage->IsCompressed) { + GLint dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat, + texImage->Width); + GLubyte *dest = _mesa_compressed_image_address(xoffset, 0, 0, + texImage->IntFormat, + texImage->Width, + texImage->Data); + transfer_compressed_teximage(ctx, 1, /* dimensions */ + width, 1, 1, /* size to replace */ + format, type, /* source format/type */ + packing, /* source packing */ + pixels, /* source data */ + texImage->IntFormat,/* dest format */ + dest, dstRowStride); + } + else { + _mesa_transfer_teximage(ctx, 1, + texImage->Format, + texImage->TexFormat, texImage->Data, + width, 1, 1, /* src size */ + xoffset, 0, 0, /* dest offsets */ + 0, /* dstRowStride */ + 0, /* dstImageStride */ + format, type, pixels, packing); + } /* GL_SGIS_generate_mipmap */ if (level == texObj->BaseLevel && texObj->GenerateMipmap) { @@ -867,8 +1005,10 @@ _mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level, } + /* - * This is the software fallback for Driver.TexSubImage2D(). + * This is the software fallback for Driver.TexSubImage2D() + * and Driver.CopyTexSubImage2D(). */ void _mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level, @@ -879,14 +1019,31 @@ _mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { - _mesa_transfer_teximage(ctx, 2, - _mesa_base_tex_format(ctx, texImage->IntFormat), - texImage->TexFormat, texImage->Data, - width, height, 1, /* src size */ - xoffset, yoffset, 0, /* dest offsets */ - texImage->Width * texImage->TexFormat->TexelBytes, - 0, /* dstImageStride */ - format, type, pixels, packing); + if (texImage->IsCompressed) { + GLint dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat, + texImage->Width); + GLubyte *dest = _mesa_compressed_image_address(xoffset, yoffset, 0, + texImage->IntFormat, + texImage->Width, + texImage->Data); + transfer_compressed_teximage(ctx, 2, /* dimensions */ + width, height, 1, /* size to replace */ + format, type, /* source format/type */ + packing, /* source packing */ + pixels, /* source data */ + texImage->IntFormat,/* dest format */ + dest, dstRowStride); + } + else { + _mesa_transfer_teximage(ctx, 2, + texImage->Format, + texImage->TexFormat, texImage->Data, + width, height, 1, /* src size */ + xoffset, yoffset, 0, /* dest offsets */ + texImage->Width *texImage->TexFormat->TexelBytes, + 0, /* dstImageStride */ + format, type, pixels, packing); + } /* GL_SGIS_generate_mipmap */ if (level == texObj->BaseLevel && texObj->GenerateMipmap) { @@ -899,6 +1056,7 @@ _mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level, /* * This is the software fallback for Driver.TexSubImage3D(). + * and Driver.CopyTexSubImage3D(). */ void _mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level, @@ -909,15 +1067,33 @@ _mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { - const GLint texelBytes = texImage->TexFormat->TexelBytes; - _mesa_transfer_teximage(ctx, 3, - _mesa_base_tex_format(ctx, texImage->IntFormat), + if (texImage->IsCompressed) { + GLint dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat, + texImage->Width); + GLubyte *dest = _mesa_compressed_image_address(xoffset, yoffset, zoffset, + texImage->IntFormat, + texImage->Width, + texImage->Data); + transfer_compressed_teximage(ctx, 3, /* dimensions */ + width, height, depth,/* size to replace */ + format, type, /* source format/type */ + packing, /* source packing */ + pixels, /* source data */ + texImage->IntFormat,/* dest format */ + dest, dstRowStride); + } + else { + const GLint texelBytes = texImage->TexFormat->TexelBytes; + _mesa_transfer_teximage(ctx, 3, + texImage->Format, texImage->TexFormat, texImage->Data, width, height, depth, /* src size */ xoffset, yoffset, xoffset, /* dest offsets */ - texImage->Width * texelBytes, + texImage->Width * texelBytes, /* dst row stride */ texImage->Width * texImage->Height * texelBytes, format, type, pixels, packing); + } + /* GL_SGIS_generate_mipmap */ if (level == texObj->BaseLevel && texObj->GenerateMipmap) { _mesa_generate_mipmap(ctx, target, @@ -940,9 +1116,7 @@ _mesa_store_compressed_teximage1d(GLcontext *ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { - /* Nothing here. - * The device driver has to do it all. - */ + /* this space intentionally left blank */ } @@ -958,9 +1132,33 @@ _mesa_store_compressed_teximage2d(GLcontext *ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { - /* Nothing here. - * The device driver has to do it all. + /* This is pretty simple, basically just do a memcpy without worrying + * about the usual image unpacking or image transfer operations. */ + ASSERT(texObj); + ASSERT(texImage); + ASSERT(texImage->Width > 0); + ASSERT(texImage->Height > 0); + ASSERT(texImage->Depth == 1); + ASSERT(texImage->Data == NULL); /* was freed in glCompressedTexImage2DARB */ + + /* choose the texture format */ + assert(ctx->Driver.ChooseTextureFormat); + texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx, + internalFormat, 0, 0); + assert(texImage->TexFormat); + texImage->FetchTexel = texImage->TexFormat->FetchTexel2D; + + /* allocate storage */ + texImage->Data = MESA_PBUFFER_ALLOC(imageSize); + if (!texImage->Data) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2DARB"); + return; + } + + /* copy the data */ + ASSERT(texImage->CompressedSize == imageSize); + MEMCPY(texImage->Data, data, imageSize); } @@ -977,31 +1175,90 @@ _mesa_store_compressed_teximage3d(GLcontext *ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { - /* Nothing here. - * The device driver has to do it all. - */ + /* this space intentionally left blank */ } -/* - * Fallback for Driver.GetCompressedTexImage3D() - * This will probably work find for hardware drivers. That is, hardware - * drivers won't have to override this function, unless the compressed - * texture must first be fetched from the TRAM. +/** + * Fallback for Driver.CompressedTexSubImage1D() */ void -_mesa_get_compressed_teximage(GLcontext *ctx, GLenum target, - GLint level, void *image, - const struct gl_texture_object *texObj, - struct gl_texture_image *texImage) +_mesa_store_compressed_texsubimage1d(GLcontext *ctx, GLenum target, + GLint level, + GLint xoffset, GLsizei width, + GLenum format, + GLsizei imageSize, const GLvoid *data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) { - assert(texImage->IsCompressed); - assert(texImage->CompressedSize > 0); - MEMCPY(image, texImage->Data, texImage->CompressedSize); + /* this space intentionally left blank */ } +/** + * Fallback for Driver.CompressedTexSubImage2D() + */ +void +_mesa_store_compressed_texsubimage2d(GLcontext *ctx, GLenum target, + GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, + GLsizei imageSize, const GLvoid *data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + GLint bytesPerRow, destRowStride, srcRowStride; + GLint i, rows; + GLubyte *dest; + const GLubyte *src; + + /* these should have been caught sooner */ + ASSERT((width & 3) == 0 || width == 2 || width == 1); + ASSERT((height & 3) == 0 || height == 2 || height == 1); + ASSERT((xoffset & 3) == 0); + ASSERT((yoffset & 3) == 0); + + srcRowStride = _mesa_compressed_row_stride(texImage->IntFormat, width); + src = (const GLubyte *) data; + + destRowStride = _mesa_compressed_row_stride(texImage->IntFormat, + texImage->Width); + dest = _mesa_compressed_image_address(xoffset, yoffset, 0, + texImage->IntFormat, + texImage->Width, texImage->Data); + + bytesPerRow = srcRowStride; + rows = height / 4; + + for (i = 0; i < rows; i++) { + MEMCPY(dest, src, bytesPerRow); + dest += destRowStride; + src += srcRowStride; + } +} + + +/** + * Fallback for Driver.CompressedTexSubImage3D() + */ +void +_mesa_store_compressed_texsubimage3d(GLcontext *ctx, GLenum target, + GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, + GLsizei imageSize, const GLvoid *data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + /* this space intentionally left blank */ +} + + + + /* * This is the fallback for Driver.TestProxyTexImage(). @@ -1633,6 +1890,8 @@ _mesa_generate_mipmap(GLcontext *ctx, GLenum target, const struct gl_texture_unit *texUnit, struct gl_texture_object *texObj) { + const GLubyte *srcData; + GLubyte *dstData; GLint level; GLint maxLevels = 0; @@ -1661,6 +1920,29 @@ _mesa_generate_mipmap(GLcontext *ctx, GLenum target, return; } + /* setup for compressed textures */ + { + const struct gl_texture_image *srcImage; + srcImage = texObj->Image[texObj->BaseLevel]; + if (srcImage->IsCompressed) { + /* allocate storage for uncompressed images */ + GLint size = _mesa_bytes_per_pixel(srcImage->Format, CHAN_TYPE) + * srcImage->Width * srcImage->Height * srcImage->Depth; + srcData = MALLOC(size); + if (!srcData) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "generate mipmaps"); + return; + } + dstData = MALLOC(size / 2); /* 1/4 would probably be OK */ + if (!dstData) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "generate mipmaps"); + FREE((void *) srcData); + return; + } + /* XXX decompress base image here */ + } + } + for (level = texObj->BaseLevel; level < texObj->MaxLevel && level < maxLevels - 1; level++) { /* generate image[level+1] from image[level] */ @@ -1670,13 +1952,13 @@ _mesa_generate_mipmap(GLcontext *ctx, GLenum target, GLint dstWidth, dstHeight, dstDepth; GLint border, bytesPerTexel; + /* get src image parameters */ srcImage = texObj->Image[level]; ASSERT(srcImage); srcWidth = srcImage->Width; srcHeight = srcImage->Height; srcDepth = srcImage->Depth; border = srcImage->Border; - bytesPerTexel = srcImage->TexFormat->TexelBytes; /* compute next (level+1) image size */ if (srcWidth - 2 * border > 1) { @@ -1702,6 +1984,10 @@ _mesa_generate_mipmap(GLcontext *ctx, GLenum target, dstHeight == srcHeight && dstDepth == srcDepth) { /* all done */ + if (srcImage->IsCompressed) { + FREE((void *) srcData); + FREE(dstData); + } return; } @@ -1722,56 +2008,82 @@ _mesa_generate_mipmap(GLcontext *ctx, GLenum target, /* initialize new image */ _mesa_init_teximage_fields(ctx, target, dstImage, dstWidth, dstHeight, - dstDepth, border, srcImage->Format); + dstDepth, border, srcImage->IntFormat); dstImage->DriverData = NULL; dstImage->TexFormat = srcImage->TexFormat; dstImage->FetchTexel = srcImage->FetchTexel; ASSERT(dstImage->TexFormat); ASSERT(dstImage->FetchTexel); - ASSERT(dstWidth * dstHeight * dstDepth * bytesPerTexel > 0); - - /* alloc new image buffer */ - dstImage->Data = MESA_PBUFFER_ALLOC(dstWidth * dstHeight * dstDepth - * bytesPerTexel); - if (!dstImage->Data) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps"); - return; + /* Alloc new teximage data buffer. + * Setup src and dest data pointers. + */ + if (dstImage->IsCompressed) { + ASSERT(dstImage->CompressedSize > 0); /* set by init_teximage_fields*/ + dstImage->Data = MESA_PBUFFER_ALLOC(dstImage->CompressedSize); + if (!dstImage->Data) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps"); + return; + } + /* srcData and dstData are all set */ + ASSERT(srcData); + ASSERT(dstData); + } + else { + bytesPerTexel = srcImage->TexFormat->TexelBytes; + ASSERT(dstWidth * dstHeight * dstDepth * bytesPerTexel > 0); + dstImage->Data = MESA_PBUFFER_ALLOC(dstWidth * dstHeight * dstDepth + * bytesPerTexel); + if (!dstImage->Data) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps"); + return; + } + srcData = (const GLubyte *) srcImage->Data; + dstData = (GLubyte *) dstImage->Data; } /* * We use simple 2x2 averaging to compute the next mipmap level. */ switch (target) { - case GL_TEXTURE_1D: - make_1d_mipmap(srcImage->TexFormat, border, - srcWidth, (const GLubyte *) srcImage->Data, - dstWidth, (GLubyte *) dstImage->Data); - break; - case GL_TEXTURE_2D: - case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: - make_2d_mipmap(srcImage->TexFormat, border, - srcWidth, srcHeight, (const GLubyte *) srcImage->Data, - dstWidth, dstHeight, (GLubyte *) dstImage->Data); - break; - case GL_TEXTURE_3D: - make_3d_mipmap(srcImage->TexFormat, border, - srcWidth, srcHeight, srcDepth, - (const GLubyte *) srcImage->Data, - dstWidth, dstHeight, dstDepth, - (GLubyte *) dstImage->Data); - break; - case GL_TEXTURE_RECTANGLE_NV: - /* no mipmaps, do nothing */ - break; - default: - _mesa_problem(ctx, "bad dimensions in _mesa_generate_mipmaps"); - return; + case GL_TEXTURE_1D: + make_1d_mipmap(srcImage->TexFormat, border, + srcWidth, srcData, + dstWidth, dstData); + break; + case GL_TEXTURE_2D: + case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: + make_2d_mipmap(srcImage->TexFormat, border, + srcWidth, srcHeight, srcData, + dstWidth, dstHeight, dstData); + break; + case GL_TEXTURE_3D: + make_3d_mipmap(srcImage->TexFormat, border, + srcWidth, srcHeight, srcDepth, srcData, + dstWidth, dstHeight, dstDepth, dstData); + break; + case GL_TEXTURE_RECTANGLE_NV: + /* no mipmaps, do nothing */ + break; + default: + _mesa_problem(ctx, "bad dimensions in _mesa_generate_mipmaps"); + return; } + + if (dstImage->IsCompressed) { + GLubyte *temp; + /* XXX compress from dstData into dstImage->Data */ + + /* swap src and dest pointers */ + temp = (GLubyte *) srcData; + srcData = dstData; + dstData = temp; + } + } /* loop over mipmap levels */ } diff --git a/src/mesa/main/texstore.h b/src/mesa/main/texstore.h index 6b1b09a1d9..8d1e149102 100644 --- a/src/mesa/main/texstore.h +++ b/src/mesa/main/texstore.h @@ -1,4 +1,4 @@ -/* $Id: texstore.h,v 1.10 2002/09/16 17:57:14 brianp Exp $ */ +/* $Id: texstore.h,v 1.11 2002/09/27 02:45:38 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -136,10 +136,33 @@ _mesa_store_compressed_teximage3d(GLcontext *ctx, GLenum target, GLint level, extern void -_mesa_get_compressed_teximage(GLcontext *ctx, GLenum target, - GLint level, void *image, - const struct gl_texture_object *texObj, - struct gl_texture_image *texImage); +_mesa_store_compressed_texsubimage1d(GLcontext *ctx, GLenum target, + GLint level, + GLint xoffset, GLsizei width, + GLenum format, + GLsizei imageSize, const GLvoid *data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); + +extern void +_mesa_store_compressed_texsubimage2d(GLcontext *ctx, GLenum target, + GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, + GLsizei imageSize, const GLvoid *data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); + +extern void +_mesa_store_compressed_texsubimage3d(GLcontext *ctx, GLenum target, + GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, + GLsizei imageSize, const GLvoid *data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); extern GLboolean diff --git a/src/mesa/main/texutil.c b/src/mesa/main/texutil.c index 75bd3b2263..28a715a723 100644 --- a/src/mesa/main/texutil.c +++ b/src/mesa/main/texutil.c @@ -1,8 +1,8 @@ -/* $Id: texutil.c,v 1.31 2002/09/21 16:51:25 brianp Exp $ */ +/* $Id: texutil.c,v 1.32 2002/09/27 02:45:38 brianp Exp $ */ /* * Mesa 3-D graphics library - * Version: 4.0.3 + * Version: 4.1 * * Copyright (C) 1999-2002 Brian Paul All Rights Reserved. * diff --git a/src/mesa/swrast/s_texstore.c b/src/mesa/swrast/s_texstore.c index 2ed4c6c954..9291220936 100644 --- a/src/mesa/swrast/s_texstore.c +++ b/src/mesa/swrast/s_texstore.c @@ -1,4 +1,4 @@ -/* $Id: s_texstore.c,v 1.7 2002/09/16 17:57:14 brianp Exp $ */ +/* $Id: s_texstore.c,v 1.8 2002/09/27 02:45:39 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -144,8 +144,8 @@ is_depth_format(GLenum format) */ void _swrast_copy_teximage1d( GLcontext *ctx, GLenum target, GLint level, - GLenum internalFormat, - GLint x, GLint y, GLsizei width, GLint border ) + GLenum internalFormat, + GLint x, GLint y, GLsizei width, GLint border ) { struct gl_texture_unit *texUnit; struct gl_texture_object *texObj; @@ -202,9 +202,9 @@ _swrast_copy_teximage1d( GLcontext *ctx, GLenum target, GLint level, */ void _swrast_copy_teximage2d( GLcontext *ctx, GLenum target, GLint level, - GLenum internalFormat, - GLint x, GLint y, GLsizei width, GLsizei height, - GLint border ) + GLenum internalFormat, + GLint x, GLint y, GLsizei width, GLsizei height, + GLint border ) { struct gl_texture_unit *texUnit; struct gl_texture_object *texObj; @@ -260,8 +260,8 @@ _swrast_copy_teximage2d( GLcontext *ctx, GLenum target, GLint level, * Fallback for Driver.CopyTexSubImage1D(). */ void -_swrast_copy_texsubimage1d(GLcontext *ctx, GLenum target, GLint level, - GLint xoffset, GLint x, GLint y, GLsizei width) +_swrast_copy_texsubimage1d( GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint x, GLint y, GLsizei width ) { struct gl_texture_unit *texUnit; struct gl_texture_object *texObj; @@ -275,48 +275,31 @@ _swrast_copy_texsubimage1d(GLcontext *ctx, GLenum target, GLint level, ASSERT(ctx->Driver.TexImage1D); - if (texImage->Format != GL_DEPTH_COMPONENT) { - /* read RGBA image from framebuffer */ - GLchan *image = read_color_image(ctx, x, y, width, 1); + if (texImage->Format == GL_DEPTH_COMPONENT) { + /* read depth image from framebuffer */ + GLfloat *image = read_depth_image(ctx, x, y, width, 1); if (!image) { - _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage1D" ); + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage1D"); return; } -#if 0 - /* - * XXX this is a bit of a hack. We need to be sure that the alpha - * channel is 1.0 if the internal texture format is not supposed to - * have an alpha channel. This is because some drivers may store - * RGB textures as RGBA and the texutil.c code isn't smart enough - * to set the alpha channel to 1.0 in this situation. - */ - if (texImage->Format == GL_LUMINANCE || - texImage->Format == GL_RGB) { - const GLuint n = width * 4; - GLuint i; - for (i = 0; i < n; i += 4) { - image[i + 3] = CHAN_MAX; - } - } -#endif - /* now call glTexSubImage1D to do the real work */ + /* call glTexSubImage1D to redefine the texture */ (*ctx->Driver.TexSubImage1D)(ctx, target, level, xoffset, width, - GL_RGBA, CHAN_TYPE, image, + GL_DEPTH_COMPONENT, GL_FLOAT, image, &_mesa_native_packing, texObj, texImage); FREE(image); } else { - /* read depth image from framebuffer */ - GLfloat *image = read_depth_image(ctx, x, y, width, 1); + /* read RGBA image from framebuffer */ + GLchan *image = read_color_image(ctx, x, y, width, 1); if (!image) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage1D"); + _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage1D" ); return; } - /* call glTexSubImage1D to redefine the texture */ + /* now call glTexSubImage1D to do the real work */ (*ctx->Driver.TexSubImage1D)(ctx, target, level, xoffset, width, - GL_DEPTH_COMPONENT, GL_FLOAT, image, + GL_RGBA, CHAN_TYPE, image, &_mesa_native_packing, texObj, texImage); FREE(image); } @@ -333,9 +316,9 @@ _swrast_copy_texsubimage1d(GLcontext *ctx, GLenum target, GLint level, */ void _swrast_copy_texsubimage2d( GLcontext *ctx, - GLenum target, GLint level, - GLint xoffset, GLint yoffset, - GLint x, GLint y, GLsizei width, GLsizei height ) + GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint x, GLint y, GLsizei width, GLsizei height ) { struct gl_texture_unit *texUnit; struct gl_texture_object *texObj; @@ -349,50 +332,33 @@ _swrast_copy_texsubimage2d( GLcontext *ctx, ASSERT(ctx->Driver.TexImage2D); - if (texImage->Format != GL_DEPTH_COMPONENT) { - /* read RGBA image from framebuffer */ - GLchan *image = read_color_image(ctx, x, y, width, height); + if (texImage->Format == GL_DEPTH_COMPONENT) { + /* read depth image from framebuffer */ + GLfloat *image = read_depth_image(ctx, x, y, width, height); if (!image) { - _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage2D" ); + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage2D"); return; } -#if 0 - /* - * XXX this is a bit of a hack. We need to be sure that the alpha - * channel is 1.0 if the internal texture format is not supposed to - * have an alpha channel. This is because some drivers may store - * RGB textures as RGBA and the texutil.c code isn't smart enough - * to set the alpha channel to 1.0 in this situation. - */ - if (texImage->Format == GL_LUMINANCE || - texImage->Format == GL_RGB) { - const GLuint n = width * height * 4; - GLuint i; - for (i = 0; i < n; i += 4) { - image[i + 3] = CHAN_MAX; - } - } -#endif - /* now call glTexSubImage2D to do the real work */ + /* call glTexImage1D to redefine the texture */ (*ctx->Driver.TexSubImage2D)(ctx, target, level, xoffset, yoffset, width, height, - GL_RGBA, CHAN_TYPE, image, + GL_DEPTH_COMPONENT, GL_FLOAT, image, &_mesa_native_packing, texObj, texImage); FREE(image); } else { - /* read depth image from framebuffer */ - GLfloat *image = read_depth_image(ctx, x, y, width, height); + /* read RGBA image from framebuffer */ + GLchan *image = read_color_image(ctx, x, y, width, height); if (!image) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage2D"); + _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage2D" ); return; } - /* call glTexImage1D to redefine the texture */ + /* now call glTexSubImage2D to do the real work */ (*ctx->Driver.TexSubImage2D)(ctx, target, level, xoffset, yoffset, width, height, - GL_DEPTH_COMPONENT, GL_FLOAT, image, + GL_RGBA, CHAN_TYPE, image, &_mesa_native_packing, texObj, texImage); FREE(image); } @@ -409,9 +375,9 @@ _swrast_copy_texsubimage2d( GLcontext *ctx, */ void _swrast_copy_texsubimage3d( GLcontext *ctx, - GLenum target, GLint level, - GLint xoffset, GLint yoffset, GLint zoffset, - GLint x, GLint y, GLsizei width, GLsizei height ) + GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLint x, GLint y, GLsizei width, GLsizei height ) { struct gl_texture_unit *texUnit; struct gl_texture_object *texObj; @@ -425,49 +391,33 @@ _swrast_copy_texsubimage3d( GLcontext *ctx, ASSERT(ctx->Driver.TexImage3D); - if (texImage->Format != GL_DEPTH_COMPONENT) { - /* read RGBA image from framebuffer */ - GLchan *image = read_color_image(ctx, x, y, width, height); + if (texImage->Format == GL_DEPTH_COMPONENT) { + /* read depth image from framebuffer */ + GLfloat *image = read_depth_image(ctx, x, y, width, height); if (!image) { - _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage3D" ); + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage3D"); return; } -#if 0 - /* - * XXX this is a bit of a hack. We need to be sure that the alpha - * channel is 1.0 if the internal texture format is not supposed to - * have an alpha channel. This is because some drivers may store - * RGB textures as RGBA and the texutil.c code isn't smart enough - * to set the alpha channel to 1.0 in this situation. - */ - if (texImage->Format == GL_LUMINANCE || - texImage->Format == GL_RGB) { - const GLuint n = width * height * 4; - GLuint i; - for (i = 0; i < n; i += 4) { - image[i + 3] = CHAN_MAX; - } - } -#endif - /* now call glTexSubImage3D to do the real work */ + + /* call glTexImage1D to redefine the texture */ (*ctx->Driver.TexSubImage3D)(ctx, target, level, xoffset, yoffset, zoffset, width, height, 1, - GL_RGBA, CHAN_TYPE, image, + GL_DEPTH_COMPONENT, GL_FLOAT, image, &_mesa_native_packing, texObj, texImage); FREE(image); } else { - /* read depth image from framebuffer */ - GLfloat *image = read_depth_image(ctx, x, y, width, height); + /* read RGBA image from framebuffer */ + GLchan *image = read_color_image(ctx, x, y, width, height); if (!image) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage3D"); + _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage3D" ); return; } - /* call glTexImage1D to redefine the texture */ + /* now call glTexSubImage3D to do the real work */ (*ctx->Driver.TexSubImage3D)(ctx, target, level, xoffset, yoffset, zoffset, width, height, 1, - GL_DEPTH_COMPONENT, GL_FLOAT, image, + GL_RGBA, CHAN_TYPE, image, &_mesa_native_packing, texObj, texImage); FREE(image); } -- cgit v1.2.3