summaryrefslogtreecommitdiffstats
path: root/src/mesa/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/main')
-rw-r--r--src/mesa/main/Makefile.BeOS-R51
-rw-r--r--src/mesa/main/Makefile.DJ5
-rw-r--r--src/mesa/main/Makefile.OSMesa163
-rw-r--r--src/mesa/main/Makefile.X113
-rw-r--r--src/mesa/main/Makefile.ugl1
-rw-r--r--src/mesa/main/Makefile.win1
-rw-r--r--src/mesa/main/context.c3
-rw-r--r--src/mesa/main/dd.h51
-rw-r--r--src/mesa/main/extensions.c5
-rw-r--r--src/mesa/main/get.c42
-rw-r--r--src/mesa/main/mtypes.h15
-rw-r--r--src/mesa/main/state.c5
-rw-r--r--src/mesa/main/texcompress.c159
-rw-r--r--src/mesa/main/texcompress.h58
-rw-r--r--src/mesa/main/texformat.c51
-rw-r--r--src/mesa/main/texformat.h7
-rw-r--r--src/mesa/main/texformat_tmp.h13
-rw-r--r--src/mesa/main/teximage.c784
-rw-r--r--src/mesa/main/texstate.c18
-rw-r--r--src/mesa/main/texstore.c634
-rw-r--r--src/mesa/main/texstore.h33
-rw-r--r--src/mesa/main/texutil.c4
22 files changed, 1288 insertions, 608 deletions
diff --git a/src/mesa/main/Makefile.BeOS-R5 b/src/mesa/main/Makefile.BeOS-R5
index 65303863a23..00deb0e0077 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 57187420f58..92a9f090449 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 4613f1a2703..1f3b09206ac 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 19a90b03b23..378df24eb82 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 f8f00fa411b..ae9ee7e5412 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 77814140a71..2b3f50e192f 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 4a0b4ed23d6..986dbc5aca9 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 fcf0ceeb0de..8f40846975e 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.
- * <target>, <level>, <image> are specified by user.
- * <texObj> is the source texture object.
- * <texImage> 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 05603974319..0129c8601af 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 4ccec6b9d81..4eee2c9fa76 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 d3c6c6196d3..3509be79877 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 d3d0baa934d..24e127a93fc 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 00000000000..0ba9aa9a4cd
--- /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 00000000000..53571673f00
--- /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 2c95b838592..1941c7a7b38 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 d1e7544a420..09997820eaf 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 f796928673f..9f84c39b3c8 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 <[email protected]>
+ * 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 769f74eda74..6ec00c07402 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
- /* <pixels> may be null! */
+ /* Give the texture to the driver! <pixels> 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
- /* <pixels> may be null! */
+ /* Give the texture to the driver! <pixels> 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
- /* <pixels> may be null! */
+ /* Give the texture to the driver! <pixels> 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 302f071093a..1287bdf2bf8 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 07404a26094..899cf044fa7 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 6b1b09a1d90..8d1e149102b 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 75bd3b22633..28a715a7237 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.
*