summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgareth <gareth>2001-03-06 04:37:36 +0000
committergareth <gareth>2001-03-06 04:37:36 +0000
commit86e3f5696de77926473bad2a1d700eb5569f8c6c (patch)
tree809d5c85665de4e74a73f0f3104f0f57385149da
parent2819b0e7e1edccbc3ff52b4b90241ac94f78d1e9 (diff)
Merge tdfx-3-1-0 branch.
-rw-r--r--xc/extras/Mesa/src/image.c23
-rw-r--r--xc/extras/Mesa/src/macros.h39
-rw-r--r--xc/extras/Mesa/src/texformat.c351
-rw-r--r--xc/extras/Mesa/src/texformat.h80
-rw-r--r--xc/extras/Mesa/src/teximage.c140
-rw-r--r--xc/extras/Mesa/src/teximage.h13
-rw-r--r--xc/extras/Mesa/src/texstate.c14
-rw-r--r--xc/extras/Mesa/src/texutil.c2829
-rw-r--r--xc/extras/Mesa/src/texutil.h103
-rw-r--r--xc/extras/Mesa/src/texutil_tmp.h375
-rw-r--r--xc/extras/Mesa/src/tritemp.h31
-rw-r--r--xc/extras/Mesa/src/types.h25
-rw-r--r--xc/lib/GL/mesa/src/Imakefile9
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810span.c6
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/Imakefile2
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgapixel.c6
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgatex.c194
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/Imakefile6
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_context.c8
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_dd.c7
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c8
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_state.c16
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_tex.c2330
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_tex.h2
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_texmem.c509
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_texobj.h24
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_texstate.c1103
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/Imakefile2
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/tdfx_context.c48
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/tdfx_context.h80
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/tdfx_dd.c46
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/tdfx_render.c15
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/tdfx_state.c10
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/tdfx_tex.c2339
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/tdfx_tex.h121
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/tdfx_texman.c1564
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/tdfx_texman.h66
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/tdfx_texstate.c423
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/tdfx_texstate.h44
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/tdfx_wrapper.h2
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/tdfx_xmesa.c13
-rw-r--r--xc/programs/Xserver/GL/mesa/src/Imakefile5
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h60
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_sarea.h2
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h2
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_cp.c50
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drm.h20
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.c4
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.h30
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_state.c234
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmRadeon.c41
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/drm.h2
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/xf86drmRadeon.h52
53 files changed, 6781 insertions, 6747 deletions
diff --git a/xc/extras/Mesa/src/image.c b/xc/extras/Mesa/src/image.c
index c0f463c39..5ffb84dce 100644
--- a/xc/extras/Mesa/src/image.c
+++ b/xc/extras/Mesa/src/image.c
@@ -2,19 +2,19 @@
/*
* Mesa 3-D graphics library
* Version: 3.4.1
- *
+ *
* Copyright (C) 1999-2000 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
@@ -1545,7 +1545,6 @@ _mesa_pack_rgba_span( GLcontext *ctx,
_mesa_pack_float_rgba_span(ctx, n, (const GLfloat (*)[4]) rgba,
format, type, destination,
packing, applyTransferOps);
-
}
}
@@ -1811,7 +1810,7 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4],
alphaIndex = 0;
stride = 1;
break;
- case GL_LUMINANCE:
+ case GL_LUMINANCE:
redIndex = greenIndex = blueIndex = 0;
alphaIndex = -1;
stride = 1;
@@ -2159,7 +2158,7 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4],
GLuint i;
for (i = 0; i < n; i ++) {
GLuint p = uisrc[i];
- rgba[i][rComp] = UBYTE_COLOR_TO_FLOAT_COLOR((p >> 24) );
+ rgba[i][rComp] = UBYTE_COLOR_TO_FLOAT_COLOR((p >> 24) );
rgba[i][gComp] = UBYTE_COLOR_TO_FLOAT_COLOR((p >> 16) & 0xff);
rgba[i][bComp] = UBYTE_COLOR_TO_FLOAT_COLOR((p >> 8) & 0xff);
rgba[i][aComp] = UBYTE_COLOR_TO_FLOAT_COLOR((p ) & 0xff);
@@ -2173,7 +2172,7 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4],
rgba[i][rComp] = UBYTE_COLOR_TO_FLOAT_COLOR((p ) & 0xff);
rgba[i][gComp] = UBYTE_COLOR_TO_FLOAT_COLOR((p >> 8) & 0xff);
rgba[i][bComp] = UBYTE_COLOR_TO_FLOAT_COLOR((p >> 16) & 0xff);
- rgba[i][aComp] = UBYTE_COLOR_TO_FLOAT_COLOR((p >> 24) );
+ rgba[i][aComp] = UBYTE_COLOR_TO_FLOAT_COLOR((p >> 24) );
}
}
break;
@@ -2262,7 +2261,7 @@ _mesa_unpack_ubyte_color_span( GLcontext *ctx,
GLboolean applyTransferOps )
{
ASSERT(dstFormat == GL_ALPHA ||
- dstFormat == GL_LUMINANCE ||
+ dstFormat == GL_LUMINANCE ||
dstFormat == GL_LUMINANCE_ALPHA ||
dstFormat == GL_INTENSITY ||
dstFormat == GL_RGB ||
@@ -2474,7 +2473,7 @@ _mesa_unpack_ubyte_color_span( GLcontext *ctx,
dstRedIndex = dstGreenIndex = dstBlueIndex = -1;
dstLuminanceIndex = dstIntensityIndex = -1;
break;
- case GL_LUMINANCE:
+ case GL_LUMINANCE:
dstLuminanceIndex = 0;
dstRedIndex = dstGreenIndex = dstBlueIndex = dstAlphaIndex = -1;
dstIntensityIndex = -1;
@@ -2581,7 +2580,7 @@ _mesa_unpack_float_color_span( GLcontext *ctx,
GLboolean applyTransferOps, GLboolean clamp )
{
ASSERT(dstFormat == GL_ALPHA ||
- dstFormat == GL_LUMINANCE ||
+ dstFormat == GL_LUMINANCE ||
dstFormat == GL_LUMINANCE_ALPHA ||
dstFormat == GL_INTENSITY ||
dstFormat == GL_RGB ||
@@ -2743,7 +2742,7 @@ _mesa_unpack_float_color_span( GLcontext *ctx,
dstRedIndex = dstGreenIndex = dstBlueIndex = -1;
dstLuminanceIndex = dstIntensityIndex = -1;
break;
- case GL_LUMINANCE:
+ case GL_LUMINANCE:
dstLuminanceIndex = 0;
dstRedIndex = dstGreenIndex = dstBlueIndex = dstAlphaIndex = -1;
dstIntensityIndex = -1;
diff --git a/xc/extras/Mesa/src/macros.h b/xc/extras/Mesa/src/macros.h
index 16038d3b1..8010e28bd 100644
--- a/xc/extras/Mesa/src/macros.h
+++ b/xc/extras/Mesa/src/macros.h
@@ -2,19 +2,19 @@
/*
* Mesa 3-D graphics library
* Version: 3.3
- *
+ *
* Copyright (C) 1999 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
@@ -89,7 +89,7 @@
#define TEST_BITS(WORD, BITS) ((WORD) & (BITS))
-/* Stepping a GLfloat pointer by a byte stride
+/* Stepping a GLfloat pointer by a byte stride
*/
#define STRIDE_F(p, i) (p = (GLfloat *)((GLubyte *)p + i))
#define STRIDE_UI(p, i) (p = (GLuint *)((GLubyte *)p + i))
@@ -160,7 +160,7 @@ do { \
case 2: (DST)[1] = (SRC)[1]; \
case 1: (DST)[0] = (SRC)[0]; \
} \
-} while(0)
+} while(0)
#define SUB_4V( DST, SRCA, SRCB ) \
do { \
@@ -496,4 +496,31 @@ do { \
#define FLOAT_TO_INT(X) ( (GLint) (2147483647.0 * (X)) )
+
+/* Generic color packing macros
+ */
+
+#define PACK_COLOR_8888( a, b, c, d ) \
+ (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
+
+#define PACK_COLOR_888( a, b, c ) \
+ (((a) << 16) | ((b) << 8) | (c))
+
+#define PACK_COLOR_565( a, b, c ) \
+ ((((a) & 0xf8) << 8) | (((b) & 0xfc) << 3) | (((c) & 0xf8) >> 3))
+
+#define PACK_COLOR_1555( a, b, c, d ) \
+ ((((b) & 0xf8) << 7) | (((c) & 0xf8) << 2) | (((d) & 0xf8) >> 3) | \
+ ((a) ? 0x8000 : 0))
+
+#define PACK_COLOR_4444( a, b, c, d ) \
+ ((((a) & 0xf0) << 8) | (((b) & 0xf0) << 4) | ((c) & 0xf0) | ((d) >> 4))
+
+#define PACK_COLOR_88( a, b ) \
+ (((a) << 8) | (b))
+
+#define PACK_COLOR_332( a, b, c ) \
+ (((a) & 0xe0) | (((b) & 0xe0) >> 3) | (((c) & 0xc0) >> 6))
+
+
#endif /*MACROS_H*/
diff --git a/xc/extras/Mesa/src/texformat.c b/xc/extras/Mesa/src/texformat.c
new file mode 100644
index 000000000..f85725843
--- /dev/null
+++ b/xc/extras/Mesa/src/texformat.c
@@ -0,0 +1,351 @@
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 3.4
+ *
+ * Copyright (C) 1999-2000 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.
+ *
+ * Author:
+ * Gareth Hughes <gareth@valinux.com>
+ */
+
+#ifdef PC_HEADER
+#include "all.h"
+#else
+#include "glheader.h"
+#include "context.h"
+#include "image.h"
+#include "mem.h"
+#include "mmath.h"
+#include "span.h"
+#include "texformat.h"
+#include "teximage.h"
+#include "texstate.h"
+#include "types.h"
+#endif
+
+
+/* ================================================================
+ * Texture internal formats:
+ */
+
+const struct gl_texture_format _mesa_texformat_rgba8888 = {
+ MESA_FORMAT_RGBA8888, /* IntFormat */
+ 8, /* RedBits */
+ 8, /* GreenBits */
+ 8, /* BlueBits */
+ 8, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 4, /* TexelBytes */
+};
+
+const struct gl_texture_format _mesa_texformat_abgr8888 = {
+ MESA_FORMAT_ABGR8888, /* IntFormat */
+ 8, /* RedBits */
+ 8, /* GreenBits */
+ 8, /* BlueBits */
+ 8, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 4, /* TexelBytes */
+};
+
+const struct gl_texture_format _mesa_texformat_argb8888 = {
+ MESA_FORMAT_ARGB8888, /* IntFormat */
+ 8, /* RedBits */
+ 8, /* GreenBits */
+ 8, /* BlueBits */
+ 8, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 4, /* TexelBytes */
+};
+
+const struct gl_texture_format _mesa_texformat_rgb888 = {
+ MESA_FORMAT_RGB888, /* IntFormat */
+ 8, /* RedBits */
+ 8, /* GreenBits */
+ 8, /* BlueBits */
+ 0, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 3, /* TexelBytes */
+};
+
+const struct gl_texture_format _mesa_texformat_bgr888 = {
+ MESA_FORMAT_BGR888, /* IntFormat */
+ 8, /* RedBits */
+ 8, /* GreenBits */
+ 8, /* BlueBits */
+ 0, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 3, /* TexelBytes */
+};
+
+const struct gl_texture_format _mesa_texformat_rgb565 = {
+ MESA_FORMAT_RGB565, /* IntFormat */
+ 5, /* RedBits */
+ 6, /* GreenBits */
+ 5, /* BlueBits */
+ 0, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 2, /* TexelBytes */
+};
+
+const struct gl_texture_format _mesa_texformat_argb4444 = {
+ MESA_FORMAT_ARGB4444, /* IntFormat */
+ 4, /* RedBits */
+ 4, /* GreenBits */
+ 4, /* BlueBits */
+ 4, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 2, /* TexelBytes */
+};
+
+const struct gl_texture_format _mesa_texformat_argb1555 = {
+ MESA_FORMAT_ARGB1555, /* IntFormat */
+ 5, /* RedBits */
+ 5, /* GreenBits */
+ 5, /* BlueBits */
+ 1, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 2, /* TexelBytes */
+};
+
+const struct gl_texture_format _mesa_texformat_al88 = {
+ MESA_FORMAT_AL88, /* IntFormat */
+ 0, /* RedBits */
+ 0, /* GreenBits */
+ 0, /* BlueBits */
+ 8, /* AlphaBits */
+ 8, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 2, /* TexelBytes */
+};
+
+const struct gl_texture_format _mesa_texformat_rgb332 = {
+ MESA_FORMAT_RGB332, /* IntFormat */
+ 3, /* RedBits */
+ 3, /* GreenBits */
+ 2, /* BlueBits */
+ 0, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 1, /* TexelBytes */
+};
+
+const struct gl_texture_format _mesa_texformat_a8 = {
+ MESA_FORMAT_A8, /* IntFormat */
+ 0, /* RedBits */
+ 0, /* GreenBits */
+ 0, /* BlueBits */
+ 8, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 1, /* TexelBytes */
+};
+
+const struct gl_texture_format _mesa_texformat_l8 = {
+ MESA_FORMAT_L8, /* IntFormat */
+ 0, /* RedBits */
+ 0, /* GreenBits */
+ 0, /* BlueBits */
+ 0, /* AlphaBits */
+ 8, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 1, /* TexelBytes */
+};
+
+const struct gl_texture_format _mesa_texformat_i8 = {
+ MESA_FORMAT_I8, /* IntFormat */
+ 0, /* RedBits */
+ 0, /* GreenBits */
+ 0, /* BlueBits */
+ 0, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 8, /* IntensityBits */
+ 0, /* IndexBits */
+ 1, /* TexelBytes */
+};
+
+const struct gl_texture_format _mesa_texformat_ci8 = {
+ MESA_FORMAT_CI8, /* IntFormat */
+ 0, /* RedBits */
+ 0, /* GreenBits */
+ 0, /* BlueBits */
+ 0, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 8, /* IndexBits */
+ 1, /* TexelBytes */
+};
+
+const struct gl_texture_format _mesa_null_texformat = {
+ -1, /* IntFormat */
+ 0, /* RedBits */
+ 0, /* GreenBits */
+ 0, /* BlueBits */
+ 0, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 0, /* TexelBytes */
+};
+
+
+
+/*
+ * 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.
+ * Return -1 if invalid enum.
+ */
+void _mesa_init_texture_format( GLcontext *ctx,
+ struct gl_texture_image *texImage,
+ GLenum internalFormat )
+{
+ texImage->IntFormat = internalFormat;
+
+ /* Ask the driver for the base format, if it doesn't know, it will
+ * return -1;
+ */
+ if ( ctx->Driver.BaseCompressedTexFormat ) {
+ GLint format = 0; /* Silence compiler warning */
+ format = (*ctx->Driver.BaseCompressedTexFormat)( ctx, format );
+ if ( format >= 0 ) {
+ internalFormat = format;
+ }
+ }
+
+ switch ( internalFormat ) {
+ /* GH: Bias towards GL_RGB, GL_RGBA texture formats. This has
+ * got to be better than sticking them way down the end of this
+ * huge list.
+ */
+ case 4: /* Quake3 uses this... */
+ case GL_RGBA:
+ texImage->Format = GL_RGBA;
+ texImage->TexFormat = &_mesa_texformat_abgr8888;
+ break;
+
+ case 3: /* ... and this. */
+ case GL_RGB:
+ texImage->Format = GL_RGB;
+ texImage->TexFormat = &_mesa_texformat_bgr888;
+ break;
+
+ /* GH: Okay, keep checking as normal. Still test for GL_RGB,
+ * GL_RGBA formats first.
+ */
+ case GL_RGBA2:
+ case GL_RGBA4:
+ case GL_RGB5_A1:
+ case GL_RGBA8:
+ case GL_RGB10_A2:
+ case GL_RGBA12:
+ case GL_RGBA16:
+ texImage->Format = GL_RGBA;
+ texImage->TexFormat = &_mesa_texformat_abgr8888;
+ break;
+
+ case GL_R3_G3_B2:
+ case GL_RGB4:
+ case GL_RGB5:
+ case GL_RGB8:
+ case GL_RGB10:
+ case GL_RGB12:
+ case GL_RGB16:
+ texImage->Format = GL_RGB;
+ texImage->TexFormat = &_mesa_texformat_bgr888;
+ break;
+
+ case GL_ALPHA:
+ case GL_ALPHA4:
+ case GL_ALPHA8:
+ case GL_ALPHA12:
+ case GL_ALPHA16:
+ texImage->Format = GL_ALPHA;
+ texImage->TexFormat = &_mesa_texformat_a8;
+ break;
+
+ case 1:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE4:
+ case GL_LUMINANCE8:
+ case GL_LUMINANCE12:
+ case GL_LUMINANCE16:
+ texImage->Format = GL_LUMINANCE;
+ texImage->TexFormat = &_mesa_texformat_l8;
+ break;
+
+ case 2:
+ case GL_LUMINANCE_ALPHA:
+ case GL_LUMINANCE4_ALPHA4:
+ case GL_LUMINANCE6_ALPHA2:
+ case GL_LUMINANCE8_ALPHA8:
+ case GL_LUMINANCE12_ALPHA4:
+ case GL_LUMINANCE12_ALPHA12:
+ case GL_LUMINANCE16_ALPHA16:
+ texImage->Format = GL_LUMINANCE_ALPHA;
+ texImage->TexFormat = &_mesa_texformat_al88;
+ break;
+
+ case GL_INTENSITY:
+ case GL_INTENSITY4:
+ case GL_INTENSITY8:
+ case GL_INTENSITY12:
+ case GL_INTENSITY16:
+ texImage->Format = GL_INTENSITY;
+ texImage->TexFormat = &_mesa_texformat_i8;
+ break;
+
+ case GL_COLOR_INDEX:
+ case GL_COLOR_INDEX1_EXT:
+ case GL_COLOR_INDEX2_EXT:
+ case GL_COLOR_INDEX4_EXT:
+ case GL_COLOR_INDEX8_EXT:
+ case GL_COLOR_INDEX12_EXT:
+ case GL_COLOR_INDEX16_EXT:
+ texImage->Format = GL_COLOR_INDEX;
+ texImage->TexFormat = &_mesa_texformat_ci8;
+ break;
+
+ default:
+ gl_problem( ctx, "unexpected format in _mesa_init_texture_format" );
+ return;
+ }
+}
diff --git a/xc/extras/Mesa/src/texformat.h b/xc/extras/Mesa/src/texformat.h
new file mode 100644
index 000000000..8f5e7de75
--- /dev/null
+++ b/xc/extras/Mesa/src/texformat.h
@@ -0,0 +1,80 @@
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 3.4
+ *
+ * Copyright (C) 1999-2000 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.
+ *
+ * Author:
+ * Gareth Hughes <gareth@valinux.com>
+ */
+
+#ifndef TEXFORMAT_H
+#define TEXFORMAT_H
+
+#include "types.h"
+
+
+/* The Mesa internal texture image types. These will be set to their
+ * default value, but may be changed by drivers as required.
+ */
+ /* msb <------ TEXEL BITS -----------> lsb */
+enum _format { /* ---- ---- ---- ---- ---- ---- ---- ---- */
+ MESA_FORMAT_RGBA8888, /* RRRR RRRR GGGG GGGG BBBB BBBB AAAA AAAA */
+ MESA_FORMAT_ABGR8888, /* AAAA AAAA BBBB BBBB GGGG GGGG RRRR RRRR */
+ MESA_FORMAT_ARGB8888, /* AAAA AAAA RRRR RRRR GGGG GGGG BBBB BBBB */
+ MESA_FORMAT_RGB888, /* RRRR RRRR GGGG GGGG BBBB BBBB */
+ MESA_FORMAT_BGR888, /* BBBB BBBB GGGG GGGG RRRR RRRR */
+ MESA_FORMAT_RGB565, /* RRRR RGGG GGGB BBBB */
+ MESA_FORMAT_ARGB4444, /* AAAA RRRR GGGG BBBB */
+ MESA_FORMAT_ARGB1555, /* ARRR RRGG GGGB BBBB */
+ MESA_FORMAT_AL88, /* AAAA AAAA LLLL LLLL */
+ MESA_FORMAT_RGB332, /* RRRG GGBB */
+ MESA_FORMAT_A8, /* AAAA AAAA */
+ MESA_FORMAT_L8, /* LLLL LLLL */
+ MESA_FORMAT_I8, /* IIII IIII */
+ MESA_FORMAT_CI8 /* CCCC CCCC */
+};
+
+
+extern void
+_mesa_init_texture_format( GLcontext *ctx,
+ struct gl_texture_image *texImage,
+ GLenum internalFormat );
+
+
+extern const struct gl_texture_format _mesa_texformat_rgba8888;
+extern const struct gl_texture_format _mesa_texformat_abgr8888;
+extern const struct gl_texture_format _mesa_texformat_argb8888;
+extern const struct gl_texture_format _mesa_texformat_rgb888;
+extern const struct gl_texture_format _mesa_texformat_bgr888;
+extern const struct gl_texture_format _mesa_texformat_rgb565;
+extern const struct gl_texture_format _mesa_texformat_argb4444;
+extern const struct gl_texture_format _mesa_texformat_argb1555;
+extern const struct gl_texture_format _mesa_texformat_al88;
+extern const struct gl_texture_format _mesa_texformat_rgb332;
+extern const struct gl_texture_format _mesa_texformat_a8;
+extern const struct gl_texture_format _mesa_texformat_l8;
+extern const struct gl_texture_format _mesa_texformat_i8;
+extern const struct gl_texture_format _mesa_texformat_ci8;
+
+extern const struct gl_texture_format _mesa_null_texformat;
+
+#endif
diff --git a/xc/extras/Mesa/src/teximage.c b/xc/extras/Mesa/src/teximage.c
index 4b71d5178..fc610cb0b 100644
--- a/xc/extras/Mesa/src/teximage.c
+++ b/xc/extras/Mesa/src/teximage.c
@@ -2,19 +2,19 @@
/*
* Mesa 3-D graphics library
* Version: 3.4
- *
+ *
* Copyright (C) 1999-2000 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
@@ -33,6 +33,7 @@
#include "mem.h"
#include "mmath.h"
#include "span.h"
+#include "texformat.h"
#include "teximage.h"
#include "texstate.h"
#include "types.h"
@@ -300,115 +301,6 @@ is_compressed_format(GLcontext *ctx, GLenum internalFormat)
-/*
- * Examine the texImage->Format field and set the Red, Green, Blue, etc
- * texel component sizes to default values.
- * These fields are set only here by core Mesa but device drivers may
- * overwritting these fields to indicate true texel resolution.
- */
-static void
-set_teximage_component_sizes( struct gl_texture_image *texImage )
-{
- switch (texImage->Format) {
- case GL_ALPHA:
- texImage->RedBits = 0;
- texImage->GreenBits = 0;
- texImage->BlueBits = 0;
- texImage->AlphaBits = 8;
- texImage->IntensityBits = 0;
- texImage->LuminanceBits = 0;
- texImage->IndexBits = 0;
- break;
- case GL_LUMINANCE:
- texImage->RedBits = 0;
- texImage->GreenBits = 0;
- texImage->BlueBits = 0;
- texImage->AlphaBits = 0;
- texImage->IntensityBits = 0;
- texImage->LuminanceBits = 8;
- texImage->IndexBits = 0;
- break;
- case GL_LUMINANCE_ALPHA:
- texImage->RedBits = 0;
- texImage->GreenBits = 0;
- texImage->BlueBits = 0;
- texImage->AlphaBits = 8;
- texImage->IntensityBits = 0;
- texImage->LuminanceBits = 8;
- texImage->IndexBits = 0;
- break;
- case GL_INTENSITY:
- texImage->RedBits = 0;
- texImage->GreenBits = 0;
- texImage->BlueBits = 0;
- texImage->AlphaBits = 0;
- texImage->IntensityBits = 8;
- texImage->LuminanceBits = 0;
- texImage->IndexBits = 0;
- break;
- case GL_RED:
- texImage->RedBits = 8;
- texImage->GreenBits = 0;
- texImage->BlueBits = 0;
- texImage->AlphaBits = 0;
- texImage->IntensityBits = 0;
- texImage->LuminanceBits = 0;
- texImage->IndexBits = 0;
- break;
- case GL_GREEN:
- texImage->RedBits = 0;
- texImage->GreenBits = 8;
- texImage->BlueBits = 0;
- texImage->AlphaBits = 0;
- texImage->IntensityBits = 0;
- texImage->LuminanceBits = 0;
- texImage->IndexBits = 0;
- break;
- case GL_BLUE:
- texImage->RedBits = 0;
- texImage->GreenBits = 0;
- texImage->BlueBits = 8;
- texImage->AlphaBits = 0;
- texImage->IntensityBits = 0;
- texImage->LuminanceBits = 0;
- texImage->IndexBits = 0;
- break;
- case GL_RGB:
- case GL_BGR:
- texImage->RedBits = 8;
- texImage->GreenBits = 8;
- texImage->BlueBits = 8;
- texImage->AlphaBits = 0;
- texImage->IntensityBits = 0;
- texImage->LuminanceBits = 0;
- texImage->IndexBits = 0;
- break;
- case GL_RGBA:
- case GL_BGRA:
- case GL_ABGR_EXT:
- texImage->RedBits = 8;
- texImage->GreenBits = 8;
- texImage->BlueBits = 8;
- texImage->AlphaBits = 8;
- texImage->IntensityBits = 0;
- texImage->LuminanceBits = 0;
- texImage->IndexBits = 0;
- break;
- case GL_COLOR_INDEX:
- texImage->RedBits = 0;
- texImage->GreenBits = 0;
- texImage->BlueBits = 0;
- texImage->AlphaBits = 0;
- texImage->IntensityBits = 0;
- texImage->LuminanceBits = 0;
- texImage->IndexBits = 8;
- break;
- default:
- gl_problem(NULL, "unexpected format in set_teximage_component_sizes");
- }
-}
-
-
static void
set_tex_image(struct gl_texture_object *tObj,
GLenum target, GLint level,
@@ -467,9 +359,7 @@ init_texture_image( GLcontext *ctx,
{
ASSERT(img);
ASSERT(!img->Data);
- img->Format = (GLenum) _mesa_base_tex_format(ctx, internalFormat);
- set_teximage_component_sizes( img );
- img->IntFormat = (GLenum) internalFormat;
+ _mesa_init_texture_format( ctx, img, internalFormat );
img->Border = border;
img->Width = width;
img->Height = height;
@@ -745,7 +635,7 @@ make_texture_image( GLcontext *ctx,
}
return; /* all done */
}
- }
+ }
/*
@@ -851,13 +741,6 @@ clear_proxy_teximage(struct gl_texture_image *img)
ASSERT(img);
img->Format = 0;
img->IntFormat = 0;
- img->RedBits = 0;
- img->GreenBits = 0;
- img->BlueBits = 0;
- img->AlphaBits = 0;
- img->IntensityBits = 0;
- img->LuminanceBits = 0;
- img->IndexBits = 0;
img->Border = 0;
img->Width = 0;
img->Height = 0;
@@ -871,6 +754,7 @@ clear_proxy_teximage(struct gl_texture_image *img)
img->Data = NULL;
img->IsCompressed = 0;
img->CompressedSize = 0;
+ img->TexFormat = &_mesa_null_texformat;
}
@@ -2521,7 +2405,7 @@ _mesa_CopyTexImage1D( GLenum target, GLint level,
return;
if (ctx->Pixel.MapColorFlag || ctx->Pixel.ScaleOrBiasRGBA
- || !ctx->Driver.CopyTexImage1D
+ || !ctx->Driver.CopyTexImage1D
|| !(*ctx->Driver.CopyTexImage1D)(ctx, target, level,
internalFormat, x, y, width, border))
{
@@ -2616,7 +2500,7 @@ _mesa_CopyTexSubImage1D( GLenum target, GLint level,
gl_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage2D" );
return;
}
-
+
/* now call glTexSubImage1D to do the real work */
unpackSave = ctx->Unpack;
ctx->Unpack = _mesa_native_packing;
@@ -2668,7 +2552,7 @@ _mesa_CopyTexSubImage2D( GLenum target, GLint level,
_mesa_TexSubImage2D(target, level, xoffset, yoffset, width, height,
GL_RGBA, GL_UNSIGNED_BYTE, image);
ctx->Unpack = unpackSave;
-
+
FREE(image);
}
}
@@ -2713,7 +2597,7 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level,
_mesa_TexSubImage3D(target, level, xoffset, yoffset, zoffset,
width, height, 1, GL_RGBA, GL_UNSIGNED_BYTE, image);
ctx->Unpack = unpackSave;
-
+
FREE(image);
}
}
diff --git a/xc/extras/Mesa/src/teximage.h b/xc/extras/Mesa/src/teximage.h
index ebc45e690..45ce79a1b 100644
--- a/xc/extras/Mesa/src/teximage.h
+++ b/xc/extras/Mesa/src/teximage.h
@@ -2,19 +2,19 @@
/*
* Mesa 3-D graphics library
* Version: 3.4
- *
+ *
* Copyright (C) 1999-2000 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
@@ -142,7 +142,7 @@ _mesa_CopyTexImage2D( GLenum target, GLint level,
extern void
-_mesa_CopyTexSubImage1D( GLenum target, GLint level, GLint xoffset,
+_mesa_CopyTexSubImage1D( GLenum target, GLint level, GLint xoffset,
GLint x, GLint y, GLsizei width );
@@ -152,7 +152,7 @@ _mesa_CopyTexSubImage2D( GLenum target, GLint level,
GLint x, GLint y, GLsizei width, GLsizei height );
-extern void
+extern void
_mesa_CopyTexSubImage3D( GLenum target, GLint level,
GLint xoffset, GLint yoffset, GLint zoffset,
GLint x, GLint y, GLsizei width, GLsizei height );
@@ -204,4 +204,3 @@ _mesa_GetCompressedTexImageARB(GLenum target, GLint lod, GLvoid *img);
#endif
-
diff --git a/xc/extras/Mesa/src/texstate.c b/xc/extras/Mesa/src/texstate.c
index 08204bd88..d74feb578 100644
--- a/xc/extras/Mesa/src/texstate.c
+++ b/xc/extras/Mesa/src/texstate.c
@@ -890,25 +890,25 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level,
*params = img->Border;
return;
case GL_TEXTURE_RED_SIZE:
- *params = img->RedBits;
+ *params = img->TexFormat->RedBits;
return;
case GL_TEXTURE_GREEN_SIZE:
- *params = img->GreenBits;
+ *params = img->TexFormat->GreenBits;
return;
case GL_TEXTURE_BLUE_SIZE:
- *params = img->BlueBits;
+ *params = img->TexFormat->BlueBits;
return;
case GL_TEXTURE_ALPHA_SIZE:
- *params = img->AlphaBits;
+ *params = img->TexFormat->AlphaBits;
return;
case GL_TEXTURE_INTENSITY_SIZE:
- *params = img->IntensityBits;
+ *params = img->TexFormat->IntensityBits;
return;
case GL_TEXTURE_LUMINANCE_SIZE:
- *params = img->LuminanceBits;
+ *params = img->TexFormat->LuminanceBits;
return;
case GL_TEXTURE_INDEX_SIZE_EXT:
- *params = img->IndexBits;
+ *params = img->TexFormat->IndexBits;
return;
/* GL_ARB_texture_compression */
diff --git a/xc/extras/Mesa/src/texutil.c b/xc/extras/Mesa/src/texutil.c
index 313ef1455..4143830c1 100644
--- a/xc/extras/Mesa/src/texutil.c
+++ b/xc/extras/Mesa/src/texutil.c
@@ -2,1687 +2,1304 @@
/*
* Mesa 3-D graphics library
* Version: 3.4
- *
+ *
* Copyright (C) 1999-2000 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.
+ *
+ * Authors:
+ * Gareth Hughes <gareth@valinux.com>
*/
-
#ifdef PC_HEADER
#include "all.h"
#else
#include "glheader.h"
#include "context.h"
+#include "enums.h"
#include "image.h"
#include "mem.h"
+#include "texformat.h"
#include "texutil.h"
#include "types.h"
#endif
+#define DBG 0
-/*
- * Texture utilities which may be useful to device drivers.
- * See the texutil.h for the list of supported internal formats.
- * It's expected that new formats will be added for new hardware.
- */
+struct gl_texture_convert {
+ GLint xoffset, yoffset, zoffset; /* Subimage offset */
+ GLint width, height, depth; /* Subimage region */
-/*
- * If the system is little endian and can do 4-byte word stores on
- * non 4-byte-aligned addresses then we can use this optimization.
- */
-#if defined(__i386__)
-#define DO_32BIT_STORES000
+ GLint imageWidth, imageHeight; /* Full image dimensions */
+ GLenum format, type;
+
+ const struct gl_pixelstore_attrib *packing;
+
+ const GLvoid *srcImage;
+ GLvoid *dstImage;
+
+ GLint index;
+};
+
+typedef GLboolean (*convert_func)( struct gl_texture_convert *convert );
+typedef void (*unconvert_func)( struct gl_texture_convert *convert );
+
+#define CONVERT_STRIDE_BIT 0x1
+#define CONVERT_PACKING_BIT 0x2
+
+#ifdef __GNUC__
+#define ERROR_STRING __FUNCTION__
+#else
+#define ERROR_STRING __FILE__ ":" __LINE__
#endif
+#define UNCONVERT_ERROR( format ) \
+do { \
+ static char buffer[128]; \
+ sprintf( buffer, "illegal format %s in " ERROR_STRING "\n", \
+ gl_lookup_enum_by_nr( format ) ); \
+ gl_problem( NULL, buffer ); \
+} while (0)
-/*
- * Convert texture image data into one a specific internal format.
- * Input:
- * dstFormat - the destination internal format
- * dstWidth, dstHeight - the destination image size
- * dstImage - pointer to destination image buffer
- * dstRowStride - bytes to jump between image rows
- * srcWidth, srcHeight - size of texture image
- * srcFormat, srcType - format and datatype of source image
- * srcImage - pointer to user's texture image
- * packing - describes how user's texture image is packed.
- * Return: pointer to resulting image data or NULL if error or out of memory
- * or NULL if we can't process the given image format/type/internalFormat
- * combination.
- *
- * Supported type conversions:
- * srcFormat srcType dstFormat
- * GL_INTENSITY GL_UNSIGNED_BYTE MESA_I8
- * GL_LUMINANCE GL_UNSIGNED_BYTE MESA_L8
- * GL_ALPHA GL_UNSIGNED_BYTE MESA_A8
- * GL_COLOR_INDEX GL_UNSIGNED_BYTE MESA_C8
- * GL_LUMINANCE_ALPHA GL_UNSIGNED_BYTE MESA_A8_L8
- * GL_RGB GL_UNSIGNED_BYTE MESA_R5_G6_B5
- * GL_RGB GL_UNSIGNED_SHORT_5_6_5 MESA_R5_G6_B5
- * GL_RGBA GL_UNSIGNED_BYTE MESA_A4_R4_G4_B4
- * GL_BGRA GL_UNSIGNED_SHORT_4_4_4_4_REV MESA_A4_R4_G4_B4
- * GL_BGRA GL_UNSIGHED_SHORT_1_5_5_5_REV MESA_A1_R5_G5_B5
- * GL_RGBA GL_UNSIGNED_BYTE MESA_A1_R5_G5_B5
- * GL_BGRA GL_UNSIGNED_INT_8_8_8_8_REV MESA_A8_R8_G8_B8
- * GL_RGBA GL_UNSIGNED_BYTE MESA_A8_R8_G8_B8
- * GL_RGB GL_UNSIGNED_BYTE MESA_A8_R8_G8_B8
- * more to be added for new drivers...
- *
- * Notes:
- * Some hardware only supports texture images of specific aspect ratios.
- * This code will do power-of-two image up-scaling if that's needed.
- *
- *
+/* ================================================================
+ * RGBA8888 textures:
*/
-GLboolean
-_mesa_convert_teximage(MesaIntTexFormat dstFormat,
- GLint dstWidth, GLint dstHeight, GLvoid *dstImage,
- GLint dstRowStride,
- GLint srcWidth, GLint srcHeight,
- GLenum srcFormat, GLenum srcType,
- const GLvoid *srcImage,
- const struct gl_pixelstore_attrib *packing)
+
+#define DST_TYPE GLuint
+#define DST_TEXELS_PER_DWORD 1
+
+#define CONVERT_TEXEL( src ) \
+ PACK_COLOR_8888( src[3], src[2], src[1], src[0] )
+
+#define CONVERT_DIRECT
+
+#define SRC_TEXEL_BYTES 4
+
+#define TAG(x) x##_rgba8888_direct
+#define PRESERVE_DST_TYPE
+#include "texutil_tmp.h"
+
+
+#define CONVERT_TEXEL( src ) \
+ PACK_COLOR_8888( src[0], src[1], src[2], src[3] )
+
+#define CONVERT_TEXEL_DWORD( src ) CONVERT_TEXEL( src )
+
+#define SRC_TEXEL_BYTES 4
+
+#define TAG(x) x##_abgr8888_to_rgba8888
+#define PRESERVE_DST_TYPE
+#include "texutil_tmp.h"
+
+
+#define CONVERT_TEXEL( src ) \
+ PACK_COLOR_8888( src[0], src[1], src[2], 0xff )
+
+#define CONVERT_TEXEL_DWORD( src ) CONVERT_TEXEL( src )
+
+#define SRC_TEXEL_BYTES 3
+
+#define TAG(x) x##_bgr888_to_rgba8888
+#include "texutil_tmp.h"
+
+
+#define CONVERT_RGBA8888( name ) \
+static GLboolean \
+convert_##name##_rgba8888( struct gl_texture_convert *convert ) \
+{ \
+ convert_func *tab; \
+ GLint index = convert->index; \
+ \
+ if ( convert->format == GL_ABGR_EXT && \
+ convert->type == GL_UNSIGNED_INT_8_8_8_8_REV ) \
+ { \
+ tab = name##_tab_rgba8888_direct; \
+ } \
+ else if ( convert->format == GL_RGBA && \
+ ( convert->type == GL_UNSIGNED_BYTE || \
+ convert->type == GL_UNSIGNED_INT_8_8_8_8 ) ) \
+ { \
+ tab = name##_tab_abgr8888_to_rgba8888; \
+ } \
+ else if ( convert->format == GL_RGB && \
+ convert->type == GL_UNSIGNED_BYTE ) \
+ { \
+ tab = name##_tab_bgr888_to_rgba8888; \
+ } \
+ else \
+ { \
+ /* Can't handle this source format/type combination */ \
+ return GL_FALSE; \
+ } \
+ \
+ return tab[index]( convert ); \
+}
+
+CONVERT_RGBA8888( texsubimage2d )
+CONVERT_RGBA8888( texsubimage3d )
+
+
+static void
+unconvert_teximage_rgba8888( struct gl_texture_convert *convert )
{
- const GLint wScale = dstWidth / srcWidth; /* must be power of two */
- const GLint hScale = dstHeight / srcHeight; /* must be power of two */
- ASSERT(dstWidth >= srcWidth);
- ASSERT(dstHeight >= srcHeight);
- ASSERT(dstImage);
- ASSERT(srcImage);
- ASSERT(packing);
-
- switch (dstFormat) {
- case MESA_I8:
- case MESA_L8:
- case MESA_A8:
- case MESA_C8:
- if (srcType != GL_UNSIGNED_BYTE ||
- ((srcFormat != GL_INTENSITY) &&
- (srcFormat != GL_LUMINANCE) &&
- (srcFormat != GL_ALPHA) &&
- (srcFormat != GL_COLOR_INDEX))) {
- /* bad internal format / srcFormat combination */
- return GL_FALSE;
- }
- else {
- /* store as 8-bit texels */
- if (wScale == 1 && hScale == 1) {
- /* no scaling needed - fast case */
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
- srcFormat, srcType, 0, 0, 0);
- const GLint srcStride = _mesa_image_row_stride(packing,
- srcWidth, srcFormat, srcType);
- GLubyte *dst = (GLubyte *) dstImage;
- GLint row;
- for (row = 0; row < dstHeight; row++) {
- MEMCPY(dst, src, dstWidth * sizeof(GLubyte));
- dst += dstRowStride;
- src += srcStride;
- }
- }
- else {
- /* must rescale image */
- GLubyte *dst = (GLubyte *) dstImage;
- GLint row;
- for (row = 0; row < dstHeight; row++) {
- GLint srcRow = row / hScale;
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth,
- srcHeight, srcFormat, srcType, 0, srcRow, 0);
- GLint col;
- for (col = 0; col < dstWidth; col++) {
- dst[col] = src[col / wScale];
- }
- dst += dstRowStride;
- }
- }
- }
- break;
-
- case MESA_A8_L8:
- if (srcType != GL_UNSIGNED_BYTE || srcFormat != GL_LUMINANCE_ALPHA) {
- return GL_FALSE;
- }
- else {
- /* store as 16-bit texels */
- if (wScale == 1 && hScale == 1) {
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
- srcFormat, srcType, 0, 0, 0);
- const GLint srcStride = _mesa_image_row_stride(packing,
- srcWidth, srcFormat, srcType);
- GLushort *dst = (GLushort *) dstImage;
- GLint row, col;
- for (row = 0; row < dstHeight; row++) {
- for (col = 0; col < dstWidth; col++) {
- GLubyte luminance = src[col * 2 + 0];
- GLubyte alpha = src[col * 2 + 1];
- dst[col] = ((GLushort) alpha << 8) | luminance;
- }
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- src += srcStride;
- }
- }
- else {
- /* must rescale */
- GLushort *dst = (GLushort *) dstImage;
- GLint row, col;
- for (row = 0; row < dstHeight; row++) {
- GLint srcRow = row / hScale;
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth,
- srcHeight, srcFormat, srcType, 0, srcRow, 0);
- const GLint srcStride = _mesa_image_row_stride(packing,
- srcWidth, srcFormat, srcType);
- for (col = 0; col < dstWidth; col++) {
- GLint srcCol = col / wScale;
- GLubyte luminance = src[srcCol * 2 + 0];
- GLubyte alpha = src[srcCol * 2 + 1];
- dst[col] = ((GLushort) alpha << 8) | luminance;
- }
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- src += srcStride;
- }
- }
- }
- break;
-
- case MESA_R5_G6_B5:
- if (srcFormat == GL_RGB && srcType == GL_UNSIGNED_SHORT_5_6_5) {
- /* special, optimized case */
- if (wScale == 1 && hScale == 1) {
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
- srcFormat, srcType, 0, 0, 0);
- const GLint srcStride = _mesa_image_row_stride(packing,
- srcWidth, srcFormat, srcType);
- GLushort *dst = (GLushort *) dstImage;
- GLint row;
- for (row = 0; row < dstHeight; row++) {
- MEMCPY(dst, src, dstWidth * sizeof(GLushort));
- src += srcStride;
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
- }
- else {
- /* must rescale image */
- GLushort *dst = (GLushort *) dstImage;
- GLint row;
- for (row = 0; row < dstHeight; row++) {
- GLint srcRow = row / hScale;
- const GLushort *src = (const GLushort *)
- _mesa_image_address(packing, srcImage, srcWidth,
- srcHeight, srcFormat, srcType, 0, srcRow, 0);
- GLint col;
- for (col = 0; col < dstWidth; col++) {
- dst[col] = src[col / wScale];
- }
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
- }
- }
- else if (srcFormat == GL_RGB && srcType == GL_UNSIGNED_BYTE) {
- /* general case */
- if (wScale == 1 && hScale == 1) {
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
- srcFormat, srcType, 0, 0, 0);
- const GLint srcStride = _mesa_image_row_stride(packing,
- srcWidth, srcFormat, srcType);
-#ifdef DO_32BIT_STORES
- GLuint *dst = (GLuint *) dstImage;
- GLint row;
- for (row = 0; row < dstHeight; row++) {
- GLint col, col3;
- GLint halfDstWidth = dstWidth >> 1;
- for (col = col3 = 0; col < halfDstWidth; col++, col3 += 6) {
- GLubyte r0 = src[col3 + 0];
- GLubyte g0 = src[col3 + 1];
- GLubyte b0 = src[col3 + 2];
- GLubyte r1 = src[col3 + 3];
- GLubyte g1 = src[col3 + 4];
- GLubyte b1 = src[col3 + 5];
- GLuint d0 = ((r0 & 0xf8) << 8)
- | ((g0 & 0xfc) << 3)
- | ((b0 & 0xf8) >> 3);
- GLuint d1 = ((r1 & 0xf8) << 8)
- | ((g1 & 0xfc) << 3)
- | ((b1 & 0xf8) >> 3);
- dst[col] = (d1 << 16) | d0;
- }
- src += srcStride;
- dst = (GLuint *) ((GLubyte *) dst + dstRowStride);
- }
-#else /* 16-bit stores */
- GLushort *dst = (GLushort *) dstImage;
- GLint row;
- for (row = 0; row < dstHeight; row++) {
- GLint col, col3;
- for (col = col3 = 0; col < dstWidth; col++, col3 += 3) {
- GLubyte r = src[col3 + 0];
- GLubyte g = src[col3 + 1];
- GLubyte b = src[col3 + 2];
- dst[col] = ((r & 0xf8) << 8)
- | ((g & 0xfc) << 3)
- | ((b & 0xf8) >> 3);
- }
- src += srcStride;
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
-#endif
- }
- else {
- /* must rescale image */
- GLushort *dst = (GLushort *) dstImage;
- GLint row;
- for (row = 0; row < dstHeight; row++) {
- GLint srcRow = row / hScale;
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth,
- srcHeight, srcFormat, srcType, 0, srcRow, 0);
- GLint col;
- for (col = 0; col < dstWidth; col++) {
- GLint col3 = (col / wScale) * 3;
- GLubyte r = src[col3 + 0];
- GLubyte g = src[col3 + 1];
- GLubyte b = src[col3 + 2];
- dst[col] = ((r & 0xf8) << 8)
- | ((g & 0xfc) << 3)
- | ((b & 0xf8) >> 3);
- }
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
- }
- }
- else if (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE) {
- /* general case (used by Quake3) */
- if (wScale == 1 && hScale == 1) {
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
- srcFormat, srcType, 0, 0, 0);
- const GLint srcStride = _mesa_image_row_stride(packing,
- srcWidth, srcFormat, srcType);
-#ifdef DO_32BIT_STORES
- GLuint *dst = dstImage;
- GLint row;
- for (row = 0; row < dstHeight; row++) {
- GLint col, col4;
- GLint halfDstWidth = dstWidth >> 1;
- for (col = col4 = 0; col < halfDstWidth; col++, col4 += 8) {
- GLubyte r0 = src[col4 + 0];
- GLubyte g0 = src[col4 + 1];
- GLubyte b0 = src[col4 + 2];
- GLubyte r1 = src[col4 + 4];
- GLubyte g1 = src[col4 + 5];
- GLubyte b1 = src[col4 + 6];
- GLuint d0 = ((r0 & 0xf8) << 8)
- | ((g0 & 0xfc) << 3)
- | ((b0 & 0xf8) >> 3);
- GLuint d1 = ((r1 & 0xf8) << 8)
- | ((g1 & 0xfc) << 3)
- | ((b1 & 0xf8) >> 3);
- dst[col] = (d1 << 16) | d0;
- }
- src += srcStride;
- dst = (GLuint *) ((GLubyte *) dst + dstRowStride);
- }
-#else /* 16-bit stores */
- GLushort *dst = (GLushort *) dstImage;
- GLint row;
- for (row = 0; row < dstHeight; row++) {
- GLint col, col4;
- for (col = col4 = 0; col < dstWidth; col++, col4 += 4) {
- GLubyte r = src[col4 + 0];
- GLubyte g = src[col4 + 1];
- GLubyte b = src[col4 + 2];
- dst[col] = ((r & 0xf8) << 8)
- | ((g & 0xfc) << 3)
- | ((b & 0xf8) >> 3);
- }
- src += srcStride;
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
-#endif
- }
- else {
- /* must rescale image */
- GLushort *dst = (GLushort *) dstImage;
- GLint row;
- for (row = 0; row < dstHeight; row++) {
- GLint srcRow = row / hScale;
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth,
- srcHeight, srcFormat, srcType, 0, srcRow, 0);
- GLint col;
- for (col = 0; col < dstWidth; col++) {
- GLint col4 = (col / wScale) * 4;
- GLubyte r = src[col4 + 0];
- GLubyte g = src[col4 + 1];
- GLubyte b = src[col4 + 2];
- dst[col] = ((r & 0xf8) << 8)
- | ((g & 0xfc) << 3)
- | ((b & 0xf8) >> 3);
- }
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
- }
- }
- else {
- /* can't handle this srcFormat/srcType combination */
- return GL_FALSE;
- }
- break;
-
- case MESA_A4_R4_G4_B4:
- /* store as 16-bit texels (GR_TEXFMT_ARGB_4444) */
- if (srcFormat == GL_BGRA && srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV){
- /* special, optimized case */
- if (wScale == 1 && hScale == 1) {
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
- srcFormat, srcType, 0, 0, 0);
- const GLint srcStride = _mesa_image_row_stride(packing,
- srcWidth, srcFormat, srcType);
- GLushort *dst = (GLushort *) dstImage;
- GLint row;
- for (row = 0; row < dstHeight; row++) {
- MEMCPY(dst, src, dstWidth * sizeof(GLushort));
- src += srcStride;
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
- }
- else {
- /* must rescale image */
- GLushort *dst = (GLushort *) dstImage;
- GLint row;
- for (row = 0; row < dstHeight; row++) {
- GLint srcRow = row / hScale;
- const GLushort *src = (const GLushort *)
- _mesa_image_address(packing, srcImage, srcWidth,
- srcHeight, srcFormat, srcType, 0, srcRow, 0);
- GLint col;
- for (col = 0; col < dstWidth; col++) {
- dst[col] = src[col / wScale];
- }
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
- }
- }
- else if (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE) {
- /* general case */
- if (wScale == 1 && hScale == 1) {
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
- srcFormat, srcType, 0, 0, 0);
- const GLint srcStride = _mesa_image_row_stride(packing,
- srcWidth, srcFormat, srcType);
-#ifdef DO_32BIT_STORES
- GLuint *dst = dstImage;
- GLint row;
- for (row = 0; row < dstHeight; row++) {
- GLint col, col4;
- GLint halfDstWidth = dstWidth >> 1;
- for (col = col4 = 0; col < halfDstWidth; col++, col4 += 8) {
- GLubyte r0 = src[col4 + 0];
- GLubyte g0 = src[col4 + 1];
- GLubyte b0 = src[col4 + 2];
- GLubyte a0 = src[col4 + 3];
- GLubyte r1 = src[col4 + 4];
- GLubyte g1 = src[col4 + 5];
- GLubyte b1 = src[col4 + 6];
- GLubyte a1 = src[col4 + 7];
- GLuint d0 = ((a0 & 0xf0) << 8)
- | ((r0 & 0xf0) << 4)
- | ((g0 & 0xf0) )
- | ((b0 & 0xf0) >> 4);
- GLuint d1 = ((a1 & 0xf0) << 8)
- | ((r1 & 0xf0) << 4)
- | ((g1 & 0xf0) )
- | ((b1 & 0xf0) >> 4);
- dst[col] = (d1 << 16) | d0;
- }
- src += srcStride;
- dst = (GLuint *) ((GLubyte *) dst + dstRowStride);
- }
-#else /* 16-bit stores */
- GLushort *dst = (GLushort *) dstImage;
- GLint row;
- for (row = 0; row < dstHeight; row++) {
- GLint col, col4;
- for (col = col4 = 0; col < dstWidth; col++, col4 += 4) {
- GLubyte r = src[col4 + 0];
- GLubyte g = src[col4 + 1];
- GLubyte b = src[col4 + 2];
- GLubyte a = src[col4 + 3];
- dst[col] = ((a & 0xf0) << 8)
- | ((r & 0xf0) << 4)
- | ((g & 0xf0) )
- | ((b & 0xf0) >> 4);
- }
- src += srcStride;
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
-#endif
- }
- else {
- /* must rescale image */
- GLushort *dst = (GLushort *) dstImage;
- GLint row;
- for (row = 0; row < dstHeight; row++) {
- GLint srcRow = row / hScale;
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth,
- srcHeight, srcFormat, srcType, 0, srcRow, 0);
- GLint col;
- for (col = 0; col < dstWidth; col++) {
- GLint col4 = (col / wScale) * 4;
- GLubyte r = src[col4 + 0];
- GLubyte g = src[col4 + 1];
- GLubyte b = src[col4 + 2];
- GLubyte a = src[col4 + 3];
- dst[col] = ((a & 0xf0) << 8)
- | ((r & 0xf0) << 4)
- | ((g & 0xf0) )
- | ((b & 0xf0) >> 4);
- }
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
- }
- }
- else {
- /* can't handle this format/srcType combination */
- return GL_FALSE;
- }
- break;
-
- case MESA_A1_R5_G5_B5:
- /* store as 16-bit texels (GR_TEXFMT_ARGB_1555) */
- if (srcFormat == GL_BGRA && srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV){
- /* special, optimized case */
- if (wScale == 1 && hScale == 1) {
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
- srcFormat, srcType, 0, 0, 0);
- const GLint srcStride = _mesa_image_row_stride(packing,
- srcWidth, srcFormat, srcType);
- GLushort *dst = (GLushort *) dstImage;
- GLint row;
- for (row = 0; row < dstHeight; row++) {
- MEMCPY(dst, src, dstWidth * sizeof(GLushort));
- src += srcStride;
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
- }
- else {
- /* must rescale image */
- GLushort *dst = (GLushort *) dstImage;
- GLint row;
- for (row = 0; row < dstHeight; row++) {
- GLint srcRow = row / hScale;
- const GLushort *src = (const GLushort *)
- _mesa_image_address(packing, srcImage, srcWidth,
- srcHeight, srcFormat, srcType, 0, srcRow, 0);
- GLint col;
- for (col = 0; col < dstWidth; col++) {
- dst[col] = src[col / wScale];
- }
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
- }
- }
- else if (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE) {
- /* general case */
- if (wScale == 1 && hScale == 1) {
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
- srcFormat, srcType, 0, 0, 0);
- const GLint srcStride = _mesa_image_row_stride(packing,
- srcWidth, srcFormat, srcType);
- GLushort *dst = (GLushort *) dstImage;
- GLint row;
- for (row = 0; row < dstHeight; row++) {
- GLint col, col4;
- for (col = col4 = 0; col < dstWidth; col++, col4 += 4) {
- GLubyte r = src[col4 + 0];
- GLubyte g = src[col4 + 1];
- GLubyte b = src[col4 + 2];
- GLubyte a = src[col4 + 3];
- dst[col] = ((a & 0x80) << 8)
- | ((r & 0xf8) << 7)
- | ((g & 0xf8) << 2)
- | ((b & 0xf8) >> 3);
- }
- src += srcStride;
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
- }
- else {
- /* must rescale image */
- GLushort *dst = (GLushort *) dstImage;
- GLint row;
- for (row = 0; row < dstHeight; row++) {
- GLint srcRow = row / hScale;
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth,
- srcHeight, srcFormat, srcType, 0, srcRow, 0);
- GLint col;
- for (col = 0; col < dstWidth; col++) {
- GLint col4 = (col / wScale) * 4;
- GLubyte r = src[col4 + 0];
- GLubyte g = src[col4 + 1];
- GLubyte b = src[col4 + 2];
- GLubyte a = src[col4 + 3];
- dst[col] = ((a & 0x80) << 8)
- | ((r & 0xf8) << 7)
- | ((g & 0xf8) << 2)
- | ((b & 0xf8) >> 3);
- }
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
- }
- }
- else {
- /* can't handle this source format/type combination */
- return GL_FALSE;
- }
- break;
-
- case MESA_A8_R8_G8_B8:
- case MESA_FF_R8_G8_B8:
- /* 32-bit texels */
- if (srcFormat == GL_BGRA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV){
- /* special, optimized case */
- if (wScale == 1 && hScale == 1) {
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
- srcFormat, srcType, 0, 0, 0);
- const GLint srcStride = _mesa_image_row_stride(packing,
- srcWidth, srcFormat, srcType);
- GLuint *dst = (GLuint *) dstImage;
- GLint row;
- for (row = 0; row < dstHeight; row++) {
- MEMCPY(dst, src, dstWidth * sizeof(GLuint));
- src += srcStride;
- dst = (GLuint *) ((GLubyte *) dst + dstRowStride);
- }
- }
- else {
- /* must rescale image */
- GLuint *dst = (GLuint *) dstImage;
- GLint row;
- for (row = 0; row < dstHeight; row++) {
- GLint srcRow = row / hScale;
- const GLuint *src = (const GLuint *)
- _mesa_image_address(packing, srcImage, srcWidth,
- srcHeight, srcFormat, srcType, 0, srcRow, 0);
- GLint col;
- for (col = 0; col < dstWidth; col++) {
- dst[col] = src[col / wScale];
- }
- dst = (GLuint *) ((GLubyte *) dst + dstRowStride);
- }
- }
- }
- else if (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE) {
- /* general case */
- if (wScale == 1 && hScale == 1) {
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
- srcFormat, srcType, 0, 0, 0);
- const GLint srcStride = _mesa_image_row_stride(packing,
- srcWidth, srcFormat, srcType);
- GLuint *dst = (GLuint *) dstImage;
- GLint row;
- for (row = 0; row < dstHeight; row++) {
- GLint col, col4;
- for (col = col4 = 0; col < dstWidth; col++, col4 += 4) {
- GLubyte r = src[col4 + 0];
- GLubyte g = src[col4 + 1];
- GLubyte b = src[col4 + 2];
- GLubyte a = src[col4 + 3];
- dst[col] = (a << 24) | (r << 16) | (g << 8) | b;
- }
- src += srcStride;
- dst = (GLuint *) ((GLubyte *) dst + dstRowStride);
- }
- }
- else {
- /* must rescale image */
- GLuint *dst = (GLuint *) dstImage;
- GLint row;
- for (row = 0; row < dstHeight; row++) {
- GLint srcRow = row / hScale;
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth,
- srcHeight, srcFormat, srcType, 0, srcRow, 0);
- GLint col;
- for (col = 0; col < dstWidth; col++) {
- GLint col4 = (col / wScale) * 4;
- GLubyte r = src[col4 + 0];
- GLubyte g = src[col4 + 1];
- GLubyte b = src[col4 + 2];
- GLubyte a = src[col4 + 3];
- dst[col] = (a << 24) | (r << 16) | (g << 8) | b;
- }
- dst = (GLuint *) ((GLubyte *) dst + dstRowStride);
- }
- }
- }
- else if (srcFormat == GL_RGB && srcType == GL_UNSIGNED_BYTE) {
- /* general case */
- if (wScale == 1 && hScale == 1) {
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
- srcFormat, srcType, 0, 0, 0);
- const GLint srcStride = _mesa_image_row_stride(packing,
- srcWidth, srcFormat, srcType);
- GLuint *dst = (GLuint *) dstImage;
- GLint row;
- for (row = 0; row < dstHeight; row++) {
- GLint col, col3;
- for (col = col3 = 0; col < dstWidth; col++, col3 += 3) {
- GLubyte r = src[col3 + 0];
- GLubyte g = src[col3 + 1];
- GLubyte b = src[col3 + 2];
- GLubyte a = 255;
- dst[col] = (a << 24) | (r << 16) | (g << 8) | b;
- }
- src += srcStride;
- dst = (GLuint *) ((GLubyte *) dst + dstRowStride);
- }
- }
- else {
- /* must rescale image */
- GLuint *dst = (GLuint *) dstImage;
- GLint row;
- for (row = 0; row < dstHeight; row++) {
- GLint srcRow = row / hScale;
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth,
- srcHeight, srcFormat, srcType, 0, srcRow, 0);
- GLint col;
- for (col = 0; col < dstWidth; col++) {
- GLint col3 = (col / wScale) * 3;
- GLubyte r = src[col3 + 0];
- GLubyte g = src[col3 + 1];
- GLubyte b = src[col3 + 2];
- GLubyte a = 255;
- dst[col] = (a << 24) | (r << 16) | (g << 8) | b;
- }
- dst = (GLuint *) ((GLubyte *) dst + dstRowStride);
- }
- }
- }
- else {
- /* can't handle this source format/type combination */
- return GL_FALSE;
- }
- if (dstFormat == MESA_FF_R8_G8_B8) {
- /* set alpha bytes to 0xff */
- GLint i;
- GLubyte *dst = (GLubyte *) dstImage;
- for (i = 0; i < dstWidth * dstHeight; i++) {
- dst[i * 4 + 3] = 0xff;
- }
- }
- break;
-
- default:
- /* unexpected internal format! */
- return GL_FALSE;
+ const GLubyte *src = (const GLubyte *)convert->srcImage;
+ GLint texels, i;
+
+ texels = convert->width * convert->height * convert->depth;
+
+ switch ( convert->format ) {
+ case GL_RGBA: {
+ GLuint *dst = (GLuint *)convert->dstImage;
+ for ( i = 0 ; i < texels ; i++ ) {
+ *dst++ = PACK_COLOR_8888( src[0], src[1], src[2], src[3] );
+ src += 4;
+ }
+ break;
+ }
+ case GL_RGB: {
+ GLubyte *dst = (GLubyte *)convert->dstImage;
+ for ( i = 0 ; i < texels ; i++ ) {
+ *dst++ = src[3];
+ *dst++ = src[2];
+ *dst++ = src[1];
+ src += 4;
+ }
+ break;
+ }
+ default:
+ UNCONVERT_ERROR( convert->format );
+ break;
}
- return GL_TRUE;
}
-/*
- * Replace a subregion of a texture image with new data.
- * Input:
- * dstFormat - destination image format
- * dstXoffset, dstYoffset - destination for new subregion (in texels)
- * dstWidth, dstHeight - total size of dest image (in texels)
- * dstImage - pointer to dest image
- * dstRowStride - bytes to jump between image rows (in bytes)
- * width, height - size of region to copy/replace (in texels)
- * srcWidth, srcHeight - size of the corresponding gl_texture_image
- * srcFormat, srcType - source image format and datatype
- * srcImage - source image
- * packing - source image packing information.
- * Return: GL_TRUE or GL_FALSE for success, failure
- *
- * Notes:
- * Like _mesa_convert_teximage(), we can do power-of-two image scaling
- * to accomodate hardware with texture image aspect ratio constraints.
- * dstWidth / srcWidth is used to compute the horizontal scaling factor and
- * dstHeight / srcHeight is used to compute the vertical scaling factor.
+/* ================================================================
+ * ABGR8888 textures:
*/
-GLboolean
-_mesa_convert_texsubimage(MesaIntTexFormat dstFormat,
- GLint dstXoffset, GLint dstYoffset,
- GLint dstWidth, GLint dstHeight, GLvoid *dstImage,
- GLint dstRowStride,
- GLint width, GLint height,
- GLint srcWidth, GLint srcHeight,
- GLenum srcFormat, GLenum srcType,
- const GLvoid *srcImage,
- const struct gl_pixelstore_attrib *packing)
+
+#define DST_TYPE GLuint
+#define DST_TEXELS_PER_DWORD 1
+
+#define CONVERT_TEXEL( src ) \
+ PACK_COLOR_8888( src[3], src[2], src[1], src[0] )
+
+#define CONVERT_DIRECT
+
+#define SRC_TEXEL_BYTES 4
+
+#define TAG(x) x##_abgr8888_direct
+#define PRESERVE_DST_TYPE
+#include "texutil_tmp.h"
+
+
+#define CONVERT_TEXEL( src ) \
+ PACK_COLOR_8888( 0xff, src[2], src[1], src[0] )
+
+#define CONVERT_TEXEL_DWORD( src ) CONVERT_TEXEL( src )
+
+#define SRC_TEXEL_BYTES 3
+
+#define TAG(x) x##_bgr888_to_abgr8888
+#include "texutil_tmp.h"
+
+
+#define CONVERT_ABGR8888( name ) \
+static GLboolean \
+convert_##name##_abgr8888( struct gl_texture_convert *convert ) \
+{ \
+ convert_func *tab; \
+ GLint index = convert->index; \
+ \
+ if ( convert->format == GL_RGBA && \
+ convert->type == GL_UNSIGNED_BYTE ) \
+ { \
+ tab = name##_tab_abgr8888_direct; \
+ } \
+ else if ( convert->format == GL_RGB && \
+ convert->type == GL_UNSIGNED_BYTE ) \
+ { \
+ tab = name##_tab_bgr888_to_abgr8888; \
+ } \
+ else \
+ { \
+ /* Can't handle this source format/type combination */ \
+ return GL_FALSE; \
+ } \
+ \
+ return tab[index]( convert ); \
+}
+
+CONVERT_ABGR8888( texsubimage2d )
+CONVERT_ABGR8888( texsubimage3d )
+
+
+static void
+unconvert_teximage_abgr8888( struct gl_texture_convert *convert )
{
- const GLint wScale = dstWidth / srcWidth; /* must be power of two */
- const GLint hScale = dstHeight / srcHeight; /* must be power of two */
- ASSERT(dstWidth >= srcWidth);
- ASSERT(dstHeight >= srcHeight);
- ASSERT(dstImage);
- ASSERT(srcImage);
- ASSERT(packing);
-
- width *= wScale;
- height *= hScale;
- dstXoffset *= wScale;
- dstYoffset *= hScale;
-
- /* XXX hscale != 1 and wscale != 1 not tested!!!! */
-
- switch (dstFormat) {
- case MESA_I8:
- case MESA_L8:
- case MESA_A8:
- case MESA_C8:
- if (srcType != GL_UNSIGNED_BYTE ||
- ((srcFormat != GL_INTENSITY) &&
- (srcFormat != GL_LUMINANCE) &&
- (srcFormat != GL_ALPHA) &&
- (srcFormat != GL_COLOR_INDEX))) {
- /* bad internal format / srcFormat combination */
- return GL_FALSE;
- }
- else {
- /* store as 8-bit texels */
- if (wScale == 1 && hScale == 1) {
- /* no scaling needed - fast case */
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
- srcFormat, srcType, 0, 0, 0);
- const GLint srcRowStride = _mesa_image_row_stride(packing,
- width, srcFormat, srcType);
- GLubyte *dst = (GLubyte *) dstImage
- + dstYoffset * dstRowStride + dstXoffset;
- const GLint rowSize = width * sizeof(GLubyte);
- GLint row;
- if (dstRowStride == srcRowStride && dstRowStride == rowSize) {
- MEMCPY(dst, src, rowSize * height);
- }
- else {
- for (row = 0; row < height; row++) {
- MEMCPY(dst, src, rowSize);
- dst += dstRowStride;
- src += srcRowStride;
- }
- }
- }
- else {
- /* must rescale image */
- GLubyte *dst = (GLubyte *) dstImage
- + dstYoffset * dstRowStride + dstXoffset;
- GLint row;
- for (row = 0; row < height; row++) {
- GLint srcRow = row / hScale;
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth,
- srcHeight, srcFormat, srcType, 0, srcRow, 0);
- GLint col;
- for (col = 0; col < width; col++) {
- dst[col] = src[col / wScale];
- }
- dst += dstRowStride;
- }
- }
- }
- break;
-
- case MESA_A8_L8:
- if (srcType != GL_UNSIGNED_BYTE || srcFormat != GL_LUMINANCE_ALPHA) {
- return GL_FALSE;
- }
- else {
- /* store as 16-bit texels */
- if (wScale == 1 && hScale == 1) {
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
- srcFormat, srcType, 0, 0, 0);
- const GLint srcStride = _mesa_image_row_stride(packing,
- width, srcFormat, srcType);
- GLushort *dst = (GLushort *) ((GLubyte *) dstImage
- + dstYoffset * dstRowStride) + dstXoffset;
- GLint row, col;
- for (row = 0; row < height; row++) {
- for (col = 0; col < width; col++) {
- GLubyte luminance = src[col * 2 + 0];
- GLubyte alpha = src[col * 2 + 1];
- dst[col] = ((GLushort) alpha << 8) | luminance;
- }
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- src += srcStride;
- }
- }
- else {
- /* must rescale */
- GLushort *dst = (GLushort *) ((GLubyte *) dstImage
- + dstYoffset * dstRowStride) + dstXoffset;
- GLint row, col;
- for (row = 0; row < height; row++) {
- GLint srcRow = row / hScale;
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth,
- srcHeight, srcFormat, srcType, 0, srcRow, 0);
- const GLint srcStride = _mesa_image_row_stride(packing,
- width, srcFormat, srcType);
- for (col = 0; col < width; col++) {
- GLint srcCol = col / wScale;
- GLubyte luminance = src[srcCol * 2 + 0];
- GLubyte alpha = src[srcCol * 2 + 1];
- dst[col] = ((GLushort) alpha << 8) | luminance;
- }
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- src += srcStride;
- }
- }
- }
- break;
-
- case MESA_R5_G6_B5:
- if (srcFormat == GL_RGB && srcType == GL_UNSIGNED_SHORT_5_6_5) {
- /* special, optimized case */
- if (wScale == 1 && hScale == 1) {
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
- srcFormat, srcType, 0, 0, 0);
- const GLint srcStride = _mesa_image_row_stride(packing,
- width, srcFormat, srcType);
- GLushort *dst = (GLushort *) ((GLubyte *) dstImage
- + dstYoffset * dstRowStride) + dstXoffset;
- GLint row;
- for (row = 0; row < height; row++) {
- MEMCPY(dst, src, width * sizeof(GLushort));
- src += srcStride;
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
- }
- else {
- /* must rescale image */
- GLushort *dst = (GLushort *) ((GLubyte *) dstImage
- + dstYoffset * dstRowStride) + dstXoffset;
- GLint row;
- for (row = 0; row < height; row++) {
- GLint srcRow = row / hScale;
- const GLushort *src = (const GLushort *)
- _mesa_image_address(packing, srcImage, srcWidth,
- srcHeight, srcFormat, srcType, 0, srcRow, 0);
- GLint col;
- for (col = 0; col < width; col++) {
- dst[col] = src[col / wScale];
- }
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
- }
- }
- else if (srcFormat == GL_RGB && srcType == GL_UNSIGNED_BYTE) {
- /* general case */
- if (wScale == 1 && hScale == 1) {
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
- srcFormat, srcType, 0, 0, 0);
- const GLint srcStride = _mesa_image_row_stride(packing,
- width, srcFormat, srcType);
- GLushort *dst = (GLushort *) ((GLubyte *) dstImage
- + dstYoffset * dstRowStride) + dstXoffset;
- GLint row;
- for (row = 0; row < height; row++) {
- GLint col, col3;
- for (col = col3 = 0; col < width; col++, col3 += 3) {
- GLubyte r = src[col3 + 0];
- GLubyte g = src[col3 + 1];
- GLubyte b = src[col3 + 2];
- dst[col] = ((r & 0xf8) << 8)
- | ((g & 0xfc) << 3)
- | ((b & 0xf8) >> 3);
- }
- src += srcStride;
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
- }
- else {
- /* must rescale image */
- GLushort *dst = (GLushort *) ((GLubyte *) dstImage
- + dstYoffset * dstRowStride) + dstXoffset;
- GLint row;
- for (row = 0; row < height; row++) {
- GLint srcRow = row / hScale;
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth,
- srcHeight, srcFormat, srcType, 0, srcRow, 0);
- GLint col;
- for (col = 0; col < width; col++) {
- GLint col3 = (col / wScale) * 3;
- GLubyte r = src[col3 + 0];
- GLubyte g = src[col3 + 1];
- GLubyte b = src[col3 + 2];
- dst[col] = ((r & 0xf8) << 8)
- | ((g & 0xfc) << 3)
- | ((b & 0xf8) >> 3);
- }
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
- }
- }
- else if (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE) {
- /* general case (used by Quake3) */
- if (wScale == 1 && hScale == 1) {
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
- srcFormat, srcType, 0, 0, 0);
- const GLint srcStride = _mesa_image_row_stride(packing,
- width, srcFormat, srcType);
- GLushort *dst = (GLushort *) ((GLubyte *) dstImage
- + dstYoffset * dstRowStride) + dstXoffset;
- GLint row;
- for (row = 0; row < height; row++) {
- GLint col, col4;
- for (col = col4 = 0; col < width; col++, col4 += 4) {
- GLubyte r = src[col4 + 0];
- GLubyte g = src[col4 + 1];
- GLubyte b = src[col4 + 2];
- dst[col] = ((r & 0xf8) << 8)
- | ((g & 0xfc) << 3)
- | ((b & 0xf8) >> 3);
- }
- src += srcStride;
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
- }
- else {
- /* must rescale image */
- GLushort *dst = (GLushort *) ((GLubyte *) dstImage
- + dstYoffset * dstRowStride) + dstXoffset;
- GLint row;
- for (row = 0; row < height; row++) {
- GLint srcRow = row / hScale;
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth,
- srcHeight, srcFormat, srcType, 0, srcRow, 0);
- GLint col;
- for (col = 0; col < width; col++) {
- GLint col4 = (col / wScale) * 4;
- GLubyte r = src[col4 + 0];
- GLubyte g = src[col4 + 1];
- GLubyte b = src[col4 + 2];
- dst[col] = ((r & 0xf8) << 8)
- | ((g & 0xfc) << 3)
- | ((b & 0xf8) >> 3);
- }
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
- }
- }
- else {
- /* can't handle this srcFormat/srcType combination */
- return GL_FALSE;
- }
- break;
-
- case MESA_A4_R4_G4_B4:
- /* store as 16-bit texels (GR_TEXFMT_ARGB_4444) */
- if (srcFormat == GL_BGRA && srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV){
- /* special, optimized case */
- if (wScale == 1 && hScale == 1) {
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
- srcFormat, srcType, 0, 0, 0);
- const GLint srcStride = _mesa_image_row_stride(packing,
- width, srcFormat, srcType);
- GLushort *dst = (GLushort *) ((GLubyte *) dstImage
- + dstYoffset * dstRowStride) + dstXoffset;
- GLint row;
- for (row = 0; row < height; row++) {
- MEMCPY(dst, src, width * sizeof(GLushort));
- src += srcStride;
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
- }
- else {
- /* must rescale image */
- GLushort *dst = (GLushort *) ((GLubyte *) dstImage
- + dstYoffset * dstRowStride) + dstXoffset;
- GLint row;
- for (row = 0; row < height; row++) {
- GLint srcRow = row / hScale;
- const GLushort *src = (const GLushort *)
- _mesa_image_address(packing, srcImage, srcWidth,
- srcHeight, srcFormat, srcType, 0, srcRow, 0);
- GLint col;
- for (col = 0; col < width; col++) {
- dst[col] = src[col / wScale];
- }
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
- }
- }
- else if (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE) {
- /* general case */
- if (wScale == 1 && hScale == 1) {
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
- srcFormat, srcType, 0, 0, 0);
- const GLint srcStride = _mesa_image_row_stride(packing,
- width, srcFormat, srcType);
- GLushort *dst = (GLushort *) ((GLubyte *) dstImage
- + dstYoffset * dstRowStride) + dstXoffset;
- GLint row;
- for (row = 0; row < height; row++) {
- GLint col, col4;
- for (col = col4 = 0; col < width; col++, col4 += 4) {
- GLubyte r = src[col4 + 0];
- GLubyte g = src[col4 + 1];
- GLubyte b = src[col4 + 2];
- GLubyte a = src[col4 + 3];
- dst[col] = ((a & 0xf0) << 8)
- | ((r & 0xf0) << 4)
- | ((g & 0xf0) )
- | ((b & 0xf0) >> 4);
- }
- src += srcStride;
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
- }
- else {
- /* must rescale image */
- GLushort *dst = (GLushort *) ((GLubyte *) dstImage
- + dstYoffset * dstRowStride) + dstXoffset;
- GLint row;
- for (row = 0; row < height; row++) {
- GLint srcRow = row / hScale;
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth,
- srcHeight, srcFormat, srcType, 0, srcRow, 0);
- GLint col;
- for (col = 0; col < width; col++) {
- GLint col4 = (col / wScale) * 4;
- GLubyte r = src[col4 + 0];
- GLubyte g = src[col4 + 1];
- GLubyte b = src[col4 + 2];
- GLubyte a = src[col4 + 3];
- dst[col] = ((a & 0xf0) << 8)
- | ((r & 0xf0) << 4)
- | ((g & 0xf0) )
- | ((b & 0xf0) >> 4);
- }
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
- }
- }
- else {
- /* can't handle this format/srcType combination */
- return GL_FALSE;
- }
- break;
-
- case MESA_A1_R5_G5_B5:
- /* store as 16-bit texels (GR_TEXFMT_ARGB_1555) */
- if (srcFormat == GL_BGRA && srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV){
- /* special, optimized case */
- if (wScale == 1 && hScale == 1) {
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
- srcFormat, srcType, 0, 0, 0);
- const GLint srcStride = _mesa_image_row_stride(packing,
- width, srcFormat, srcType);
- GLushort *dst = (GLushort *) ((GLubyte *) dstImage
- + dstYoffset * dstRowStride) + dstXoffset;
- GLint row;
- for (row = 0; row < height; row++) {
- MEMCPY(dst, src, width * sizeof(GLushort));
- src += srcStride;
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
- }
- else {
- /* must rescale image */
- GLushort *dst = (GLushort *) ((GLubyte *) dstImage
- + dstYoffset * dstRowStride) + dstXoffset;
- GLint row;
- for (row = 0; row < height; row++) {
- GLint srcRow = row / hScale;
- const GLushort *src = (const GLushort *)
- _mesa_image_address(packing, srcImage, srcWidth,
- srcHeight, srcFormat, srcType, 0, srcRow, 0);
- GLint col;
- for (col = 0; col < width; col++) {
- dst[col] = src[col / wScale];
- }
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
- }
- }
- else if (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE) {
- /* general case */
- if (wScale == 1 && hScale == 1) {
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
- srcFormat, srcType, 0, 0, 0);
- const GLint srcStride = _mesa_image_row_stride(packing,
- width, srcFormat, srcType);
- GLushort *dst = (GLushort *) ((GLubyte *) dstImage
- + dstYoffset * dstRowStride) + dstXoffset;
- GLint row;
- for (row = 0; row < height; row++) {
- GLint col, col4;
- for (col = col4 = 0; col < width; col++, col4 += 4) {
- GLubyte r = src[col4 + 0];
- GLubyte g = src[col4 + 1];
- GLubyte b = src[col4 + 2];
- GLubyte a = src[col4 + 3];
- dst[col] = ((a & 0x80) << 8)
- | ((r & 0xf8) << 7)
- | ((g & 0xf8) << 2)
- | ((b & 0xf8) >> 3);
- }
- src += srcStride;
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
- }
- else {
- /* must rescale image */
- GLushort *dst = (GLushort *) ((GLubyte *) dstImage
- + dstYoffset * dstRowStride) + dstXoffset;
- GLint row;
- for (row = 0; row < height; row++) {
- GLint srcRow = row / hScale;
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth,
- srcHeight, srcFormat, srcType, 0, srcRow, 0);
- GLint col;
- for (col = 0; col < width; col++) {
- GLint col4 = (col / wScale) * 4;
- GLubyte r = src[col4 + 0];
- GLubyte g = src[col4 + 1];
- GLubyte b = src[col4 + 2];
- GLubyte a = src[col4 + 3];
- dst[col] = ((a & 0x80) << 8)
- | ((r & 0xf8) << 7)
- | ((g & 0xf8) << 2)
- | ((b & 0xf8) >> 3);
- }
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
- }
- }
- else {
- /* can't handle this source format/type combination */
- return GL_FALSE;
- }
- break;
-
- case MESA_A8_R8_G8_B8:
- case MESA_FF_R8_G8_B8:
- /* 32-bit texels */
- if (srcFormat == GL_BGRA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) {
- /* special, optimized case */
- if (wScale == 1 && hScale == 1) {
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
- srcFormat, srcType, 0, 0, 0);
- const GLint srcStride = _mesa_image_row_stride(packing,
- width, srcFormat, srcType);
- GLuint *dst = (GLuint *) ((GLubyte *) dstImage
- + dstYoffset * dstRowStride) + dstXoffset;
- GLint row;
- for (row = 0; row < height; row++) {
- MEMCPY(dst, src, width * sizeof(GLuint));
- src += srcStride;
- dst = (GLuint *) ((GLubyte *) dst + dstRowStride);
- }
- }
- else {
- /* must rescale image */
- GLuint *dst = (GLuint *) ((GLubyte *) dstImage
- + dstYoffset * dstRowStride) + dstXoffset;
- GLint row;
- for (row = 0; row < height; row++) {
- GLint srcRow = row / hScale;
- const GLuint *src = (const GLuint *)
- _mesa_image_address(packing, srcImage, srcWidth,
- srcHeight, srcFormat, srcType, 0, srcRow, 0);
- GLint col;
- for (col = 0; col < width; col++) {
- dst[col] = src[col / wScale];
- }
- dst = (GLuint *) ((GLubyte *) dst + dstRowStride);
- }
- }
- if (dstFormat == MESA_FF_R8_G8_B8) {
- /* set alpha bytes to 0xff */
- GLint row, col;
- GLubyte *dst = (GLubyte *) dstImage
- + dstYoffset * dstRowStride + dstXoffset * 4;
- assert(wScale == 1 && hScale == 1); /* XXX not done */
- for (row = 0; row < height; row++) {
- for (col = 0; col < width; col++) {
- dst[col * 4 + 3] = 0xff;
- }
- dst = dst + dstRowStride;
- }
- }
- }
- else if (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE) {
- /* general case */
- const GLubyte aMask = (dstFormat==MESA_FF_R8_G8_B8) ? 0xff : 0x00;
- if (wScale == 1 && hScale == 1) {
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
- srcFormat, srcType, 0, 0, 0);
- const GLint srcStride = _mesa_image_row_stride(packing,
- width, srcFormat, srcType);
- GLuint *dst = (GLuint *) ((GLubyte *) dstImage
- + dstYoffset * dstRowStride) + dstXoffset;
- GLint row;
- for (row = 0; row < height; row++) {
- GLint col, col4;
- for (col = col4 = 0; col < width; col++, col4 += 4) {
- GLubyte r = src[col4 + 0];
- GLubyte g = src[col4 + 1];
- GLubyte b = src[col4 + 2];
- GLubyte a = src[col4 + 3] | aMask;
- dst[col] = (a << 24) | (r << 16) | (g << 8) | b;
- }
- src += srcStride;
- dst = (GLuint *) ((GLubyte *) dst + dstRowStride);
- }
- }
- else {
- /* must rescale image */
- GLuint *dst = (GLuint *) ((GLubyte *) dstImage
- + dstYoffset * dstRowStride) + dstXoffset;
- GLint row;
- for (row = 0; row < height; row++) {
- GLint srcRow = row / hScale;
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth,
- srcHeight, srcFormat, srcType, 0, srcRow, 0);
- GLint col;
- for (col = 0; col < width; col++) {
- GLint col4 = (col / wScale) * 4;
- GLubyte r = src[col4 + 0];
- GLubyte g = src[col4 + 1];
- GLubyte b = src[col4 + 2];
- GLubyte a = src[col4 + 3] | aMask;
- dst[col] = (a << 24) | (r << 16) | (g << 8) | b;
- }
- dst = (GLuint *) ((GLubyte *) dst + dstRowStride);
- }
- }
- }
- else {
- /* can't handle this source format/type combination */
- return GL_FALSE;
- }
- break;
-
-
- default:
- /* unexpected internal format! */
- return GL_FALSE;
+ const GLubyte *src = (const GLubyte *)convert->srcImage;
+ GLint texels, i;
+
+ texels = convert->width * convert->height * convert->depth;
+
+ switch ( convert->format ) {
+ case GL_RGBA:
+ MEMCPY( convert->dstImage, src, texels * 4 );
+ break;
+ case GL_RGB: {
+ GLubyte *dst = (GLubyte *)convert->dstImage;
+ for ( i = 0 ; i < texels ; i++ ) {
+ *dst++ = src[0];
+ *dst++ = src[1];
+ *dst++ = src[2];
+ src += 4;
+ }
+ break;
+ }
+ default:
+ UNCONVERT_ERROR( convert->format );
+ break;
}
- return GL_TRUE;
}
+/* ================================================================
+ * ARGB8888 textures:
+ */
-/*
- * Used to convert 16-bit texels into GLubyte color components.
+#define DST_TYPE GLuint
+#define DST_TEXELS_PER_DWORD 1
+
+#define CONVERT_TEXEL( src ) \
+ PACK_COLOR_8888( src[3], src[2], src[1], src[0] )
+
+#define CONVERT_DIRECT
+
+#define SRC_TEXEL_BYTES 4
+
+#define TAG(x) x##_argb8888_direct
+#define PRESERVE_DST_TYPE
+#include "texutil_tmp.h"
+
+
+#define CONVERT_TEXEL( src ) \
+ PACK_COLOR_8888( src[3], src[0], src[1], src[2] )
+
+#define CONVERT_TEXEL_DWORD( src ) CONVERT_TEXEL( src )
+
+#define SRC_TEXEL_BYTES 4
+
+#define TAG(x) x##_abgr8888_to_argb8888
+#define PRESERVE_DST_TYPE
+#include "texutil_tmp.h"
+
+
+#define CONVERT_TEXEL( src ) \
+ PACK_COLOR_8888( 0xff, src[0], src[1], src[2] )
+
+#define CONVERT_TEXEL_DWORD( src ) CONVERT_TEXEL( src )
+
+#define SRC_TEXEL_BYTES 3
+
+#define TAG(x) x##_bgr888_to_argb8888
+#include "texutil_tmp.h"
+
+
+#define CONVERT_ARGB8888( name ) \
+static GLboolean \
+convert_##name##_argb8888( struct gl_texture_convert *convert ) \
+{ \
+ convert_func *tab; \
+ GLint index = convert->index; \
+ \
+ if ( convert->format == GL_BGRA && \
+ convert->type == GL_UNSIGNED_INT_8_8_8_8_REV ) \
+ { \
+ tab = name##_tab_argb8888_direct; \
+ } \
+ else if ( convert->format == GL_RGBA && \
+ convert->type == GL_UNSIGNED_BYTE ) \
+ { \
+ tab = name##_tab_abgr8888_to_argb8888; \
+ } \
+ else if ( convert->format == GL_RGB && \
+ convert->type == GL_UNSIGNED_BYTE ) \
+ { \
+ tab = name##_tab_bgr888_to_argb8888; \
+ } \
+ else \
+ { \
+ /* Can't handle this source format/type combination */ \
+ return GL_FALSE; \
+ } \
+ \
+ return tab[index]( convert ); \
+}
+
+CONVERT_ARGB8888( texsubimage2d )
+CONVERT_ARGB8888( texsubimage3d )
+
+
+static void
+unconvert_teximage_argb8888( struct gl_texture_convert *convert )
+{
+ const GLubyte *src = (const GLubyte *)convert->srcImage;
+ GLint texels, i;
+
+ texels = convert->width * convert->height * convert->depth;
+
+ switch ( convert->format ) {
+ case GL_RGBA: {
+ GLuint *dst = (GLuint *)convert->dstImage;
+ for ( i = 0 ; i < texels ; i++ ) {
+ *dst++ = PACK_COLOR_8888( src[3], src[0], src[1], src[2] );
+ src += 4;
+ }
+ break;
+ }
+ case GL_RGB: {
+ GLubyte *dst = (GLubyte *)convert->dstImage;
+ for ( i = 0 ; i < texels ; i++ ) {
+ *dst++ = src[2];
+ *dst++ = src[1];
+ *dst++ = src[0];
+ src += 4;
+ }
+ break;
+ }
+ default:
+ UNCONVERT_ERROR( convert->format );
+ break;
+ }
+}
+
+
+
+/* ================================================================
+ * RGB888 textures:
+ */
+
+static GLboolean
+convert_texsubimage2d_rgb888( struct gl_texture_convert *convert )
+{
+ /* This is a placeholder for now...
+ */
+ return GL_FALSE;
+}
+
+static GLboolean
+convert_texsubimage3d_rgb888( struct gl_texture_convert *convert )
+{
+ /* This is a placeholder for now...
+ */
+ return GL_FALSE;
+}
+
+
+static void
+unconvert_teximage_rgb888( struct gl_texture_convert *convert )
+{
+ UNCONVERT_ERROR( convert->format );
+}
+
+
+
+/* ================================================================
+ * BGR888 textures:
*/
-static GLubyte R5G6B5toRed[0xffff];
-static GLubyte R5G6B5toGreen[0xffff];
-static GLubyte R5G6B5toBlue[0xffff];
-static GLubyte A4R4G4B4toRed[0xffff];
-static GLubyte A4R4G4B4toGreen[0xffff];
-static GLubyte A4R4G4B4toBlue[0xffff];
-static GLubyte A4R4G4B4toAlpha[0xffff];
+static GLboolean
+convert_texsubimage2d_bgr888( struct gl_texture_convert *convert )
+{
+ /* This is a placeholder for now...
+ */
+ return GL_FALSE;
+}
+
+static GLboolean
+convert_texsubimage3d_bgr888( struct gl_texture_convert *convert )
+{
+ /* This is a placeholder for now...
+ */
+ return GL_FALSE;
+}
+
+
+static void
+unconvert_teximage_bgr888( struct gl_texture_convert *convert )
+{
+ UNCONVERT_ERROR( convert->format );
+}
+
+
+
+/* ================================================================
+ * RGB565 textures:
+ */
+
+#define DST_TYPE GLushort
+#define DST_TEXELS_PER_DWORD 2
+
+#define CONVERT_TEXEL( src ) \
+ PACK_COLOR_565( src[0], src[1], src[2] )
+
+#define CONVERT_DIRECT
+
+#define SRC_TEXEL_BYTES 2
+
+#define TAG(x) x##_rgb565_direct
+#define PRESERVE_DST_TYPE
+#include "texutil_tmp.h"
+
+
+#define CONVERT_TEXEL( src ) \
+ PACK_COLOR_565( src[0], src[1], src[2] )
+
+#define CONVERT_TEXEL_DWORD( src ) \
+ ((PACK_COLOR_565( src[0], src[1], src[2] )) | \
+ (PACK_COLOR_565( src[3], src[4], src[5] ) << 16))
+
+#define SRC_TEXEL_BYTES 3
+
+#define TAG(x) x##_bgr888_to_rgb565
+#define PRESERVE_DST_TYPE
+#include "texutil_tmp.h"
+
+
+#define CONVERT_TEXEL( src ) \
+ PACK_COLOR_565( src[0], src[1], src[2] )
+
+#define CONVERT_TEXEL_DWORD( src ) \
+ ((PACK_COLOR_565( src[0], src[1], src[2] )) | \
+ (PACK_COLOR_565( src[4], src[5], src[6] ) << 16))
+
+#define SRC_TEXEL_BYTES 4
+
+#define TAG(x) x##_abgr8888_to_rgb565
+#include "texutil_tmp.h"
+
+
+#define CONVERT_RGB565( name ) \
+static GLboolean \
+convert_##name##_rgb565( struct gl_texture_convert *convert ) \
+{ \
+ convert_func *tab; \
+ GLint index = convert->index; \
+ \
+ if ( convert->format == GL_RGB && \
+ convert->type == GL_UNSIGNED_SHORT_5_6_5 ) \
+ { \
+ tab = name##_tab_rgb565_direct; \
+ } \
+ else if ( convert->format == GL_RGB && \
+ convert->type == GL_UNSIGNED_BYTE ) \
+ { \
+ tab = name##_tab_bgr888_to_rgb565; \
+ } \
+ else if ( convert->format == GL_RGBA && \
+ convert->type == GL_UNSIGNED_BYTE ) \
+ { \
+ tab = name##_tab_abgr8888_to_rgb565; \
+ } \
+ else \
+ { \
+ /* Can't handle this source format/type combination */ \
+ return GL_FALSE; \
+ } \
+ \
+ return tab[index]( convert ); \
+}
+
+CONVERT_RGB565( texsubimage2d )
+CONVERT_RGB565( texsubimage3d )
+
+
+static void
+unconvert_teximage_rgb565( struct gl_texture_convert *convert )
+{
+ const GLushort *src = (const GLushort *)convert->srcImage;
+ GLubyte *dst = (GLubyte *)convert->dstImage;
+ GLint texels, i;
+
+ texels = convert->width * convert->height * convert->depth;
+
+ switch ( convert->format ) {
+ case GL_RGBA:
+ for ( i = 0 ; i < texels ; i++ ) {
+ GLushort s = *src++;
+ *dst++ = ((s >> 8) & 0xf8) * 255 / 0xf8;
+ *dst++ = ((s >> 3) & 0xfc) * 255 / 0xfc;
+ *dst++ = ((s << 3) & 0xf8) * 255 / 0xf8;
+ *dst++ = 0xff;
+ }
+ break;
+ case GL_RGB:
+ for ( i = 0 ; i < texels ; i++ ) {
+ GLushort s = *src++;
+ *dst++ = ((s >> 8) & 0xf8) * 255 / 0xf8;
+ *dst++ = ((s >> 3) & 0xfc) * 255 / 0xfc;
+ *dst++ = ((s << 3) & 0xf8) * 255 / 0xf8;
+ }
+ break;
+ default:
+ UNCONVERT_ERROR( convert->format );
+ break;
+ }
+}
+
+
+
+/* ================================================================
+ * ARGB4444 textures:
+ */
+
+#define DST_TYPE GLushort
+#define DST_TEXELS_PER_DWORD 2
+
+#define CONVERT_TEXEL( src ) \
+ PACK_COLOR_4444( src[3], src[0], src[1], src[2] )
+
+#define CONVERT_DIRECT
+
+#define SRC_TEXEL_BYTES 2
+
+#define TAG(x) x##_argb4444_direct
+#define PRESERVE_DST_TYPE
+#include "texutil_tmp.h"
+
+
+#define CONVERT_TEXEL( src ) \
+ PACK_COLOR_4444( src[3], src[0], src[1], src[2] )
+
+#define CONVERT_TEXEL_DWORD( src ) \
+ ((PACK_COLOR_4444( src[3], src[0], src[1], src[2] )) | \
+ (PACK_COLOR_4444( src[7], src[4], src[5], src[6] ) << 16))
+
+#define SRC_TEXEL_BYTES 4
+
+#define TAG(x) x##_rgba8888_to_argb4444
+#include "texutil_tmp.h"
+
+
+#define CONVERT_ARGB4444( name ) \
+static GLboolean \
+convert_##name##_argb4444( struct gl_texture_convert *convert ) \
+{ \
+ convert_func *tab; \
+ GLint index = convert->index; \
+ \
+ if ( convert->format == GL_BGRA && \
+ convert->type == GL_UNSIGNED_SHORT_4_4_4_4_REV ) \
+ { \
+ tab = name##_tab_argb4444_direct; \
+ } \
+ else if ( convert->format == GL_RGBA && \
+ convert->type == GL_UNSIGNED_BYTE ) \
+ { \
+ tab = name##_tab_rgba8888_to_argb4444; \
+ } \
+ else \
+ { \
+ /* Can't handle this source format/type combination */ \
+ return GL_FALSE; \
+ } \
+ \
+ return tab[index]( convert ); \
+}
+
+CONVERT_ARGB4444( texsubimage2d )
+CONVERT_ARGB4444( texsubimage3d )
-static GLubyte A1R5G5B5toRed[0xffff];
-static GLubyte A1R5G5B5toGreen[0xffff];
-static GLubyte A1R5G5B5toBlue[0xffff];
-static GLubyte A1R5G5B5toAlpha[0xffff];
static void
-generate_lookup_tables(void)
+unconvert_teximage_argb4444( struct gl_texture_convert *convert )
{
- GLint i;
- for (i = 0; i <= 0xffff; i++) {
- GLint r = (i >> 8) & 0xf8;
- GLint g = (i >> 3) & 0xfc;
- GLint b = (i << 3) & 0xf8;
- r = r * 255 / 0xf8;
- g = g * 255 / 0xfc;
- b = b * 255 / 0xf8;
- R5G6B5toRed[i] = r;
- R5G6B5toGreen[i] = g;
- R5G6B5toBlue[i] = b;
+ const GLushort *src = (const GLushort *)convert->srcImage;
+ GLubyte *dst = (GLubyte *)convert->dstImage;
+ GLint texels, i;
+
+ texels = convert->width * convert->height * convert->depth;
+
+ switch ( convert->format ) {
+ case GL_RGBA:
+ for ( i = 0 ; i < texels ; i++ ) {
+ GLushort s = *src++;
+ *dst++ = ((s >> 8) & 0xf) * 255 / 0xf;
+ *dst++ = ((s >> 4) & 0xf) * 255 / 0xf;
+ *dst++ = ((s ) & 0xf) * 255 / 0xf;
+ *dst++ = ((s >> 12) & 0xf) * 255 / 0xf;
+ }
+ break;
+ default:
+ UNCONVERT_ERROR( convert->format );
+ break;
}
+}
+
+
+
+/* ================================================================
+ * ARGB1555 textures:
+ */
+
+#define DST_TYPE GLushort
+#define DST_TEXELS_PER_DWORD 2
+
+#define CONVERT_TEXEL( src ) \
+ PACK_COLOR_1555( src[3], src[0], src[1], src[2] )
+
+#define CONVERT_DIRECT
+
+#define SRC_TEXEL_BYTES 2
- for (i = 0; i <= 0xffff; i++) {
- GLint r = (i >> 8) & 0xf;
- GLint g = (i >> 4) & 0xf;
- GLint b = (i ) & 0xf;
- GLint a = (i >> 12) & 0xf;
- r = r * 255 / 0xf;
- g = g * 255 / 0xf;
- b = b * 255 / 0xf;
- a = a * 255 / 0xf;
- A4R4G4B4toRed[i] = r;
- A4R4G4B4toGreen[i] = g;
- A4R4G4B4toBlue[i] = b;
- A4R4G4B4toAlpha[i] = a;
+#define TAG(x) x##_argb1555_direct
+#define PRESERVE_DST_TYPE
+#include "texutil_tmp.h"
+
+
+#define CONVERT_TEXEL( src ) \
+ PACK_COLOR_1555( src[3], src[0], src[1], src[2] )
+
+#define CONVERT_TEXEL_DWORD( src ) \
+ ((PACK_COLOR_1555( src[3], src[0], src[1], src[2] )) | \
+ (PACK_COLOR_1555( src[7], src[4], src[5], src[6] ) << 16))
+
+#define SRC_TEXEL_BYTES 4
+
+#define TAG(x) x##_rgba8888_to_argb1555
+#include "texutil_tmp.h"
+
+
+#define CONVERT_ARGB1555( name ) \
+static GLboolean \
+convert_##name##_argb1555( struct gl_texture_convert *convert ) \
+{ \
+ convert_func *tab; \
+ GLint index = convert->index; \
+ \
+ if ( convert->format == GL_BGRA && \
+ convert->type == GL_UNSIGNED_SHORT_1_5_5_5_REV ) \
+ { \
+ tab = name##_tab_argb1555_direct; \
+ } \
+ else if ( convert->format == GL_RGBA && \
+ convert->type == GL_UNSIGNED_BYTE ) \
+ { \
+ tab = name##_tab_rgba8888_to_argb1555; \
+ } \
+ else \
+ { \
+ /* Can't handle this source format/type combination */ \
+ return GL_FALSE; \
+ } \
+ \
+ return tab[index]( convert ); \
+}
+
+CONVERT_ARGB1555( texsubimage2d )
+CONVERT_ARGB1555( texsubimage3d )
+
+
+static void
+unconvert_teximage_argb1555( struct gl_texture_convert *convert )
+{
+ const GLushort *src = (const GLushort *)convert->srcImage;
+ GLubyte *dst = (GLubyte *)convert->dstImage;
+ GLint texels, i;
+
+ texels = convert->width * convert->height * convert->depth;
+
+ switch ( convert->format ) {
+ case GL_RGBA:
+ for ( i = 0 ; i < texels ; i++ ) {
+ GLushort s = *src++;
+ *dst++ = ((s >> 10) & 0xf8) * 255 / 0xf8;
+ *dst++ = ((s >> 5) & 0xf8) * 255 / 0xf8;
+ *dst++ = ((s ) & 0xf8) * 255 / 0xf8;
+ *dst++ = ((s >> 15) & 0x01) * 255;
+ }
+ break;
+ default:
+ UNCONVERT_ERROR( convert->format );
+ break;
}
+}
+
+
+
+/* ================================================================
+ * AL88 textures:
+ */
+
+#define DST_TYPE GLushort
+#define DST_TEXELS_PER_DWORD 2
- for (i = 0; i <= 0xffff; i++) {
- GLint r = (i >> 10) & 0xf8;
- GLint g = (i >> 5) & 0xf8;
- GLint b = (i ) & 0xf8;
- GLint a = (i >> 15) & 0x1;
- r = r * 255 / 0xf8;
- g = g * 255 / 0xf8;
- b = b * 255 / 0xf8;
- a = a * 255;
- A1R5G5B5toRed[i] = r;
- A1R5G5B5toGreen[i] = g;
- A1R5G5B5toBlue[i] = b;
- A1R5G5B5toAlpha[i] = a;
+#define CONVERT_TEXEL( src ) \
+ PACK_COLOR_88( src[0], src[1] )
+
+#define CONVERT_DIRECT
+
+#define SRC_TEXEL_BYTES 2
+
+#define TAG(x) x##_al88_direct
+#define PRESERVE_DST_TYPE
+#include "texutil_tmp.h"
+
+
+#define CONVERT_TEXEL( src ) \
+ PACK_COLOR_88( src[0], 0x00 )
+
+#define CONVERT_TEXEL_DWORD( src ) \
+ ((PACK_COLOR_88( src[0], 0x00 )) | \
+ (PACK_COLOR_88( src[1], 0x00 ) << 16))
+
+#define SRC_TEXEL_BYTES 1
+
+#define TAG(x) x##_a8_to_al88
+#define PRESERVE_DST_TYPE
+#include "texutil_tmp.h"
+
+
+#define CONVERT_TEXEL( src ) \
+ PACK_COLOR_88( 0xff, src[0] )
+
+#define CONVERT_TEXEL_DWORD( src ) \
+ ((PACK_COLOR_88( 0xff, src[0] )) | \
+ (PACK_COLOR_88( 0xff, src[1] ) << 16))
+
+#define SRC_TEXEL_BYTES 1
+
+#define TAG(x) x##_l8_to_al88
+#include "texutil_tmp.h"
+
+
+#define CONVERT_AL88( name ) \
+static GLboolean \
+convert_##name##_al88( struct gl_texture_convert *convert ) \
+{ \
+ convert_func *tab; \
+ GLint index = convert->index; \
+ \
+ if ( convert->format == GL_LUMINANCE_ALPHA && \
+ convert->type == GL_UNSIGNED_BYTE ) \
+ { \
+ tab = name##_tab_al88_direct; \
+ } \
+ else if ( convert->format == GL_ALPHA && \
+ convert->type == GL_UNSIGNED_BYTE ) \
+ { \
+ tab = name##_tab_a8_to_al88; \
+ } \
+ else if ( convert->format == GL_LUMINANCE && \
+ convert->type == GL_UNSIGNED_BYTE ) \
+ { \
+ tab = name##_tab_l8_to_al88; \
+ } \
+ else \
+ { \
+ /* Can't handle this source format/type combination */ \
+ return GL_FALSE; \
+ } \
+ \
+ return tab[index]( convert ); \
+}
+
+CONVERT_AL88( texsubimage2d )
+CONVERT_AL88( texsubimage3d )
+
+
+static void
+unconvert_teximage_al88( struct gl_texture_convert *convert )
+{
+ const GLubyte *src = (const GLubyte *)convert->srcImage;
+ GLint texels, i;
+
+ texels = convert->width * convert->height * convert->depth;
+
+ switch ( convert->format ) {
+ case GL_LUMINANCE_ALPHA:
+ MEMCPY( convert->dstImage, src, texels * 2 );
+ break;
+ case GL_ALPHA: {
+ GLubyte *dst = (GLubyte *)convert->dstImage;
+ for ( i = 0 ; i < texels ; i++ ) {
+ *dst++ = src[1];
+ src += 2;
+ }
+ break;
+ }
+ case GL_LUMINANCE: {
+ GLubyte *dst = (GLubyte *)convert->dstImage;
+ for ( i = 0 ; i < texels ; i++ ) {
+ *dst++ = src[0];
+ src += 2;
+ }
+ break;
+ }
+ default:
+ UNCONVERT_ERROR( convert->format );
+ break;
}
}
-/*
- * Convert a texture image from an internal format to one of Mesa's
- * core internal formats. This is likely to be used by glGetTexImage
- * and for fetching texture images when falling back to software rendering.
- *
- * Input:
- * srcFormat - source image format
- * srcWidth, srcHeight - source image size
- * srcImage - source image pointer
- * srcRowStride - bytes to jump between image rows
- * dstWidth, dstHeight - size of dest image
- * dstFormat - format of dest image (must be one of Mesa's IntFormat values)
- * dstImage - pointer to dest image
- * Notes:
- * This function will do power of two image down-scaling to accomodate
- * drivers with limited texture image aspect ratios.
- * The implicit dest data type is GL_UNSIGNED_BYTE.
+/* ================================================================
+ * RGB332 textures:
+ */
+
+static GLboolean
+convert_texsubimage2d_rgb332( struct gl_texture_convert *convert )
+{
+ /* This is a placeholder for now...
+ */
+ return GL_FALSE;
+}
+
+static GLboolean
+convert_texsubimage3d_rgb332( struct gl_texture_convert *convert )
+{
+ /* This is a placeholder for now...
+ */
+ return GL_FALSE;
+}
+
+
+static void
+unconvert_teximage_rgb332( struct gl_texture_convert *convert )
+{
+ UNCONVERT_ERROR( convert->format );
+}
+
+
+
+/* ================================================================
+ * CI8 (and all other single-byte texel) textures:
*/
-void
-_mesa_unconvert_teximage(MesaIntTexFormat srcFormat,
- GLint srcWidth, GLint srcHeight,
- const GLvoid *srcImage, GLint srcRowStride,
- GLint dstWidth, GLint dstHeight,
- GLenum dstFormat, GLubyte *dstImage)
+
+#define DST_TYPE GLubyte
+#define DST_TEXELS_PER_DWORD 4
+
+#define CONVERT_TEXEL( src ) src[0]
+
+#define CONVERT_DIRECT
+
+#define SRC_TEXEL_BYTES 1
+
+#define TAG(x) x##_ci8_direct
+#include "texutil_tmp.h"
+
+
+#define CONVERT_CI8( name ) \
+static GLboolean \
+convert_##name##_ci8( struct gl_texture_convert *convert ) \
+{ \
+ convert_func *tab; \
+ GLint index = convert->index; \
+ \
+ if ( ( convert->format == GL_ALPHA || \
+ convert->format == GL_LUMINANCE || \
+ convert->format == GL_INTENSITY || \
+ convert->format == GL_COLOR_INDEX ) && \
+ convert->type == GL_UNSIGNED_BYTE ) \
+ { \
+ tab = name##_tab_ci8_direct; \
+ } \
+ else \
+ { \
+ /* Can't handle this source format/type combination */ \
+ return GL_FALSE; \
+ } \
+ \
+ return tab[index]( convert ); \
+}
+
+CONVERT_CI8( texsubimage2d )
+CONVERT_CI8( texsubimage3d )
+
+
+static void
+unconvert_teximage_ci8( struct gl_texture_convert *convert )
{
- static GLboolean firstCall = GL_TRUE;
- const GLint wScale = srcWidth / dstWidth; /* must be power of two */
- const GLint hScale = srcHeight / dstHeight; /* must be power of two */
- ASSERT(srcWidth >= dstWidth);
- ASSERT(srcHeight >= dstHeight);
- ASSERT(dstImage);
- ASSERT(srcImage);
-
- if (firstCall) {
- generate_lookup_tables();
- firstCall = GL_FALSE;
+ const GLubyte *src = (const GLubyte *)convert->srcImage;
+ GLint texels;
+
+ texels = convert->width * convert->height * convert->depth;
+
+ switch ( convert->format ) {
+ case GL_ALPHA:
+ case GL_LUMINANCE:
+ case GL_INTENSITY:
+ case GL_COLOR_INDEX:
+ MEMCPY( convert->dstImage, src, texels );
+ break;
+ default:
+ UNCONVERT_ERROR( convert->format );
+ break;
}
+}
- switch (srcFormat) {
- case MESA_I8:
- case MESA_L8:
- case MESA_A8:
- case MESA_C8:
-#ifdef DEBUG
- if (srcFormat == MESA_I8) {
- ASSERT(dstFormat == GL_INTENSITY);
- }
- else if (srcFormat == MESA_L8) {
- ASSERT(dstFormat == GL_LUMINANCE);
- }
- else if (srcFormat == MESA_A8) {
- ASSERT(dstFormat == GL_ALPHA);
- }
- else if (srcFormat == MESA_C8) {
- ASSERT(dstFormat == GL_COLOR_INDEX);
- }
-#endif
- if (wScale == 1 && hScale == 1) {
- /* easy! */
- MEMCPY(dstImage, srcImage, dstWidth * dstHeight * sizeof(GLubyte));
- }
- else {
- /* rescale */
- const GLubyte *src8 = (const GLubyte *) srcImage;
- GLint row, col;
- for (row = 0; row < dstHeight; row++) {
- GLint srcRow = row * hScale;
- for (col = 0; col < dstWidth; col++) {
- GLint srcCol = col * wScale;
- *dstImage++ = src8[srcRow * srcWidth + srcCol];
- }
- }
- }
- break;
- case MESA_A8_L8:
- ASSERT(dstFormat == GL_LUMINANCE_ALPHA);
- if (wScale == 1 && hScale == 1) {
- GLint i, n = dstWidth * dstHeight;
- const GLushort *texel = (const GLushort *) srcImage;
- for (i = 0; i < n; i++) {
- const GLushort tex = *texel++;
- *dstImage++ = (tex & 0xff); /* luminance */
- *dstImage++ = (tex >> 8); /* alpha */
- }
- }
- else {
- /* rescale */
- const GLushort *src16 = (const GLushort *) srcImage;
- GLint row, col;
- for (row = 0; row < dstHeight; row++) {
- GLint srcRow = row * hScale;
- for (col = 0; col < dstWidth; col++) {
- GLint srcCol = col * wScale;
- const GLushort tex = src16[srcRow * srcWidth + srcCol];
- *dstImage++ = (tex & 0xff); /* luminance */
- *dstImage++ = (tex >> 8); /* alpha */
- }
- }
- }
- break;
- case MESA_R5_G6_B5:
- ASSERT(dstFormat == GL_RGB);
- if (wScale == 1 && hScale == 1) {
- GLint i, n = dstWidth * dstHeight;
- const GLushort *texel = (const GLushort *) srcImage;
- for (i = 0; i < n; i++) {
- const GLushort tex = *texel++;
- *dstImage++ = R5G6B5toRed[tex];
- *dstImage++ = R5G6B5toGreen[tex];
- *dstImage++ = R5G6B5toBlue[tex];
- }
- }
- else {
- /* rescale */
- const GLushort *src16 = (const GLushort *) srcImage;
- GLint row, col;
- for (row = 0; row < dstHeight; row++) {
- GLint srcRow = row * hScale;
- for (col = 0; col < dstWidth; col++) {
- GLint srcCol = col * wScale;
- const GLushort tex = src16[srcRow * srcWidth + srcCol];
- *dstImage++ = R5G6B5toRed[tex];
- *dstImage++ = R5G6B5toGreen[tex];
- *dstImage++ = R5G6B5toBlue[tex];
- }
- }
- }
- break;
- case MESA_A4_R4_G4_B4:
- ASSERT(dstFormat == GL_RGBA);
- if (wScale == 1 && hScale == 1) {
- GLint i, n = dstWidth * dstHeight;
- const GLushort *texel = (const GLushort *) srcImage;
- for (i = 0; i < n; i++) {
- const GLushort tex = *texel++;
- *dstImage++ = A4R4G4B4toRed[tex];
- *dstImage++ = A4R4G4B4toGreen[tex];
- *dstImage++ = A4R4G4B4toBlue[tex];
- *dstImage++ = A4R4G4B4toAlpha[tex];
- }
- }
- else {
- /* rescale */
- const GLushort *src16 = (const GLushort *) srcImage;
- GLint row, col;
- for (row = 0; row < dstHeight; row++) {
- GLint srcRow = row * hScale;
- for (col = 0; col < dstWidth; col++) {
- GLint srcCol = col * wScale;
- const GLushort tex = src16[srcRow * srcWidth + srcCol];
- *dstImage++ = A4R4G4B4toRed[tex];
- *dstImage++ = A4R4G4B4toGreen[tex];
- *dstImage++ = A4R4G4B4toBlue[tex];
- *dstImage++ = A4R4G4B4toAlpha[tex];
- }
- }
- }
- break;
- case MESA_A1_R5_G5_B5:
- ASSERT(dstFormat == GL_RGBA);
- if (wScale == 1 && hScale == 1) {
- GLint i, n = dstWidth * dstHeight;
- const GLushort *texel = (const GLushort *) srcImage;
- for (i = 0; i < n; i++) {
- const GLushort tex = *texel++;
- *dstImage++ = A1R5G5B5toRed[tex];
- *dstImage++ = A1R5G5B5toGreen[tex];
- *dstImage++ = A1R5G5B5toBlue[tex];
- *dstImage++ = A1R5G5B5toAlpha[tex];
- }
- }
- else {
- /* rescale */
- const GLushort *src16 = (const GLushort *) srcImage;
- GLint row, col;
- for (row = 0; row < dstHeight; row++) {
- GLint srcRow = row * hScale;
- for (col = 0; col < dstWidth; col++) {
- GLint srcCol = col * wScale;
- const GLushort tex = src16[srcRow * srcWidth + srcCol];
- *dstImage++ = A1R5G5B5toRed[tex];
- *dstImage++ = A1R5G5B5toGreen[tex];
- *dstImage++ = A1R5G5B5toBlue[tex];
- *dstImage++ = A1R5G5B5toAlpha[tex];
- }
- }
- }
- break;
- case MESA_A8_R8_G8_B8:
- case MESA_FF_R8_G8_B8:
- ASSERT(dstFormat == GL_RGBA);
- if (wScale == 1 && hScale == 1) {
- GLint i, n = dstWidth * dstHeight;
- const GLuint *texel = (const GLuint *) srcImage;
- for (i = 0; i < n; i++) {
- const GLuint tex = *texel++;
- *dstImage++ = (tex >> 16) & 0xff; /* R */
- *dstImage++ = (tex >> 8) & 0xff; /* G */
- *dstImage++ = (tex ) & 0xff; /* B */
- *dstImage++ = (tex >> 24) & 0xff; /* A */
- }
- }
- else {
- /* rescale */
- const GLuint *src = (const GLuint *) srcImage;
- GLint row, col;
- for (row = 0; row < dstHeight; row++) {
- GLint srcRow = row * hScale;
- for (col = 0; col < dstWidth; col++) {
- GLint srcCol = col * wScale;
- const GLuint tex = src[srcRow * srcWidth + srcCol];
- *dstImage++ = (tex >> 16) & 0xff; /* R */
- *dstImage++ = (tex >> 8) & 0xff; /* G */
- *dstImage++ = (tex ) & 0xff; /* B */
- *dstImage++ = (tex >> 24) & 0xff; /* A */
- }
- }
- }
- break;
- default:
- gl_problem(NULL, "bad srcFormat in _mesa_uncovert_teximage()");
+
+
+/* ================================================================
+ * Global entry points
+ */
+
+static convert_func gl_convert_texsubimage2d_tab[] = {
+ convert_texsubimage2d_rgba8888,
+ convert_texsubimage2d_abgr8888,
+ convert_texsubimage2d_argb8888,
+ convert_texsubimage2d_rgb888,
+ convert_texsubimage2d_bgr888,
+ convert_texsubimage2d_rgb565,
+ convert_texsubimage2d_argb4444,
+ convert_texsubimage2d_argb1555,
+ convert_texsubimage2d_al88,
+ convert_texsubimage2d_rgb332,
+ convert_texsubimage2d_ci8, /* These are all the same... */
+ convert_texsubimage2d_ci8,
+ convert_texsubimage2d_ci8,
+ convert_texsubimage2d_ci8,
+};
+
+static convert_func gl_convert_texsubimage3d_tab[] = {
+ convert_texsubimage3d_rgba8888,
+ convert_texsubimage3d_abgr8888,
+ convert_texsubimage3d_argb8888,
+ convert_texsubimage3d_rgb888,
+ convert_texsubimage3d_bgr888,
+ convert_texsubimage3d_rgb565,
+ convert_texsubimage3d_argb4444,
+ convert_texsubimage3d_argb1555,
+ convert_texsubimage3d_al88,
+ convert_texsubimage3d_rgb332,
+ convert_texsubimage3d_ci8, /* These are all the same... */
+ convert_texsubimage3d_ci8,
+ convert_texsubimage3d_ci8,
+ convert_texsubimage3d_ci8,
+};
+
+static unconvert_func gl_unconvert_teximage_tab[] = {
+ unconvert_teximage_rgba8888,
+ unconvert_teximage_abgr8888,
+ unconvert_teximage_argb8888,
+ unconvert_teximage_rgb888,
+ unconvert_teximage_bgr888,
+ unconvert_teximage_rgb565,
+ unconvert_teximage_argb4444,
+ unconvert_teximage_argb1555,
+ unconvert_teximage_al88,
+ unconvert_teximage_rgb332,
+ unconvert_teximage_ci8, /* These are all the same... */
+ unconvert_teximage_ci8,
+ unconvert_teximage_ci8,
+ unconvert_teximage_ci8,
+};
+
+
+/* See if we need to care about the pixel store attributes when we're
+ * converting the texture image. This should be stored as
+ * packing->_SomeBoolean and updated when the values change, to avoid
+ * testing every time...
+ */
+static INLINE GLboolean
+convert_needs_packing( const struct gl_pixelstore_attrib *packing,
+ GLenum format, GLenum type )
+{
+ if ( ( packing->Alignment == 1 ||
+ ( packing->Alignment == 4 && /* Pick up the common Q3A case... */
+ format == GL_RGBA && type == GL_UNSIGNED_BYTE ) ) &&
+ packing->RowLength == 0 &&
+ packing->SkipPixels == 0 &&
+ packing->SkipRows == 0 &&
+ packing->ImageHeight == 0 &&
+ packing->SkipImages == 0 &&
+ packing->SwapBytes == GL_FALSE &&
+ packing->LsbFirst == GL_FALSE ) {
+ return GL_FALSE;
+ } else {
+ return GL_TRUE;
}
}
+GLboolean
+_mesa_convert_texsubimage1d( GLint mesaFormat,
+ GLint xoffset,
+ GLint width,
+ GLenum format, GLenum type,
+ const struct gl_pixelstore_attrib *packing,
+ const GLvoid *srcImage, GLvoid *dstImage )
+{
+ struct gl_texture_convert convert;
-/*
- * Given an internal Mesa driver texture format, fill in the component
- * bit sizes in the given texture image struct.
+ ASSERT( packing );
+ ASSERT( srcImage );
+ ASSERT( dstImage );
+
+ ASSERT( mesaFormat >= MESA_FORMAT_RGBA8888 );
+ ASSERT( mesaFormat <= MESA_FORMAT_CI8 );
+
+ /* Make it easier to pass all the parameters around.
+ */
+ convert.xoffset = xoffset;
+ convert.yoffset = 0;
+ convert.width = width;
+ convert.height = 1;
+ convert.format = format;
+ convert.type = type;
+ convert.packing = packing;
+ convert.srcImage = srcImage;
+ convert.dstImage = dstImage;
+
+ convert.index = 0;
+
+ if ( convert_needs_packing( packing, format, type ) )
+ convert.index |= CONVERT_PACKING_BIT;
+
+ return gl_convert_texsubimage2d_tab[mesaFormat]( &convert );
+}
+
+GLboolean
+_mesa_convert_texsubimage2d( GLint mesaFormat,
+ GLint xoffset, GLint yoffset,
+ GLint width, GLint height,
+ GLint imageWidth,
+ GLenum format, GLenum type,
+ const struct gl_pixelstore_attrib *packing,
+ const GLvoid *srcImage, GLvoid *dstImage )
+{
+ struct gl_texture_convert convert;
+
+ ASSERT( packing );
+ ASSERT( srcImage );
+ ASSERT( dstImage );
+
+ ASSERT( mesaFormat >= MESA_FORMAT_RGBA8888 );
+ ASSERT( mesaFormat <= MESA_FORMAT_CI8 );
+
+ /* Make it easier to pass all the parameters around.
+ */
+ convert.xoffset = xoffset;
+ convert.yoffset = yoffset;
+ convert.width = width;
+ convert.height = height;
+ convert.imageWidth = imageWidth;
+ convert.format = format;
+ convert.type = type;
+ convert.packing = packing;
+ convert.srcImage = srcImage;
+ convert.dstImage = dstImage;
+
+ convert.index = 0;
+
+ if ( convert_needs_packing( packing, format, type ) )
+ convert.index |= CONVERT_PACKING_BIT;
+
+ if ( width != imageWidth )
+ convert.index |= CONVERT_STRIDE_BIT;
+
+ return gl_convert_texsubimage2d_tab[mesaFormat]( &convert );
+}
+
+GLboolean
+_mesa_convert_texsubimage3d( GLint mesaFormat,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLint width, GLint height, GLint depth,
+ GLint imageWidth, GLint imageHeight,
+ GLenum format, GLenum type,
+ const struct gl_pixelstore_attrib *packing,
+ const GLvoid *srcImage, GLvoid *dstImage )
+{
+ struct gl_texture_convert convert;
+
+ ASSERT( packing );
+ ASSERT( srcImage );
+ ASSERT( dstImage );
+
+ ASSERT( mesaFormat >= MESA_FORMAT_RGBA8888 );
+ ASSERT( mesaFormat <= MESA_FORMAT_CI8 );
+
+ /* Make it easier to pass all the parameters around.
+ */
+ convert.xoffset = xoffset;
+ convert.yoffset = yoffset;
+ convert.zoffset = zoffset;
+ convert.width = width;
+ convert.height = height;
+ convert.depth = depth;
+ convert.imageWidth = imageWidth;
+ convert.imageHeight = imageHeight;
+ convert.format = format;
+ convert.type = type;
+ convert.packing = packing;
+ convert.srcImage = srcImage;
+ convert.dstImage = dstImage;
+
+ convert.index = 0;
+
+ if ( convert_needs_packing( packing, format, type ) )
+ convert.index |= CONVERT_PACKING_BIT;
+
+ if ( width != imageWidth || height != imageHeight )
+ convert.index |= CONVERT_STRIDE_BIT;
+
+ return gl_convert_texsubimage3d_tab[mesaFormat]( &convert );
+}
+
+
+
+void _mesa_unconvert_teximage1d( GLint mesaFormat, GLenum format, GLint width,
+ const GLvoid *srcImage, GLvoid *dstImage )
+{
+ struct gl_texture_convert convert;
+
+ ASSERT( srcImage );
+ ASSERT( dstImage );
+
+ ASSERT( mesaFormat >= MESA_FORMAT_RGBA8888 );
+ ASSERT( mesaFormat <= MESA_FORMAT_CI8 );
+
+ /* Make it easier to pass all the parameters around.
+ */
+ convert.width = width;
+ convert.height = 1;
+ convert.depth = 1;
+ convert.format = format;
+ convert.srcImage = srcImage;
+ convert.dstImage = dstImage;
+
+ gl_unconvert_teximage_tab[mesaFormat]( &convert );
+}
+
+void _mesa_unconvert_teximage2d( GLint mesaFormat, GLenum format,
+ GLint width, GLint height,
+ const GLvoid *srcImage, GLvoid *dstImage )
+{
+ struct gl_texture_convert convert;
+
+ ASSERT( srcImage );
+ ASSERT( dstImage );
+
+ ASSERT( mesaFormat >= MESA_FORMAT_RGBA8888 );
+ ASSERT( mesaFormat <= MESA_FORMAT_CI8 );
+
+ /* Make it easier to pass all the parameters around.
+ */
+ convert.width = width;
+ convert.height = height;
+ convert.depth = 1;
+ convert.format = format;
+ convert.srcImage = srcImage;
+ convert.dstImage = dstImage;
+
+ gl_unconvert_teximage_tab[mesaFormat]( &convert );
+}
+
+void _mesa_unconvert_teximage3d( GLint mesaFormat, GLenum format,
+ GLint width, GLint height, GLint depth,
+ const GLvoid *srcImage, GLvoid *dstImage )
+{
+ struct gl_texture_convert convert;
+
+ ASSERT( srcImage );
+ ASSERT( dstImage );
+
+ ASSERT( mesaFormat >= MESA_FORMAT_RGBA8888 );
+ ASSERT( mesaFormat <= MESA_FORMAT_CI8 );
+
+ /* Make it easier to pass all the parameters around.
+ */
+ convert.width = width;
+ convert.height = height;
+ convert.depth = depth;
+ convert.format = format;
+ convert.srcImage = srcImage;
+ convert.dstImage = dstImage;
+
+ gl_unconvert_teximage_tab[mesaFormat]( &convert );
+}
+
+
+
+/* Nearest filtering only (for broken hardware that can't support
+ * all aspect ratios). This can be made a lot faster, but I don't
+ * really care enough...
*/
-void
-_mesa_set_teximage_component_sizes(MesaIntTexFormat mesaFormat,
- struct gl_texture_image *texImage)
+void _mesa_rescale_teximage2d( const struct gl_texture_format *texFormat,
+ GLint srcWidth, GLint srcHeight,
+ GLint dstWidth, GLint dstHeight,
+ const GLvoid *srcImage, GLvoid *dstImage )
{
- static const GLint bitSizes [][8] = {
- /* format R G B A I L C */
- { MESA_I8, 0, 0, 0, 0, 8, 0, 0 },
- { MESA_L8, 0, 0, 0, 0, 0, 8, 0 },
- { MESA_A8, 0, 0, 0, 8, 0, 0, 0 },
- { MESA_C8, 0, 0, 0, 0, 0, 0, 8 },
- { MESA_A8_L8, 0, 0, 0, 8, 0, 8, 0 },
- { MESA_R5_G6_B5, 5, 6, 5, 0, 0, 0, 0 },
- { MESA_A4_R4_G4_B4, 4, 4, 4, 4, 0, 0, 0 },
- { MESA_A1_R5_G5_B5, 5, 5, 5, 1, 0, 0, 0 },
- { MESA_A8_R8_G8_B8, 8, 8, 8, 8, 0, 0, 0 },
- { MESA_FF_R8_G8_B8, 8, 8, 8, 8, 0, 0, 0 },
- { -1, 0, 0, 0, 0, 0, 0, 0 }
- };
- GLint i;
- for (i = 0; i < bitSizes[i][0] >= 0; i++) {
- if (bitSizes[i][0] == mesaFormat) {
- texImage->RedBits = bitSizes[i][1];
- texImage->GreenBits = bitSizes[i][2];
- texImage->BlueBits = bitSizes[i][3];
- texImage->AlphaBits = bitSizes[i][4];
- texImage->IntensityBits = bitSizes[i][5];
- texImage->LuminanceBits = bitSizes[i][6];
- texImage->IndexBits = bitSizes[i][7];
- return;
- }
+ GLint row, col;
+
+#define INNER_LOOP( HOP, WOP ) \
+ for ( row = 0 ; row < dstHeight ; row++ ) { \
+ GLint srcRow = row HOP hScale; \
+ for ( col = 0 ; col < dstWidth ; col++ ) { \
+ GLint srcCol = col WOP wScale; \
+ *dst++ = src[srcRow * srcWidth + srcCol]; \
+ } \
+ } \
+
+#define RESCALE_IMAGE( TYPE ) \
+do { \
+ const TYPE *src = (const TYPE *)srcImage; \
+ TYPE *dst = (TYPE *)dstImage; \
+ \
+ if ( srcHeight <= dstHeight ) { \
+ const GLint hScale = dstHeight / srcHeight; \
+ if ( srcWidth <= dstWidth ) { \
+ const GLint wScale = dstWidth / srcWidth; \
+ INNER_LOOP( /, / ); \
+ } \
+ else { \
+ const GLint wScale = srcWidth / dstWidth; \
+ INNER_LOOP( /, * ); \
+ } \
+ } \
+ else { \
+ const GLint hScale = srcHeight / dstHeight; \
+ if ( srcWidth <= dstWidth ) { \
+ const GLint wScale = dstWidth / srcWidth; \
+ INNER_LOOP( *, / ); \
+ } \
+ else { \
+ const GLint wScale = srcWidth / dstWidth; \
+ INNER_LOOP( *, * ); \
+ } \
+ } \
+} while (0)
+
+ switch ( texFormat->TexelBytes ) {
+ case 4:
+ RESCALE_IMAGE( GLuint );
+ break;
+
+ case 2:
+ RESCALE_IMAGE( GLushort );
+ break;
+
+ case 1:
+ RESCALE_IMAGE( GLubyte );
+ break;
}
- gl_problem(NULL, "bad format in _mesa_set_teximage_component_sizes");
}
diff --git a/xc/extras/Mesa/src/texutil.h b/xc/extras/Mesa/src/texutil.h
index 22e916d50..a3e842667 100644
--- a/xc/extras/Mesa/src/texutil.h
+++ b/xc/extras/Mesa/src/texutil.h
@@ -2,91 +2,86 @@
/*
* Mesa 3-D graphics library
* Version: 3.4
- *
+ *
* Copyright (C) 1999-2000 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.
+ *
+ * Authors:
+ * Gareth Hughes <gareth@valinux.com>
*/
#ifndef TEXUTIL_H
#define TEXUTIL_H
-
#include "types.h"
-
-
-
-/*
- * NOTE: "FF" means fill with byte value 0xff
- */
- /* msb <------ TEXEL BITS -----------> lsb */
-typedef enum { /* ---- ---- ---- ---- ---- ---- ---- ---- */
- MESA_I8, /* IIII IIII */
- MESA_L8, /* LLLL LLLL */
- MESA_A8, /* AAAA AAAA */
- MESA_C8, /* CCCC CCCC */
- MESA_A8_L8, /* AAAA AAAA LLLL LLLL */
- MESA_R5_G6_B5, /* RRRR RGGG GGGB BBBB */
- MESA_A4_R4_G4_B4, /* AAAA RRRR GGGG BBBB */
- MESA_A1_R5_G5_B5, /* ARRR RRGG GGGB BBBB */
- MESA_A8_R8_G8_B8, /* AAAA AAAA RRRR RRRR GGGG GGGG BBBB BBBB */
- MESA_FF_R8_G8_B8 /* FFFF FFFF RRRR RRRR GGGG GGGG BBBB BBBB */
-} MesaIntTexFormat;
-
-
-
+#include "texformat.h"
extern GLboolean
-_mesa_convert_teximage(MesaIntTexFormat dstFormat,
- GLint dstWidth, GLint dstHeight, GLvoid *dstImage,
- GLint dstRowStride,
- GLint srcWidth, GLint srcHeight,
- GLenum srcFormat, GLenum srcType,
- const GLvoid *srcImage,
- const struct gl_pixelstore_attrib *packing);
-
-
+_mesa_convert_texsubimage1d( GLint mesaFormat,
+ GLint xoffset,
+ GLint width,
+ GLenum format, GLenum type,
+ const struct gl_pixelstore_attrib *packing,
+ const GLvoid *srcImage, GLvoid *dstImage );
extern GLboolean
-_mesa_convert_texsubimage(MesaIntTexFormat dstFormat,
- GLint dstXoffset, GLint dstYoffset,
- GLint dstWidth, GLint dstHeight, GLvoid *dstImage,
- GLint dstRowStride,
- GLint width, GLint height,
- GLint srcWidth, GLint srcHeight,
- GLenum srcFormat, GLenum srcType,
- const GLvoid *srcImage,
- const struct gl_pixelstore_attrib *packing);
-
+_mesa_convert_texsubimage2d( GLint mesaFormat,
+ GLint xoffset, GLint yoffset,
+ GLint width, GLint height,
+ GLint imageWidth,
+ GLenum format, GLenum type,
+ const struct gl_pixelstore_attrib *packing,
+ const GLvoid *srcImage, GLvoid *dstImage );
+extern GLboolean
+_mesa_convert_texsubimage3d( GLint mesaFormat,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLint width, GLint height, GLint depth,
+ GLint imageWidth, GLint imageHeight,
+ GLenum format, GLenum type,
+ const struct gl_pixelstore_attrib *packing,
+ const GLvoid *srcImage, GLvoid *dstImage );
+
+/* Deprecated in 3.5:
+ */
extern void
-_mesa_unconvert_teximage(MesaIntTexFormat srcFormat,
- GLint srcWidth, GLint srcHeight,
- const GLvoid *srcImage, GLint srcRowStride,
- GLint dstWidth, GLint dstHeight,
- GLenum dstFormat, GLubyte *dstImage);
+_mesa_unconvert_teximage1d( GLint mesaFormat, GLenum format, GLint width,
+ const GLvoid *srcImage, GLvoid *dstImage );
+extern void
+_mesa_unconvert_teximage2d( GLint mesaFormat, GLenum format,
+ GLint width, GLint height,
+ const GLvoid *srcImage, GLvoid *dstImage );
extern void
-_mesa_set_teximage_component_sizes(MesaIntTexFormat mesaFormat,
- struct gl_texture_image *texImage);
+_mesa_unconvert_teximage3d( GLint mesaFormat, GLenum format,
+ GLint width, GLint height, GLint depth,
+ const GLvoid *srcImage, GLvoid *dstImage );
+/* Nearest filtering only (for broken hardware that can't support
+ * all aspect ratios). FIXME: Make this a subimage update as well...
+ */
+extern void
+_mesa_rescale_teximage2d( const struct gl_texture_format *texFormat,
+ GLint srcWidth, GLint srcHeight,
+ GLint dstWidth, GLint dstHeight,
+ const GLvoid *srcImage, GLvoid *dstImage );
#endif
-
diff --git a/xc/extras/Mesa/src/texutil_tmp.h b/xc/extras/Mesa/src/texutil_tmp.h
new file mode 100644
index 000000000..ea6c4ee52
--- /dev/null
+++ b/xc/extras/Mesa/src/texutil_tmp.h
@@ -0,0 +1,375 @@
+/*
+ * NOTE: All 3D code is untested and most definitely broken...
+ */
+
+#define DST_TEXEL_BYTES (4 / DST_TEXELS_PER_DWORD)
+#define DST_ROW_WIDTH (convert->width * DST_TEXEL_BYTES)
+#define DST_ROW_STRIDE (convert->imageWidth * DST_TEXEL_BYTES)
+#define DST_IMG_STRIDE (convert->imageWidth * \
+ convert->imageHeight * DST_TEXEL_BYTES)
+
+
+/* ================================================================
+ * PRE: No pixelstore attribs, width == imageWidth.
+ */
+static GLboolean
+TAG(texsubimage2d)( struct gl_texture_convert *convert )
+{
+ const GLubyte *src = (const GLubyte *)convert->srcImage;
+ GLuint *dst = (GLuint *)((GLubyte *)convert->dstImage +
+ (convert->yoffset * convert->imageWidth +
+ convert->xoffset) * DST_TEXEL_BYTES);
+ GLint dwords, i;
+ (void) dwords; (void) i;
+
+ if ( DBG )
+ fprintf( stderr, __FUNCTION__ "\n" );
+
+#ifdef CONVERT_DIRECT
+ MEMCPY( dst, src, convert->height * DST_ROW_WIDTH );
+#else
+ dwords = (convert->width * convert->height +
+ DST_TEXELS_PER_DWORD - 1) / DST_TEXELS_PER_DWORD;
+
+ for ( i = 0 ; i < dwords ; i++ ) {
+ *dst++ = CONVERT_TEXEL_DWORD( src );
+ src += SRC_TEXEL_BYTES * DST_TEXELS_PER_DWORD;
+ }
+#endif
+
+ return GL_TRUE;
+}
+
+/* PRE: As above, height == imageHeight also.
+ */
+static GLboolean
+TAG(texsubimage3d)( struct gl_texture_convert *convert )
+{
+ const GLubyte *src = (const GLubyte *)convert->srcImage;
+ GLuint *dst = (GLuint *)((GLubyte *)convert->dstImage +
+ ((convert->zoffset * convert->height +
+ convert->yoffset) * convert->width +
+ convert->xoffset) * DST_TEXEL_BYTES);
+ GLint dwords, i;
+ (void) dwords; (void) i;
+
+ if ( DBG )
+ fprintf( stderr, __FUNCTION__ "\n" );
+
+#ifdef CONVERT_DIRECT
+ MEMCPY( dst, src, convert->depth * convert->height * DST_ROW_WIDTH );
+#else
+ dwords = (convert->width * convert->height * convert->depth +
+ DST_TEXELS_PER_DWORD - 1) / DST_TEXELS_PER_DWORD;
+
+ for ( i = 0 ; i < dwords ; i++ ) {
+ *dst++ = CONVERT_TEXEL_DWORD( src );
+ src += SRC_TEXEL_BYTES * DST_TEXELS_PER_DWORD;
+ }
+#endif
+
+ return GL_TRUE;
+}
+
+
+
+/* ================================================================
+ * PRE: No pixelstore attribs, width != imageWidth.
+ */
+static GLboolean
+TAG(texsubimage2d_stride)( struct gl_texture_convert *convert )
+{
+ const GLubyte *src = (const GLubyte *)convert->srcImage;
+ DST_TYPE *dst = (DST_TYPE *)((GLubyte *)convert->dstImage +
+ (convert->yoffset * convert->imageWidth +
+ convert->xoffset) * DST_TEXEL_BYTES);
+ GLint adjust;
+ GLint row, col;
+
+ adjust = convert->imageWidth - convert->width;
+
+ if ( DBG ) {
+ fprintf( stderr, __FUNCTION__ ":\n" );
+ fprintf( stderr, " x=%d y=%d w=%d h=%d s=%d\n",
+ convert->xoffset, convert->yoffset, convert->width,
+ convert->height, convert->imageWidth );
+ fprintf( stderr, " adjust=%d\n", adjust );
+ }
+
+ for ( row = 0 ; row < convert->height ; row++ ) {
+ for ( col = 0 ; col < convert->width ; col++ ) {
+ *dst++ = CONVERT_TEXEL( src );
+ src += SRC_TEXEL_BYTES;
+ }
+ dst += adjust;
+ }
+
+ return GL_TRUE;
+}
+
+/* PRE: As above, or height != imageHeight also.
+ */
+static GLboolean
+TAG(texsubimage3d_stride)( struct gl_texture_convert *convert )
+{
+ const GLubyte *src = (const GLubyte *)convert->srcImage;
+ DST_TYPE *dst = (DST_TYPE *)((GLubyte *)convert->dstImage +
+ ((convert->zoffset * convert->imageHeight +
+ convert->yoffset) * convert->imageWidth +
+ convert->xoffset) * DST_TEXEL_BYTES);
+ GLint adjust;
+ GLint row, col, img;
+
+ adjust = convert->imageWidth - convert->width;
+
+ if ( DBG ) {
+ fprintf( stderr, __FUNCTION__ ":\n" );
+ fprintf( stderr, " x=%d y=%d w=%d h=%d s=%d\n",
+ convert->xoffset, convert->yoffset, convert->width,
+ convert->height, convert->imageWidth );
+ fprintf( stderr, " adjust=%d\n", adjust );
+ }
+
+ for ( img = 0 ; img < convert->depth ; img++ ) {
+ for ( row = 0 ; row < convert->height ; row++ ) {
+ for ( col = 0 ; col < convert->width ; col++ ) {
+ *dst++ = CONVERT_TEXEL( src );
+ src += SRC_TEXEL_BYTES;
+ }
+ dst += adjust;
+ }
+ /* FIXME: ... */
+ }
+
+ return GL_TRUE;
+}
+
+
+
+/* ================================================================
+ * PRE: Require pixelstore attribs, width == imageWidth.
+ */
+static GLboolean
+TAG(texsubimage2d_pack)( struct gl_texture_convert *convert )
+{
+ const GLubyte *src = (const GLubyte *)
+ _mesa_image_address( convert->packing, convert->srcImage,
+ convert->width, convert->height,
+ convert->format, convert->type, 0, 0, 0 );
+ const GLint srcRowStride =
+ _mesa_image_row_stride( convert->packing, convert->width,
+ convert->format, convert->type );
+ GLuint *dst = (GLuint *)((GLubyte *)convert->dstImage +
+ (convert->yoffset * convert->width +
+ convert->xoffset) * DST_TEXEL_BYTES);
+ GLint width;
+ GLint row, col;
+ (void) col;
+
+ if ( DBG )
+ fprintf( stderr, __FUNCTION__ "\n" );
+
+ width = ((convert->width + DST_TEXELS_PER_DWORD - 1)
+ & ~(DST_TEXELS_PER_DWORD - 1));
+
+ for ( row = 0 ; row < convert->height ; row++ ) {
+#ifdef CONVERT_DIRECT
+ MEMCPY( dst, src, DST_ROW_STRIDE );
+ src += srcRowStride;
+ dst = (GLuint *)((GLubyte *)dst + DST_ROW_STRIDE);
+#else
+ const GLubyte *srcRow = src;
+ for ( col = width / DST_TEXELS_PER_DWORD ; col ; col-- ) {
+ *dst++ = CONVERT_TEXEL_DWORD( src );
+ src += SRC_TEXEL_BYTES * DST_TEXELS_PER_DWORD;
+ }
+ src = srcRow + srcRowStride;
+#endif
+ }
+
+ return GL_TRUE;
+}
+
+/* PRE: as above, height == imageHeight also.
+ */
+static GLboolean
+TAG(texsubimage3d_pack)( struct gl_texture_convert *convert )
+{
+ const GLubyte *src = (const GLubyte *)
+ _mesa_image_address( convert->packing, convert->srcImage,
+ convert->width, convert->height,
+ convert->format, convert->type, 0, 0, 0 );
+ const GLint srcRowStride =
+ _mesa_image_row_stride( convert->packing, convert->width,
+ convert->format, convert->type );
+ GLuint *dst = (GLuint *)((GLubyte *)convert->dstImage +
+ ((convert->zoffset * convert->height +
+ convert->yoffset) * convert->width +
+ convert->xoffset) * DST_TEXEL_BYTES);
+ GLint width;
+ GLint row, col, img;
+ (void) col;
+
+ if ( DBG )
+ fprintf( stderr, __FUNCTION__ "\n" );
+
+ width = ((convert->width + DST_TEXELS_PER_DWORD - 1)
+ & ~(DST_TEXELS_PER_DWORD - 1));
+
+ for ( img = 0 ; img < convert->depth ; img++ ) {
+ for ( row = 0 ; row < convert->height ; row++ ) {
+#ifdef CONVERT_DIRECT
+ MEMCPY( dst, src, DST_ROW_STRIDE );
+ src += srcRowStride;
+ dst = (GLuint *)((GLubyte *)dst + DST_ROW_STRIDE);
+#else
+ const GLubyte *srcRow = src;
+ for ( col = width / DST_TEXELS_PER_DWORD ; col ; col-- ) {
+ *dst++ = CONVERT_TEXEL_DWORD( src );
+ src += SRC_TEXEL_BYTES * DST_TEXELS_PER_DWORD;
+ }
+ src = srcRow + srcRowStride;
+#endif
+ }
+ }
+
+ return GL_TRUE;
+}
+
+
+
+/* ================================================================
+ * PRE: Require pixelstore attribs, width != imageWidth.
+ */
+static GLboolean
+TAG(texsubimage2d_stride_pack)( struct gl_texture_convert *convert )
+{
+ const GLubyte *src = (const GLubyte *)
+ _mesa_image_address( convert->packing, convert->srcImage,
+ convert->width, convert->height,
+ convert->format, convert->type, 0, 0, 0 );
+ const GLint srcRowStride =
+ _mesa_image_row_stride( convert->packing, convert->width,
+ convert->format, convert->type );
+ DST_TYPE *dst = (DST_TYPE *)((GLubyte *)convert->dstImage +
+ (convert->yoffset * convert->imageWidth +
+ convert->xoffset) * DST_TEXEL_BYTES);
+ GLint adjust;
+ GLint row, col;
+ (void) col;
+
+ adjust = convert->imageWidth - convert->width;
+
+ if ( DBG ) {
+ fprintf( stderr, __FUNCTION__ ":\n" );
+ fprintf( stderr, " x=%d y=%d w=%d h=%d s=%d\n",
+ convert->xoffset, convert->yoffset, convert->width,
+ convert->height, convert->imageWidth );
+ fprintf( stderr, " adjust=%d\n", adjust );
+ }
+
+ for ( row = 0 ; row < convert->height ; row++ ) {
+#ifdef CONVERT_DIRECT
+ MEMCPY( dst, src, DST_ROW_WIDTH );
+ src += srcRowStride;
+ dst += convert->imageWidth;
+#else
+ const GLubyte *srcRow = src;
+ for ( col = 0 ; col < convert->width ; col++ ) {
+ *dst++ = CONVERT_TEXEL( src );
+ src += SRC_TEXEL_BYTES;
+ }
+ src = srcRow + srcRowStride;
+ dst += adjust;
+#endif
+ }
+
+ return GL_TRUE;
+}
+
+/* PRE: As above, or height != imageHeight also.
+ */
+static GLboolean
+TAG(texsubimage3d_stride_pack)( struct gl_texture_convert *convert )
+{
+ const GLubyte *src = (const GLubyte *)
+ _mesa_image_address( convert->packing, convert->srcImage,
+ convert->width, convert->height,
+ convert->format, convert->type, 0, 0, 0 );
+ const GLint srcRowStride =
+ _mesa_image_row_stride( convert->packing, convert->width,
+ convert->format, convert->type );
+ DST_TYPE *dst = (DST_TYPE *)((GLubyte *)convert->dstImage +
+ ((convert->zoffset * convert->imageHeight +
+ convert->yoffset) * convert->imageWidth +
+ convert->xoffset) * DST_TEXEL_BYTES);
+ GLint adjust;
+ GLint row, col, img;
+ (void) col;
+
+ adjust = convert->imageWidth - convert->width;
+
+ if ( DBG ) {
+ fprintf( stderr, __FUNCTION__ ":\n" );
+ fprintf( stderr, " x=%d y=%d w=%d h=%d s=%d\n",
+ convert->xoffset, convert->yoffset, convert->width,
+ convert->height, convert->imageWidth );
+ fprintf( stderr, " adjust=%d\n", adjust );
+ }
+
+ for ( img = 0 ; img < convert->depth ; img++ ) {
+ for ( row = 0 ; row < convert->height ; row++ ) {
+#ifdef CONVERT_DIRECT
+ MEMCPY( dst, src, DST_ROW_WIDTH );
+ src += srcRowStride;
+ dst += convert->imageWidth;
+#else
+ const GLubyte *srcRow = src;
+ for ( col = 0 ; col < convert->width ; col++ ) {
+ *dst++ = CONVERT_TEXEL( src );
+ src += SRC_TEXEL_BYTES;
+ }
+ src = srcRow + srcRowStride;
+ dst += adjust;
+#endif
+ }
+ /* FIXME: ... */
+ }
+
+ return GL_TRUE;
+}
+
+
+
+static convert_func TAG(texsubimage2d_tab)[] = {
+ TAG(texsubimage2d),
+ TAG(texsubimage2d_stride),
+ TAG(texsubimage2d_pack),
+ TAG(texsubimage2d_stride_pack),
+};
+
+static convert_func TAG(texsubimage3d_tab)[] = {
+ TAG(texsubimage3d),
+ TAG(texsubimage3d_stride),
+ TAG(texsubimage3d_pack),
+ TAG(texsubimage3d_stride_pack),
+};
+
+
+#ifndef PRESERVE_DST_TYPE
+#undef DST_TYPE
+#undef DST_TEXELS_PER_DWORD
+#endif
+
+#undef SRC_TEXEL_BYTES
+#undef DST_TEXEL_BYTES
+#undef DST_ROW_WIDTH
+#undef DST_ROW_STRIDE
+
+#undef CONVERT_TEXEL
+#undef CONVERT_TEXEL_DWORD
+#undef CONVERT_DIRECT
+
+#undef TAG
+
+#undef PRESERVE_DST_TYPE
diff --git a/xc/extras/Mesa/src/tritemp.h b/xc/extras/Mesa/src/tritemp.h
index 03a38852c..71e62a31a 100644
--- a/xc/extras/Mesa/src/tritemp.h
+++ b/xc/extras/Mesa/src/tritemp.h
@@ -1,21 +1,20 @@
-/* $Id: tritemp.h,v 1.15 2001/02/12 20:42:42 brianp Exp $ */
/*
* Mesa 3-D graphics library
* Version: 3.4.1
- *
+ *
* Copyright (C) 1999-2001 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
@@ -57,7 +56,7 @@
*
* Optionally, one may provide one-time setup code per triangle:
* SETUP_CODE - code which is to be executed once per triangle
- *
+ *
* The following macro MUST be defined:
* INNER_LOOP(LEFT,RIGHT,Y) - code to write a span of pixels.
* Something like:
@@ -227,7 +226,7 @@
* By stepping rasterization parameters along the major edge,
* we can avoid recomputing them at the discontinuity where
* the top and bottom edges meet. However, this forces us to
- * be able to scan both left-to-right and right-to-left.
+ * be able to scan both left-to-right and right-to-left.
* Also, we must determine whether the major edge is at the
* left or right side of the triangle. We do this by
* computing the magnitude of the cross-product of the major
@@ -445,7 +444,7 @@
dtdy = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx);
} else {
dtdx = 0;
- dtdy = 0;
+ dtdy = 0;
}
if (VB->TexCoordPtr[0]->size > 2)
@@ -553,7 +552,7 @@
* inside the triangle.
*
* Next we creep down the major edge until we reach that y,
- * and compute the corresponding x coordinate on the edge.
+ * and compute the corresponding x coordinate on the edge.
* Then we find the half-integral x that lies on or just
* inside the edge. This is the first pixel that might lie in
* the interior of the triangle. (We won't know for sure
@@ -784,7 +783,7 @@
t0 = VB->TexCoordPtr[0]->data[vLower][1] * T_SCALE;
ft = (GLfixed)(t0 * FIXED_SCALE + dtdx * adjx + dtdy * adjy) + FIXED_HALF;
fdtOuter = SignedFloatToFixed(dtdy + dxOuter * dtdx);
- }
+ }
else
{
t0 = 0;
@@ -801,7 +800,7 @@
sLeft = s0 + (dsdx * adjx + dsdy * adjy) * (1.0F/FIXED_SCALE);
dsOuter = dsdy + dxOuter * dsdx;
if (VB->TexCoordPtr[0]->size > 1)
- {
+ {
t0 = VB->TexCoordPtr[0]->data[vLower][1] * invW;
tLeft = t0 + (dtdx * adjx + dtdy * adjy) * (1.0F/FIXED_SCALE);
dtOuter = dtdy + dxOuter * dtdx;
@@ -809,7 +808,7 @@
tLeft = dtOuter = 0;
}
if (VB->TexCoordPtr[0]->size > 2)
- {
+ {
u0 = VB->TexCoordPtr[0]->data[vLower][2] * invW;
uLeft = u0 + (dudx * adjx + dudy * adjy) * (1.0F/FIXED_SCALE);
duOuter = dudy + dxOuter * dudx;
@@ -817,7 +816,7 @@
uLeft = duOuter = 0;
}
if (VB->TexCoordPtr[0]->size > 3)
- {
+ {
v0 = VB->TexCoordPtr[0]->data[vLower][3] * invW;
} else {
v0 = invW;
@@ -834,7 +833,7 @@
s1Left = s0 + (ds1dx * adjx + ds1dy * adjy) * (1.0F/FIXED_SCALE);
ds1Outer = ds1dy + dxOuter * ds1dx;
if (VB->TexCoordPtr[0]->size > 1)
- {
+ {
t0 = VB->TexCoordPtr[1]->data[vLower][1] * invW;
t1Left = t0 + (dt1dx * adjx + dt1dy * adjy) * (1.0F/FIXED_SCALE);
dt1Outer = dt1dy + dxOuter * dt1dx;
@@ -842,7 +841,7 @@
t1Left = dt1Outer = 0;
}
if (VB->TexCoordPtr[0]->size > 2)
- {
+ {
u0 = VB->TexCoordPtr[1]->data[vLower][2] * invW;
u1Left = u0 + (du1dx * adjx + du1dy * adjy) * (1.0F/FIXED_SCALE);
du1Outer = du1dy + dxOuter * du1dx;
@@ -850,7 +849,7 @@
u1Left = du1Outer = 0;
}
if (VB->TexCoordPtr[0]->size > 3)
- {
+ {
v0 = VB->TexCoordPtr[1]->data[vLower][3] * invW;
} else {
v0 = invW;
diff --git a/xc/extras/Mesa/src/types.h b/xc/extras/Mesa/src/types.h
index 804de925e..5c297eb2a 100644
--- a/xc/extras/Mesa/src/types.h
+++ b/xc/extras/Mesa/src/types.h
@@ -1,4 +1,4 @@
-/* -*- mode: C; tab-width:8; c-basic-offset:8 -*- */
+/* -*- mode: C; tab-width:8; c-basic-offset:3 -*- */
/*
* Mesa 3-D graphics library
@@ -171,7 +171,21 @@ typedef void (*TextureSampleFunc)( const struct gl_texture_object *tObj,
const GLfloat u[], const GLfloat lambda[],
GLubyte rgba[][4] );
+/* Texture format record */
+/* GH: This is an interim structure until 3.5 */
+struct gl_texture_format {
+ GLint IntFormat; /* One of the MESA_FORMAT_* values */
+ GLubyte RedBits; /* Bits per texel component */
+ GLubyte GreenBits;
+ GLubyte BlueBits;
+ GLubyte AlphaBits;
+ GLubyte LuminanceBits;
+ GLubyte IntensityBits;
+ GLubyte IndexBits;
+
+ GLint TexelBytes;
+};
/* Texture image record */
struct gl_texture_image {
@@ -180,13 +194,6 @@ struct gl_texture_image {
* GL_COLOR_INDEX only
*/
GLenum IntFormat; /* Internal format as given by the user */
- GLubyte RedBits; /* Bits per texel component */
- GLubyte GreenBits; /* These are initialized by Mesa but */
- GLubyte BlueBits; /* may be reassigned by the device */
- GLubyte AlphaBits; /* driver to indicate the true texture */
- GLubyte IntensityBits; /* color resolution. */
- GLubyte LuminanceBits;
- GLubyte IndexBits;
GLuint Border; /* 0 or 1 */
GLuint Width; /* = 2^WidthLog2 + 2*Border */
GLuint Height; /* = 2^HeightLog2 + 2*Border */
@@ -200,6 +207,8 @@ struct gl_texture_image {
GLuint MaxLog2; /* = MAX(WidthLog2, HeightLog2) */
GLubyte *Data; /* Image data as unsigned bytes */
+ const struct gl_texture_format *TexFormat;
+
GLboolean IsCompressed; /* GL_ARB_texture_compression */
GLuint CompressedSize; /* GL_ARB_texture_compression */
diff --git a/xc/lib/GL/mesa/src/Imakefile b/xc/lib/GL/mesa/src/Imakefile
index cc88803f4..7ccc16fd7 100644
--- a/xc/lib/GL/mesa/src/Imakefile
+++ b/xc/lib/GL/mesa/src/Imakefile
@@ -152,6 +152,8 @@ LinkSourceFile(state.c, $(MESASRCDIR)/src)
LinkSourceFile(state.h, $(MESASRCDIR)/src)
LinkSourceFile(stencil.c, $(MESASRCDIR)/src)
LinkSourceFile(stencil.h, $(MESASRCDIR)/src)
+LinkSourceFile(texformat.c, $(MESASRCDIR)/src)
+LinkSourceFile(texformat.h, $(MESASRCDIR)/src)
LinkSourceFile(texgen_tmp.h, $(MESASRCDIR)/src)
LinkSourceFile(teximage.c, $(MESASRCDIR)/src)
LinkSourceFile(teximage.h, $(MESASRCDIR)/src)
@@ -163,6 +165,7 @@ LinkSourceFile(texture.c, $(MESASRCDIR)/src)
LinkSourceFile(texture.h, $(MESASRCDIR)/src)
LinkSourceFile(texutil.c, $(MESASRCDIR)/src)
LinkSourceFile(texutil.h, $(MESASRCDIR)/src)
+LinkSourceFile(texutil_tmp.h, $(MESASRCDIR)/src)
LinkSourceFile(trans_tmp.h, $(MESASRCDIR)/src)
LinkSourceFile(translate.c, $(MESASRCDIR)/src)
LinkSourceFile(translate.h, $(MESASRCDIR)/src)
@@ -252,6 +255,7 @@ LinkSourceFile(zoom.h, $(MESASRCDIR)/src)
stages.c \
state.c \
stencil.c \
+ texformat.c \
teximage.c \
texobj.c \
texstate.c \
@@ -325,6 +329,7 @@ LinkSourceFile(zoom.h, $(MESASRCDIR)/src)
stages.o \
state.o \
stencil.o \
+ texformat.o \
teximage.o \
texobj.o \
texstate.o \
@@ -346,8 +351,8 @@ LinkSourceFile(zoom.h, $(MESASRCDIR)/src)
zoom.o
#ifdef i386Architecture
- ASM_SRCS =
- ASM_OBJS =
+ ASM_SRCS =
+ ASM_OBJS =
#if MesaUseMMX
MMX_DEFS = -DUSE_MMX_ASM
#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810span.c b/xc/lib/GL/mesa/src/drv/i810/i810span.c
index ca9817b8a..4bf02ad13 100644
--- a/xc/lib/GL/mesa/src/drv/i810/i810span.c
+++ b/xc/lib/GL/mesa/src/drv/i810/i810span.c
@@ -30,7 +30,7 @@
dPriv->x * 2 + \
dPriv->y * pitch)
-#define INIT_MONO_PIXEL(p)
+#define INIT_MONO_PIXEL(p)
#define CLIPPIXEL(_x,_y) (_x >= minx && _x < maxx && \
_y >= miny && _y < maxy)
@@ -130,7 +130,7 @@ do { \
*(GLushort *)(buf + _x*2 + _y*pitch) = d;
#define READ_DEPTH( d, _x, _y ) \
- d = *(GLushort *)(buf + _x*2 + _y*pitch);
+ d = *(GLushort *)(buf + _x*2 + _y*pitch);
/* d = 0xffff; */
@@ -146,7 +146,7 @@ void i810DDInitSpanFuncs( GLcontext *ctx )
ctx->Driver.WriteRGBSpan = i810WriteRGBSpan_565;
ctx->Driver.WriteMonoRGBASpan = i810WriteMonoRGBASpan_565;
ctx->Driver.WriteRGBAPixels = i810WriteRGBAPixels_565;
- ctx->Driver.WriteMonoRGBAPixels = i810WriteMonoRGBAPixels_565;
+ ctx->Driver.WriteMonoRGBAPixels = i810WriteMonoRGBAPixels_565;
ctx->Driver.ReadRGBASpan = i810ReadRGBASpan_565;
ctx->Driver.ReadRGBAPixels = i810ReadRGBAPixels_565;
} else {
diff --git a/xc/lib/GL/mesa/src/drv/mga/Imakefile b/xc/lib/GL/mesa/src/drv/mga/Imakefile
index 2630d8159..e4c73ddc0 100644
--- a/xc/lib/GL/mesa/src/drv/mga/Imakefile
+++ b/xc/lib/GL/mesa/src/drv/mga/Imakefile
@@ -151,6 +151,7 @@ MESA_INCLUDES = -I. -I.. -I../../include \
../../stages.c \
../../state.c \
../../stencil.c \
+ ../../texformat.c \
../../teximage.c \
../../texobj.c \
../../texstate.c \
@@ -224,6 +225,7 @@ MESA_INCLUDES = -I. -I.. -I../../include \
../../stages.o \
../../state.o \
../../stencil.o \
+ ../../texformat.o \
../../teximage.o \
../../texobj.o \
../../texstate.o \
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgapixel.c b/xc/lib/GL/mesa/src/drv/mga/mgapixel.c
index d970e49b4..72903c209 100644
--- a/xc/lib/GL/mesa/src/drv/mga/mgapixel.c
+++ b/xc/lib/GL/mesa/src/drv/mga/mgapixel.c
@@ -545,9 +545,9 @@ mgaDDDrawPixels( GLcontext *ctx,
* negligble speedup when the buffers/images don't exactly
* match:
*/
-#if 1
+#if 0
if (cpp == 2) {
- if (!_mesa_convert_teximage( MESA_R5_G6_B5,
+ if (!_mesa_convert_teximage( MESA_FORMAT_RGB565,
width, rows,
address, bufferpitch,
width, rows,
@@ -558,7 +558,7 @@ mgaDDDrawPixels( GLcontext *ctx,
return GL_FALSE;
}
} else {
- if (!_mesa_convert_teximage( MESA_A8_R8_G8_B8,
+ if (!_mesa_convert_teximage( MESA_FORMAT_ARGB8888,
width, rows,
address, bufferpitch,
width, rows,
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatex.c b/xc/lib/GL/mesa/src/drv/mga/mgatex.c
index 35549af27..0986b04be 100644
--- a/xc/lib/GL/mesa/src/drv/mga/mgatex.c
+++ b/xc/lib/GL/mesa/src/drv/mga/mgatex.c
@@ -41,6 +41,7 @@
#include "enums.h"
#include "simple_list.h"
#include "mem.h"
+#include "texutil.h"
#define TEX_0 1
#define TEX_1 2
@@ -145,6 +146,169 @@ static void mgaSetTexBorderColor(mgaTextureObjectPtr t, GLubyte color[4])
}
+static GLint mgaChooseTexFormat( mgaContextPtr mmesa,
+ struct gl_texture_image *texImage,
+ GLenum format, GLenum type )
+{
+ const GLboolean do32bpt = mmesa->default32BitTextures;
+ const struct gl_texture_format *texFormat;
+ GLint ret;
+
+ if ( 0 )
+ fprintf( stderr, "internal=%s format=%s type=%s\n",
+ texImage->IntFormat == 3 ? "GL_RGB (3)" :
+ texImage->IntFormat == 4 ? "GL_RGBA (4)" :
+ gl_lookup_enum_by_nr( texImage->IntFormat ),
+ gl_lookup_enum_by_nr( format ),
+ gl_lookup_enum_by_nr( type ) );
+
+#define SET_FORMAT( r, gl ) \
+ do { \
+ ret = (r); \
+ texFormat = &(gl); \
+ } while (0)
+
+#define SET_FORMAT_32BPT( r32, gl32, r16, gl16 ) \
+ do { \
+ if ( do32bpt ) { \
+ ret = (r32); \
+ texFormat = &(gl32); \
+ } else { \
+ ret = (r16); \
+ texFormat = &(gl16); \
+ } \
+ } while (0)
+
+ switch ( texImage->IntFormat ) {
+ /* GH: Bias towards GL_RGB, GL_RGBA texture formats. This has
+ * got to be better than sticking them way down the end of this
+ * huge list.
+ */
+ case GL_RGBA:
+ case 4:
+ if ( format == GL_BGRA ) {
+ if ( type == GL_UNSIGNED_INT_8_8_8_8_REV ) {
+ SET_FORMAT( TMC_tformat_tw32, _mesa_texformat_argb8888 );
+ break;
+ } else if ( type == GL_UNSIGNED_SHORT_4_4_4_4_REV ) {
+ SET_FORMAT( TMC_tformat_tw12, _mesa_texformat_argb4444 );
+ break;
+ } else if ( type == GL_UNSIGNED_SHORT_1_5_5_5_REV ) {
+ SET_FORMAT( TMC_tformat_tw15, _mesa_texformat_argb1555 );
+ break;
+ }
+ }
+ SET_FORMAT_32BPT( TMC_tformat_tw32, _mesa_texformat_argb8888,
+ TMC_tformat_tw12, _mesa_texformat_argb4444 );
+ break;
+
+ case GL_RGB:
+ case 3:
+ if ( format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5 ) {
+ SET_FORMAT( TMC_tformat_tw16, _mesa_texformat_rgb565 );
+ break;
+ }
+ SET_FORMAT_32BPT( TMC_tformat_tw32, _mesa_texformat_argb8888,
+ TMC_tformat_tw16, _mesa_texformat_rgb565 );
+ break;
+
+ /* GH: Okay, keep checking as normal. Still test for GL_RGB,
+ * GL_RGBA formats first.
+ */
+ case GL_RGBA8:
+ case GL_RGB10_A2:
+ case GL_RGBA12:
+ case GL_RGBA16:
+ SET_FORMAT_32BPT( TMC_tformat_tw32, _mesa_texformat_argb8888,
+ TMC_tformat_tw12, _mesa_texformat_argb4444 );
+ break;
+
+ case GL_RGBA4:
+ case GL_RGBA2:
+ SET_FORMAT( TMC_tformat_tw12, _mesa_texformat_argb4444 );
+ break;
+
+ case GL_RGB5_A1:
+ SET_FORMAT( TMC_tformat_tw15, _mesa_texformat_argb1555 );
+ break;
+
+ case GL_RGB8:
+ case GL_RGB10:
+ case GL_RGB12:
+ case GL_RGB16:
+ SET_FORMAT_32BPT( TMC_tformat_tw32, _mesa_texformat_argb8888,
+ TMC_tformat_tw16, _mesa_texformat_rgb565 );
+ break;
+
+ case GL_RGB5:
+ case GL_RGB4:
+ case GL_R3_G3_B2:
+ SET_FORMAT( TMC_tformat_tw16, _mesa_texformat_rgb565 );
+ break;
+
+ case GL_ALPHA:
+ case GL_ALPHA4:
+ case GL_ALPHA8:
+ case GL_ALPHA12:
+ case GL_ALPHA16:
+ /* FIXME: This breaks the G200... */
+ SET_FORMAT( TMC_tformat_tw8a, _mesa_texformat_a8 );
+ break;
+
+ case 1:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE4:
+ case GL_LUMINANCE8:
+ case GL_LUMINANCE12:
+ case GL_LUMINANCE16:
+ /* FIXME: This breaks the G200... */
+ SET_FORMAT( TMC_tformat_tw8al, _mesa_texformat_al88 );
+ break;
+
+ case 2:
+ case GL_LUMINANCE_ALPHA:
+ case GL_LUMINANCE4_ALPHA4:
+ case GL_LUMINANCE6_ALPHA2:
+ case GL_LUMINANCE8_ALPHA8:
+ case GL_LUMINANCE12_ALPHA4:
+ case GL_LUMINANCE12_ALPHA12:
+ case GL_LUMINANCE16_ALPHA16:
+ /* FIXME: This breaks the G200... */
+ SET_FORMAT( TMC_tformat_tw8al, _mesa_texformat_al88 );
+ break;
+
+ case GL_INTENSITY:
+ case GL_INTENSITY4:
+ case GL_INTENSITY8:
+ case GL_INTENSITY12:
+ case GL_INTENSITY16:
+ /* FIXME: This breaks the G200... */
+ SET_FORMAT( TMC_tformat_tw8al, _mesa_texformat_al88 );
+ break;
+
+ case GL_COLOR_INDEX:
+ case GL_COLOR_INDEX1_EXT:
+ case GL_COLOR_INDEX2_EXT:
+ case GL_COLOR_INDEX4_EXT:
+ case GL_COLOR_INDEX8_EXT:
+ case GL_COLOR_INDEX12_EXT:
+ case GL_COLOR_INDEX16_EXT:
+ SET_FORMAT( TMC_tformat_tw8, _mesa_texformat_ci8 );
+ break;
+
+ default:
+ fprintf( stderr, "bad texture format in mgaChooseTexFormat() %d",
+ texImage->IntFormat );
+ return -1;
+ }
+
+ texImage->TexFormat = texFormat;
+
+ return ret;
+}
+
+
+#if 0
/*
* Input:
* baseFormat - base texture format
@@ -270,6 +434,7 @@ static void mgaChooseTexelFormat(GLenum baseFormat, GLenum intFormat,
return;
}
}
+#endif
/*
@@ -282,14 +447,12 @@ static void mgaCreateTexObj(mgaContextPtr mmesa,
struct gl_texture_object *tObj)
{
const GLint baseLevel = tObj->BaseLevel;
- const struct gl_texture_image *image = tObj->Image[baseLevel];
+ struct gl_texture_image *image = tObj->Image[baseLevel];
mgaTextureObjectPtr t;
int i, ofs;
int LastLevel;
int s, s2;
- int textureFormat;
- GLubyte redBits, greenBits, blueBits, alphaBits;
- GLubyte intensityBits, luminanceBits, indexBits;
+ int tformat;
if (!image) return;
@@ -299,11 +462,10 @@ static void mgaCreateTexObj(mgaContextPtr mmesa,
return;
}
- mgaChooseTexelFormat(image->Format, image->IntFormat,
- mmesa->default32BitTextures,
- &t->texelBytes, &textureFormat,
- &redBits, &greenBits, &blueBits, &alphaBits,
- &luminanceBits, &intensityBits, &indexBits);
+ /* FIXME: Use the real DD interface...
+ */
+ tformat = mgaChooseTexFormat( mmesa, image, image->Format,
+ GL_UNSIGNED_BYTE );
/* We are going to upload all levels that are present, even if
* later levels wouldn't be used by the current filtering mode. This
@@ -333,14 +495,13 @@ static void mgaCreateTexObj(mgaContextPtr mmesa,
t->age = 0;
t->bound = 0;
t->MemBlock = 0;
+ t->texelBytes = image->TexFormat->TexelBytes;
insert_at_tail(&(mmesa->SwappedOut), t);
/* setup hardware register values */
- t->setup.texctl = (TMC_takey_1 |
- TMC_tamask_0 |
- textureFormat );
+ t->setup.texctl = TMC_takey_1 | TMC_tamask_0 | tformat;
if (image->WidthLog2 >= 3)
t->setup.texctl |= ((image->WidthLog2 - 3) << TMC_tpitch_SHIFT);
@@ -767,7 +928,7 @@ static void mgaDDTexImage( GLcontext *ctx, GLenum target,
{
mgaContextPtr mmesa = MGA_CONTEXT( ctx );
mgaTextureObjectPtr t;
- int texelBytes, mgaFormat;
+ GLint tformat;
/* hack: cast-away const */
struct gl_texture_image *img = (struct gl_texture_image *) image;
@@ -781,11 +942,8 @@ static void mgaDDTexImage( GLcontext *ctx, GLenum target,
mmesa->new_state |= MGA_NEW_TEXTURE;
}
- mgaChooseTexelFormat(image->Format, image->IntFormat, GL_FALSE,
- &texelBytes, &mgaFormat,
- &img->RedBits, &img->GreenBits, &img->BlueBits,
- &img->AlphaBits, &img->LuminanceBits,
- &img->IntensityBits, &img->IndexBits);
+ tformat = mgaChooseTexFormat( mmesa, img, img->Format,
+ GL_UNSIGNED_BYTE );
if (0)
fprintf(stderr, "mgaDDTexImage tObj %p, level %d, image %p\n",
diff --git a/xc/lib/GL/mesa/src/drv/radeon/Imakefile b/xc/lib/GL/mesa/src/drv/radeon/Imakefile
index d862565d0..2dc0b3083 100644
--- a/xc/lib/GL/mesa/src/drv/radeon/Imakefile
+++ b/xc/lib/GL/mesa/src/drv/radeon/Imakefile
@@ -59,6 +59,8 @@ MESA_INCLUDES = -I. -I.. -I../../include \
radeon_span.c \
radeon_state.c \
radeon_tex.c \
+ radeon_texmem.c \
+ radeon_texstate.c \
radeon_tris.c \
radeon_vb.c \
radeon_xmesa.c
@@ -74,6 +76,8 @@ MESA_INCLUDES = -I. -I.. -I../../include \
radeon_span.o \
radeon_state.o \
radeon_tex.o \
+ radeon_texmem.o \
+ radeon_texstate.o \
radeon_tris.o \
radeon_vb.o \
radeon_xmesa.o
@@ -152,6 +156,7 @@ MESA_INCLUDES = -I. -I.. -I../../include \
../../stages.c \
../../state.c \
../../stencil.c \
+ ../../texformat.c \
../../teximage.c \
../../texobj.c \
../../texstate.c \
@@ -225,6 +230,7 @@ MESA_INCLUDES = -I. -I.. -I../../include \
../../stages.o \
../../state.o \
../../stencil.o \
+ ../../texformat.o \
../../teximage.o \
../../texobj.o \
../../texstate.o \
diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_context.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_context.c
index 2ead8e213..366f094ca 100644
--- a/xc/lib/GL/mesa/src/drv/radeon/radeon_context.c
+++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_context.c
@@ -133,16 +133,8 @@ GLboolean radeonCreateContext( Display *dpy, GLvisual *glVisual,
ctx->Const.MaxTextureSize = (1 << 10);
}
- /* FIXME: Support all available texture units... */
ctx->Const.MaxTextureUnits = 2;
-#if ENABLE_PERF_BOXES
- if (getenv("LIBGL_PERFORMANCE_BOXES"))
- rmesa->boxes = 1;
- else
- rmesa->boxes = 0;
-#endif
-
ctx->DriverCtx = (void *)rmesa;
radeonDDInitExtensions( ctx );
diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_dd.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_dd.c
index b86506a8d..4ef0ebd30 100644
--- a/xc/lib/GL/mesa/src/drv/radeon/radeon_dd.c
+++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_dd.c
@@ -46,7 +46,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "X86/common_x86_asm.h"
#endif
-#define RADEON_DATE "20010105"
+#define RADEON_DATE "20010305"
/* Return the width and height of the current color buffer.
@@ -100,6 +100,11 @@ static const GLubyte *radeonDDGetString( GLcontext *ctx, GLenum name )
strncat( buffer, " x86", 4 );
}
#endif
+#ifdef USE_MMX_ASM
+ if ( cpu_has_mmx ) {
+ strncat( buffer, "/MMX", 4 );
+ }
+#endif
#ifdef USE_3DNOW_ASM
if ( cpu_has_3dnow ) {
strncat( buffer, "/3DNow!", 7 );
diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c
index a02794e49..c2cd6a203 100644
--- a/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c
+++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c
@@ -321,6 +321,7 @@ void radeonFireBlitLocked( radeonContextPtr rmesa, drmBufPtr buffer,
GLint offset, GLint pitch, GLint format,
GLint x, GLint y, GLint width, GLint height )
{
+#if 0
GLint ret;
ret = drmRadeonTextureBlit( rmesa->driFd, buffer->idx,
@@ -332,6 +333,7 @@ void radeonFireBlitLocked( radeonContextPtr rmesa, drmBufPtr buffer,
fprintf( stderr, "drmRadeonTextureBlit: return = %d\n", ret );
exit( 1 );
}
+#endif
}
@@ -616,12 +618,6 @@ static GLbitfield radeonDDClear( GLcontext *ctx, GLbitfield mask,
}
#endif
-#if 0
- if ( rmesa->dirty & ~RADEON_UPLOAD_CLIPRECTS ) {
- radeonEmitHwStateLocked( rmesa );
- }
-#endif
-
for ( i = 0 ; i < rmesa->numClipRects ; ) {
GLint nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS, rmesa->numClipRects );
XF86DRIClipRectPtr box = rmesa->pClipRects;
diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_state.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_state.c
index 27cf00c0b..d80004dd6 100644
--- a/xc/lib/GL/mesa/src/drv/radeon/radeon_state.c
+++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_state.c
@@ -936,29 +936,29 @@ void radeonEmitHwStateLocked( radeonContextPtr rmesa )
if ( (rmesa->dirty & RADEON_UPLOAD_TEX0) && t0 ) {
radeon_texture_regs_t *tex = &sarea->TexState[0];
- tex->pp_txfilter = t0->setup.pp_txfilter | rmesa->lod_bias[0] << 8;
- tex->pp_txformat = t0->setup.pp_txformat | RADEON_TXF_ST_ROUTE_STQ0;
- tex->pp_txoffset = t0->setup.pp_txoffset;
+ tex->pp_txfilter = t0->pp_txfilter | rmesa->lod_bias[0] << 8;
+ tex->pp_txformat = t0->pp_txformat | RADEON_TXFORMAT_ST_ROUTE_STQ0;
+ tex->pp_txoffset = t0->pp_txoffset;
tex->pp_txcblend = rmesa->color_combine[0];
tex->pp_txablend = rmesa->alpha_combine[0];
tex->pp_tfactor = rmesa->env_color[0];
- tex->pp_border_color = t0->setup.pp_border_color;
+ tex->pp_border_color = t0->pp_border_color;
}
if ( (rmesa->dirty & RADEON_UPLOAD_TEX1) && t1 ) {
radeon_texture_regs_t *tex = &sarea->TexState[1];
- tex->pp_txfilter = t1->setup.pp_txfilter | rmesa->lod_bias[1] << 8;
- tex->pp_txformat = t1->setup.pp_txformat | RADEON_TXF_ST_ROUTE_STQ1;
- tex->pp_txoffset = t1->setup.pp_txoffset;
+ tex->pp_txfilter = t1->pp_txfilter | rmesa->lod_bias[1] << 8;
+ tex->pp_txformat = t1->pp_txformat | RADEON_TXFORMAT_ST_ROUTE_STQ1;
+ tex->pp_txoffset = t1->pp_txoffset;
tex->pp_txcblend = rmesa->color_combine[1];
tex->pp_txablend = rmesa->alpha_combine[1];
tex->pp_tfactor = rmesa->env_color[1];
- tex->pp_border_color = t1->setup.pp_border_color;
+ tex->pp_border_color = t1->pp_border_color;
}
if ( rmesa->dirty & RADEON_UPLOAD_TEX2 ) {
diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.c
index dd9c4557b..6659f7abe 100644
--- a/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.c
+++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.c
@@ -44,1963 +44,680 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "simple_list.h"
#include "enums.h"
#include "mem.h"
+#include "texutil.h"
static void radeonSetTexWrap( radeonTexObjPtr t, GLenum swrap, GLenum twrap )
{
- t->setup.pp_txfilter &= ~(RADEON_CLAMP_S_MASK | RADEON_CLAMP_T_MASK);
+ t->pp_txfilter &= ~(RADEON_CLAMP_S_MASK | RADEON_CLAMP_T_MASK);
switch ( swrap ) {
case GL_REPEAT:
- t->setup.pp_txfilter |= RADEON_CLAMP_S_WRAP;
+ t->pp_txfilter |= RADEON_CLAMP_S_WRAP;
break;
case GL_CLAMP:
- t->setup.pp_txfilter |= RADEON_CLAMP_S_CLAMP_LAST;
+ t->pp_txfilter |= RADEON_CLAMP_S_CLAMP_LAST;
break;
case GL_CLAMP_TO_EDGE:
- t->setup.pp_txfilter |= RADEON_CLAMP_S_CLAMP_LAST;
+ t->pp_txfilter |= RADEON_CLAMP_S_CLAMP_LAST;
break;
}
switch ( twrap ) {
case GL_REPEAT:
- t->setup.pp_txfilter |= RADEON_CLAMP_T_WRAP;
+ t->pp_txfilter |= RADEON_CLAMP_T_WRAP;
break;
case GL_CLAMP:
- t->setup.pp_txfilter |= RADEON_CLAMP_T_CLAMP_LAST;
+ t->pp_txfilter |= RADEON_CLAMP_T_CLAMP_LAST;
break;
case GL_CLAMP_TO_EDGE:
- t->setup.pp_txfilter |= RADEON_CLAMP_T_CLAMP_LAST;
+ t->pp_txfilter |= RADEON_CLAMP_T_CLAMP_LAST;
break;
}
}
static void radeonSetTexFilter( radeonTexObjPtr t, GLenum minf, GLenum magf )
{
- t->setup.pp_txfilter &= ~(RADEON_MIN_FILTER_MASK | RADEON_MAG_FILTER_MASK);
+ t->pp_txfilter &= ~(RADEON_MIN_FILTER_MASK | RADEON_MAG_FILTER_MASK);
switch ( minf ) {
case GL_NEAREST:
- t->setup.pp_txfilter |= RADEON_MIN_FILTER_NEAREST;
+ t->pp_txfilter |= RADEON_MIN_FILTER_NEAREST;
break;
case GL_LINEAR:
- t->setup.pp_txfilter |= RADEON_MIN_FILTER_LINEAR;
+ t->pp_txfilter |= RADEON_MIN_FILTER_LINEAR;
break;
case GL_NEAREST_MIPMAP_NEAREST:
- t->setup.pp_txfilter |= RADEON_MIN_FILTER_NEAREST_MIP_NEAREST;
+ t->pp_txfilter |= RADEON_MIN_FILTER_NEAREST_MIP_NEAREST;
break;
case GL_LINEAR_MIPMAP_NEAREST:
- t->setup.pp_txfilter |= RADEON_MIN_FILTER_LINEAR_MIP_NEAREST;
+ t->pp_txfilter |= RADEON_MIN_FILTER_LINEAR_MIP_NEAREST;
break;
case GL_NEAREST_MIPMAP_LINEAR:
- t->setup.pp_txfilter |= RADEON_MIN_FILTER_NEAREST_MIP_LINEAR;
+ t->pp_txfilter |= RADEON_MIN_FILTER_NEAREST_MIP_LINEAR;
break;
case GL_LINEAR_MIPMAP_LINEAR:
- t->setup.pp_txfilter |= RADEON_MIN_FILTER_LINEAR_MIP_LINEAR;
+ t->pp_txfilter |= RADEON_MIN_FILTER_LINEAR_MIP_LINEAR;
break;
}
switch ( magf ) {
case GL_NEAREST:
- t->setup.pp_txfilter |= RADEON_MAG_FILTER_NEAREST;
+ t->pp_txfilter |= RADEON_MAG_FILTER_NEAREST;
break;
case GL_LINEAR:
- t->setup.pp_txfilter |= RADEON_MAG_FILTER_LINEAR;
+ t->pp_txfilter |= RADEON_MAG_FILTER_LINEAR;
break;
}
}
static void radeonSetTexBorderColor( radeonTexObjPtr t, GLubyte c[4] )
{
- t->setup.pp_border_color = radeonPackColor( 4, c[0], c[1], c[2], c[3] );
+ t->pp_border_color = radeonPackColor( 4, c[0], c[1], c[2], c[3] );
}
-
-/* Allocate and initialize hardware state associated with texture `t'.
- */
-static radeonTexObjPtr radeonCreateTexObj( radeonContextPtr rmesa,
- struct gl_texture_object *tObj )
+static radeonTexObjPtr radeonAllocTexObj( struct gl_texture_object *tObj )
{
radeonTexObjPtr t;
- struct gl_texture_image *image;
- GLint log2Width, log2Height, log2Size, log2MinSize;
- GLint totalSize;
- GLint texelsPerDword = 0, blitWidth = 0, blitPitch = 0;
- GLint x, y, width, height;
- GLint i;
- GLuint txformat, txalpha;
-
- image = tObj->Image[0];
- if ( !image )
- return NULL;
-
- t = (radeonTexObjPtr) CALLOC( sizeof(*t) );
- if ( !t )
- return NULL;
-
- if ( RADEON_DEBUG & DEBUG_VERBOSE_API )
- fprintf( stderr, "%s( %p )\n", __FUNCTION__, tObj );
-
- switch ( image->Format ) {
- case GL_RGBA:
- if ( image->IntFormat != GL_RGBA4 &&
- ( image->IntFormat == GL_RGBA8 ||
- rmesa->radeonScreen->cpp == 4 ) ) {
- t->texelBytes = 4;
- txformat = RADEON_TXF_32BPP_ARGB8888;
- } else {
- t->texelBytes = 2;
- txformat = RADEON_TXF_16BPP_ARGB4444;
- }
- txalpha = RADEON_TXF_ALPHA_IN_MAP;
- break;
-
- case GL_RGB:
- if ( image->IntFormat != GL_RGB5 &&
- ( image->IntFormat == GL_RGB8 ||
- rmesa->radeonScreen->cpp == 4 ) ) {
- t->texelBytes = 4;
- txformat = RADEON_TXF_32BPP_ARGB8888;
- } else {
- t->texelBytes = 2;
- txformat = RADEON_TXF_16BPP_RGB565;
- }
- txalpha = 0;
- break;
-
- case GL_ALPHA:
- case GL_LUMINANCE_ALPHA:
- t->texelBytes = 2;
- txformat = RADEON_TXF_16BPP_AI88;
- txalpha = RADEON_TXF_ALPHA_IN_MAP;
- break;
-
- case GL_LUMINANCE:
- t->texelBytes = 2;
- txformat = RADEON_TXF_16BPP_AI88;
- txalpha = 0;
- break;
-
- case GL_INTENSITY:
- t->texelBytes = 1;
- txformat = RADEON_TXF_8BPP_I;
- txalpha = 0;
- break;
-
- case GL_COLOR_INDEX:
- default:
- fprintf( stderr, "%s: bad image->Format\n", __FUNCTION__ );
- FREE( t );
- return NULL;
- }
-
- /* Calculate dimensions in log domain.
- */
- for ( i = 1, log2Height = 0 ; i < image->Height ; i *= 2 ) {
- log2Height++;
- }
- for ( i = 1, log2Width = 0 ; i < image->Width ; i *= 2 ) {
- log2Width++;
- }
- if ( image->Width > image->Height ) {
- log2Size = log2Width;
- } else {
- log2Size = log2Height;
- }
-
- t->dirty_images = 0;
-
- /* The Radeon has a 64-byte minimum pitch for all blits. We
- * calculate the equivalent number of texels to simplify the
- * calculation of the texture image area.
- */
- switch ( t->texelBytes ) {
- case 1:
- texelsPerDword = 4;
- blitPitch = 64;
- break;
- case 2:
- texelsPerDword = 2;
- blitPitch = 32;
- break;
- case 4:
- texelsPerDword = 1;
- blitPitch = 16;
- break;
- }
-
- /* Select the larger of the two widths for our global texture image
- * coordinate space. As the Radeon has very strict offset rules, we
- * can't upload mipmaps directly and have to reference their location
- * from the aligned start of the whole image.
- */
- blitWidth = MAX2( image->Width, blitPitch );
-
- /* Calculate mipmap offsets and dimensions.
- */
- totalSize = 0;
- x = 0;
- y = 0;
-
- for ( i = 0 ; i <= log2Size ; i++ ) {
- GLuint size;
- image = tObj->Image[i];
- if ( !image )
- break;
-
- width = image->Width;
- height = image->Height;
-
- /* Texture images have a minimum pitch of 32 bytes (half of the
- * 64-byte minimum pitch for blits). For images that have a
- * width smaller than this, we must pad each texture image
- * scanline out to this amount.
- */
- if ( width < blitPitch / 2 ) {
- width = blitPitch / 2;
- }
-
- size = width * height * t->texelBytes;
- totalSize += size;
-
- t->dirty_images |= (1 << i);
-
- while ( width < blitWidth && height > 1 ) {
- width *= 2;
- height /= 2;
- }
-
- t->image[i].x = x;
- t->image[i].y = y;
-
- t->image[i].width = width;
- t->image[i].height = height;
-
- t->image[i].dwords = size / sizeof(CARD32);
-
- /* While blits must have a pitch of at least 64 bytes, mipmaps
- * must be aligned on a 32-byte boundary (just like each texture
- * image scanline).
- */
- if ( width >= blitWidth ) {
- y += height;
- } else {
- x += width;
- if ( x >= blitWidth ) {
- x = 0;
- y++;
- }
- }
+ t = CALLOC_STRUCT( radeon_tex_obj );
- if ( 0 )
- fprintf( stderr, "level=%d p=%d %dx%d -> %dx%d at (%d,%d) %d dwords\n",
- i, blitWidth, image->Width, image->Height,
- t->image[i].width, t->image[i].height,
- t->image[i].x, t->image[i].y,
- t->image[i].dwords );
+ if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) {
+ fprintf( stderr, "%s( %p )\n", __FUNCTION__, t );
}
- log2MinSize = log2Size - i + 1;
-
- /* Align the total size of texture memory block.
+ /* Initialize non-image-dependent parts of the state:
*/
- totalSize = (totalSize + RADEON_OFFSET_MASK) & ~RADEON_OFFSET_MASK;
-
- t->totalSize = totalSize;
-
- t->bound = 0;
- t->heap = 0;
t->tObj = tObj;
+ t->dirty_images = ~0;
+ t->pp_txfilter = RADEON_BORDER_MODE_OGL;
+ t->pp_txformat = (RADEON_TXFORMAT_ENDIAN_NO_SWAP |
+ RADEON_TXFORMAT_PERSPECTIVE_ENABLE);
- t->memBlock = NULL;
- t->bufAddr = 0;
-
- /* Hardware state:
- */
- t->setup.pp_txfilter = ((log2Size << RADEON_MAX_MIP_LEVEL_SHIFT) |
- RADEON_BORDER_MODE_OGL);
-
- t->setup.pp_txformat = (txformat | txalpha |
- (log2Width << RADEON_TXF_WIDTH_SHIFT) |
- (log2Height << RADEON_TXF_HEIGHT_SHIFT) |
- RADEON_TXF_ENDIAN_NO_SWAP |
- RADEON_TXF_PERSPECTIVE_ENABLE);
-
- t->setup.pp_txoffset = 0x00000000;
- t->setup.pp_txcblend = 0x00000000;
- t->setup.pp_txablend = 0x00000000;
- t->setup.pp_tfactor = 0x00000000;
- t->setup.pp_border_color = 0x00000000;
+ make_empty_list( t );
radeonSetTexWrap( t, tObj->WrapS, tObj->WrapT );
radeonSetTexFilter( t, tObj->MinFilter, tObj->MagFilter );
radeonSetTexBorderColor( t, tObj->BorderColor );
- tObj->DriverData = t;
-
- make_empty_list( t );
-
return t;
}
-/* Destroy hardware state associated with texture `t'.
- */
-void radeonDestroyTexObj( radeonContextPtr rmesa, radeonTexObjPtr t )
-{
-#if ENABLE_PERF_BOXES
- /* Bump the performace counter */
- rmesa->c_textureSwaps++;
-#endif
- if ( !t ) return;
-
- if ( t->memBlock ) {
- mmFreeMem( t->memBlock );
- t->memBlock = NULL;
- }
- if ( t->tObj )
- t->tObj->DriverData = NULL;
- if ( t->bound )
- rmesa->CurrentTexObj[t->bound-1] = NULL;
-
- remove_from_list( t );
- FREE( t );
-}
-
-/* Keep track of swapped out texture objects.
- */
-static void radeonSwapOutTexObj( radeonContextPtr rmesa, radeonTexObjPtr t )
+static GLint radeonChooseTexFormat( radeonContextPtr rmesa,
+ struct gl_texture_image *texImage,
+ GLenum format, GLenum type )
{
-#if ENABLE_PERF_BOXES
- /* Bump the performace counter */
- rmesa->c_textureSwaps++;
-#endif
- if ( t->memBlock ) {
- mmFreeMem( t->memBlock );
- t->memBlock = NULL;
- }
+ const GLboolean do32bpt = ( rmesa->radeonScreen->cpp == 4 );
+ const struct gl_texture_format *texFormat;
+ GLint ret;
- t->dirty_images = ~0;
- move_to_tail( &rmesa->SwappedOut, t );
-}
+ if ( 0 )
+ fprintf( stderr, "internal=%s format=%s type=%s\n",
+ texImage->IntFormat == 3 ? "GL_RGB (3)" :
+ texImage->IntFormat == 4 ? "GL_RGBA (4)" :
+ gl_lookup_enum_by_nr( texImage->IntFormat ),
+ gl_lookup_enum_by_nr( format ),
+ gl_lookup_enum_by_nr( type ) );
-/* Print out debugging information about texture LRU.
- */
-void radeonPrintLocalLRU( radeonContextPtr rmesa, int heap )
-{
- radeonTexObjPtr t;
- int sz = 1 << (rmesa->radeonScreen->logTexGranularity[heap]);
-
- fprintf( stderr, "\nLocal LRU, heap %d:\n", heap );
-
- foreach ( t, &rmesa->TexObjList[heap] ) {
- if (!t->tObj) {
- fprintf( stderr, "Placeholder %d at 0x%x sz 0x%x\n",
- t->memBlock->ofs / sz,
- t->memBlock->ofs,
- t->memBlock->size );
- } else {
- fprintf( stderr, "Texture (bound %d) at 0x%x sz 0x%x\n",
- t->bound,
- t->memBlock->ofs,
- t->memBlock->size );
- }
- }
-
- fprintf( stderr, "\n" );
-}
-
-void radeonPrintGlobalLRU( radeonContextPtr rmesa, int heap )
-{
- radeon_tex_region_t *list = rmesa->sarea->texList[heap];
- int i, j;
-
- fprintf( stderr, "\nGlobal LRU, heap %d list %p:\n", heap, list );
-
- for ( i = 0, j = RADEON_NR_TEX_REGIONS ; i < RADEON_NR_TEX_REGIONS ; i++ ) {
- fprintf( stderr, "list[%d] age %d next %d prev %d\n",
- j, list[j].age, list[j].next, list[j].prev );
- j = list[j].next;
- if ( j == RADEON_NR_TEX_REGIONS ) break;
- }
-
- if ( j != RADEON_NR_TEX_REGIONS ) {
- fprintf( stderr, "Loop detected in global LRU\n" );
- for ( i = 0 ; i < RADEON_NR_TEX_REGIONS ; i++ ) {
- fprintf( stderr, "list[%d] age %d next %d prev %d\n",
- i, list[i].age, list[i].next, list[i].prev );
- }
- }
-
- fprintf( stderr, "\n" );
-}
-
-/* Reset the global texture LRU.
- */
-static void radeonResetGlobalLRU( radeonContextPtr rmesa, int heap )
-{
- radeon_tex_region_t *list = rmesa->sarea->texList[heap];
- int sz = 1 << rmesa->radeonScreen->logTexGranularity[heap];
- int i;
-
- /*
- * (Re)initialize the global circular LRU list. The last element in
- * the array (RADEON_NR_TEX_REGIONS) is the sentinal. Keeping it at
- * the end of the array allows it to be addressed rationally when
- * looking up objects at a particular location in texture memory.
- */
- for ( i = 0 ; (i+1) * sz <= rmesa->radeonScreen->texSize[heap] ; i++ ) {
- list[i].prev = i-1;
- list[i].next = i+1;
- list[i].age = 0;
- }
-
- i--;
- list[0].prev = RADEON_NR_TEX_REGIONS;
- list[i].prev = i-1;
- list[i].next = RADEON_NR_TEX_REGIONS;
- list[RADEON_NR_TEX_REGIONS].prev = i;
- list[RADEON_NR_TEX_REGIONS].next = 0;
- rmesa->sarea->texAge[heap] = 0;
-}
-
-/* Update the local and glock texture LRUs.
- */
-static void radeonUpdateTexLRU(radeonContextPtr rmesa, radeonTexObjPtr t )
-{
- int heap = t->heap;
- radeon_tex_region_t *list = rmesa->sarea->texList[heap];
- int sz = rmesa->radeonScreen->logTexGranularity[heap];
- int start = t->memBlock->ofs >> sz;
- int end = (t->memBlock->ofs + t->memBlock->size-1) >> sz;
- int i;
-
- rmesa->lastTexAge[heap] = ++rmesa->sarea->texAge[heap];
-
- if ( !t->memBlock ) {
- fprintf( stderr, "no memblock\n\n" );
- return;
- }
-
- /* Update our local LRU */
- move_to_head( &rmesa->TexObjList[heap], t );
-
- /* Update the global LRU */
- for ( i = start ; i <= end ; i++ ) {
- list[i].in_use = 1;
- list[i].age = rmesa->lastTexAge[heap];
-
- /* remove_from_list(i) */
- list[(CARD32)list[i].next].prev = list[i].prev;
- list[(CARD32)list[i].prev].next = list[i].next;
-
- /* insert_at_head(list, i) */
- list[i].prev = RADEON_NR_TEX_REGIONS;
- list[i].next = list[RADEON_NR_TEX_REGIONS].next;
- list[(CARD32)list[RADEON_NR_TEX_REGIONS].next].prev = i;
- list[RADEON_NR_TEX_REGIONS].next = i;
- }
-
- if ( 0 ) {
- radeonPrintGlobalLRU( rmesa, t->heap );
- radeonPrintLocalLRU( rmesa, t->heap );
- }
-}
-
-/* Update our notion of what textures have been changed since we last
- * held the lock. This pertains to both our local textures and the
- * textures belonging to other clients. Keep track of other client's
- * textures by pushing a placeholder texture onto the LRU list -- these
- * are denoted by (tObj == NULL).
- */
-static void radeonTexturesGone( radeonContextPtr rmesa, int heap,
- int offset, int size, int in_use )
-{
- radeonTexObjPtr t, tmp;
-
- foreach_s ( t, tmp, &rmesa->TexObjList[heap] ) {
- if ( t->memBlock->ofs >= offset + size ||
- t->memBlock->ofs + t->memBlock->size <= offset )
- continue;
-
- /* It overlaps - kick it out. Need to hold onto the currently
- * bound objects, however.
- */
- if ( t->bound ) {
- radeonSwapOutTexObj( rmesa, t );
- } else {
- radeonDestroyTexObj( rmesa, t );
- }
- }
-
- if ( in_use ) {
- t = (radeonTexObjPtr) CALLOC( sizeof(*t) );
- if ( !t ) return;
-
- t->memBlock = mmAllocMem( rmesa->texHeap[heap], size, 0, offset );
- if ( !t->memBlock ) {
- fprintf( stderr, "Couldn't alloc placeholder sz %x ofs %x\n",
- (int)size, (int)offset );
- mmDumpMemInfo( rmesa->texHeap[heap] );
- return;
- }
- insert_at_head( &rmesa->TexObjList[heap], t );
- }
-}
-
-/* Update our client's shared texture state. If another client has
- * modified a region in which we have textures, then we need to figure
- * out which of our textures has been removed, and update our global
- * LRU.
- */
-void radeonAgeTextures( radeonContextPtr rmesa, int heap )
-{
- RADEONSAREAPrivPtr sarea = rmesa->sarea;
-
- if ( sarea->texAge[heap] != rmesa->lastTexAge[heap] ) {
- int sz = 1 << rmesa->radeonScreen->logTexGranularity[heap];
- int nr = 0;
- int idx;
-
- for ( idx = sarea->texList[heap][RADEON_NR_TEX_REGIONS].prev ;
- idx != RADEON_NR_TEX_REGIONS && nr < RADEON_NR_TEX_REGIONS ;
- idx = sarea->texList[heap][idx].prev, nr++ )
- {
- /* If switching texturing schemes, then the SAREA might not
- * have been properly cleared, so we need to reset the
- * global texture LRU.
- */
- if ( idx * sz > rmesa->radeonScreen->texSize[heap] ) {
- nr = RADEON_NR_TEX_REGIONS;
- break;
- }
-
- if ( sarea->texList[heap][idx].age > rmesa->lastTexAge[heap] ) {
- radeonTexturesGone( rmesa, heap, idx * sz, sz,
- sarea->texList[heap][idx].in_use );
- }
- }
-
- if ( nr == RADEON_NR_TEX_REGIONS ) {
- radeonTexturesGone( rmesa, heap, 0,
- rmesa->radeonScreen->texSize[heap], 0 );
- radeonResetGlobalLRU( rmesa, heap );
- }
-
- rmesa->dirty |= (RADEON_UPLOAD_CONTEXT |
- RADEON_UPLOAD_TEX0IMAGES |
- RADEON_UPLOAD_TEX1IMAGES);
- rmesa->lastTexAge[heap] = sarea->texAge[heap];
- }
-}
-
-
-/* ================================================================
- * Texture image conversions
- */
-
-/* Convert a block of Mesa-formatted texture to an 8bpp hardware format.
- */
-static void radeonConvertTexture8bpp( CARD32 *dst,
- struct gl_texture_image *image,
- int x, int y, int width, int height,
- int pitch )
-{
- CARD8 *src;
- int i, j;
-
- if ( width < 4 ) {
- width = 4;
- }
-
-#define ALIGN_DST \
+#define SET_FORMAT( r, gl ) \
do { \
- if ( width < 32 ) { \
- dst += ((32 - width) / 4); \
- } \
+ ret = (r); \
+ texFormat = &(gl); \
} while (0)
- switch ( image->Format ) {
- case GL_INTENSITY:
- for ( i = 0 ; i < height ; i++ ) {
- src = (CARD8 *)image->Data + ((y + i) * pitch + x);
- for ( j = width >> 2 ; j ; j-- ) {
- *dst++ = src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
- src += 4;
- }
- ALIGN_DST;
- }
- break;
-
- case GL_COLOR_INDEX:
- default:
- fprintf( stderr, "%s: unsupported format 0x%x\n",
- __FUNCTION__, image->Format );
- break;
- }
-}
-#undef ALIGN_DST
-
-/* Convert a block of Mesa-formatted texture to a 16bpp hardware format.
- */
-static void radeonConvertTexture16bpp( CARD32 *dst,
- struct gl_texture_image *image,
- int x, int y, int width, int height,
- int pitch )
-{
- CARD8 *src;
- int i, j;
-
- if ( width < 2 ) {
- width = 2;
- }
-
-#define ALIGN_DST \
+#define SET_FORMAT_32BPT( r32, gl32, r16, gl16 ) \
do { \
- if ( width < 16 ) { \
- dst += ((16 - width) / 2); \
+ if ( do32bpt ) { \
+ ret = (r32); \
+ texFormat = &(gl32); \
+ } else { \
+ ret = (r16); \
+ texFormat = &(gl16); \
} \
} while (0)
- switch ( image->Format ) {
+ switch ( texImage->IntFormat ) {
+ /* GH: Bias towards GL_RGB, GL_RGBA texture formats. This has
+ * got to be better than sticking them way down the end of this
+ * huge list.
+ */
case GL_RGBA:
- for ( i = 0 ; i < height ; i++ ) {
- src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 4;
- for ( j = width >> 1 ; j ; j-- ) {
- *dst++ = ((RADEONPACKCOLOR4444( src[0], src[1], src[2], src[3] )) |
- (RADEONPACKCOLOR4444( src[4], src[5], src[6], src[7] ) << 16));
- src += 8;
+ case 4:
+ if ( format == GL_BGRA ) {
+ if ( type == GL_UNSIGNED_INT_8_8_8_8_REV ) {
+ SET_FORMAT( RADEON_TXFORMAT_ARGB8888, _mesa_texformat_argb8888 );
+ break;
+ } else if ( type == GL_UNSIGNED_SHORT_4_4_4_4_REV ) {
+ SET_FORMAT( RADEON_TXFORMAT_ARGB4444, _mesa_texformat_argb4444 );
+ break;
+ } else if ( type == GL_UNSIGNED_SHORT_1_5_5_5_REV ) {
+ SET_FORMAT( RADEON_TXFORMAT_ARGB1555, _mesa_texformat_argb1555 );
+ break;
}
- ALIGN_DST;
}
+ SET_FORMAT_32BPT( RADEON_TXFORMAT_RGBA8888, _mesa_texformat_rgba8888,
+ RADEON_TXFORMAT_ARGB4444, _mesa_texformat_argb4444 );
break;
case GL_RGB:
- {
- for ( i = 0 ; i < height ; i++ ) {
- src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 3;
- for ( j = width >> 1 ; j ; j-- ) {
- *dst++ = ((RADEONPACKCOLOR565( src[0], src[1], src[2] )) |
- (RADEONPACKCOLOR565( src[3], src[4], src[5] ) << 16));
- src += 6;
- }
- ALIGN_DST;
+ case 3:
+ if ( format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5 ) {
+ SET_FORMAT( RADEON_TXFORMAT_RGB565, _mesa_texformat_rgb565 );
+ break;
}
- }
+ SET_FORMAT_32BPT( RADEON_TXFORMAT_RGBA8888, _mesa_texformat_rgba8888,
+ RADEON_TXFORMAT_RGB565, _mesa_texformat_rgb565 );
break;
- case GL_ALPHA:
- for ( i = 0 ; i < height ; i++ ) {
- src = (CARD8 *)image->Data + ((y + i) * pitch + x);
- for ( j = width >> 1 ; j ; j-- ) {
- *dst++ = ((RADEONPACKCOLOR88( 0x00, src[0] )) |
- (RADEONPACKCOLOR88( 0x00, src[1] ) << 16));
- src += 2;
- }
- ALIGN_DST;
- }
+ /* GH: Okay, keep checking as normal. Still test for GL_RGB,
+ * GL_RGBA formats first.
+ */
+ case GL_RGBA8:
+ case GL_RGB10_A2:
+ case GL_RGBA12:
+ case GL_RGBA16:
+ SET_FORMAT_32BPT( RADEON_TXFORMAT_RGBA8888, _mesa_texformat_rgba8888,
+ RADEON_TXFORMAT_ARGB4444, _mesa_texformat_argb4444 );
break;
- case GL_LUMINANCE:
- for ( i = 0 ; i < height ; i++ ) {
- src = (CARD8 *)image->Data + ((y + i) * pitch + x);
- for ( j = width >> 1 ; j ; j-- ) {
- *dst++ = ((RADEONPACKCOLOR88( src[0], 0xff )) |
- (RADEONPACKCOLOR88( src[1], 0xff ) << 16));
- src += 2;
- }
- ALIGN_DST;
- }
+ case GL_RGBA4:
+ case GL_RGBA2:
+ SET_FORMAT( RADEON_TXFORMAT_ARGB4444, _mesa_texformat_argb4444 );
break;
- case GL_LUMINANCE_ALPHA:
- for ( i = 0 ; i < height ; i++ ) {
- src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 2;
- for ( j = width >> 1 ; j ; j-- ) {
- *dst++ = ((RADEONPACKCOLOR88( src[0], src[1] )) |
- (RADEONPACKCOLOR88( src[2], src[3] ) << 16));
- src += 4;
- }
- ALIGN_DST;
- }
+ case GL_RGB5_A1:
+ SET_FORMAT( RADEON_TXFORMAT_ARGB1555, _mesa_texformat_argb1555 );
break;
- default:
- fprintf( stderr, "%s: unsupported format 0x%x\n",
- __FUNCTION__, image->Format );
+ case GL_RGB8:
+ case GL_RGB10:
+ case GL_RGB12:
+ case GL_RGB16:
+ SET_FORMAT_32BPT( RADEON_TXFORMAT_RGBA8888, _mesa_texformat_rgba8888,
+ RADEON_TXFORMAT_RGB565, _mesa_texformat_rgb565 );
break;
- }
-}
-#undef ALIGN_DST
-/* Convert a block of Mesa-formatted texture to a 32bpp hardware format.
- */
-static void radeonConvertTexture32bpp( CARD32 *dst,
- struct gl_texture_image *image,
- int x, int y, int width, int height,
- int pitch )
-{
- CARD8 *src;
- int i, j;
+ case GL_RGB5:
+ case GL_RGB4:
+ case GL_R3_G3_B2:
+ SET_FORMAT( RADEON_TXFORMAT_RGB565, _mesa_texformat_rgb565 );
+ break;
-#define ALIGN_DST \
- do { \
- if ( width < 8 ) { \
- dst += (8 - width); \
- } \
- } while (0)
+ case GL_ALPHA:
+ case GL_ALPHA4:
+ case GL_ALPHA8:
+ case GL_ALPHA12:
+ case GL_ALPHA16:
+ SET_FORMAT( RADEON_TXFORMAT_AI88, _mesa_texformat_al88 );
+ break;
- switch ( image->Format ) {
- case GL_RGBA:
- for ( i = 0 ; i < height ; i++ ) {
- src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 4;
- for ( j = width ; j ; j-- ) {
- *dst++ = RADEONPACKCOLOR8888( src[0], src[1], src[2], src[3] );
- src += 4;
- }
- ALIGN_DST;
- }
+ case 1:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE4:
+ case GL_LUMINANCE8:
+ case GL_LUMINANCE12:
+ case GL_LUMINANCE16:
+ SET_FORMAT( RADEON_TXFORMAT_AI88, _mesa_texformat_al88 );
break;
- case GL_RGB:
- for ( i = 0 ; i < height ; i++ ) {
- src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 3;
- for ( j = width ; j ; j-- ) {
- *dst++ = RADEONPACKCOLOR8888( src[0], src[1], src[2], 0xff );
- src += 3;
- }
- ALIGN_DST;
- }
+ case 2:
+ case GL_LUMINANCE_ALPHA:
+ case GL_LUMINANCE4_ALPHA4:
+ case GL_LUMINANCE6_ALPHA2:
+ case GL_LUMINANCE8_ALPHA8:
+ case GL_LUMINANCE12_ALPHA4:
+ case GL_LUMINANCE12_ALPHA12:
+ case GL_LUMINANCE16_ALPHA16:
+ SET_FORMAT( RADEON_TXFORMAT_AI88, _mesa_texformat_al88 );
break;
- default:
- fprintf( stderr, "%s: unsupported format 0x%x\n",
- __FUNCTION__, image->Format );
+ case GL_INTENSITY:
+ case GL_INTENSITY4:
+ case GL_INTENSITY8:
+ case GL_INTENSITY12:
+ case GL_INTENSITY16:
+ SET_FORMAT( RADEON_TXFORMAT_I8, _mesa_texformat_i8 );
break;
+
+ case GL_COLOR_INDEX:
+ case GL_COLOR_INDEX1_EXT:
+ case GL_COLOR_INDEX2_EXT:
+ case GL_COLOR_INDEX4_EXT:
+ case GL_COLOR_INDEX8_EXT:
+ case GL_COLOR_INDEX12_EXT:
+ case GL_COLOR_INDEX16_EXT:
+ default:
+ fprintf( stderr, "bad texture format in radeonChooseTexFormat() %d",
+ texImage->IntFormat );
+ return -1;
}
+
+ texImage->TexFormat = texFormat;
+
+ return ret;
}
-/* Upload the texture image associated with texture `t' at level `level'
- * at the address relative to `start'.
+
+/* ================================================================
+ * Texture image callbacks
*/
-static void radeonUploadSubImage( radeonContextPtr rmesa,
- radeonTexObjPtr t, GLint level,
- GLint x, GLint y, GLint width, GLint height )
-{
- struct gl_texture_image *image;
- GLint texelsPerDword = 0;
- GLint imageX, imageY, imageWidth, imageHeight;
- GLint blitX, blitY, blitWidth, blitHeight;
- GLint imageRows, blitRows;
- GLint remaining ;
- GLint format, dwords;
- CARD32 pitch, offset;
- drmBufPtr buffer;
- CARD32 *dst;
-
- /* Ensure we have a valid texture to upload */
- if ( ( level < 0 ) || ( level >= RADEON_MAX_TEXTURE_LEVELS ) )
- return;
- image = t->tObj->Image[level];
- if ( !image )
- return;
+static GLboolean
+radeonDDTexImage1D( GLcontext *ctx, GLenum target, GLint level,
+ GLenum format, GLenum type, const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage,
+ GLboolean *retainInternalCopy )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ radeonTexObjPtr t = (radeonTexObjPtr)texObj->DriverData;
+ const struct gl_texture_format *texFormat;
+ GLuint texSize;
+ GLint txformat;
+ GLubyte *data;
- switch ( t->texelBytes ) {
- case 1:
- texelsPerDword = 4;
- break;
- case 2:
- texelsPerDword = 2;
- break;
- case 4:
- texelsPerDword = 1;
- break;
- }
+ if ( target != GL_TEXTURE_1D )
+ return GL_FALSE;
- format = t->setup.pp_txformat & RADEON_TXF_FORMAT_MASK;
-
- imageX = 0;
- imageY = 0;
- imageWidth = image->Width;
- imageHeight = image->Height;
-
- blitX = t->image[level].x;
- blitY = t->image[level].y;
- blitWidth = t->image[level].width;
- blitHeight = t->image[level].height;
-
- dwords = t->image[level].dwords;
- offset = t->bufAddr;
- pitch = (t->image[0].width * t->texelBytes) / 64;
-
-#if ENABLE_PERF_BOXES
- /* Bump the performace counter */
- rmesa->c_textureBytes += (dwords << 2);
-#endif
-
- if ( RADEON_DEBUG & DEBUG_VERBOSE_MSG ) {
- fprintf( stderr, " upload image: %d,%d at %d,%d\n",
- imageWidth, imageHeight, imageX, imageY );
- fprintf( stderr, " upload blit: %d,%d at %d,%d\n",
- blitWidth, blitHeight, blitX, blitY );
- fprintf( stderr, " blit ofs: 0x%07x pitch: 0x%x dwords: %d "
- "level: %d format: %x\n",
- (GLuint)offset, (GLuint)pitch, dwords, level, format );
+ if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) {
+ fprintf( stderr, "%s( %p )\n", __FUNCTION__, t );
}
- /* Subdivide the texture if required */
- if ( dwords <= RADEON_BUFFER_MAX_DWORDS / 2 ) {
- imageRows = imageHeight;
- blitRows = blitHeight;
+ if ( t ) {
+ if ( t->bound ) FLUSH_BATCH( rmesa );
+ radeonSwapOutTexObj( rmesa, t );
} else {
- imageRows = (RADEON_BUFFER_MAX_DWORDS * texelsPerDword)/(2 * imageWidth);
- blitRows = (RADEON_BUFFER_MAX_DWORDS * texelsPerDword) / (2 * blitWidth);
+ t = radeonAllocTexObj( texObj );
+ texObj->DriverData = t;
}
- for ( remaining = imageHeight ;
- remaining > 0 ;
- remaining -= imageRows, imageY += imageRows, blitY += blitRows )
- {
- if ( remaining >= imageRows ) {
- imageHeight = imageRows;
- blitHeight = blitRows;
- } else {
- imageHeight = remaining;
- blitHeight = blitRows;
- }
- dwords = blitWidth * blitHeight / texelsPerDword;
-
- if ( RADEON_DEBUG & DEBUG_VERBOSE_MSG ) {
- fprintf( stderr, " blitting: %d,%d at %d,%d\n",
- imageWidth, imageHeight, imageX, imageY );
- fprintf( stderr, " %d,%d at %d,%d - %d dwords\n",
- blitWidth, blitHeight, blitX, blitY, dwords );
- }
-
- /* Grab the indirect buffer for the texture blit */
- buffer = radeonGetBufferLocked( rmesa );
+ txformat = radeonChooseTexFormat( rmesa, texImage, format, type );
+ if ( txformat < 0 )
+ return GL_FALSE;
- dst = (CARD32 *)((char *)buffer->address + RADEON_HOSTDATA_BLIT_OFFSET);
+ texFormat = texImage->TexFormat;
+ texSize = texImage->Width * texFormat->TexelBytes;
- /* Actually do the texture conversion */
- switch ( t->texelBytes ) {
- case 1:
- radeonConvertTexture8bpp( dst, image,
- imageX, imageY, imageWidth, imageHeight,
- imageWidth );
- break;
- case 2:
- radeonConvertTexture16bpp( dst, image,
- imageX, imageY, imageWidth, imageHeight,
- imageWidth );
- break;
- case 4:
- radeonConvertTexture32bpp( dst, image,
- imageX, imageY, imageWidth, imageHeight,
- imageWidth );
- break;
- }
-
- radeonFireBlitLocked( rmesa, buffer,
- offset, pitch, format,
- blitX, blitY, blitWidth, blitHeight );
+ /* We really shouldn't have to keep the texture image, it should be
+ * hung from the main texImage structure.
+ */
+ if ( t->image[level].data ) {
+ FREE( t->image[level].data );
+ t->image[level].data = NULL;
}
- rmesa->new_state |= RADEON_NEW_CONTEXT;
- rmesa->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_MASKS;
-}
+ data = (GLubyte *) MALLOC( texSize );
+ if ( !data )
+ return GL_FALSE;
-/* Upload the texture images associated with texture `t'. This might
- * require removing our own and/or other client's texture objects to
- * make room for these images.
- */
-/* NOTE: This function is only called while holding the hardware lock */
-int radeonUploadTexImages( radeonContextPtr rmesa, radeonTexObjPtr t )
-{
- int i;
- int heap;
-
- if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) {
- fprintf( stderr, "%s( %p, %p )\n",
- __FUNCTION__, rmesa->glCtx, t );
+ if ( !_mesa_convert_texsubimage1d( texFormat->IntFormat,
+ 0, texImage->Width,
+ format, type, packing,
+ pixels, data ) ) {
+ /*fprintf( stderr, " *** convert failed!\n" );*/
+ FREE( data );
+ return GL_FALSE;
}
- if ( !t )
- return 0;
-
- /* Choose the heap appropriately */
- heap = t->heap = RADEON_CARD_HEAP;
-#if 0
- if ( !rmesa->radeonScreen->IsPCI &&
- t->totalSize > rmesa->radeonScreen->texSize[heap] ) {
- heap = t->heap = RADEON_AGP_HEAP;
- }
-#endif
-
- /* Do we need to eject LRU texture objects? */
- if ( !t->memBlock ) {
- /* Allocate a memory block on a 4k boundary (1<<12 == 4096) */
- t->memBlock = mmAllocMem( rmesa->texHeap[heap],
- t->totalSize, 12, 0 );
-
-#if 0
- /* Try AGP before kicking anything out of local mem */
- if ( !t->memBlock && heap == RADEON_CARD_HEAP ) {
- t->memBlock = mmAllocMem( rmesa->texHeap[RADEON_AGP_HEAP],
- t->totalSize, 12, 0 );
-
- if ( t->memBlock )
- heap = t->heap = RADEON_AGP_HEAP;
- }
-#endif
-
- /* Kick out textures until the requested texture fits */
- while ( !t->memBlock ) {
- if ( rmesa->TexObjList[heap].prev->bound ) {
- fprintf( stderr,
- "radeonUploadTexImages: ran into bound texture\n" );
- return -1;
- }
- if ( rmesa->TexObjList[heap].prev ==
- &rmesa->TexObjList[heap] ) {
- if ( rmesa->radeonScreen->IsPCI ) {
- fprintf( stderr, "radeonUploadTexImages: upload texture "
- "failure on local texture heaps, sz=%d\n",
- t->totalSize );
- return -1;
-#if 0
- } else if ( heap == RADEON_CARD_HEAP ) {
- heap = t->heap = RADEON_AGP_HEAP;
- continue;
-#endif
- } else {
- fprintf( stderr, "radeonUploadTexImages: upload texture "
- "failure on both local and AGP texture heaps, "
- "sz=%d\n",
- t->totalSize );
- return -1;
- }
- }
+ t->image[level].data = data;
+ t->dirty_images |= (1 << level);
- radeonDestroyTexObj( rmesa, rmesa->TexObjList[heap].prev );
+ /* Format-specific hardware state:
+ */
+ t->pp_txformat &= ~(RADEON_TXFORMAT_FORMAT_MASK |
+ RADEON_TXFORMAT_ALPHA_IN_MAP);
+ t->pp_txformat |= txformat;
- t->memBlock = mmAllocMem( rmesa->texHeap[heap],
- t->totalSize, 12, 0 );
- }
+ if ( txformat == RADEON_TXFORMAT_RGBA8888 ||
+ txformat == RADEON_TXFORMAT_ARGB4444 ||
+ txformat == RADEON_TXFORMAT_ARGB1555 ||
+ txformat == RADEON_TXFORMAT_AI88 ) {
+ t->pp_txformat |= RADEON_TXFORMAT_ALPHA_IN_MAP;
+ }
- /* Set the base offset of the texture image */
- t->bufAddr = rmesa->radeonScreen->texOffset[heap] + t->memBlock->ofs;
+ rmesa->new_state |= RADEON_NEW_TEXTURE;
- t->setup.pp_txoffset = t->bufAddr;
-#if 0
- /* Fix AGP texture offsets */
- if ( heap == RADEON_AGP_HEAP ) {
- t->setup.pp_tx_offset += RADEON_AGP_TEX_OFFSET +
- rmesa->radeonScreen->agpTexOffset;
- }
-#endif
+ *retainInternalCopy = GL_FALSE;
+ return GL_TRUE;
+}
- /* Force loading the new state into the hardware */
- switch ( t->bound ) {
- case 1:
- rmesa->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_TEX0;
- break;
+static GLboolean
+radeonDDTexImage2D( GLcontext *ctx, GLenum target, GLint level,
+ GLenum format, GLenum type, const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage,
+ GLboolean *retainInternalCopy )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ radeonTexObjPtr t = (radeonTexObjPtr)texObj->DriverData;
+ const struct gl_texture_format *texFormat;
+ GLuint texSize;
+ GLint txformat;
+ GLubyte *data;
- case 2:
- rmesa->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_TEX1;
- break;
+ if ( target != GL_TEXTURE_2D )
+ return GL_FALSE;
- default:
- return -1;
- }
+ if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) {
+ fprintf( stderr, "%s( %p )\n", __FUNCTION__, t );
}
- /* Let the world know we've used this memory recently */
- radeonUpdateTexLRU( rmesa, t );
+ if ( t ) {
+ if ( t->bound ) FLUSH_BATCH( rmesa );
+ radeonSwapOutTexObj( rmesa, t );
+ } else {
+ t = radeonAllocTexObj( texObj );
+ texObj->DriverData = t;
+ }
- /* Upload any images that are new */
- if ( t->dirty_images ) {
- int num_levels = ((t->setup.pp_txfilter & RADEON_MAX_MIP_LEVEL_MASK) >>
- RADEON_MAX_MIP_LEVEL_SHIFT);
+ txformat = radeonChooseTexFormat( rmesa, texImage, format, type );
+ if ( txformat < 0 )
+ return GL_FALSE;
- for ( i = 0 ; i <= num_levels ; i++ ) {
- if ( t->dirty_images & (1 << i) ) {
- radeonUploadSubImage( rmesa, t, i, 0, 0,
- t->image[i].width, t->image[i].height );
- }
- }
+ texFormat = texImage->TexFormat;
+ texSize = texImage->Width * texImage->Height * texFormat->TexelBytes;
- rmesa->dirty |= RADEON_UPLOAD_CONTEXT;
+ /* We really shouldn't have to keep the texture image, it should be
+ * hung from the main texImage structure.
+ */
+ if ( t->image[level].data ) {
+ FREE( t->image[level].data );
+ t->image[level].data = NULL;
}
- t->dirty_images = 0;
- return 0;
-}
-
+ data = (GLubyte *) MALLOC( texSize );
+ if ( !data )
+ return GL_FALSE;
-/* ================================================================
- * Texture combine functions
- */
+ if ( !_mesa_convert_texsubimage2d( texFormat->IntFormat,
+ 0, 0, texImage->Width, texImage->Height,
+ texImage->Width, format, type, packing,
+ pixels, data ) ) {
+ if ( 0 )
+ fprintf( stderr, " *** convert failed! %s/%s-> %s\n",
+ gl_lookup_enum_by_nr( format ),
+ gl_lookup_enum_by_nr( type ),
+ gl_lookup_enum_by_nr( texImage->IntFormat ) );
+ FREE( data );
+ return GL_FALSE;
+ }
-#define RADEON_DISABLE 0
-#define RADEON_REPLACE 1
-#define RADEON_MODULATE 2
-#define RADEON_DECAL 3
-#define RADEON_BLEND 4
-#define RADEON_ADD 5
-#define RADEON_MAX_COMBFUNC 6
+ t->image[level].data = data;
+ t->dirty_images |= (1 << level);
-static GLuint radeon_color_combine[][RADEON_MAX_COMBFUNC] =
-{
- /* Unit 0:
- */
- {
- /* Disable combiner stage
- */
- (RADEON_COLOR_ARG_A_ZERO |
- RADEON_COLOR_ARG_B_ZERO |
- RADEON_COLOR_ARG_C_CURRENT_COLOR |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_REPLACE = 0x00802800
- */
- (RADEON_COLOR_ARG_A_ZERO |
- RADEON_COLOR_ARG_B_ZERO |
- RADEON_COLOR_ARG_C_T0_COLOR |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_MODULATE = 0x00800142
- */
- (RADEON_COLOR_ARG_A_CURRENT_COLOR |
- RADEON_COLOR_ARG_B_T0_COLOR |
- RADEON_COLOR_ARG_C_ZERO |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_DECAL = 0x008c2d42
- */
- (RADEON_COLOR_ARG_A_CURRENT_COLOR |
- RADEON_COLOR_ARG_B_T0_COLOR |
- RADEON_COLOR_ARG_C_T0_ALPHA |
- RADEON_BLEND_CTL_BLEND |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_BLEND = 0x008c2902
- */
- (RADEON_COLOR_ARG_A_CURRENT_COLOR |
- RADEON_COLOR_ARG_B_TFACTOR_COLOR |
- RADEON_COLOR_ARG_C_T0_COLOR |
- RADEON_BLEND_CTL_BLEND |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_ADD = 0x00812802
- */
- (RADEON_COLOR_ARG_A_CURRENT_COLOR |
- RADEON_COLOR_ARG_B_ZERO |
- RADEON_COLOR_ARG_C_T0_COLOR |
- RADEON_COMP_ARG_B |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
- },
-
- /* Unit 1:
- */
- {
- /* Disable combiner stage
- */
- (RADEON_COLOR_ARG_A_ZERO |
- RADEON_COLOR_ARG_B_ZERO |
- RADEON_COLOR_ARG_C_CURRENT_COLOR |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_REPLACE = 0x00803000
- */
- (RADEON_COLOR_ARG_A_ZERO |
- RADEON_COLOR_ARG_B_ZERO |
- RADEON_COLOR_ARG_C_T1_COLOR |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_MODULATE = 0x00800182
- */
- (RADEON_COLOR_ARG_A_CURRENT_COLOR |
- RADEON_COLOR_ARG_B_T1_COLOR |
- RADEON_COLOR_ARG_C_ZERO |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_DECAL = 0x008c3582
- */
- (RADEON_COLOR_ARG_A_CURRENT_COLOR |
- RADEON_COLOR_ARG_B_T1_COLOR |
- RADEON_COLOR_ARG_C_T1_ALPHA |
- RADEON_BLEND_CTL_BLEND |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_BLEND = 0x008c3102
- */
- (RADEON_COLOR_ARG_A_CURRENT_COLOR |
- RADEON_COLOR_ARG_B_TFACTOR_COLOR |
- RADEON_COLOR_ARG_C_T1_COLOR |
- RADEON_BLEND_CTL_BLEND |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_ADD = 0x00813002
- */
- (RADEON_COLOR_ARG_A_CURRENT_COLOR |
- RADEON_COLOR_ARG_B_ZERO |
- RADEON_COLOR_ARG_C_T1_COLOR |
- RADEON_COMP_ARG_B |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
- },
-
- /* Unit 2:
+ /* Format-specific hardware state:
*/
- {
- /* Disable combiner stage
- */
- (RADEON_COLOR_ARG_A_ZERO |
- RADEON_COLOR_ARG_B_ZERO |
- RADEON_COLOR_ARG_C_CURRENT_COLOR |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_REPLACE = 0x00803800
- */
- (RADEON_COLOR_ARG_A_ZERO |
- RADEON_COLOR_ARG_B_ZERO |
- RADEON_COLOR_ARG_C_T2_COLOR |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_MODULATE = 0x008001c2
- */
- (RADEON_COLOR_ARG_A_CURRENT_COLOR |
- RADEON_COLOR_ARG_B_T2_COLOR |
- RADEON_COLOR_ARG_C_ZERO |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_DECAL = 0x008c3dc2
- */
- (RADEON_COLOR_ARG_A_CURRENT_COLOR |
- RADEON_COLOR_ARG_B_T2_COLOR |
- RADEON_COLOR_ARG_C_T2_ALPHA |
- RADEON_BLEND_CTL_BLEND |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_BLEND = 0x008c3902
- */
- (RADEON_COLOR_ARG_A_CURRENT_COLOR |
- RADEON_COLOR_ARG_B_TFACTOR_COLOR |
- RADEON_COLOR_ARG_C_T2_COLOR |
- RADEON_BLEND_CTL_BLEND |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_ADD = 0x00813802
- */
- (RADEON_COLOR_ARG_A_CURRENT_COLOR |
- RADEON_COLOR_ARG_B_ZERO |
- RADEON_COLOR_ARG_C_T2_COLOR |
- RADEON_COMP_ARG_B |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
- }
-};
+ t->pp_txformat &= ~(RADEON_TXFORMAT_FORMAT_MASK |
+ RADEON_TXFORMAT_ALPHA_IN_MAP);
+ t->pp_txformat |= txformat;
-static GLuint radeon_alpha_combine[][RADEON_MAX_COMBFUNC] =
-{
- /* Unit 0:
- */
- {
- /* Disable combiner stage
- */
- (RADEON_ALPHA_ARG_A_ZERO |
- RADEON_ALPHA_ARG_B_ZERO |
- RADEON_ALPHA_ARG_C_CURRENT_ALPHA |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_REPLACE = 0x00800500
- */
- (RADEON_ALPHA_ARG_A_ZERO |
- RADEON_ALPHA_ARG_B_ZERO |
- RADEON_ALPHA_ARG_C_T0_ALPHA |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_MODULATE = 0x00800051
- */
- (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
- RADEON_ALPHA_ARG_B_T0_ALPHA |
- RADEON_ALPHA_ARG_C_ZERO |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_DECAL = 0x00800100
- */
- (RADEON_ALPHA_ARG_A_ZERO |
- RADEON_ALPHA_ARG_B_ZERO |
- RADEON_ALPHA_ARG_C_CURRENT_ALPHA |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_BLEND = 0x00800051
- */
- (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
- RADEON_ALPHA_ARG_B_TFACTOR_ALPHA |
- RADEON_ALPHA_ARG_C_T0_ALPHA |
- RADEON_BLEND_CTL_BLEND |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_ADD = 0x00800051
- */
- (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
- RADEON_ALPHA_ARG_B_ZERO |
- RADEON_ALPHA_ARG_C_T0_ALPHA |
- RADEON_COMP_ARG_B |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
- },
-
- /* Unit 1:
- */
- {
- /* Disable combiner stage
- */
- (RADEON_ALPHA_ARG_A_ZERO |
- RADEON_ALPHA_ARG_B_ZERO |
- RADEON_ALPHA_ARG_C_CURRENT_ALPHA |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_REPLACE = 0x00800600
- */
- (RADEON_ALPHA_ARG_A_ZERO |
- RADEON_ALPHA_ARG_B_ZERO |
- RADEON_ALPHA_ARG_C_T1_ALPHA |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_MODULATE = 0x00800061
- */
- (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
- RADEON_ALPHA_ARG_B_T1_ALPHA |
- RADEON_ALPHA_ARG_C_ZERO |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_DECAL = 0x00800100
- */
- (RADEON_ALPHA_ARG_A_ZERO |
- RADEON_ALPHA_ARG_B_ZERO |
- RADEON_ALPHA_ARG_C_CURRENT_ALPHA |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_BLEND = 0x00800061
- */
- (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
- RADEON_ALPHA_ARG_B_TFACTOR_ALPHA |
- RADEON_ALPHA_ARG_C_T1_ALPHA |
- RADEON_BLEND_CTL_BLEND |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_ADD = 0x00800061
- */
- (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
- RADEON_ALPHA_ARG_B_ZERO |
- RADEON_ALPHA_ARG_C_T1_ALPHA |
- RADEON_COMP_ARG_B |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
- },
-
- /* Unit 2:
- */
- {
- /* Disable combiner stage
- */
- (RADEON_ALPHA_ARG_A_ZERO |
- RADEON_ALPHA_ARG_B_ZERO |
- RADEON_ALPHA_ARG_C_CURRENT_ALPHA |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_REPLACE = 0x00800700
- */
- (RADEON_ALPHA_ARG_A_ZERO |
- RADEON_ALPHA_ARG_B_ZERO |
- RADEON_ALPHA_ARG_C_T2_ALPHA |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_MODULATE = 0x00800071
- */
- (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
- RADEON_ALPHA_ARG_B_T2_ALPHA |
- RADEON_ALPHA_ARG_C_ZERO |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_DECAL = 0x00800100
- */
- (RADEON_ALPHA_ARG_A_ZERO |
- RADEON_ALPHA_ARG_B_ZERO |
- RADEON_ALPHA_ARG_C_CURRENT_ALPHA |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_BLEND = 0x00800071
- */
- (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
- RADEON_ALPHA_ARG_B_TFACTOR_ALPHA |
- RADEON_ALPHA_ARG_C_T2_ALPHA |
- RADEON_BLEND_CTL_BLEND |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_ADD = 0x00800021
- */
- (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
- RADEON_ALPHA_ARG_B_ZERO |
- RADEON_ALPHA_ARG_C_T2_ALPHA |
- RADEON_COMP_ARG_B |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
+ if ( txformat == RADEON_TXFORMAT_RGBA8888 ||
+ txformat == RADEON_TXFORMAT_ARGB4444 ||
+ txformat == RADEON_TXFORMAT_ARGB1555 ||
+ txformat == RADEON_TXFORMAT_AI88 ) {
+ t->pp_txformat |= RADEON_TXFORMAT_ALPHA_IN_MAP;
}
-};
+ rmesa->new_state |= RADEON_NEW_TEXTURE;
-/* GL_EXT_texture_env_combine support
- */
+ *retainInternalCopy = GL_FALSE;
+ return GL_TRUE;
+}
-/* The color tables have combine functions for GL_SRC_COLOR,
- * GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA.
+/* GH: This is undoubtedly broken...
*/
-static GLuint radeon_texture_color[][RADEON_MAX_TEXTURE_UNITS] =
-{
- {
- RADEON_COLOR_ARG_A_T0_COLOR,
- RADEON_COLOR_ARG_A_T1_COLOR,
- RADEON_COLOR_ARG_A_T2_COLOR
- },
- {
- RADEON_COLOR_ARG_A_T0_COLOR | RADEON_COMP_ARG_A,
- RADEON_COLOR_ARG_A_T1_COLOR | RADEON_COMP_ARG_A,
- RADEON_COLOR_ARG_A_T2_COLOR | RADEON_COMP_ARG_A
- },
- {
- RADEON_COLOR_ARG_A_T0_ALPHA,
- RADEON_COLOR_ARG_A_T1_ALPHA,
- RADEON_COLOR_ARG_A_T2_ALPHA
- },
- {
- RADEON_COLOR_ARG_A_T0_ALPHA | RADEON_COMP_ARG_A,
- RADEON_COLOR_ARG_A_T1_ALPHA | RADEON_COMP_ARG_A,
- RADEON_COLOR_ARG_A_T2_ALPHA | RADEON_COMP_ARG_A
- },
-};
-
-static GLuint radeon_tfactor_color[] =
+static GLboolean
+radeonDDTexImage3D( GLcontext *ctx, GLenum target, GLint level,
+ GLenum format, GLenum type, const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage,
+ GLboolean *retainInternalCopy )
{
- RADEON_COLOR_ARG_A_TFACTOR_COLOR,
- RADEON_COLOR_ARG_A_TFACTOR_COLOR | RADEON_COMP_ARG_A,
- RADEON_COLOR_ARG_A_TFACTOR_ALPHA,
- RADEON_COLOR_ARG_A_TFACTOR_ALPHA | RADEON_COMP_ARG_A
-};
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ radeonTexObjPtr t = (radeonTexObjPtr)texObj->DriverData;
+ const struct gl_texture_format *texFormat;
+ GLuint texSize;
+ GLint txformat;
+ GLubyte *data;
-static GLuint radeon_primary_color[] =
-{
- RADEON_COLOR_ARG_A_DIFFUSE_COLOR,
- RADEON_COLOR_ARG_A_DIFFUSE_COLOR | RADEON_COMP_ARG_A,
- RADEON_COLOR_ARG_A_DIFFUSE_ALPHA,
- RADEON_COLOR_ARG_A_DIFFUSE_ALPHA | RADEON_COMP_ARG_A
-};
+ if ( target != GL_TEXTURE_3D )
+ return GL_FALSE;
-static GLuint radeon_previous_color[] =
-{
- RADEON_COLOR_ARG_A_CURRENT_COLOR,
- RADEON_COLOR_ARG_A_CURRENT_COLOR | RADEON_COMP_ARG_A,
- RADEON_COLOR_ARG_A_CURRENT_ALPHA,
- RADEON_COLOR_ARG_A_CURRENT_ALPHA | RADEON_COMP_ARG_A
-};
+ if ( t ) {
+ if ( t->bound ) FLUSH_BATCH( rmesa );
+ radeonSwapOutTexObj( rmesa, t );
+ } else {
+ t = radeonAllocTexObj( texObj );
+ texObj->DriverData = t;
+ }
-/* The alpha tables only have GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA.
- */
-static GLuint radeon_texture_alpha[][RADEON_MAX_TEXTURE_UNITS] =
-{
- {
- RADEON_ALPHA_ARG_A_T0_ALPHA,
- RADEON_ALPHA_ARG_A_T1_ALPHA,
- RADEON_ALPHA_ARG_A_T2_ALPHA
- },
- {
- RADEON_ALPHA_ARG_A_T0_ALPHA | RADEON_COMP_ARG_A,
- RADEON_ALPHA_ARG_A_T1_ALPHA | RADEON_COMP_ARG_A,
- RADEON_ALPHA_ARG_A_T2_ALPHA | RADEON_COMP_ARG_A
- },
-};
-
-static GLuint radeon_tfactor_alpha[] =
-{
- RADEON_ALPHA_ARG_A_TFACTOR_ALPHA,
- RADEON_ALPHA_ARG_A_TFACTOR_ALPHA | RADEON_COMP_ARG_A
-};
+ txformat = radeonChooseTexFormat( rmesa, texImage, format, type );
+ if ( txformat < 0 )
+ return GL_FALSE;
-static GLuint radeon_primary_alpha[] =
-{
- RADEON_ALPHA_ARG_A_DIFFUSE_ALPHA,
- RADEON_ALPHA_ARG_A_DIFFUSE_ALPHA | RADEON_COMP_ARG_A
-};
+ texFormat = texImage->TexFormat;
+ texSize = (texImage->Width * texImage->Height *
+ texImage->Depth * texFormat->TexelBytes);
-static GLuint radeon_previous_alpha[] =
-{
- RADEON_ALPHA_ARG_A_CURRENT_ALPHA,
- RADEON_ALPHA_ARG_A_CURRENT_ALPHA | RADEON_COMP_ARG_A
-};
+ /* We really shouldn't have to keep the texture image, it should be
+ * hung from the main texImage structure.
+ */
+ if ( t->image[level].data ) {
+ FREE( t->image[level].data );
+ t->image[level].data = NULL;
+ }
+ data = (GLubyte *) MALLOC( texSize );
+ if ( !data )
+ return GL_FALSE;
-/* Extract the arg from slot A, shift it into the correct argument slot
- * and set the corresponding complement bit.
- */
-#define RADEON_COLOR_ARG( n, arg ) \
-do { \
- color_combine |= \
- ((color_arg[n] & RADEON_COLOR_ARG_MASK) \
- << RADEON_COLOR_ARG_##arg##_SHIFT); \
- color_combine |= \
- ((color_arg[n] >> RADEON_COMP_ARG_SHIFT) \
- << RADEON_COMP_ARG_##arg##_SHIFT); \
-} while (0)
-
-#define RADEON_ALPHA_ARG( n, arg ) \
-do { \
- alpha_combine |= \
- ((alpha_arg[n] & RADEON_ALPHA_ARG_MASK) \
- << RADEON_ALPHA_ARG_##arg##_SHIFT); \
- alpha_combine |= \
- ((alpha_arg[n] >> RADEON_COMP_ARG_SHIFT) \
- << RADEON_COMP_ARG_##arg##_SHIFT); \
-} while (0)
+ if ( !_mesa_convert_texsubimage3d( texFormat->IntFormat,
+ 0, 0, 0, texImage->Width,
+ texImage->Height, texImage->Depth,
+ texImage->Width, texImage->Height,
+ format, type, packing,
+ pixels, data ) ) {
+ FREE( data );
+ return GL_FALSE;
+ }
+
+ t->image[level].data = data;
+ t->dirty_images |= (1 << level);
+ rmesa->new_state |= RADEON_NEW_TEXTURE;
+
+ *retainInternalCopy = GL_FALSE;
+ return GL_TRUE;
+}
/* ================================================================
- * Texture unit state management
+ * Texture subimage callbacks
*/
-static void radeonUpdateTextureEnv( GLcontext *ctx, int unit )
+static GLboolean
+radeonDDTexSubImage1D( GLcontext *ctx, GLenum target, GLint level,
+ GLint xoffset, GLsizei width,
+ GLenum format, GLenum type,
+ const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage )
{
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- int source = rmesa->tmu_source[unit];
- struct gl_texture_object *tObj;
- struct gl_texture_unit *texUnit;
- GLuint enabled;
- GLuint color_combine, alpha_combine;
- GLuint color_arg[3], alpha_arg[3];
- GLuint i, numColorArgs = 0, numAlphaArgs = 0;
- GLuint op;
+ radeonTexObjPtr t = (radeonTexObjPtr)texObj->DriverData;
+ const struct gl_texture_format *texFormat;
- if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) {
- fprintf( stderr, "%s( %p, %d )\n",
- __FUNCTION__, ctx, unit );
- }
-
- enabled = (ctx->Texture.ReallyEnabled >> (source * 4)) & TEXTURE0_ANY;
- if ( enabled != TEXTURE0_2D && enabled != TEXTURE0_1D )
- return;
+ if ( target != GL_TEXTURE_1D )
+ return GL_FALSE;
- /* Only update the hardware texture state if the texture is current,
- * complete and enabled.
+ /* FIXME: Can this ever be NULL???
*/
- texUnit = &ctx->Texture.Unit[source];
- tObj = texUnit->Current;
- if ( !tObj || !tObj->Complete )
- return;
-
- if ( ( tObj != texUnit->CurrentD[2] ) &&
- ( tObj != texUnit->CurrentD[1] ) )
- return;
+ ASSERT( t );
- /* Set the texture environment state. Isn't this nice and clean?
- * The Radeon will automagically set the texture alpha to 0xff when
- * the texture format does not include an alpha component. This
- * reduces the amount of special-casing we have to do, alpha-only
- * textures being a notable exception.
- */
- switch ( texUnit->EnvMode ) {
- case GL_REPLACE:
- switch ( tObj->Image[0]->Format ) {
- case GL_RGBA:
- case GL_RGB:
- case GL_LUMINANCE:
- case GL_LUMINANCE_ALPHA:
- case GL_INTENSITY:
- color_combine = radeon_color_combine[unit][RADEON_REPLACE];
- alpha_combine = radeon_alpha_combine[unit][RADEON_REPLACE];
- break;
- case GL_ALPHA:
- color_combine = radeon_color_combine[unit][RADEON_DISABLE];
- alpha_combine = radeon_alpha_combine[unit][RADEON_REPLACE];
- break;
- case GL_COLOR_INDEX:
- default:
- return;
- }
- break;
-
- case GL_MODULATE:
- switch ( tObj->Image[0]->Format ) {
- case GL_RGBA:
- case GL_RGB:
- case GL_LUMINANCE:
- case GL_LUMINANCE_ALPHA:
- case GL_INTENSITY:
- color_combine = radeon_color_combine[unit][RADEON_MODULATE];
- alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE];
- break;
- case GL_ALPHA:
- color_combine = radeon_color_combine[unit][RADEON_DISABLE];
- alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE];
- break;
- case GL_COLOR_INDEX:
- default:
- return;
- }
- break;
-
- case GL_DECAL:
- switch ( tObj->Image[0]->Format ) {
- case GL_RGBA:
- case GL_RGB:
- color_combine = radeon_color_combine[unit][RADEON_DECAL];
- alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE];
- break;
- case GL_ALPHA:
- case GL_LUMINANCE:
- case GL_LUMINANCE_ALPHA:
- case GL_INTENSITY:
- color_combine = radeon_color_combine[unit][RADEON_DISABLE];
- alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE];
- break;
- case GL_COLOR_INDEX:
- default:
- return;
- }
- break;
-
- case GL_BLEND:
- switch ( tObj->Image[0]->Format ) {
- case GL_RGBA:
- case GL_RGB:
- case GL_LUMINANCE:
- case GL_LUMINANCE_ALPHA:
- color_combine = radeon_color_combine[unit][RADEON_BLEND];
- alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE];
- break;
- case GL_ALPHA:
- color_combine = radeon_color_combine[unit][RADEON_DISABLE];
- alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE];
- break;
- case GL_INTENSITY:
- color_combine = radeon_color_combine[unit][RADEON_BLEND];
- alpha_combine = radeon_alpha_combine[unit][RADEON_BLEND];
- break;
- case GL_COLOR_INDEX:
- default:
- return;
- }
- break;
-
- case GL_ADD:
- switch ( tObj->Image[0]->Format ) {
- case GL_RGBA:
- case GL_RGB:
- case GL_LUMINANCE:
- case GL_LUMINANCE_ALPHA:
- color_combine = radeon_color_combine[unit][RADEON_ADD];
- alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE];
- break;
- case GL_ALPHA:
- color_combine = radeon_color_combine[unit][RADEON_DISABLE];
- alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE];
- break;
- case GL_INTENSITY:
- color_combine = radeon_color_combine[unit][RADEON_ADD];
- alpha_combine = radeon_alpha_combine[unit][RADEON_ADD];
- break;
- case GL_COLOR_INDEX:
- default:
- return;
- }
- break;
+ if ( t->bound ) {
+ FLUSH_VB( ctx, "radeonDDTexSubImage2D" );
+ FLUSH_BATCH( rmesa );
+ }
- case GL_COMBINE_EXT:
- /* Step 0:
- * Calculate how many arguments we need to process.
- */
- switch ( texUnit->CombineModeRGB ) {
- case GL_REPLACE:
- numColorArgs = 1;
- break;
- case GL_MODULATE:
- case GL_ADD:
- case GL_ADD_SIGNED_EXT:
- case GL_DOT3_RGB_EXT:
- case GL_DOT3_RGBA_EXT:
- numColorArgs = 2;
- break;
- case GL_INTERPOLATE_EXT:
- numColorArgs = 3;
- break;
- default:
- return;
- }
+ texFormat = texImage->TexFormat;
- switch ( texUnit->CombineModeA ) {
- case GL_REPLACE:
- numAlphaArgs = 1;
- break;
- case GL_MODULATE:
- case GL_ADD:
- case GL_ADD_SIGNED_EXT:
- numAlphaArgs = 2;
- break;
- case GL_INTERPOLATE_EXT:
- numAlphaArgs = 3;
- break;
- default:
- return;
- }
+ if ( !_mesa_convert_texsubimage1d( texFormat->IntFormat,
+ xoffset, width, format, type, packing,
+ pixels, t->image[level].data ) ) {
+ /*fprintf( stderr, " *** convert failed!\n" );*/
+ return GL_FALSE;
+ }
- /* Step 1:
- * Extract the color and alpha combine function arguments.
- */
- for ( i = 0 ; i < numColorArgs ; i++ ) {
- op = texUnit->CombineOperandRGB[i] - GL_SRC_COLOR;
- switch ( texUnit->CombineSourceRGB[i] ) {
- case GL_TEXTURE:
- color_arg[i] = radeon_texture_color[op][unit];
- break;
- case GL_CONSTANT_EXT:
- color_arg[i] = radeon_tfactor_color[op];
- break;
- case GL_PRIMARY_COLOR_EXT:
- color_arg[i] = radeon_primary_color[op];
- break;
- case GL_PREVIOUS_EXT:
- color_arg[i] = radeon_previous_color[op];
- break;
- default:
- return;
- }
- }
+ t->dirty_images |= (1 << level);
+ rmesa->new_state |= RADEON_NEW_TEXTURE;
- for ( i = 0 ; i < numAlphaArgs ; i++ ) {
- op = texUnit->CombineOperandA[i] - GL_SRC_ALPHA;
- switch ( texUnit->CombineSourceA[i] ) {
- case GL_TEXTURE:
- alpha_arg[i] = radeon_texture_alpha[op][unit];
- break;
- case GL_CONSTANT_EXT:
- alpha_arg[i] = radeon_tfactor_alpha[op];
- break;
- case GL_PRIMARY_COLOR_EXT:
- alpha_arg[i] = radeon_primary_alpha[op];
- break;
- case GL_PREVIOUS_EXT:
- alpha_arg[i] = radeon_previous_alpha[op];
- break;
- default:
- return;
- }
- }
+ return GL_TRUE;
+}
- /* Step 2:
- * Build up the color and alpha combine functions.
- */
- switch ( texUnit->CombineModeRGB ) {
- case GL_REPLACE:
- color_combine = (RADEON_COLOR_ARG_A_ZERO |
- RADEON_COLOR_ARG_B_ZERO |
- RADEON_BLEND_CTL_ADD |
- RADEON_CLAMP_TX);
- RADEON_COLOR_ARG( 0, C );
- break;
- case GL_MODULATE:
- color_combine = (RADEON_COLOR_ARG_C_ZERO |
- RADEON_BLEND_CTL_ADD |
- RADEON_CLAMP_TX);
- RADEON_COLOR_ARG( 0, A );
- RADEON_COLOR_ARG( 1, B );
- break;
- case GL_ADD:
- color_combine = (RADEON_COLOR_ARG_B_ZERO |
- RADEON_COMP_ARG_B |
- RADEON_BLEND_CTL_ADD |
- RADEON_CLAMP_TX);
- RADEON_COLOR_ARG( 0, A );
- RADEON_COLOR_ARG( 1, C );
- break;
- case GL_ADD_SIGNED_EXT:
- color_combine = (RADEON_COLOR_ARG_B_ZERO |
- RADEON_COMP_ARG_B |
- RADEON_BLEND_CTL_ADDSIGNED |
- RADEON_CLAMP_TX);
- RADEON_COLOR_ARG( 0, A );
- RADEON_COLOR_ARG( 1, C );
- break;
- case GL_INTERPOLATE_EXT:
- color_combine = (RADEON_BLEND_CTL_BLEND |
- RADEON_CLAMP_TX);
- RADEON_COLOR_ARG( 0, B );
- RADEON_COLOR_ARG( 1, A );
- RADEON_COLOR_ARG( 2, C );
- break;
- case GL_DOT3_RGB_EXT:
- case GL_DOT3_RGBA_EXT:
- color_combine = (RADEON_COLOR_ARG_C_ZERO |
- RADEON_BLEND_CTL_DOT3 |
- RADEON_CLAMP_TX);
- RADEON_COLOR_ARG( 0, A );
- RADEON_COLOR_ARG( 1, B );
- break;
- default:
- return;
- }
+static GLboolean
+radeonDDTexSubImage2D( GLcontext *ctx, GLenum target, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ radeonTexObjPtr t = (radeonTexObjPtr)texObj->DriverData;
+ const struct gl_texture_format *texFormat;
- switch ( texUnit->CombineModeA ) {
- case GL_REPLACE:
- alpha_combine = (RADEON_ALPHA_ARG_A_ZERO |
- RADEON_ALPHA_ARG_B_ZERO |
- RADEON_BLEND_CTL_ADD |
- RADEON_CLAMP_TX);
- RADEON_ALPHA_ARG( 0, C );
- break;
- case GL_MODULATE:
- alpha_combine = (RADEON_ALPHA_ARG_C_ZERO |
- RADEON_BLEND_CTL_ADD |
- RADEON_CLAMP_TX);
- RADEON_ALPHA_ARG( 0, A );
- RADEON_ALPHA_ARG( 1, B );
- break;
- case GL_ADD:
- alpha_combine = (RADEON_ALPHA_ARG_B_ZERO |
- RADEON_COMP_ARG_B |
- RADEON_BLEND_CTL_ADD |
- RADEON_CLAMP_TX);
- RADEON_ALPHA_ARG( 0, A );
- RADEON_ALPHA_ARG( 1, C );
- break;
- case GL_ADD_SIGNED_EXT:
- alpha_combine = (RADEON_ALPHA_ARG_B_ZERO |
- RADEON_COMP_ARG_B |
- RADEON_BLEND_CTL_ADDSIGNED |
- RADEON_CLAMP_TX);
- RADEON_ALPHA_ARG( 0, A );
- RADEON_ALPHA_ARG( 1, C );
- break;
- case GL_INTERPOLATE_EXT:
- alpha_combine = (RADEON_BLEND_CTL_BLEND |
- RADEON_CLAMP_TX);
- RADEON_ALPHA_ARG( 0, B );
- RADEON_ALPHA_ARG( 1, A );
- RADEON_ALPHA_ARG( 2, C );
- break;
- default:
- return;
- }
+ if ( target != GL_TEXTURE_2D )
+ return GL_FALSE;
- if ( texUnit->CombineModeRGB == GL_DOT3_RGB_EXT ) {
- alpha_combine |= RADEON_DOT_ALPHA_DONT_REPLICATE;
- }
+ /* FIXME: Can this ever be NULL???
+ */
+ ASSERT( t );
- /* Step 3:
- * Apply the scale factor. The EXT extension has a somewhat
- * unnecessary restriction that the scale must be 4x. The ARB
- * extension will likely drop this and we can just apply the
- * scale factors regardless.
- */
- if ( texUnit->CombineModeRGB != GL_DOT3_RGB_EXT &&
- texUnit->CombineModeRGB != GL_DOT3_RGBA_EXT ) {
- color_combine |= (texUnit->CombineScaleShiftRGB << 21);
- alpha_combine |= (texUnit->CombineScaleShiftA << 21);
- } else {
- color_combine |= RADEON_SCALE_4X;
- alpha_combine |= RADEON_SCALE_4X;
- }
+ if ( t->bound ) {
+ FLUSH_VB( ctx, "radeonDDTexSubImage2D" );
+ FLUSH_BATCH( rmesa );
+ }
- /* All done!
- */
- break;
+ texFormat = texImage->TexFormat;
- default:
- return;
+ if ( !_mesa_convert_texsubimage2d( texFormat->IntFormat,
+ xoffset, yoffset, width, height,
+ texImage->Width, format, type, packing,
+ pixels, t->image[level].data ) ) {
+ /*fprintf( stderr, " *** convert failed!\n" );*/
+ return GL_FALSE;
}
- rmesa->color_combine[source] = color_combine;
- rmesa->alpha_combine[source] = alpha_combine;
+ t->dirty_images |= (1 << level);
+ rmesa->new_state |= RADEON_NEW_TEXTURE;
+
+ return GL_TRUE;
}
-static void radeonUpdateTextureObject( GLcontext *ctx, int unit )
+/* GH: This is undoubtedly broken...
+ */
+static GLboolean
+radeonDDTexSubImage3D( GLcontext *ctx, GLenum target, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLint depth,
+ GLenum format, GLenum type,
+ const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage )
{
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- int source = rmesa->tmu_source[unit];
- struct gl_texture_object *tObj;
- radeonTexObjPtr t;
- GLuint enabled;
-
- if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) {
- fprintf( stderr, "%s( %p, %d )\n",
- __FUNCTION__, ctx, unit );
- }
+ radeonTexObjPtr t = (radeonTexObjPtr)texObj->DriverData;
+ const struct gl_texture_format *texFormat;
- enabled = (ctx->Texture.ReallyEnabled >> (source * 4)) & TEXTURE0_ANY;
- if ( enabled != TEXTURE0_2D && enabled != TEXTURE0_1D ) {
- if ( enabled )
- rmesa->Fallback |= RADEON_FALLBACK_TEXTURE;
- return;
- }
+ if ( target != GL_TEXTURE_3D )
+ return GL_FALSE;
- /* Only update the hardware texture state if the texture is current,
- * complete and enabled.
+ /* FIXME: Can this ever be NULL???
*/
- tObj = ctx->Texture.Unit[source].Current;
- if ( !tObj || !tObj->Complete )
- return;
+ ASSERT( t );
- if ( ( tObj != ctx->Texture.Unit[source].CurrentD[2] ) &&
- ( tObj != ctx->Texture.Unit[source].CurrentD[1] ) )
- return;
-
- if ( !tObj->DriverData ) {
- /* If this is the first time the texture has been used, then create
- * a new texture object for it.
- */
- radeonCreateTexObj( rmesa, tObj );
-
- if ( !tObj->DriverData ) {
- /* Can't create a texture object... */
- fprintf( stderr, "%s: texture object creation failed!\n",
- __FUNCTION__ );
- rmesa->Fallback |= RADEON_FALLBACK_TEXTURE;
- return;
- }
- }
-
- /* We definately have a valid texture now */
- t = tObj->DriverData;
-
- /* Force the texture unit state to be loaded into the hardware */
- rmesa->dirty |= RADEON_UPLOAD_CONTEXT | (RADEON_UPLOAD_TEX0 << unit);
+ if ( t->bound )
+ FLUSH_BATCH( rmesa );
- /* Force any texture images to be loaded into the hardware */
- if ( t->dirty_images )
- rmesa->dirty |= (RADEON_UPLOAD_TEX0IMAGES << unit);
+ texFormat = texImage->TexFormat;
- /* Bind to the given texture unit */
- rmesa->CurrentTexObj[unit] = t;
- t->bound = unit + 1;
+ if ( !_mesa_convert_texsubimage3d( texFormat->IntFormat,
+ xoffset, yoffset, zoffset,
+ width, height, depth,
+ texImage->Width, texImage->Height,
+ format, type, packing,
+ pixels, t->image[level].data ) ) {
+ /*fprintf( stderr, " *** convert failed!\n" );*/
+ return GL_FALSE;
+ }
- if ( t->memBlock )
- radeonUpdateTexLRU( rmesa, t );
+ t->dirty_images |= (1 << level);
+ rmesa->new_state |= RADEON_NEW_TEXTURE;
- switch ( unit ) {
- case 0:
- rmesa->setup.pp_cntl |= (RADEON_TEX_0_ENABLE |
- RADEON_TEX_BLEND_0_ENABLE);
- break;
- case 1:
- rmesa->setup.pp_cntl |= (RADEON_TEX_1_ENABLE |
- RADEON_TEX_BLEND_1_ENABLE);
- break;
- }
+ return GL_TRUE;
}
-void radeonUpdateTextureState( GLcontext *ctx )
-{
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
-
- if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) {
- fprintf( stderr, "%s( %p ) en=0x%x\n",
- __FUNCTION__, ctx, ctx->Texture.ReallyEnabled );
- }
- /* Clear any texturing fallbacks */
- rmesa->Fallback &= ~RADEON_FALLBACK_TEXTURE;
+/* ================================================================
+ * DEPRECATED...
+ */
- /* Unbind any currently bound textures */
- if ( rmesa->CurrentTexObj[0] ) rmesa->CurrentTexObj[0]->bound = 0;
- if ( rmesa->CurrentTexObj[1] ) rmesa->CurrentTexObj[1]->bound = 0;
- rmesa->CurrentTexObj[0] = NULL;
- rmesa->CurrentTexObj[1] = NULL;
+static GLvoid *radeonDDGetTexImage( GLcontext *ctx, GLenum target, GLint level,
+ const struct gl_texture_object *texObj,
+ GLenum *formatOut, GLenum *typeOut,
+ GLboolean *freeImageOut )
+{
+ const struct gl_texture_image *texImage = texObj->Image[level];
+ const struct gl_texture_format *texFormat = texImage->TexFormat;
+ radeonTexObjPtr t = (radeonTexObjPtr)texObj->DriverData;
+ GLubyte *data;
- if ( ctx->Enabled & (TEXTURE0_3D|TEXTURE1_3D) )
- rmesa->Fallback |= RADEON_FALLBACK_TEXTURE;
+ if ( !t || !t->image[level].data )
+ return NULL;
- /* Disable all texturing until it is known to be good */
- rmesa->setup.pp_cntl &= ~(RADEON_TEX_ENABLE_MASK |
- RADEON_TEX_BLEND_ENABLE_MASK);
+ data = (GLubyte *) MALLOC( texImage->Width * texImage->Height * 4 );
+ if ( !data )
+ return NULL;
- radeonUpdateTextureObject( ctx, 0 );
- radeonUpdateTextureEnv( ctx, 0 );
+ if ( 0 )
+ fprintf( stderr, " in=%d out=%s\n",
+ texFormat->IntFormat,
+ gl_lookup_enum_by_nr( texImage->Format ) );
- if ( rmesa->multitex ) {
- radeonUpdateTextureObject( ctx, 1 );
- radeonUpdateTextureEnv( ctx, 1 );
+ switch ( target ) {
+ case GL_TEXTURE_1D:
+ _mesa_unconvert_teximage1d( texFormat->IntFormat, texImage->Format,
+ texImage->Width,
+ t->image[level].data, data );
+ break;
+ case GL_TEXTURE_2D:
+ _mesa_unconvert_teximage2d( texFormat->IntFormat, texImage->Format,
+ texImage->Width, texImage->Height,
+ t->image[level].data, data );
+ break;
+ default:
+ return NULL;
}
- rmesa->dirty |= RADEON_UPLOAD_CONTEXT;
+ *formatOut = texImage->Format;
+ *typeOut = GL_UNSIGNED_BYTE;
+ *freeImageOut = GL_TRUE;
+
+ return data;
}
/* ================================================================
- * DD interface texturing functions
- *
- * FIXME: Many of these are deprecated -- we should move to the new
- * single-copy texture interface.
+ * Texture state callbacks
*/
+
#define SCALED_FLOAT_TO_BYTE( x, scale ) \
((((GLint)((256.0F / scale) * (x))) - 1) / 2)
@@ -2067,79 +784,6 @@ static void radeonDDTexEnv( GLcontext *ctx, GLenum target,
}
}
-static void radeonDDTexImage( GLcontext *ctx, GLenum target,
- struct gl_texture_object *tObj, GLint level,
- GLint internalFormat,
- const struct gl_texture_image *image )
-{
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- radeonTexObjPtr t;
-
- if ( RADEON_DEBUG & DEBUG_VERBOSE_API )
- fprintf( stderr, "%s( %p, level %d )\n", __FUNCTION__, tObj, level );
-
- if ( ( target != GL_TEXTURE_2D ) &&
- ( target != GL_TEXTURE_1D ) )
- return;
-
- if ( level >= RADEON_MAX_TEXTURE_LEVELS )
- return;
-
- t = (radeonTexObjPtr)tObj->DriverData;
- if ( t ) {
- if ( t->bound ) FLUSH_BATCH( rmesa );
-
- /* Destroy the old texture, and upload a new one. The actual
- * uploading of the texture image occurs in the UploadSubImage
- * function.
- */
- radeonDestroyTexObj( rmesa, t );
- rmesa->new_state |= RADEON_NEW_TEXTURE;
- }
-}
-
-static void radeonDDTexSubImage( GLcontext *ctx, GLenum target,
- struct gl_texture_object *tObj, GLint level,
- GLint xoffset, GLint yoffset,
- GLsizei width, GLsizei height,
- GLint internalFormat,
- const struct gl_texture_image *image )
-{
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- radeonTexObjPtr t;
-
- if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) {
- fprintf( stderr, "%s( %p, level %d ) size: %d,%d of %d,%d\n",
- __FUNCTION__, tObj, level, width, height,
- image->Width, image->Height );
- }
-
- if ( ( target != GL_TEXTURE_2D ) &&
- ( target != GL_TEXTURE_1D ) )
- return;
-
- if ( level >= RADEON_MAX_TEXTURE_LEVELS )
- return;
-
- t = (radeonTexObjPtr)tObj->DriverData;
- if ( t ) {
- if ( t->bound ) FLUSH_BATCH( rmesa );
-
-#if 0
- /* FIXME: Only upload textures if we already have space in the heap.
- */
- LOCK_HARDWARE( rmesa );
- radeonUploadSubImage( rmesa, t, level,
- xoffset, yoffset, width, height );
- UNLOCK_HARDWARE( rmesa );
-#else
- radeonDestroyTexObj( rmesa, t );
-#endif
- /* Update the context state */
- rmesa->new_state |= RADEON_NEW_TEXTURE;
- }
-}
-
static void radeonDDTexParameter( GLcontext *ctx, GLenum target,
struct gl_texture_object *tObj,
GLenum pname, const GLfloat *params )
@@ -2156,7 +800,7 @@ static void radeonDDTexParameter( GLcontext *ctx, GLenum target,
* created with current state before it is used, so we don't have
* to do anything now.
*/
- if ( !t || !t->bound )
+ if ( !t )
return;
if ( ( target != GL_TEXTURE_2D ) &&
@@ -2192,25 +836,38 @@ static void radeonDDBindTexture( GLcontext *ctx, GLenum target,
struct gl_texture_object *tObj )
{
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- GLint unit = ctx->Texture.CurrentUnit;
+ radeonTexObjPtr t = (radeonTexObjPtr) tObj->DriverData;
+ GLuint unit = ctx->Texture.CurrentUnit;
if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) {
fprintf( stderr, "%s( %p ) unit=%d\n",
- __FUNCTION__, tObj, ctx->Texture.CurrentUnit );
+ __FUNCTION__, tObj, unit );
}
FLUSH_BATCH( rmesa );
+ if ( !t ) {
+ t = radeonAllocTexObj( tObj );
+ tObj->DriverData = t;
+ }
+
+ /* Unbind a currently bound texture.
+ */
if ( rmesa->CurrentTexObj[unit] ) {
- rmesa->CurrentTexObj[unit]->bound = 0;
+ rmesa->CurrentTexObj[unit]->bound &= ~(unit + 1);
rmesa->CurrentTexObj[unit] = NULL;
}
+ /* Bind to the given texture unit.
+ */
+ rmesa->CurrentTexObj[unit] = t;
+ t->bound |= unit + 1;
+
rmesa->new_state |= RADEON_NEW_TEXTURE;
}
static void radeonDDDeleteTexture( GLcontext *ctx,
- struct gl_texture_object *tObj )
+ struct gl_texture_object *tObj )
{
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
radeonTexObjPtr t = (radeonTexObjPtr)tObj->DriverData;
@@ -2218,8 +875,8 @@ static void radeonDDDeleteTexture( GLcontext *ctx,
if ( t ) {
if ( t->bound ) {
FLUSH_BATCH( rmesa );
-
- rmesa->CurrentTexObj[t->bound-1] = 0;
+ if ( t->bound & TEX_0 ) rmesa->CurrentTexObj[0] = NULL;
+ if ( t->bound & TEX_1 ) rmesa->CurrentTexObj[1] = NULL;
rmesa->new_state |= RADEON_NEW_TEXTURE;
}
@@ -2240,14 +897,19 @@ static GLboolean radeonDDIsTextureResident( GLcontext *ctx,
void radeonDDInitTextureFuncs( GLcontext *ctx )
{
+ ctx->Driver.TexImage1D = radeonDDTexImage1D;
+ ctx->Driver.TexImage2D = radeonDDTexImage2D;
+ ctx->Driver.TexImage3D = NULL /*radeonDDTexImage3D*/;
+ ctx->Driver.TexSubImage1D = radeonDDTexSubImage1D;
+ ctx->Driver.TexSubImage2D = radeonDDTexSubImage2D;
+ ctx->Driver.TexSubImage3D = NULL /*radeonDDTexSubImage3D*/;
+ ctx->Driver.GetTexImage = radeonDDGetTexImage;
ctx->Driver.TexEnv = radeonDDTexEnv;
- ctx->Driver.TexImage = radeonDDTexImage;
- ctx->Driver.TexSubImage = radeonDDTexSubImage;
ctx->Driver.TexParameter = radeonDDTexParameter;
ctx->Driver.BindTexture = radeonDDBindTexture;
ctx->Driver.DeleteTexture = radeonDDDeleteTexture;
- ctx->Driver.UpdateTexturePalette = NULL;
- ctx->Driver.ActiveTexture = NULL;
ctx->Driver.IsTextureResident = radeonDDIsTextureResident;
ctx->Driver.PrioritizeTexture = NULL;
+ ctx->Driver.ActiveTexture = NULL;
+ ctx->Driver.UpdateTexturePalette = NULL;
}
diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.h
index 6bf967761..967048dd1 100644
--- a/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.h
+++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.h
@@ -45,9 +45,11 @@ extern int radeonUploadTexImages( radeonContextPtr rmesa, radeonTexObjPtr t );
extern void radeonAgeTextures( radeonContextPtr rmesa, int heap );
extern void radeonDestroyTexObj( radeonContextPtr rmesa, radeonTexObjPtr t );
+extern void radeonSwapOutTexObj( radeonContextPtr rmesa, radeonTexObjPtr t );
extern void radeonPrintLocalLRU( radeonContextPtr rmesa, int heap );
extern void radeonPrintGlobalLRU( radeonContextPtr rmesa, int heap );
+extern void radeonUpdateTexLRU(radeonContextPtr rmesa, radeonTexObjPtr t );
extern void radeonDDInitTextureFuncs( GLcontext *ctx );
diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_texmem.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_texmem.c
new file mode 100644
index 000000000..52c202bee
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_texmem.c
@@ -0,0 +1,509 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
+ VA Linux Systems Inc., Fremont, California.
+
+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
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, 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 (including the next
+paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS 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.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <martin@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ *
+ */
+
+#include "radeon_context.h"
+#include "radeon_state.h"
+#include "radeon_ioctl.h"
+#include "radeon_vb.h"
+#include "radeon_tex.h"
+
+#include "mmath.h"
+#include "simple_list.h"
+#include "enums.h"
+#include "mem.h"
+
+
+/* Destroy hardware state associated with texture `t'.
+ */
+void radeonDestroyTexObj( radeonContextPtr rmesa, radeonTexObjPtr t )
+{
+#if ENABLE_PERF_BOXES
+ /* Bump the performace counter */
+ rmesa->c_textureSwaps++;
+#endif
+ if ( !t ) return;
+
+ if ( t->memBlock ) {
+ mmFreeMem( t->memBlock );
+ t->memBlock = NULL;
+ }
+
+ if ( t->tObj )
+ t->tObj->DriverData = NULL;
+
+ if ( t->bound & TEX_0 ) rmesa->CurrentTexObj[0] = NULL;
+ if ( t->bound & TEX_1 ) rmesa->CurrentTexObj[1] = NULL;
+
+ remove_from_list( t );
+ FREE( t );
+}
+
+/* Keep track of swapped out texture objects.
+ */
+void radeonSwapOutTexObj( radeonContextPtr rmesa, radeonTexObjPtr t )
+{
+#if ENABLE_PERF_BOXES
+ /* Bump the performace counter */
+ rmesa->c_textureSwaps++;
+#endif
+ if ( t->memBlock ) {
+ mmFreeMem( t->memBlock );
+ t->memBlock = NULL;
+ }
+
+ t->dirty_images = ~0;
+ move_to_tail( &rmesa->SwappedOut, t );
+}
+
+/* Print out debugging information about texture LRU.
+ */
+void radeonPrintLocalLRU( radeonContextPtr rmesa, int heap )
+{
+ radeonTexObjPtr t;
+ int sz = 1 << (rmesa->radeonScreen->logTexGranularity[heap]);
+
+ fprintf( stderr, "\nLocal LRU, heap %d:\n", heap );
+
+ foreach ( t, &rmesa->TexObjList[heap] ) {
+ if (!t->tObj) {
+ fprintf( stderr, "Placeholder %d at 0x%x sz 0x%x\n",
+ t->memBlock->ofs / sz,
+ t->memBlock->ofs,
+ t->memBlock->size );
+ } else {
+ fprintf( stderr, "Texture (bound %d) at 0x%x sz 0x%x\n",
+ t->bound,
+ t->memBlock->ofs,
+ t->memBlock->size );
+ }
+ }
+
+ fprintf( stderr, "\n" );
+}
+
+void radeonPrintGlobalLRU( radeonContextPtr rmesa, int heap )
+{
+ radeon_tex_region_t *list = rmesa->sarea->texList[heap];
+ int i, j;
+
+ fprintf( stderr, "\nGlobal LRU, heap %d list %p:\n", heap, list );
+
+ for ( i = 0, j = RADEON_NR_TEX_REGIONS ; i < RADEON_NR_TEX_REGIONS ; i++ ) {
+ fprintf( stderr, "list[%d] age %d next %d prev %d\n",
+ j, list[j].age, list[j].next, list[j].prev );
+ j = list[j].next;
+ if ( j == RADEON_NR_TEX_REGIONS ) break;
+ }
+
+ if ( j != RADEON_NR_TEX_REGIONS ) {
+ fprintf( stderr, "Loop detected in global LRU\n" );
+ for ( i = 0 ; i < RADEON_NR_TEX_REGIONS ; i++ ) {
+ fprintf( stderr, "list[%d] age %d next %d prev %d\n",
+ i, list[i].age, list[i].next, list[i].prev );
+ }
+ }
+
+ fprintf( stderr, "\n" );
+}
+
+/* Reset the global texture LRU.
+ */
+static void radeonResetGlobalLRU( radeonContextPtr rmesa, int heap )
+{
+ radeon_tex_region_t *list = rmesa->sarea->texList[heap];
+ int sz = 1 << rmesa->radeonScreen->logTexGranularity[heap];
+ int i;
+
+ /*
+ * (Re)initialize the global circular LRU list. The last element in
+ * the array (RADEON_NR_TEX_REGIONS) is the sentinal. Keeping it at
+ * the end of the array allows it to be addressed rationally when
+ * looking up objects at a particular location in texture memory.
+ */
+ for ( i = 0 ; (i+1) * sz <= rmesa->radeonScreen->texSize[heap] ; i++ ) {
+ list[i].prev = i-1;
+ list[i].next = i+1;
+ list[i].age = 0;
+ }
+
+ i--;
+ list[0].prev = RADEON_NR_TEX_REGIONS;
+ list[i].prev = i-1;
+ list[i].next = RADEON_NR_TEX_REGIONS;
+ list[RADEON_NR_TEX_REGIONS].prev = i;
+ list[RADEON_NR_TEX_REGIONS].next = 0;
+ rmesa->sarea->texAge[heap] = 0;
+}
+
+/* Update the local and glock texture LRUs.
+ */
+void radeonUpdateTexLRU(radeonContextPtr rmesa, radeonTexObjPtr t )
+{
+ int heap = t->heap;
+ radeon_tex_region_t *list = rmesa->sarea->texList[heap];
+ int sz = rmesa->radeonScreen->logTexGranularity[heap];
+ int start = t->memBlock->ofs >> sz;
+ int end = (t->memBlock->ofs + t->memBlock->size-1) >> sz;
+ int i;
+
+ rmesa->lastTexAge[heap] = ++rmesa->sarea->texAge[heap];
+
+ if ( !t->memBlock ) {
+ fprintf( stderr, "no memblock\n\n" );
+ return;
+ }
+
+ /* Update our local LRU */
+ move_to_head( &rmesa->TexObjList[heap], t );
+
+ /* Update the global LRU */
+ for ( i = start ; i <= end ; i++ ) {
+ list[i].in_use = 1;
+ list[i].age = rmesa->lastTexAge[heap];
+
+ /* remove_from_list(i) */
+ list[(CARD32)list[i].next].prev = list[i].prev;
+ list[(CARD32)list[i].prev].next = list[i].next;
+
+ /* insert_at_head(list, i) */
+ list[i].prev = RADEON_NR_TEX_REGIONS;
+ list[i].next = list[RADEON_NR_TEX_REGIONS].next;
+ list[(CARD32)list[RADEON_NR_TEX_REGIONS].next].prev = i;
+ list[RADEON_NR_TEX_REGIONS].next = i;
+ }
+
+ if ( 0 ) {
+ radeonPrintGlobalLRU( rmesa, t->heap );
+ radeonPrintLocalLRU( rmesa, t->heap );
+ }
+}
+
+/* Update our notion of what textures have been changed since we last
+ * held the lock. This pertains to both our local textures and the
+ * textures belonging to other clients. Keep track of other client's
+ * textures by pushing a placeholder texture onto the LRU list -- these
+ * are denoted by (tObj == NULL).
+ */
+static void radeonTexturesGone( radeonContextPtr rmesa, int heap,
+ int offset, int size, int in_use )
+{
+ radeonTexObjPtr t, tmp;
+
+ foreach_s ( t, tmp, &rmesa->TexObjList[heap] ) {
+ if ( t->memBlock->ofs >= offset + size ||
+ t->memBlock->ofs + t->memBlock->size <= offset )
+ continue;
+
+ /* It overlaps - kick it out. Need to hold onto the currently
+ * bound objects, however.
+ */
+ if ( t->bound ) {
+ radeonSwapOutTexObj( rmesa, t );
+ } else {
+ radeonDestroyTexObj( rmesa, t );
+ }
+ }
+
+ if ( in_use ) {
+ t = (radeonTexObjPtr) CALLOC( sizeof(*t) );
+ if ( !t ) return;
+
+ t->memBlock = mmAllocMem( rmesa->texHeap[heap], size, 0, offset );
+ if ( !t->memBlock ) {
+ fprintf( stderr, "Couldn't alloc placeholder sz %x ofs %x\n",
+ (int)size, (int)offset );
+ mmDumpMemInfo( rmesa->texHeap[heap] );
+ return;
+ }
+ insert_at_head( &rmesa->TexObjList[heap], t );
+ }
+}
+
+/* Update our client's shared texture state. If another client has
+ * modified a region in which we have textures, then we need to figure
+ * out which of our textures has been removed, and update our global
+ * LRU.
+ */
+void radeonAgeTextures( radeonContextPtr rmesa, int heap )
+{
+ RADEONSAREAPrivPtr sarea = rmesa->sarea;
+
+ if ( sarea->texAge[heap] != rmesa->lastTexAge[heap] ) {
+ int sz = 1 << rmesa->radeonScreen->logTexGranularity[heap];
+ int nr = 0;
+ int idx;
+
+ for ( idx = sarea->texList[heap][RADEON_NR_TEX_REGIONS].prev ;
+ idx != RADEON_NR_TEX_REGIONS && nr < RADEON_NR_TEX_REGIONS ;
+ idx = sarea->texList[heap][idx].prev, nr++ )
+ {
+ /* If switching texturing schemes, then the SAREA might not
+ * have been properly cleared, so we need to reset the
+ * global texture LRU.
+ */
+ if ( idx * sz > rmesa->radeonScreen->texSize[heap] ) {
+ nr = RADEON_NR_TEX_REGIONS;
+ break;
+ }
+
+ if ( sarea->texList[heap][idx].age > rmesa->lastTexAge[heap] ) {
+ radeonTexturesGone( rmesa, heap, idx * sz, sz,
+ sarea->texList[heap][idx].in_use );
+ }
+ }
+
+ if ( nr == RADEON_NR_TEX_REGIONS ) {
+ radeonTexturesGone( rmesa, heap, 0,
+ rmesa->radeonScreen->texSize[heap], 0 );
+ radeonResetGlobalLRU( rmesa, heap );
+ }
+
+ rmesa->dirty |= (RADEON_UPLOAD_CONTEXT |
+ RADEON_UPLOAD_TEX0IMAGES |
+ RADEON_UPLOAD_TEX1IMAGES);
+ rmesa->lastTexAge[heap] = sarea->texAge[heap];
+ }
+}
+
+
+/* ================================================================
+ * Texture image uploads
+ */
+
+/* Upload the texture image associated with texture `t' at level `level'
+ * at the address relative to `start'.
+ */
+static void radeonUploadSubImage( radeonContextPtr rmesa,
+ radeonTexObjPtr t, GLint level,
+ GLint x, GLint y, GLint width, GLint height )
+{
+ struct gl_texture_image *texImage;
+ const struct gl_texture_format *texFormat;
+ GLint texelsPerDword = 0;
+ GLint imageX, imageY, imageWidth, imageHeight;
+ GLint blitX, blitY, blitWidth, blitHeight;
+ GLint imageRows, blitRows;
+ GLint remaining;
+ GLint format, dwords;
+ CARD32 pitch, offset;
+ drmBufPtr buffer;
+ CARD32 *dst;
+ GLint ret;
+
+ /* Ensure we have a valid texture to upload */
+ texImage = t->tObj->Image[level];
+ if ( !texImage )
+ return;
+
+ texFormat = texImage->TexFormat;
+
+ switch ( texFormat->TexelBytes ) {
+ case 1:
+ texelsPerDword = 4;
+ break;
+ case 2:
+ texelsPerDword = 2;
+ break;
+ case 4:
+ texelsPerDword = 1;
+ break;
+ }
+
+ format = t->pp_txformat & RADEON_TXFORMAT_FORMAT_MASK;
+
+ imageX = 0;
+ imageY = 0;
+ imageWidth = texImage->Width;
+ imageHeight = texImage->Height;
+
+ blitX = t->image[level].x;
+ blitY = t->image[level].y;
+ blitWidth = t->image[level].width;
+ blitHeight = t->image[level].height;
+
+ /* dwords = t->image[level].dwords; */
+ offset = t->bufAddr;
+ pitch = (t->image[0].width * texFormat->TexelBytes) / 64;
+
+ if ( RADEON_DEBUG & DEBUG_VERBOSE_MSG ) {
+ fprintf( stderr, " upload image: %d,%d at %d,%d\n",
+ imageWidth, imageHeight, imageX, imageY );
+ fprintf( stderr, " upload blit: %d,%d at %d,%d\n",
+ blitWidth, blitHeight, blitX, blitY );
+ fprintf( stderr, " blit ofs: 0x%07x pitch: 0x%x "
+ "level: %d format: %x\n",
+ (GLuint)offset, (GLuint)pitch, level, format );
+ }
+
+ ret = drmRadeonLoadTexture( rmesa->driFd, offset, pitch, format,
+ imageWidth, imageHeight, &t->image[level] );
+
+ if ( ret ) {
+ UNLOCK_HARDWARE( rmesa );
+ fprintf( stderr, "drmRadeonTextureBlit: return = %d\n", ret );
+ exit( 1 );
+ }
+
+ rmesa->new_state |= RADEON_NEW_CONTEXT;
+ rmesa->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_MASKS;
+}
+
+/* Upload the texture images associated with texture `t'. This might
+ * require removing our own and/or other client's texture objects to
+ * make room for these images.
+ */
+/* NOTE: This function is only called while holding the hardware lock */
+int radeonUploadTexImages( radeonContextPtr rmesa, radeonTexObjPtr t )
+{
+ int i;
+ int heap;
+
+ if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) {
+ fprintf( stderr, "%s( %p, %p )\n",
+ __FUNCTION__, rmesa->glCtx, t->tObj );
+ }
+
+ if ( !t )
+ return 0;
+
+ /* Choose the heap appropriately */
+ heap = t->heap = RADEON_CARD_HEAP;
+#if 0
+ if ( !rmesa->radeonScreen->IsPCI &&
+ t->totalSize > rmesa->radeonScreen->texSize[heap] ) {
+ heap = t->heap = RADEON_AGP_HEAP;
+ }
+#endif
+
+ /* Do we need to eject LRU texture objects? */
+ if ( !t->memBlock ) {
+ /* Allocate a memory block on a 4k boundary (1<<12 == 4096) */
+ t->memBlock = mmAllocMem( rmesa->texHeap[heap],
+ t->totalSize, 12, 0 );
+
+#if 0
+ /* Try AGP before kicking anything out of local mem */
+ if ( !t->memBlock && heap == RADEON_CARD_HEAP ) {
+ t->memBlock = mmAllocMem( rmesa->texHeap[RADEON_AGP_HEAP],
+ t->totalSize, 12, 0 );
+
+ if ( t->memBlock )
+ heap = t->heap = RADEON_AGP_HEAP;
+ }
+#endif
+
+ /* Kick out textures until the requested texture fits */
+ while ( !t->memBlock ) {
+ if ( rmesa->TexObjList[heap].prev->bound ) {
+ fprintf( stderr,
+ "radeonUploadTexImages: ran into bound texture\n" );
+ return -1;
+ }
+ if ( rmesa->TexObjList[heap].prev ==
+ &rmesa->TexObjList[heap] ) {
+ if ( rmesa->radeonScreen->IsPCI ) {
+ fprintf( stderr, "radeonUploadTexImages: upload texture "
+ "failure on local texture heaps, sz=%d\n",
+ t->totalSize );
+ return -1;
+#if 0
+ } else if ( heap == RADEON_CARD_HEAP ) {
+ heap = t->heap = RADEON_AGP_HEAP;
+ continue;
+#endif
+ } else {
+ fprintf( stderr, "radeonUploadTexImages: upload texture "
+ "failure on both local and AGP texture heaps, "
+ "sz=%d\n",
+ t->totalSize );
+ return -1;
+ }
+ }
+
+ radeonDestroyTexObj( rmesa, rmesa->TexObjList[heap].prev );
+
+ t->memBlock = mmAllocMem( rmesa->texHeap[heap],
+ t->totalSize, 12, 0 );
+ }
+
+ /* Set the base offset of the texture image */
+ t->bufAddr = rmesa->radeonScreen->texOffset[heap] + t->memBlock->ofs;
+
+ t->pp_txoffset = t->bufAddr;
+#if 0
+ /* Fix AGP texture offsets */
+ if ( heap == RADEON_AGP_HEAP ) {
+ t->setup.pp_tx_offset += RADEON_AGP_TEX_OFFSET +
+ rmesa->radeonScreen->agpTexOffset;
+ }
+#endif
+
+ /* Force loading the new state into the hardware */
+ switch ( t->bound ) {
+ case 1:
+ rmesa->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_TEX0;
+ break;
+
+ case 2:
+ rmesa->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_TEX1;
+ break;
+
+ default:
+ return -1;
+ }
+ }
+
+ /* Let the world know we've used this memory recently */
+ radeonUpdateTexLRU( rmesa, t );
+
+ /* Upload any images that are new */
+ if ( t->dirty_images ) {
+ int levels = ((t->pp_txfilter & RADEON_MAX_MIP_LEVEL_MASK) >>
+ RADEON_MAX_MIP_LEVEL_SHIFT);
+
+ for ( i = 0 ; i <= levels ; i++ ) {
+ if ( t->dirty_images & (1 << i) ) {
+ radeonUploadSubImage( rmesa, t, i, 0, 0,
+ t->image[i].width, t->image[i].height );
+ }
+ }
+
+ rmesa->dirty |= RADEON_UPLOAD_CONTEXT;
+ }
+
+ t->dirty_images = 0;
+ return 0;
+}
diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_texobj.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_texobj.h
index b63d5c6a7..7cec84e9a 100644
--- a/xc/lib/GL/mesa/src/drv/radeon/radeon_texobj.h
+++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_texobj.h
@@ -40,17 +40,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "radeon_sarea.h"
#include "mm.h"
-/* Handle the Radeon's tightly packed mipmaps and strict offset,
- * pitch rules for blits by assigning each mipmap a set of
- * coordinates that can be used for a hostdata blit.
- */
-typedef struct {
- GLuint x; /* Blit coordinates */
- GLuint y;
- GLuint width; /* Blit dimensions */
- GLuint height;
- GLuint dwords; /* Size of image level */
-} radeonTexImage;
+#define TEX_0 1
+#define TEX_1 2
typedef struct radeon_tex_obj radeonTexObj, *radeonTexObjPtr;
@@ -72,16 +63,15 @@ struct radeon_tex_obj {
GLint bound; /* Texture unit currently bound to */
GLint heap; /* Texture heap currently stored in */
- radeonTexImage image[RADEON_MAX_TEXTURE_LEVELS]; /* Image data for all
- mipmap levels */
+ drmRadeonTexImage image[RADEON_MAX_TEXTURE_LEVELS];
GLint totalSize; /* Total size of the texture
including all mipmap levels */
- GLint texelBytes; /* Number of bytes per texel */
-
- GLboolean hasAlpha;
- radeon_texture_regs_t setup; /* Setup regs for texture */
+ GLuint pp_txfilter; /* Hardware register values */
+ GLuint pp_txformat;
+ GLuint pp_txoffset;
+ GLuint pp_border_color;
};
#endif /* __RADEON_TEXOBJ_H__ */
diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_texstate.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_texstate.c
new file mode 100644
index 000000000..2a076717e
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_texstate.c
@@ -0,0 +1,1103 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
+ VA Linux Systems Inc., Fremont, California.
+
+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
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, 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 (including the next
+paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS 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.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <martin@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ *
+ */
+
+#include "radeon_context.h"
+#include "radeon_state.h"
+#include "radeon_ioctl.h"
+#include "radeon_vb.h"
+#include "radeon_tex.h"
+
+#include "mmath.h"
+#include "simple_list.h"
+#include "enums.h"
+#include "mem.h"
+
+static void radeonSetTexImages( radeonContextPtr rmesa,
+ struct gl_texture_object *tObj )
+{
+ radeonTexObjPtr t = (radeonTexObjPtr)tObj->DriverData;
+ struct gl_texture_image *texImage = tObj->Image[0];
+ const struct gl_texture_format *texFormat = texImage->TexFormat;
+ GLint log2Width, log2Height, log2Size;
+ GLint totalSize;
+ GLint texelsPerDword = 0, blitWidth = 0, blitPitch = 0;
+ GLint x, y, width, height;
+ GLint i;
+
+ /* Calculate dimensions in log domain.
+ */
+ for ( i = 1, log2Height = 0 ; i < texImage->Height ; i *= 2 ) {
+ log2Height++;
+ }
+ for ( i = 1, log2Width = 0 ; i < texImage->Width ; i *= 2 ) {
+ log2Width++;
+ }
+ log2Size = MAX2( log2Width, log2Height );
+
+ /* The Radeon has a 64-byte minimum pitch for all blits. We
+ * calculate the equivalent number of texels to simplify the
+ * calculation of the texture image area.
+ */
+ switch ( texFormat->TexelBytes ) {
+ case 4:
+ texelsPerDword = 1;
+ blitPitch = 16;
+ break;
+ case 2:
+ texelsPerDword = 2;
+ blitPitch = 32;
+ break;
+ case 1:
+ texelsPerDword = 4;
+ blitPitch = 64;
+ break;
+ }
+
+ /* Select the larger of the two widths for our global texture image
+ * coordinate space. As the Radeon has very strict offset rules, we
+ * can't upload mipmaps directly and have to reference their location
+ * from the aligned start of the whole image.
+ */
+ blitWidth = MAX2( texImage->Width, blitPitch );
+
+ /* Calculate mipmap offsets and dimensions.
+ */
+ totalSize = 0;
+ x = 0;
+ y = 0;
+
+ for ( i = 0 ; i <= log2Size ; i++ ) {
+ GLuint size;
+
+ texImage = tObj->Image[i];
+ if ( !texImage )
+ break;
+
+ width = texImage->Width;
+ height = texImage->Height;
+
+ /* Texture images have a minimum pitch of 32 bytes (half of the
+ * 64-byte minimum pitch for blits). For images that have a
+ * width smaller than this, we must pad each texture image
+ * scanline out to this amount.
+ */
+ if ( width < blitPitch / 2 ) {
+ width = blitPitch / 2;
+ }
+
+ size = width * height * texFormat->TexelBytes;
+ totalSize += size;
+ ASSERT( (totalSize & 31) == 0 );
+
+ while ( width < blitWidth && height > 1 ) {
+ width *= 2;
+ height /= 2;
+ }
+
+ t->image[i].x = x;
+ t->image[i].y = y;
+
+ t->image[i].width = width;
+ t->image[i].height = height;
+
+ /* While blits must have a pitch of at least 64 bytes, mipmaps
+ * must be aligned on a 32-byte boundary (just like each texture
+ * image scanline).
+ */
+ if ( width >= blitWidth ) {
+ y += height;
+ } else {
+ x += width;
+ if ( x >= blitWidth ) {
+ x = 0;
+ y++;
+ }
+ }
+
+ if ( 0 ) {
+ fprintf( stderr, "level=%d p=%d %dx%d -> %dx%d at (%d,%d)\n",
+ i, blitWidth, texImage->Width, texImage->Height,
+ t->image[i].width, t->image[i].height,
+ t->image[i].x, t->image[i].y );
+ }
+ }
+
+ /* Align the total size of texture memory block.
+ */
+ t->totalSize = (totalSize + RADEON_OFFSET_MASK) & ~RADEON_OFFSET_MASK;
+
+ /* Hardware state:
+ */
+ t->pp_txfilter &= ~RADEON_MAX_MIP_LEVEL_MASK;
+ t->pp_txfilter |= i << RADEON_MAX_MIP_LEVEL_SHIFT;
+
+ t->pp_txformat &= ~(RADEON_TXFORMAT_WIDTH_MASK |
+ RADEON_TXFORMAT_HEIGHT_MASK);
+ t->pp_txformat |= ((log2Width << RADEON_TXFORMAT_WIDTH_SHIFT) |
+ (log2Height << RADEON_TXFORMAT_HEIGHT_SHIFT));
+}
+
+
+/* ================================================================
+ * Texture combine functions
+ */
+
+#define RADEON_DISABLE 0
+#define RADEON_REPLACE 1
+#define RADEON_MODULATE 2
+#define RADEON_DECAL 3
+#define RADEON_BLEND 4
+#define RADEON_ADD 5
+#define RADEON_MAX_COMBFUNC 6
+
+static GLuint radeon_color_combine[][RADEON_MAX_COMBFUNC] =
+{
+ /* Unit 0:
+ */
+ {
+ /* Disable combiner stage
+ */
+ (RADEON_COLOR_ARG_A_ZERO |
+ RADEON_COLOR_ARG_B_ZERO |
+ RADEON_COLOR_ARG_C_CURRENT_COLOR |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_REPLACE = 0x00802800
+ */
+ (RADEON_COLOR_ARG_A_ZERO |
+ RADEON_COLOR_ARG_B_ZERO |
+ RADEON_COLOR_ARG_C_T0_COLOR |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_MODULATE = 0x00800142
+ */
+ (RADEON_COLOR_ARG_A_CURRENT_COLOR |
+ RADEON_COLOR_ARG_B_T0_COLOR |
+ RADEON_COLOR_ARG_C_ZERO |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_DECAL = 0x008c2d42
+ */
+ (RADEON_COLOR_ARG_A_CURRENT_COLOR |
+ RADEON_COLOR_ARG_B_T0_COLOR |
+ RADEON_COLOR_ARG_C_T0_ALPHA |
+ RADEON_BLEND_CTL_BLEND |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_BLEND = 0x008c2902
+ */
+ (RADEON_COLOR_ARG_A_CURRENT_COLOR |
+ RADEON_COLOR_ARG_B_TFACTOR_COLOR |
+ RADEON_COLOR_ARG_C_T0_COLOR |
+ RADEON_BLEND_CTL_BLEND |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_ADD = 0x00812802
+ */
+ (RADEON_COLOR_ARG_A_CURRENT_COLOR |
+ RADEON_COLOR_ARG_B_ZERO |
+ RADEON_COLOR_ARG_C_T0_COLOR |
+ RADEON_COMP_ARG_B |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+ },
+
+ /* Unit 1:
+ */
+ {
+ /* Disable combiner stage
+ */
+ (RADEON_COLOR_ARG_A_ZERO |
+ RADEON_COLOR_ARG_B_ZERO |
+ RADEON_COLOR_ARG_C_CURRENT_COLOR |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_REPLACE = 0x00803000
+ */
+ (RADEON_COLOR_ARG_A_ZERO |
+ RADEON_COLOR_ARG_B_ZERO |
+ RADEON_COLOR_ARG_C_T1_COLOR |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_MODULATE = 0x00800182
+ */
+ (RADEON_COLOR_ARG_A_CURRENT_COLOR |
+ RADEON_COLOR_ARG_B_T1_COLOR |
+ RADEON_COLOR_ARG_C_ZERO |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_DECAL = 0x008c3582
+ */
+ (RADEON_COLOR_ARG_A_CURRENT_COLOR |
+ RADEON_COLOR_ARG_B_T1_COLOR |
+ RADEON_COLOR_ARG_C_T1_ALPHA |
+ RADEON_BLEND_CTL_BLEND |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_BLEND = 0x008c3102
+ */
+ (RADEON_COLOR_ARG_A_CURRENT_COLOR |
+ RADEON_COLOR_ARG_B_TFACTOR_COLOR |
+ RADEON_COLOR_ARG_C_T1_COLOR |
+ RADEON_BLEND_CTL_BLEND |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_ADD = 0x00813002
+ */
+ (RADEON_COLOR_ARG_A_CURRENT_COLOR |
+ RADEON_COLOR_ARG_B_ZERO |
+ RADEON_COLOR_ARG_C_T1_COLOR |
+ RADEON_COMP_ARG_B |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+ },
+
+ /* Unit 2:
+ */
+ {
+ /* Disable combiner stage
+ */
+ (RADEON_COLOR_ARG_A_ZERO |
+ RADEON_COLOR_ARG_B_ZERO |
+ RADEON_COLOR_ARG_C_CURRENT_COLOR |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_REPLACE = 0x00803800
+ */
+ (RADEON_COLOR_ARG_A_ZERO |
+ RADEON_COLOR_ARG_B_ZERO |
+ RADEON_COLOR_ARG_C_T2_COLOR |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_MODULATE = 0x008001c2
+ */
+ (RADEON_COLOR_ARG_A_CURRENT_COLOR |
+ RADEON_COLOR_ARG_B_T2_COLOR |
+ RADEON_COLOR_ARG_C_ZERO |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_DECAL = 0x008c3dc2
+ */
+ (RADEON_COLOR_ARG_A_CURRENT_COLOR |
+ RADEON_COLOR_ARG_B_T2_COLOR |
+ RADEON_COLOR_ARG_C_T2_ALPHA |
+ RADEON_BLEND_CTL_BLEND |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_BLEND = 0x008c3902
+ */
+ (RADEON_COLOR_ARG_A_CURRENT_COLOR |
+ RADEON_COLOR_ARG_B_TFACTOR_COLOR |
+ RADEON_COLOR_ARG_C_T2_COLOR |
+ RADEON_BLEND_CTL_BLEND |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_ADD = 0x00813802
+ */
+ (RADEON_COLOR_ARG_A_CURRENT_COLOR |
+ RADEON_COLOR_ARG_B_ZERO |
+ RADEON_COLOR_ARG_C_T2_COLOR |
+ RADEON_COMP_ARG_B |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+ }
+};
+
+static GLuint radeon_alpha_combine[][RADEON_MAX_COMBFUNC] =
+{
+ /* Unit 0:
+ */
+ {
+ /* Disable combiner stage
+ */
+ (RADEON_ALPHA_ARG_A_ZERO |
+ RADEON_ALPHA_ARG_B_ZERO |
+ RADEON_ALPHA_ARG_C_CURRENT_ALPHA |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_REPLACE = 0x00800500
+ */
+ (RADEON_ALPHA_ARG_A_ZERO |
+ RADEON_ALPHA_ARG_B_ZERO |
+ RADEON_ALPHA_ARG_C_T0_ALPHA |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_MODULATE = 0x00800051
+ */
+ (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
+ RADEON_ALPHA_ARG_B_T0_ALPHA |
+ RADEON_ALPHA_ARG_C_ZERO |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_DECAL = 0x00800100
+ */
+ (RADEON_ALPHA_ARG_A_ZERO |
+ RADEON_ALPHA_ARG_B_ZERO |
+ RADEON_ALPHA_ARG_C_CURRENT_ALPHA |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_BLEND = 0x00800051
+ */
+ (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
+ RADEON_ALPHA_ARG_B_TFACTOR_ALPHA |
+ RADEON_ALPHA_ARG_C_T0_ALPHA |
+ RADEON_BLEND_CTL_BLEND |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_ADD = 0x00800051
+ */
+ (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
+ RADEON_ALPHA_ARG_B_ZERO |
+ RADEON_ALPHA_ARG_C_T0_ALPHA |
+ RADEON_COMP_ARG_B |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+ },
+
+ /* Unit 1:
+ */
+ {
+ /* Disable combiner stage
+ */
+ (RADEON_ALPHA_ARG_A_ZERO |
+ RADEON_ALPHA_ARG_B_ZERO |
+ RADEON_ALPHA_ARG_C_CURRENT_ALPHA |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_REPLACE = 0x00800600
+ */
+ (RADEON_ALPHA_ARG_A_ZERO |
+ RADEON_ALPHA_ARG_B_ZERO |
+ RADEON_ALPHA_ARG_C_T1_ALPHA |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_MODULATE = 0x00800061
+ */
+ (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
+ RADEON_ALPHA_ARG_B_T1_ALPHA |
+ RADEON_ALPHA_ARG_C_ZERO |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_DECAL = 0x00800100
+ */
+ (RADEON_ALPHA_ARG_A_ZERO |
+ RADEON_ALPHA_ARG_B_ZERO |
+ RADEON_ALPHA_ARG_C_CURRENT_ALPHA |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_BLEND = 0x00800061
+ */
+ (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
+ RADEON_ALPHA_ARG_B_TFACTOR_ALPHA |
+ RADEON_ALPHA_ARG_C_T1_ALPHA |
+ RADEON_BLEND_CTL_BLEND |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_ADD = 0x00800061
+ */
+ (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
+ RADEON_ALPHA_ARG_B_ZERO |
+ RADEON_ALPHA_ARG_C_T1_ALPHA |
+ RADEON_COMP_ARG_B |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+ },
+
+ /* Unit 2:
+ */
+ {
+ /* Disable combiner stage
+ */
+ (RADEON_ALPHA_ARG_A_ZERO |
+ RADEON_ALPHA_ARG_B_ZERO |
+ RADEON_ALPHA_ARG_C_CURRENT_ALPHA |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_REPLACE = 0x00800700
+ */
+ (RADEON_ALPHA_ARG_A_ZERO |
+ RADEON_ALPHA_ARG_B_ZERO |
+ RADEON_ALPHA_ARG_C_T2_ALPHA |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_MODULATE = 0x00800071
+ */
+ (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
+ RADEON_ALPHA_ARG_B_T2_ALPHA |
+ RADEON_ALPHA_ARG_C_ZERO |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_DECAL = 0x00800100
+ */
+ (RADEON_ALPHA_ARG_A_ZERO |
+ RADEON_ALPHA_ARG_B_ZERO |
+ RADEON_ALPHA_ARG_C_CURRENT_ALPHA |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_BLEND = 0x00800071
+ */
+ (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
+ RADEON_ALPHA_ARG_B_TFACTOR_ALPHA |
+ RADEON_ALPHA_ARG_C_T2_ALPHA |
+ RADEON_BLEND_CTL_BLEND |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_ADD = 0x00800021
+ */
+ (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
+ RADEON_ALPHA_ARG_B_ZERO |
+ RADEON_ALPHA_ARG_C_T2_ALPHA |
+ RADEON_COMP_ARG_B |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+ }
+};
+
+
+/* GL_EXT_texture_env_combine support
+ */
+
+/* The color tables have combine functions for GL_SRC_COLOR,
+ * GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA.
+ */
+static GLuint radeon_texture_color[][RADEON_MAX_TEXTURE_UNITS] =
+{
+ {
+ RADEON_COLOR_ARG_A_T0_COLOR,
+ RADEON_COLOR_ARG_A_T1_COLOR,
+ RADEON_COLOR_ARG_A_T2_COLOR
+ },
+ {
+ RADEON_COLOR_ARG_A_T0_COLOR | RADEON_COMP_ARG_A,
+ RADEON_COLOR_ARG_A_T1_COLOR | RADEON_COMP_ARG_A,
+ RADEON_COLOR_ARG_A_T2_COLOR | RADEON_COMP_ARG_A
+ },
+ {
+ RADEON_COLOR_ARG_A_T0_ALPHA,
+ RADEON_COLOR_ARG_A_T1_ALPHA,
+ RADEON_COLOR_ARG_A_T2_ALPHA
+ },
+ {
+ RADEON_COLOR_ARG_A_T0_ALPHA | RADEON_COMP_ARG_A,
+ RADEON_COLOR_ARG_A_T1_ALPHA | RADEON_COMP_ARG_A,
+ RADEON_COLOR_ARG_A_T2_ALPHA | RADEON_COMP_ARG_A
+ },
+};
+
+static GLuint radeon_tfactor_color[] =
+{
+ RADEON_COLOR_ARG_A_TFACTOR_COLOR,
+ RADEON_COLOR_ARG_A_TFACTOR_COLOR | RADEON_COMP_ARG_A,
+ RADEON_COLOR_ARG_A_TFACTOR_ALPHA,
+ RADEON_COLOR_ARG_A_TFACTOR_ALPHA | RADEON_COMP_ARG_A
+};
+
+static GLuint radeon_primary_color[] =
+{
+ RADEON_COLOR_ARG_A_DIFFUSE_COLOR,
+ RADEON_COLOR_ARG_A_DIFFUSE_COLOR | RADEON_COMP_ARG_A,
+ RADEON_COLOR_ARG_A_DIFFUSE_ALPHA,
+ RADEON_COLOR_ARG_A_DIFFUSE_ALPHA | RADEON_COMP_ARG_A
+};
+
+static GLuint radeon_previous_color[] =
+{
+ RADEON_COLOR_ARG_A_CURRENT_COLOR,
+ RADEON_COLOR_ARG_A_CURRENT_COLOR | RADEON_COMP_ARG_A,
+ RADEON_COLOR_ARG_A_CURRENT_ALPHA,
+ RADEON_COLOR_ARG_A_CURRENT_ALPHA | RADEON_COMP_ARG_A
+};
+
+/* The alpha tables only have GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA.
+ */
+static GLuint radeon_texture_alpha[][RADEON_MAX_TEXTURE_UNITS] =
+{
+ {
+ RADEON_ALPHA_ARG_A_T0_ALPHA,
+ RADEON_ALPHA_ARG_A_T1_ALPHA,
+ RADEON_ALPHA_ARG_A_T2_ALPHA
+ },
+ {
+ RADEON_ALPHA_ARG_A_T0_ALPHA | RADEON_COMP_ARG_A,
+ RADEON_ALPHA_ARG_A_T1_ALPHA | RADEON_COMP_ARG_A,
+ RADEON_ALPHA_ARG_A_T2_ALPHA | RADEON_COMP_ARG_A
+ },
+};
+
+static GLuint radeon_tfactor_alpha[] =
+{
+ RADEON_ALPHA_ARG_A_TFACTOR_ALPHA,
+ RADEON_ALPHA_ARG_A_TFACTOR_ALPHA | RADEON_COMP_ARG_A
+};
+
+static GLuint radeon_primary_alpha[] =
+{
+ RADEON_ALPHA_ARG_A_DIFFUSE_ALPHA,
+ RADEON_ALPHA_ARG_A_DIFFUSE_ALPHA | RADEON_COMP_ARG_A
+};
+
+static GLuint radeon_previous_alpha[] =
+{
+ RADEON_ALPHA_ARG_A_CURRENT_ALPHA,
+ RADEON_ALPHA_ARG_A_CURRENT_ALPHA | RADEON_COMP_ARG_A
+};
+
+
+/* Extract the arg from slot A, shift it into the correct argument slot
+ * and set the corresponding complement bit.
+ */
+#define RADEON_COLOR_ARG( n, arg ) \
+do { \
+ color_combine |= \
+ ((color_arg[n] & RADEON_COLOR_ARG_MASK) \
+ << RADEON_COLOR_ARG_##arg##_SHIFT); \
+ color_combine |= \
+ ((color_arg[n] >> RADEON_COMP_ARG_SHIFT) \
+ << RADEON_COMP_ARG_##arg##_SHIFT); \
+} while (0)
+
+#define RADEON_ALPHA_ARG( n, arg ) \
+do { \
+ alpha_combine |= \
+ ((alpha_arg[n] & RADEON_ALPHA_ARG_MASK) \
+ << RADEON_ALPHA_ARG_##arg##_SHIFT); \
+ alpha_combine |= \
+ ((alpha_arg[n] >> RADEON_COMP_ARG_SHIFT) \
+ << RADEON_COMP_ARG_##arg##_SHIFT); \
+} while (0)
+
+
+/* ================================================================
+ * Texture unit state management
+ */
+
+static void radeonUpdateTextureEnv( GLcontext *ctx, int unit )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ int source = rmesa->tmu_source[unit];
+ struct gl_texture_object *tObj;
+ struct gl_texture_unit *texUnit;
+ GLuint enabled;
+ GLuint color_combine, alpha_combine;
+ GLuint color_arg[3], alpha_arg[3];
+ GLuint i, numColorArgs = 0, numAlphaArgs = 0;
+ GLuint op;
+
+ if ( RADEON_DEBUG & DEBUG_VERBOSE_MSG ) {
+ fprintf( stderr, "%s( %p, %d )\n",
+ __FUNCTION__, ctx, unit );
+ }
+
+ enabled = (ctx->Texture.ReallyEnabled >> (source * 4)) & TEXTURE0_ANY;
+ if ( enabled != TEXTURE0_2D && enabled != TEXTURE0_1D )
+ return;
+
+ /* Only update the hardware texture state if the texture is current,
+ * complete and enabled.
+ */
+ texUnit = &ctx->Texture.Unit[source];
+ tObj = texUnit->Current;
+ if ( !tObj || !tObj->Complete )
+ return;
+
+ if ( ( tObj != texUnit->CurrentD[2] ) &&
+ ( tObj != texUnit->CurrentD[1] ) )
+ return;
+
+ /* Set the texture environment state. Isn't this nice and clean?
+ * The Radeon will automagically set the texture alpha to 0xff when
+ * the texture format does not include an alpha component. This
+ * reduces the amount of special-casing we have to do, alpha-only
+ * textures being a notable exception.
+ */
+ switch ( texUnit->EnvMode ) {
+ case GL_REPLACE:
+ switch ( tObj->Image[0]->Format ) {
+ case GL_RGBA:
+ case GL_RGB:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE_ALPHA:
+ case GL_INTENSITY:
+ color_combine = radeon_color_combine[unit][RADEON_REPLACE];
+ alpha_combine = radeon_alpha_combine[unit][RADEON_REPLACE];
+ break;
+ case GL_ALPHA:
+ color_combine = radeon_color_combine[unit][RADEON_DISABLE];
+ alpha_combine = radeon_alpha_combine[unit][RADEON_REPLACE];
+ break;
+ case GL_COLOR_INDEX:
+ default:
+ return;
+ }
+ break;
+
+ case GL_MODULATE:
+ switch ( tObj->Image[0]->Format ) {
+ case GL_RGBA:
+ case GL_RGB:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE_ALPHA:
+ case GL_INTENSITY:
+ color_combine = radeon_color_combine[unit][RADEON_MODULATE];
+ alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE];
+ break;
+ case GL_ALPHA:
+ color_combine = radeon_color_combine[unit][RADEON_DISABLE];
+ alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE];
+ break;
+ case GL_COLOR_INDEX:
+ default:
+ return;
+ }
+ break;
+
+ case GL_DECAL:
+ switch ( tObj->Image[0]->Format ) {
+ case GL_RGBA:
+ case GL_RGB:
+ color_combine = radeon_color_combine[unit][RADEON_DECAL];
+ alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE];
+ break;
+ case GL_ALPHA:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE_ALPHA:
+ case GL_INTENSITY:
+ color_combine = radeon_color_combine[unit][RADEON_DISABLE];
+ alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE];
+ break;
+ case GL_COLOR_INDEX:
+ default:
+ return;
+ }
+ break;
+
+ case GL_BLEND:
+ switch ( tObj->Image[0]->Format ) {
+ case GL_RGBA:
+ case GL_RGB:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE_ALPHA:
+ color_combine = radeon_color_combine[unit][RADEON_BLEND];
+ alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE];
+ break;
+ case GL_ALPHA:
+ color_combine = radeon_color_combine[unit][RADEON_DISABLE];
+ alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE];
+ break;
+ case GL_INTENSITY:
+ color_combine = radeon_color_combine[unit][RADEON_BLEND];
+ alpha_combine = radeon_alpha_combine[unit][RADEON_BLEND];
+ break;
+ case GL_COLOR_INDEX:
+ default:
+ return;
+ }
+ break;
+
+ case GL_ADD:
+ switch ( tObj->Image[0]->Format ) {
+ case GL_RGBA:
+ case GL_RGB:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE_ALPHA:
+ color_combine = radeon_color_combine[unit][RADEON_ADD];
+ alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE];
+ break;
+ case GL_ALPHA:
+ color_combine = radeon_color_combine[unit][RADEON_DISABLE];
+ alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE];
+ break;
+ case GL_INTENSITY:
+ color_combine = radeon_color_combine[unit][RADEON_ADD];
+ alpha_combine = radeon_alpha_combine[unit][RADEON_ADD];
+ break;
+ case GL_COLOR_INDEX:
+ default:
+ return;
+ }
+ break;
+
+ case GL_COMBINE_EXT:
+ /* Step 0:
+ * Calculate how many arguments we need to process.
+ */
+ switch ( texUnit->CombineModeRGB ) {
+ case GL_REPLACE:
+ numColorArgs = 1;
+ break;
+ case GL_MODULATE:
+ case GL_ADD:
+ case GL_ADD_SIGNED_EXT:
+ case GL_DOT3_RGB_EXT:
+ case GL_DOT3_RGBA_EXT:
+ numColorArgs = 2;
+ break;
+ case GL_INTERPOLATE_EXT:
+ numColorArgs = 3;
+ break;
+ default:
+ return;
+ }
+
+ switch ( texUnit->CombineModeA ) {
+ case GL_REPLACE:
+ numAlphaArgs = 1;
+ break;
+ case GL_MODULATE:
+ case GL_ADD:
+ case GL_ADD_SIGNED_EXT:
+ numAlphaArgs = 2;
+ break;
+ case GL_INTERPOLATE_EXT:
+ numAlphaArgs = 3;
+ break;
+ default:
+ return;
+ }
+
+ /* Step 1:
+ * Extract the color and alpha combine function arguments.
+ */
+ for ( i = 0 ; i < numColorArgs ; i++ ) {
+ op = texUnit->CombineOperandRGB[i] - GL_SRC_COLOR;
+ switch ( texUnit->CombineSourceRGB[i] ) {
+ case GL_TEXTURE:
+ color_arg[i] = radeon_texture_color[op][unit];
+ break;
+ case GL_CONSTANT_EXT:
+ color_arg[i] = radeon_tfactor_color[op];
+ break;
+ case GL_PRIMARY_COLOR_EXT:
+ color_arg[i] = radeon_primary_color[op];
+ break;
+ case GL_PREVIOUS_EXT:
+ color_arg[i] = radeon_previous_color[op];
+ break;
+ default:
+ return;
+ }
+ }
+
+ for ( i = 0 ; i < numAlphaArgs ; i++ ) {
+ op = texUnit->CombineOperandA[i] - GL_SRC_ALPHA;
+ switch ( texUnit->CombineSourceA[i] ) {
+ case GL_TEXTURE:
+ alpha_arg[i] = radeon_texture_alpha[op][unit];
+ break;
+ case GL_CONSTANT_EXT:
+ alpha_arg[i] = radeon_tfactor_alpha[op];
+ break;
+ case GL_PRIMARY_COLOR_EXT:
+ alpha_arg[i] = radeon_primary_alpha[op];
+ break;
+ case GL_PREVIOUS_EXT:
+ alpha_arg[i] = radeon_previous_alpha[op];
+ break;
+ default:
+ return;
+ }
+ }
+
+ /* Step 2:
+ * Build up the color and alpha combine functions.
+ */
+ switch ( texUnit->CombineModeRGB ) {
+ case GL_REPLACE:
+ color_combine = (RADEON_COLOR_ARG_A_ZERO |
+ RADEON_COLOR_ARG_B_ZERO |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_CLAMP_TX);
+ RADEON_COLOR_ARG( 0, C );
+ break;
+ case GL_MODULATE:
+ color_combine = (RADEON_COLOR_ARG_C_ZERO |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_CLAMP_TX);
+ RADEON_COLOR_ARG( 0, A );
+ RADEON_COLOR_ARG( 1, B );
+ break;
+ case GL_ADD:
+ color_combine = (RADEON_COLOR_ARG_B_ZERO |
+ RADEON_COMP_ARG_B |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_CLAMP_TX);
+ RADEON_COLOR_ARG( 0, A );
+ RADEON_COLOR_ARG( 1, C );
+ break;
+ case GL_ADD_SIGNED_EXT:
+ color_combine = (RADEON_COLOR_ARG_B_ZERO |
+ RADEON_COMP_ARG_B |
+ RADEON_BLEND_CTL_ADDSIGNED |
+ RADEON_CLAMP_TX);
+ RADEON_COLOR_ARG( 0, A );
+ RADEON_COLOR_ARG( 1, C );
+ break;
+ case GL_INTERPOLATE_EXT:
+ color_combine = (RADEON_BLEND_CTL_BLEND |
+ RADEON_CLAMP_TX);
+ RADEON_COLOR_ARG( 0, B );
+ RADEON_COLOR_ARG( 1, A );
+ RADEON_COLOR_ARG( 2, C );
+ break;
+ case GL_DOT3_RGB_EXT:
+ case GL_DOT3_RGBA_EXT:
+ color_combine = (RADEON_COLOR_ARG_C_ZERO |
+ RADEON_BLEND_CTL_DOT3 |
+ RADEON_CLAMP_TX);
+ RADEON_COLOR_ARG( 0, A );
+ RADEON_COLOR_ARG( 1, B );
+ break;
+ default:
+ return;
+ }
+
+ switch ( texUnit->CombineModeA ) {
+ case GL_REPLACE:
+ alpha_combine = (RADEON_ALPHA_ARG_A_ZERO |
+ RADEON_ALPHA_ARG_B_ZERO |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_CLAMP_TX);
+ RADEON_ALPHA_ARG( 0, C );
+ break;
+ case GL_MODULATE:
+ alpha_combine = (RADEON_ALPHA_ARG_C_ZERO |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_CLAMP_TX);
+ RADEON_ALPHA_ARG( 0, A );
+ RADEON_ALPHA_ARG( 1, B );
+ break;
+ case GL_ADD:
+ alpha_combine = (RADEON_ALPHA_ARG_B_ZERO |
+ RADEON_COMP_ARG_B |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_CLAMP_TX);
+ RADEON_ALPHA_ARG( 0, A );
+ RADEON_ALPHA_ARG( 1, C );
+ break;
+ case GL_ADD_SIGNED_EXT:
+ alpha_combine = (RADEON_ALPHA_ARG_B_ZERO |
+ RADEON_COMP_ARG_B |
+ RADEON_BLEND_CTL_ADDSIGNED |
+ RADEON_CLAMP_TX);
+ RADEON_ALPHA_ARG( 0, A );
+ RADEON_ALPHA_ARG( 1, C );
+ break;
+ case GL_INTERPOLATE_EXT:
+ alpha_combine = (RADEON_BLEND_CTL_BLEND |
+ RADEON_CLAMP_TX);
+ RADEON_ALPHA_ARG( 0, B );
+ RADEON_ALPHA_ARG( 1, A );
+ RADEON_ALPHA_ARG( 2, C );
+ break;
+ default:
+ return;
+ }
+
+ if ( texUnit->CombineModeRGB == GL_DOT3_RGB_EXT ) {
+ alpha_combine |= RADEON_DOT_ALPHA_DONT_REPLICATE;
+ }
+
+ /* Step 3:
+ * Apply the scale factor. The EXT extension has a somewhat
+ * unnecessary restriction that the scale must be 4x. The ARB
+ * extension will likely drop this and we can just apply the
+ * scale factors regardless.
+ */
+ if ( texUnit->CombineModeRGB != GL_DOT3_RGB_EXT &&
+ texUnit->CombineModeRGB != GL_DOT3_RGBA_EXT ) {
+ color_combine |= (texUnit->CombineScaleShiftRGB << 21);
+ alpha_combine |= (texUnit->CombineScaleShiftA << 21);
+ } else {
+ color_combine |= RADEON_SCALE_4X;
+ alpha_combine |= RADEON_SCALE_4X;
+ }
+
+ /* All done!
+ */
+ break;
+
+ default:
+ return;
+ }
+
+ rmesa->color_combine[source] = color_combine;
+ rmesa->alpha_combine[source] = alpha_combine;
+}
+
+static void radeonUpdateTextureObject( GLcontext *ctx, int unit )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ int source = rmesa->tmu_source[unit];
+ struct gl_texture_object *tObj;
+ radeonTexObjPtr t;
+ GLuint enabled;
+
+ if ( RADEON_DEBUG & DEBUG_VERBOSE_MSG ) {
+ fprintf( stderr, "%s( %p, %d )\n",
+ __FUNCTION__, ctx, unit );
+ }
+
+ enabled = (ctx->Texture.ReallyEnabled >> (source * 4)) & TEXTURE0_ANY;
+ if ( enabled != TEXTURE0_2D && enabled != TEXTURE0_1D ) {
+ if ( enabled )
+ rmesa->Fallback |= RADEON_FALLBACK_TEXTURE;
+ return;
+ }
+
+ /* Only update the hardware texture state if the texture is current,
+ * complete and enabled.
+ */
+ tObj = ctx->Texture.Unit[source].Current;
+ if ( !tObj || !tObj->Complete )
+ return;
+
+ if ( ( tObj != ctx->Texture.Unit[source].CurrentD[2] ) &&
+ ( tObj != ctx->Texture.Unit[source].CurrentD[1] ) )
+ return;
+
+ /* We definately have a valid texture now */
+ t = tObj->DriverData;
+
+ /* Force the texture unit state to be loaded into the hardware */
+ rmesa->dirty |= RADEON_UPLOAD_CONTEXT | (RADEON_UPLOAD_TEX0 << unit);
+
+ /* Force any texture images to be loaded into the hardware */
+ if ( t->dirty_images ) {
+ if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) {
+ fprintf( stderr, " t->dirty_images = 0x%x\n", t->dirty_images );
+ }
+ radeonSetTexImages( rmesa, tObj );
+ rmesa->dirty |= (RADEON_UPLOAD_TEX0IMAGES << unit);
+ }
+
+ if ( t->memBlock )
+ radeonUpdateTexLRU( rmesa, t );
+
+ switch ( unit ) {
+ case 0:
+ rmesa->setup.pp_cntl |= (RADEON_TEX_0_ENABLE |
+ RADEON_TEX_BLEND_0_ENABLE);
+ break;
+ case 1:
+ rmesa->setup.pp_cntl |= (RADEON_TEX_1_ENABLE |
+ RADEON_TEX_BLEND_1_ENABLE);
+ break;
+ }
+}
+
+void radeonUpdateTextureState( GLcontext *ctx )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+
+ if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) {
+ fprintf( stderr, "%s( %p ) en=0x%x\n",
+ __FUNCTION__, ctx, ctx->Texture.ReallyEnabled );
+ }
+
+ /* Clear any texturing fallbacks */
+ rmesa->Fallback &= ~RADEON_FALLBACK_TEXTURE;
+
+ /* Disable all texturing until it is known to be good */
+ rmesa->setup.pp_cntl &= ~(RADEON_TEX_ENABLE_MASK |
+ RADEON_TEX_BLEND_ENABLE_MASK);
+
+ radeonUpdateTextureObject( ctx, 0 );
+ radeonUpdateTextureEnv( ctx, 0 );
+
+ if ( rmesa->multitex ) {
+ radeonUpdateTextureObject( ctx, 1 );
+ radeonUpdateTextureEnv( ctx, 1 );
+ }
+
+ rmesa->dirty |= RADEON_UPLOAD_CONTEXT;
+}
diff --git a/xc/lib/GL/mesa/src/drv/tdfx/Imakefile b/xc/lib/GL/mesa/src/drv/tdfx/Imakefile
index ebb353844..9f45df60d 100644
--- a/xc/lib/GL/mesa/src/drv/tdfx/Imakefile
+++ b/xc/lib/GL/mesa/src/drv/tdfx/Imakefile
@@ -150,6 +150,7 @@ MESA_INCLUDES = -I. -I.. -I../../include
../../stages.c \
../../state.c \
../../stencil.c \
+ ../../texformat.c \
../../teximage.c \
../../texobj.c \
../../texstate.c \
@@ -223,6 +224,7 @@ MESA_INCLUDES = -I. -I.. -I../../include
../../stages.o \
../../state.o \
../../stencil.o \
+ ../../texformat.o \
../../teximage.o \
../../texobj.o \
../../texstate.o \
diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_context.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_context.c
index 1d6d41724..0c6e399c1 100644
--- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_context.c
+++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_context.c
@@ -43,9 +43,22 @@
#include "tdfx_render.h"
#include "tdfx_pipeline.h"
#include "tdfx_span.h"
+#include "tdfx_tex.h"
#include "tdfx_texman.h"
#include "extensions.h"
+#ifndef TDFX_DEBUG
+int TDFX_DEBUG = (0
+/* | DEBUG_ALWAYS_SYNC */
+/* | DEBUG_VERBOSE_API */
+/* | DEBUG_VERBOSE_MSG */
+/* | DEBUG_VERBOSE_LRU */
+/* | DEBUG_VERBOSE_DRI */
+/* | DEBUG_VERBOSE_IOCTL */
+/* | DEBUG_VERBOSE_2D */
+/* | DEBUG_VERBOSE_TEXTURE */
+ );
+#endif
#if 0
@@ -75,15 +88,13 @@ static void tdfxDDInitExtensions( GLcontext *ctx )
gl_extensions_disable( ctx, "GL_INGR_blend_func_separate" );
gl_extensions_enable( ctx, "GL_HP_occlusion_test" );
- if ( !fxMesa->haveTwoTMUs ) {
+ if ( fxMesa->numTMUs == 1 ) {
gl_extensions_disable( ctx, "GL_EXT_texture_env_add" );
gl_extensions_disable( ctx, "GL_ARB_multitexture" );
}
if ( TDFX_IS_NAPALM( fxMesa ) ) {
- gl_extensions_enable( ctx, "GL_ARB_texture_compression" );
gl_extensions_enable( ctx, "GL_EXT_texture_env_combine" );
- gl_extensions_enable( ctx, "GL_3DFX_texture_compression_FXT1" );
}
if (fxMesa->haveHwStencil) {
@@ -178,16 +189,10 @@ GLboolean tdfxCreateContext( Display *dpy, GLvisual *mesaVis,
fxMesa->Glide.Initialized = GL_FALSE;
fxMesa->Glide.Board = 0;
-
- if (getenv("FX_EMULATE_SINGLE_TMU")) {
- fxMesa->haveTwoTMUs = GL_FALSE;
- }
- else {
- if ( TDFX_IS_BANSHEE( fxMesa ) ) {
- fxMesa->haveTwoTMUs = GL_FALSE;
- } else {
- fxMesa->haveTwoTMUs = GL_TRUE;
- }
+ if ( getenv( "FX_EMULATE_SINGLE_TMU" ) || TDFX_IS_BANSHEE( fxMesa ) ) {
+ fxMesa->numTMUs = 1;
+ } else {
+ fxMesa->numTMUs = 2;
}
fxMesa->stats.swapBuffer = 0;
@@ -218,6 +223,7 @@ GLboolean tdfxCreateContext( Display *dpy, GLvisual *mesaVis,
tdfxDDInitStateFuncs( ctx );
tdfxDDInitRenderFuncs( ctx );
tdfxDDInitSpanFuncs( ctx );
+ tdfxDDInitTextureFuncs( ctx );
ctx->Driver.TriangleCaps = (DD_TRI_CULL |
DD_TRI_LIGHT_TWOSIDE |
@@ -448,19 +454,21 @@ void tdfxDestroyContext( tdfxContextPtr fxMesa )
}
if ( fxMesa ) {
- if (fxMesa->glCtx->Shared->RefCount == 1) {
+ GLcontext *ctx = fxMesa->glCtx;
+ struct gl_texture_object *tObj;
+
+ if ( ctx->Shared->RefCount == 1 ) {
/* This share group is about to go away, free our private
* texture object data.
*/
- struct gl_texture_object *tObj;
- tObj = fxMesa->glCtx->Shared->TexObjectList;
- while (tObj) {
- tdfxTMFreeTexture(fxMesa, tObj);
- tObj = tObj->Next;
+ LOCK_HARDWARE( fxMesa );
+ for ( tObj = ctx->Shared->TexObjectList ; tObj ; tObj = tObj->Next ) {
+ tdfxTMFreeTextureLocked( fxMesa, tObj );
}
+ UNLOCK_HARDWARE( fxMesa );
}
- tdfxTMClose(fxMesa); /* free texture memory */
+ tdfxTMClose( fxMesa ); /* free texture memory */
XFree( fxMesa );
}
diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_context.h b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_context.h
index 927c5f10a..a73347435 100644
--- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_context.h
+++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_context.h
@@ -280,9 +280,7 @@ typedef struct {
volatile int fifoOwner;
volatile int ctxOwner;
volatile int texOwner;
-}
-TDFXSAREAPriv;
-
+} TDFXSAREAPriv;
typedef struct {
GLuint swapBuffer;
@@ -292,73 +290,72 @@ typedef struct {
GLuint texSwaps;
} tdfxStats;
-
-
/*
* Memory range from startAddr to endAddr-1
*/
typedef struct mem_range {
struct mem_range *next;
FxU32 startAddr, endAddr;
-}
-tdfxMemRange;
+} tdfxMemRange;
+typedef struct {
+ GLvoid *data;
+ GLsizei width, height;
+ FxU32 size;
+} tdfxTexRawData;
typedef struct {
- GLsizei width, height; /* image size */
- GLint texelSize; /* How many bytes to a texel */
- GrTextureFormat_t glideFormat; /* Glide image format */
- void *data; /* Glide-formated texture image */
- FxU32 dataSize; /* image size in bytes */
-}
-tdfxMipMapLevel;
+ tdfxTexRawData original; /* Mesa-formatted texture image */
+ tdfxTexRawData rescaled; /* Only needed if aspect ratio > 8:1 */
+
+ GLvoid *data; /* Final version of texture image */
+ FxU32 size; /* image size in bytes */
+
+ GrTextureFormat_t glideFormat; /* Glide image format */
+ GLint wScale, hScale; /* Broken hardware... */
+} tdfxTexImage, *tdfxTexImagePtr;
#define TDFX_NUM_TMU 2
-typedef struct tdfxTexInfo_t
-{
+typedef struct {
GLboolean isInTM;
GLboolean reloadImages; /* if true, resend images to Glide */
GLuint lastTimeUsed;
FxU32 whichTMU;
GrTexInfo info;
- GrAspectRatio_t aspectRatio;
- tdfxMipMapLevel mipmapLevel[MAX_TEXTURE_LEVELS];
- tdfxMemRange *tm[TDFX_NUM_TMU];
+ tdfxTexImage image[MAX_TEXTURE_LEVELS];
+ tdfxMemRange *range[TDFX_NUM_TMU];
GLint minLevel, maxLevel;
+ GrMipMapMode_t mmMode;
+ GrAspectRatio_t aspectRatio;
+ FxBool LODblend;
GrTextureFilterMode_t minFilt;
GrTextureFilterMode_t magFilt;
GrTextureClampMode_t sClamp;
GrTextureClampMode_t tClamp;
- FxBool LODblend;
- GrMipMapMode_t mmMode;
- GLfloat sScale, tScale; /* texcoord scale factor */
+ GLfloat sScale, tScale; /* texcoord scale factor */
GuTexPalette palette;
-}
-tdfxTexInfo;
-
+} tdfxTexObj, *tdfxTexObjPtr;
-#define TDFX_TEXTURE_DATA(mesaObj) ((tdfxTexInfo *)((mesaObj)->DriverData))
+#define TDFX_TEXTURE_DATA(tObj) ((tdfxTexObjPtr)((tObj)->DriverData))
-
-/*
- * This is state which may be shared by several tdfx contexts.
+/* This is state which may be shared by several tdfx contexts.
* It hangs off of Mesa's gl_shared_state object (ctx->Shared->DriverData).
*/
-struct tdfxSharedState {
+typedef struct tdfx_shared_state {
GLboolean umaTexMemory;
- GLuint totalTexMem[TDFX_NUM_TMU]; /* constant */
- GLuint freeTexMem[TDFX_NUM_TMU]; /* changes as we go */
- tdfxMemRange *tmPool;
- tdfxMemRange *tmFree[TDFX_NUM_TMU];
-};
+ GLuint totalTexMem[TDFX_NUM_TMU]; /* constant */
+ GLuint freeTexMem[TDFX_NUM_TMU]; /* changes as we go */
+ tdfxMemRange *rangePool;
+ tdfxMemRange *freeRanges[TDFX_NUM_TMU];
+} tdfxSharedState, *tdfxSharedStatePtr;
@@ -635,6 +632,7 @@ struct tdfx_context {
GLuint tmu_source[TDFX_NUM_TMU];
GLuint tex_dest[MAX_TEXTURE_UNITS];
+ GLuint numTMUs;
GLuint SetupIndex;
GLuint SetupDone;
@@ -646,10 +644,6 @@ struct tdfx_context {
GLfloat sScale0, tScale0;
GLfloat sScale1, tScale1;
-#if 0
- GLuint last_tri_caps;
- GLuint stw_hint_state; /* for grHints */
-#endif
GLuint using_fast_path, passes, multipass;
GLuint texBindNumber;
GLint tmuSrc;
@@ -657,13 +651,6 @@ struct tdfx_context {
int screen_width;
int screen_height;
-#if 0
- void *state; /* Glide state buffer */
-
- GLint textureAlign;
- GLboolean verbose;
-#endif
- GLboolean haveTwoTMUs; /* True if we have 2 tmu's */
GLboolean haveHwStencil;
GLint maxPendingSwapBuffers;
@@ -773,6 +760,7 @@ extern int TDFX_DEBUG;
#define DEBUG_VERBOSE_DRI 0x10
#define DEBUG_VERBOSE_IOCTL 0x20
#define DEBUG_VERBOSE_2D 0x40
+#define DEBUG_VERBOSE_TEXTURE 0x80
#endif /* GLX_DIRECT_RENDERING */
diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_dd.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_dd.c
index ec5b25871..3f76fb88d 100644
--- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_dd.c
+++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_dd.c
@@ -43,9 +43,11 @@
#include "enums.h"
#include "pb.h"
+#if defined(USE_X86_ASM) || defined(USE_3DNOW_ASM) || defined(USE_KATMAI_ASM)
+#include "X86/common_x86_asm.h"
+#endif
-
-#define TDFX_DATE "20010104"
+#define TDFX_DATE "20010305"
/* These are used in calls to FX_grColorMaskv() */
@@ -63,10 +65,12 @@ static const GLubyte *tdfxDDGetString( GLcontext *ctx, GLenum name )
tdfxContextPtr fxMesa = (tdfxContextPtr) ctx->DriverCtx;
switch ( name ) {
- case GL_RENDERER:
- {
- static char buffer[100];
- char hardware[100];
+ case GL_VENDOR:
+ return "VA Linux Systems, Inc.";
+
+ case GL_RENDERER: {
+ static char buffer[128];
+ char hardware[128];
strcpy( hardware, FX_grGetString( fxMesa, GR_HARDWARE ) );
@@ -83,19 +87,41 @@ static const GLubyte *tdfxDDGetString( GLcontext *ctx, GLenum name )
strcpy( hardware, "Voodoo5" );
}
else {
- /* unexpected result: replace spaces with hyphens */
+ /* Unexpected result: replace spaces with hyphens */
int i;
for ( i = 0 ; hardware[i] ; i++ ) {
if ( hardware[i] == ' ' || hardware[i] == '\t' )
hardware[i] = '-';
}
}
- /* now make the GL_RENDERER string */
+ /* Now make the GL_RENDERER string */
sprintf( buffer, "Mesa DRI %s " TDFX_DATE, hardware );
+
+ /* Append any CPU-specific information.
+ */
+#ifdef USE_X86_ASM
+ if ( gl_x86_cpu_features ) {
+ strncat( buffer, " x86", 4 );
+ }
+#endif
+#ifdef USE_MMX_ASM
+ if ( cpu_has_mmx ) {
+ strncat( buffer, "/MMX", 4 );
+ }
+#endif
+#ifdef USE_3DNOW_ASM
+ if ( cpu_has_3dnow ) {
+ strncat( buffer, "/3DNow!", 7 );
+ }
+#endif
+#ifdef USE_KATMAI_ASM
+ if ( cpu_has_xmm ) {
+ strncat( buffer, "/SSE", 4 );
+ }
+#endif
return buffer;
}
- case GL_VENDOR:
- return "VA Linux Systems, Inc.";
+
default:
return NULL;
}
diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_render.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_render.c
index 97931a351..da60bee16 100644
--- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_render.c
+++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_render.c
@@ -594,16 +594,13 @@ static void uploadTextureImages( tdfxContextPtr fxMesa )
{
GLcontext *ctx = fxMesa->glCtx;
int unit;
- for (unit = 0; unit < TDFX_NUM_TMU; unit++) {
- if (ctx->Texture.Unit[unit].ReallyEnabled == TEXTURE0_2D) {
+ for ( unit = 0 ; unit < TDFX_NUM_TMU ; unit++ ) {
+ if ( ctx->Texture.Unit[unit].ReallyEnabled == TEXTURE0_2D ) {
struct gl_texture_object *tObj = ctx->Texture.Unit[unit].CurrentD[2];
- tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj);
- if (ti && ti->reloadImages) {
- /*
- printf("download texture image on unit %d\n", unit);
- */
- tdfxTMDownloadTexture(fxMesa, tObj);
- ti->reloadImages = GL_FALSE;
+ tdfxTexObjPtr t = TDFX_TEXTURE_DATA(tObj);
+ if ( t && t->reloadImages ) {
+ tdfxTMDownloadTextureLocked( fxMesa, tObj );
+ t->reloadImages = GL_FALSE;
}
}
}
diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_state.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_state.c
index eb9a6a98b..d630fbd8c 100644
--- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_state.c
+++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_state.c
@@ -45,7 +45,6 @@
#include "tdfx_vb.h"
#include "tdfx_tex.h"
#include "tdfx_texman.h"
-#include "tdfx_texstate.h"
#include "tdfx_tris.h"
#include "tdfx_render.h"
@@ -1535,15 +1534,6 @@ void tdfxDDInitStateFuncs( GLcontext *ctx )
ctx->Driver.Scissor = tdfxDDScissor;
ctx->Driver.ShadeModel = tdfxDDShadeModel;
- ctx->Driver.BindTexture = tdfxDDBindTexture;
- ctx->Driver.DeleteTexture = tdfxDDDeleteTexture;
- ctx->Driver.TexEnv = tdfxDDTexEnv;
- ctx->Driver.TexParameter = tdfxDDTexParameter;
- ctx->Driver.TexImage2D = tdfxDDTexImage2D;
- ctx->Driver.TexSubImage2D = tdfxDDTexSubImage2D;
- ctx->Driver.GetTexImage = tdfxDDGetTexImage;
- ctx->Driver.UpdateTexturePalette = tdfxDDTexturePalette;
-
if ( fxMesa->haveHwStencil ) {
ctx->Driver.StencilFunc = tdfxDDStencilFunc;
ctx->Driver.StencilMask = tdfxDDStencilMask;
diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_tex.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_tex.c
index c572e22a8..e0f2d2eb0 100644
--- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_tex.c
+++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_tex.c
@@ -35,39 +35,37 @@
*
*/
-#include "image.h"
-#include "texutil.h"
#include "tdfx_context.h"
#include "tdfx_tex.h"
#include "tdfx_texman.h"
+#include "enums.h"
+#include "image.h"
+#include "texutil.h"
+
+#define TX_DITHER_NONE 0x00000000
-static int
-logbase2(int n)
+static int logbase2( int n )
{
- GLint i = 1;
- GLint log2 = 0;
-
- if (n < 0) {
- return -1;
- }
-
- while (n > i) {
- i *= 2;
- log2++;
- }
- if (i != n) {
- return -1;
- }
- else {
- return log2;
- }
+ GLint i = 1;
+ GLint log2 = 0;
+
+ if ( n < 0 )
+ return -1;
+
+ while ( n > i ) {
+ i *= 2;
+ log2++;
+ }
+ if ( i != n ) {
+ return -1;
+ } else {
+ return log2;
+ }
}
-
-/*
- * Compute various texture image parameters.
+/* Compute various texture image parameters.
* Input: w, h - source texture width and height
* Output: lodlevel - Glide lod level token for the larger texture dimension
* aspectratio - Glide aspect ratio token
@@ -84,1520 +82,977 @@ logbase2(int n)
* 32 64 GR_LOD_LOG2_64 (=6) GR_ASPECT_LOG2_1x2 (=-1)
* 32 32 GR_LOD_LOG2_32 (=5) GR_ASPECT_LOG2_1x1 (=0)
*/
-static void
-tdfxTexGetInfo(const GLcontext *ctx, int w, int h,
- GrLOD_t *lodlevel, GrAspectRatio_t *aspectratio,
- float *sscale, float *tscale,
- int *wscale, int *hscale)
+static void tdfxTexGetInfo( const GLcontext *ctx, int w, int h,
+ GrLOD_t *lodlevel, GrAspectRatio_t *aspectratio,
+ float *sscale, float *tscale,
+ int *wscale, int *hscale )
{
- int logw, logh, ar, lod, ws, hs;
- float s, t;
-
- ASSERT(w >= 1);
- ASSERT(h >= 1);
-
- logw = logbase2(w);
- logh = logbase2(h);
- ar = logw - logh; /* aspect ratio = difference in log dimensions */
-
- /* Hardware only allows a maximum aspect ratio of 8x1, so handle
- |ar| > 3 by scaling the image and using an 8x1 aspect ratio */
- if (ar >= 0) {
- ASSERT(width >= height);
- lod = logw;
- s = 256.0;
- ws = 1;
- if (ar <= GR_ASPECT_LOG2_8x1) {
- t = 256 >> ar;
- hs = 1;
- }
- else {
- /* have to stretch image height */
- t = 32.0;
- hs = 1 << (ar - 3);
- }
- }
- else {
- ASSERT(width < height);
- lod = logh;
- t = 256.0;
- hs = 1;
- if (ar >= GR_ASPECT_LOG2_1x8) {
- s = 256 >> -ar;
- ws = 1;
- }
- else {
- /* have to stretch image width */
- s = 32.0;
- ws = 1 << (-ar - 3);
- }
- }
-
- if (ar < GR_ASPECT_LOG2_1x8)
- ar = GR_ASPECT_LOG2_1x8;
- else if (ar > GR_ASPECT_LOG2_8x1)
- ar = GR_ASPECT_LOG2_8x1;
-
- if (lodlevel)
- *lodlevel = (GrLOD_t) lod;
- if (aspectratio)
- *aspectratio = (GrAspectRatio_t) ar;
- if (sscale)
- *sscale = s;
- if (tscale)
- *tscale = t;
- if (wscale)
- *wscale = ws;
- if (hscale)
- *hscale = hs;
+ int logw, logh, ar, lod, ws, hs;
+ float s, t;
+
+ ASSERT( w >= 1 );
+ ASSERT( h >= 1 );
+
+ logw = logbase2( w );
+ logh = logbase2( h );
+ ar = logw - logh; /* aspect ratio = difference in log dimensions */
+
+ /* Hardware only allows a maximum aspect ratio of 8x1, so handle
+ * |ar| > 3 by scaling the image and using an 8x1 aspect ratio.
+ */
+ if ( ar >= 0 ) {
+ ASSERT( width >= height );
+ lod = logw;
+ s = 256.0;
+ ws = 1;
+ if ( ar <= GR_ASPECT_LOG2_8x1 ) {
+ t = 256 >> ar;
+ hs = 1;
+ } else {
+ /* have to stretch image height */
+ t = 32.0;
+ hs = 1 << (ar - 3);
+ }
+ } else {
+ ASSERT( width < height );
+ lod = logh;
+ t = 256.0;
+ hs = 1;
+ if ( ar >= GR_ASPECT_LOG2_1x8 ) {
+ s = 256 >> -ar;
+ ws = 1;
+ } else {
+ /* have to stretch image width */
+ s = 32.0;
+ ws = 1 << (-ar - 3);
+ }
+ }
+
+ if ( ar < GR_ASPECT_LOG2_1x8 ) {
+ ar = GR_ASPECT_LOG2_1x8;
+ } else if ( ar > GR_ASPECT_LOG2_8x1 ) {
+ ar = GR_ASPECT_LOG2_8x1;
+ }
+
+ if ( lodlevel )
+ *lodlevel = (GrLOD_t)lod;
+ if ( aspectratio )
+ *aspectratio = (GrAspectRatio_t)ar;
+ if ( sscale )
+ *sscale = s;
+ if ( tscale )
+ *tscale = t;
+ if ( wscale )
+ *wscale = ws;
+ if ( hscale )
+ *hscale = hs;
}
-/*
- * We need to call this when a texture object's minification filter
+/* We need to call this when a texture object's minification filter
* or texture image sizes change.
*/
-static void RevalidateTexture(GLcontext *ctx, struct gl_texture_object *tObj)
+static void tdfxRevalidateTexture( GLcontext *ctx,
+ struct gl_texture_object *tObj )
{
- tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj);
- GLint minl, maxl;
-
- if (!ti)
- return;
-
- minl = maxl = tObj->BaseLevel;
-
- if (tObj->Image[minl]) {
- maxl = MIN2(tObj->MaxLevel, tObj->Image[minl]->MaxLog2);
-
- /* compute largeLodLog2, aspect ratio and texcoord scale factors */
- tdfxTexGetInfo(ctx, tObj->Image[minl]->Width, tObj->Image[minl]->Height,
- &ti->info.largeLodLog2,
- &ti->info.aspectRatioLog2,
- &(ti->sScale), &(ti->tScale), NULL, NULL);
- }
-
- if (tObj->Image[maxl] && (tObj->MinFilter != GL_NEAREST) && (tObj->MinFilter != GL_LINEAR)) {
- /* mipmapping: need to compute smallLodLog2 */
- tdfxTexGetInfo(ctx, tObj->Image[maxl]->Width,
- tObj->Image[maxl]->Height,
- &ti->info.smallLodLog2, NULL,
- NULL, NULL, NULL, NULL);
- }
- else {
- /* not mipmapping: smallLodLog2 = largeLodLog2 */
- ti->info.smallLodLog2 = ti->info.largeLodLog2;
- }
-
- ti->minLevel = minl;
- ti->maxLevel = maxl;
- ti->info.data = NULL;
+ tdfxTexObjPtr t = TDFX_TEXTURE_DATA(tObj);
+ GLint minl, maxl;
+
+ if ( !t )
+ return;
+
+ minl = maxl = tObj->BaseLevel;
+
+ if ( tObj->Image[minl] ) {
+ maxl = MIN2( tObj->MaxLevel, tObj->Image[minl]->MaxLog2 );
+
+ /* Compute largeLodLog2, aspect ratio and texcoord scale factors.
+ */
+ tdfxTexGetInfo( ctx,
+ tObj->Image[minl]->Width, tObj->Image[minl]->Height,
+ &t->info.largeLodLog2, &t->info.aspectRatioLog2,
+ &t->sScale, &t->tScale, NULL, NULL );
+ }
+
+ if ( tObj->Image[maxl] &&
+ tObj->MinFilter != GL_NEAREST &&
+ tObj->MinFilter != GL_LINEAR ) {
+ /* Mipmapping: need to compute smallLodLog2 */
+ tdfxTexGetInfo( ctx,
+ tObj->Image[maxl]->Width, tObj->Image[maxl]->Height,
+ &t->info.smallLodLog2,
+ NULL, NULL, NULL, NULL, NULL );
+ } else {
+ /* Not mipmapping: smallLodLog2 = largeLodLog2 */
+ t->info.smallLodLog2 = t->info.largeLodLog2;
+ }
+
+ t->minLevel = minl;
+ t->maxLevel = maxl;
+ t->info.data = NULL;
}
-static tdfxTexInfo *
-fxAllocTexObjData(tdfxContextPtr fxMesa)
+static tdfxTexObjPtr tdfxAllocTexObj( tdfxContextPtr fxMesa )
{
- tdfxTexInfo *ti;
- int i;
+ tdfxTexObjPtr t;
+ int i;
- if (!(ti = CALLOC(sizeof(tdfxTexInfo)))) {
- gl_problem(NULL, "tdfx driver: out of memory");
- return NULL;
- }
+ t = CALLOC( sizeof(tdfxTexObj) );
+ if ( !t ) {
+ gl_problem( NULL, "tdfx driver: out of memory" );
+ return NULL;
+ }
- ti->isInTM = GL_FALSE;
+ t->isInTM = GL_FALSE;
- ti->whichTMU = TDFX_TMU_NONE;
+ t->whichTMU = TDFX_TMU_NONE;
- ti->tm[TDFX_TMU0] = NULL;
- ti->tm[TDFX_TMU1] = NULL;
+ t->range[TDFX_TMU0] = NULL;
+ t->range[TDFX_TMU1] = NULL;
- ti->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED;
- ti->magFilt = GR_TEXTUREFILTER_BILINEAR;
+ t->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED;
+ t->magFilt = GR_TEXTUREFILTER_BILINEAR;
- ti->sClamp = GR_TEXTURECLAMP_WRAP;
- ti->tClamp = GR_TEXTURECLAMP_WRAP;
+ t->sClamp = GR_TEXTURECLAMP_WRAP;
+ t->tClamp = GR_TEXTURECLAMP_WRAP;
- ti->mmMode = GR_MIPMAP_NEAREST;
- ti->LODblend = FXFALSE;
+ t->mmMode = GR_MIPMAP_NEAREST;
+ t->LODblend = FXFALSE;
- for (i = 0; i < MAX_TEXTURE_LEVELS; i++) {
- ti->mipmapLevel[i].data = NULL;
- }
+ for ( i = 0 ; i < MAX_TEXTURE_LEVELS ; i++ ) {
+ t->image[i].original.data = NULL;
+ t->image[i].rescaled.data = NULL;
+ }
- return ti;
+ return t;
}
-/*
- * Called via glBindTexture.
+/* Given an OpenGL internal texture format, return the corresponding
+ * Glide internal texture format and MesaIntTexFormat.
+ * If allow32bpp is true, we'll return 32-bit texel formats when
+ * appropriate.
*/
-
-void
-tdfxDDBindTexture(GLcontext * ctx, GLenum target,
- struct gl_texture_object *tObj)
+static GrTextureFormat_t
+tdfxTexGetFormat( tdfxContextPtr fxMesa, struct gl_texture_image *texImage,
+ GLenum format, GLenum type )
{
- tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
- tdfxTexInfo *ti;
+ const GLboolean allow32bpp = TDFX_IS_NAPALM(fxMesa);
+ const GLboolean is32bpp = ( fxMesa->fxScreen->cpp == 4 );
+ const struct gl_texture_format *texFormat;
+ GrTextureFormat_t ret;
+
+ if ( 0 )
+ fprintf( stderr, "internal=%s format=%s type=%s\n",
+ texImage->IntFormat == 3 ? "GL_RGB (3)" :
+ texImage->IntFormat == 4 ? "GL_RGBA (4)" :
+ gl_lookup_enum_by_nr( texImage->IntFormat ),
+ gl_lookup_enum_by_nr( format ),
+ gl_lookup_enum_by_nr( type ) );
+
+#define SET_FORMAT( gr, gl ) \
+ do { \
+ ret = (gr); \
+ texFormat = &(gl); \
+ } while (0)
+
+#define SET_FORMAT_32BPP( gr32, gl32, gr16, gl16 ) \
+ do { \
+ if ( allow32bpp ) { \
+ ret = (gr32); \
+ texFormat = &(gl32); \
+ } else { \
+ ret = (gr16); \
+ texFormat = &(gl16); \
+ } \
+ } while (0)
+
+ switch ( texImage->IntFormat ) {
+ /* GH: Bias towards GL_RGB, GL_RGBA texture formats. This has
+ * got to be better than sticking them way down the end of this
+ * huge list.
+ */
+ case GL_RGBA:
+ case 4:
+ if ( format == GL_BGRA ) {
+ if ( type == GL_UNSIGNED_INT_8_8_8_8_REV && allow32bpp ) {
+ SET_FORMAT( GR_TEXFMT_ARGB_8888, _mesa_texformat_argb8888 );
+ break;
+ } else if ( type == GL_UNSIGNED_SHORT_4_4_4_4_REV ) {
+ SET_FORMAT( GR_TEXFMT_ARGB_4444, _mesa_texformat_argb4444 );
+ break;
+ } else if ( type == GL_UNSIGNED_SHORT_1_5_5_5_REV ) {
+ SET_FORMAT( GR_TEXFMT_ARGB_1555, _mesa_texformat_argb1555 );
+ break;
+ }
+ }
+ if ( allow32bpp && is32bpp ) {
+ SET_FORMAT( GR_TEXFMT_ARGB_8888, _mesa_texformat_rgba8888 );
+ } else {
+ SET_FORMAT( GR_TEXFMT_ARGB_4444, _mesa_texformat_argb4444 );
+ }
+ break;
+
+ case GL_RGB:
+ case 3:
+ if ( format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5 ) {
+ SET_FORMAT( GR_TEXFMT_RGB_565, _mesa_texformat_rgb565 );
+ break;
+ }
+ if ( allow32bpp && is32bpp ) {
+ SET_FORMAT( GR_TEXFMT_ARGB_8888, _mesa_texformat_rgba8888 );
+ } else {
+ SET_FORMAT( GR_TEXFMT_RGB_565, _mesa_texformat_rgb565 );
+ }
+ break;
+
+ /* GH: Okay, keep checking as normal. Still test for GL_RGB,
+ * GL_RGBA formats first.
+ */
+ case GL_RGBA8:
+ case GL_RGB10_A2:
+ case GL_RGBA12:
+ case GL_RGBA16:
+ SET_FORMAT_32BPP( GR_TEXFMT_ARGB_8888, _mesa_texformat_argb8888,
+ GR_TEXFMT_ARGB_4444, _mesa_texformat_argb4444 );
+ break;
+
+ case GL_RGBA4:
+ case GL_RGBA2:
+ SET_FORMAT( GR_TEXFMT_ARGB_4444, _mesa_texformat_argb4444 );
+ break;
+
+ case GL_RGB5_A1:
+ SET_FORMAT( GR_TEXFMT_ARGB_1555, _mesa_texformat_argb1555 );
+ break;
+
+ case GL_RGB8:
+ case GL_RGB10:
+ case GL_RGB12:
+ case GL_RGB16:
+ SET_FORMAT_32BPP( GR_TEXFMT_ARGB_8888, _mesa_texformat_argb8888,
+ GR_TEXFMT_RGB_565, _mesa_texformat_rgb565 );
+ break;
+
+ case GL_RGB5:
+ case GL_RGB4:
+ case GL_R3_G3_B2:
+ SET_FORMAT( GR_TEXFMT_RGB_565, _mesa_texformat_rgb565 );
+ break;
+
+ case GL_ALPHA:
+ case GL_ALPHA4:
+ case GL_ALPHA8:
+ case GL_ALPHA12:
+ case GL_ALPHA16:
+ SET_FORMAT( GR_TEXFMT_ALPHA_8, _mesa_texformat_a8 );
+ break;
+
+ case 1:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE4:
+ case GL_LUMINANCE8:
+ case GL_LUMINANCE12:
+ case GL_LUMINANCE16:
+ SET_FORMAT( GR_TEXFMT_INTENSITY_8, _mesa_texformat_l8 );
+ break;
+
+ case 2:
+ case GL_LUMINANCE_ALPHA:
+ case GL_LUMINANCE4_ALPHA4:
+ case GL_LUMINANCE6_ALPHA2:
+ case GL_LUMINANCE8_ALPHA8:
+ case GL_LUMINANCE12_ALPHA4:
+ case GL_LUMINANCE12_ALPHA12:
+ case GL_LUMINANCE16_ALPHA16:
+ SET_FORMAT( GR_TEXFMT_ALPHA_INTENSITY_88, _mesa_texformat_al88 );
+ break;
+
+ case GL_INTENSITY:
+ case GL_INTENSITY4:
+ case GL_INTENSITY8:
+ case GL_INTENSITY12:
+ case GL_INTENSITY16:
+ SET_FORMAT( GR_TEXFMT_ALPHA_8, _mesa_texformat_i8 );
+ break;
+
+ case GL_COLOR_INDEX:
+ case GL_COLOR_INDEX1_EXT:
+ case GL_COLOR_INDEX2_EXT:
+ case GL_COLOR_INDEX4_EXT:
+ case GL_COLOR_INDEX8_EXT:
+ case GL_COLOR_INDEX12_EXT:
+ case GL_COLOR_INDEX16_EXT:
+ SET_FORMAT( GR_TEXFMT_P_8, _mesa_texformat_ci8 );
+ break;
+
+ default:
+ fprintf( stderr, "bad texture format in fxTexGetFormat() %d",
+ texImage->IntFormat );
+ return -1;
+ }
+
+ texImage->TexFormat = texFormat;
+
+ return ret;
+}
- if (MESA_VERBOSE & VERBOSE_DRIVER) {
- fprintf(stderr, "fxmesa: fxDDTexBind(%d,%p)\n", tObj->Name,
- tObj->DriverData);
- }
- if (target != GL_TEXTURE_2D)
- return;
+static GLboolean
+tdfxDDTexImage2D( GLcontext *ctx, GLenum target, GLint level,
+ GLenum format, GLenum type, const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage,
+ GLboolean *retainInternalCopy )
+{
+ tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
+ const struct gl_texture_format *texFormat;
+ GrTextureFormat_t glideFormat;
+ tdfxTexObjPtr t;
+ tdfxTexImagePtr image;
+ GLint dstWidth, dstHeight, wScale, hScale;
+ GLint size;
+ void *data;
+
+ if ( 0 ) {
+ printf("TexImage id=%d int 0x%x format 0x%x type 0x%x %dx%d\n",
+ texObj->Name, texImage->IntFormat, format, type,
+ texImage->Width, texImage->Height);
+ }
+
+ if ( target != GL_TEXTURE_2D || texImage->Border > 0 )
+ return GL_FALSE;
+
+ if ( !texObj->DriverData )
+ texObj->DriverData = tdfxAllocTexObj( fxMesa );
+
+ t = TDFX_TEXTURE_DATA(texObj);
+ image = &t->image[level];
+
+ /* Determine the appropriate GL internal texel format, Mesa internal
+ * texel format, and texelSize (bytes) given the user's internal
+ * texture format hint.
+ */
+ glideFormat = tdfxTexGetFormat( fxMesa, texImage, format, type );
- if (!tObj->DriverData) {
- tObj->DriverData = fxAllocTexObjData(fxMesa);
- }
+ /* Get the destination internal format.
+ */
+ texFormat = texImage->TexFormat;
- ti = TDFX_TEXTURE_DATA(tObj);
- ti->lastTimeUsed = fxMesa->texBindNumber++;
+ /* Determine width and height scale factors for texture. Remember,
+ * Glide is limited to 8:1 aspect ratios.
+ */
+ tdfxTexGetInfo( ctx,
+ texImage->Width, texImage->Height,
+ NULL, NULL, NULL, NULL,
+ &wScale, &hScale );
+ dstWidth = texImage->Width * wScale;
+ dstHeight = texImage->Height * hScale;
+
+ /* Allocate new storage for texture image, if needed. This
+ * conditional wants to set uncompressedImage to point to the
+ * uncompressed image, and mml->data to the texture data. If the
+ * image is uncompressed, these are identical. If the image is not
+ * compressed, these are different.
+ */
+ if ( !image->original.data || image->glideFormat != glideFormat ||
+ image->original.width != texImage->Width ||
+ image->original.height != texImage->Height )
+ {
+ if ( image->original.data ) {
+ FREE( image->original.data );
+ image->original.data = NULL;
+ }
+ if ( image->rescaled.data ) {
+ FREE( image->rescaled.data );
+ image->rescaled.data = NULL;
+ }
+
+ size = texImage->Width * texImage->Height * texFormat->TexelBytes;
+ image->original.data = (void *) MALLOC( size );
+ if ( !image->original.data )
+ return GL_FALSE;
+
+ image->original.width = texImage->Width;
+ image->original.height = texImage->Height;
+ image->original.size = size;
+
+ image->glideFormat = glideFormat;
+ image->wScale = wScale;
+ image->hScale = hScale;
+
+ t->info.format = glideFormat;
+ tdfxTMMoveOutTM( fxMesa, texObj );
+ }
+
+ /* Store the texture image into the 'original' space.
+ */
+ if ( !_mesa_convert_texsubimage2d( texFormat->IntFormat,
+ 0, 0, texImage->Width,
+ texImage->Height, texImage->Width,
+ format, type, packing, pixels,
+ image->original.data ) ) {
+ return GL_FALSE;
+ }
+
+ data = image->original.data;
+ size = image->original.size;
+
+ /* GH: Sigh...
+ */
+ if ( wScale > 1 || hScale > 1 ) {
+ if ( image->rescaled.data ) {
+ FREE( image->rescaled.data );
+ image->rescaled.data = NULL;
+ }
- fxMesa->new_state |= TDFX_NEW_TEXTURE;
-}
+ size = dstWidth * dstHeight * texFormat->TexelBytes;
+ image->rescaled.data = (void *) MALLOC( size );
+ if ( !image->rescaled.data )
+ return GL_FALSE;
+ image->rescaled.width = dstWidth;
+ image->rescaled.height = dstHeight;
+ image->rescaled.size = size;
-/*
- * Called via glTexEnv.
- */
-void
-tdfxDDTexEnv(GLcontext * ctx, GLenum target, GLenum pname,
- const GLfloat * param)
-{
- tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
-
- if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) {
- if (param)
- fprintf(stderr, "fxmesa: texenv(%x,%x)\n", pname,
- (GLint) (*param));
- else
- fprintf(stderr, "fxmesa: texenv(%x)\n", pname);
- }
+ _mesa_rescale_teximage2d( texFormat,
+ texImage->Width, texImage->Height,
+ dstWidth, dstHeight,
+ image->original.data, image->rescaled.data );
- fxMesa->new_state |= TDFX_NEW_TEXTURE;
-}
+ data = image->rescaled.data;
+ }
+ image->data = data;
+ image->size = size;
-/*
- * Called via glTexParameter.
- */
-void
-tdfxDDTexParameter(GLcontext * ctx, GLenum target,
- struct gl_texture_object *tObj,
- GLenum pname, const GLfloat * params)
-{
- tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
- GLenum param = (GLenum) (GLint) params[0];
- tdfxTexInfo *ti;
-
- if (MESA_VERBOSE & VERBOSE_DRIVER) {
- fprintf(stderr, "fxmesa: fxDDTexParam(%d,%p,%x,%x)\n", tObj->Name,
- tObj->DriverData, pname, param);
- }
-
- if (target != GL_TEXTURE_2D)
- return;
-
- if (!tObj->DriverData)
- tObj->DriverData = fxAllocTexObjData(fxMesa);
-
- ti = TDFX_TEXTURE_DATA(tObj);
-
- switch (pname) {
- case GL_TEXTURE_MIN_FILTER:
- switch (param) {
- case GL_NEAREST:
- ti->mmMode = GR_MIPMAP_DISABLE;
- ti->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED;
- ti->LODblend = FXFALSE;
- break;
- case GL_LINEAR:
- ti->mmMode = GR_MIPMAP_DISABLE;
- ti->minFilt = GR_TEXTUREFILTER_BILINEAR;
- ti->LODblend = FXFALSE;
- break;
- case GL_NEAREST_MIPMAP_LINEAR:
- if (TDFX_IS_NAPALM(fxMesa)) {
- if (fxMesa->haveTwoTMUs) {
- ti->mmMode = GR_MIPMAP_NEAREST;
- ti->LODblend = FXTRUE;
- }
- else {
- ti->mmMode = GR_MIPMAP_NEAREST_DITHER;
- ti->LODblend = FXFALSE;
- }
- ti->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED;
- break;
- }
- /* XXX Voodoo3/Banshee mipmap blending seems to produce
- * incorrectly filtered colors for the smallest mipmap levels.
- * To work-around we fall-through here and use a different filter.
- */
- case GL_NEAREST_MIPMAP_NEAREST:
- ti->mmMode = GR_MIPMAP_NEAREST;
- ti->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED;
- ti->LODblend = FXFALSE;
- break;
- case GL_LINEAR_MIPMAP_LINEAR:
- if (TDFX_IS_NAPALM(fxMesa)) {
- if (fxMesa->haveTwoTMUs) {
- ti->mmMode = GR_MIPMAP_NEAREST;
- ti->LODblend = FXTRUE;
- }
- else {
- ti->mmMode = GR_MIPMAP_NEAREST_DITHER;
- ti->LODblend = FXFALSE;
- }
- ti->minFilt = GR_TEXTUREFILTER_BILINEAR;
- break;
- }
- /* XXX Voodoo3/Banshee mipmap blending seems to produce
- * incorrectly filtered colors for the smallest mipmap levels.
- * To work-around we fall-through here and use a different filter.
- */
- case GL_LINEAR_MIPMAP_NEAREST:
- ti->mmMode = GR_MIPMAP_NEAREST;
- ti->minFilt = GR_TEXTUREFILTER_BILINEAR;
- ti->LODblend = FXFALSE;
- break;
- default:
- break;
- }
- RevalidateTexture(ctx, tObj);
- fxMesa->new_state |= TDFX_NEW_TEXTURE;
- break;
-
- case GL_TEXTURE_MAG_FILTER:
- switch (param) {
- case GL_NEAREST:
- ti->magFilt = GR_TEXTUREFILTER_POINT_SAMPLED;
- break;
- case GL_LINEAR:
- ti->magFilt = GR_TEXTUREFILTER_BILINEAR;
- break;
- default:
- break;
- }
- fxMesa->new_state |= TDFX_NEW_TEXTURE;
- break;
-
- case GL_TEXTURE_WRAP_S:
- switch (param) {
- case GL_CLAMP:
- ti->sClamp = GR_TEXTURECLAMP_CLAMP;
- break;
- case GL_REPEAT:
- ti->sClamp = GR_TEXTURECLAMP_WRAP;
- break;
- default:
- break;
- }
- fxMesa->new_state |= TDFX_NEW_TEXTURE;
- break;
-
- case GL_TEXTURE_WRAP_T:
- switch (param) {
- case GL_CLAMP:
- ti->tClamp = GR_TEXTURECLAMP_CLAMP;
- break;
- case GL_REPEAT:
- ti->tClamp = GR_TEXTURECLAMP_WRAP;
- break;
- default:
- break;
- }
- fxMesa->new_state |= TDFX_NEW_TEXTURE;
- break;
-
- case GL_TEXTURE_BORDER_COLOR:
- /* TO DO */
- break;
- case GL_TEXTURE_MIN_LOD:
- /* TO DO */
- break;
- case GL_TEXTURE_MAX_LOD:
- /* TO DO */
- break;
- case GL_TEXTURE_BASE_LEVEL:
- RevalidateTexture(ctx, tObj);
- break;
- case GL_TEXTURE_MAX_LEVEL:
- RevalidateTexture(ctx, tObj);
- break;
-
- default:
- break;
- }
-}
+ tdfxRevalidateTexture( ctx, texObj );
+ t->reloadImages = GL_TRUE;
+ fxMesa->new_state |= TDFX_NEW_TEXTURE;
-/*
- * Called via glDeleteTextures to delete a texture object.
- * Here, we delete the Glide data associated with the texture.
- */
-void
-tdfxDDDeleteTexture(GLcontext * ctx, struct gl_texture_object *tObj)
-{
- tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
- tdfxTMFreeTexture(fxMesa, tObj);
- fxMesa->new_state |= TDFX_NEW_TEXTURE;
+ *retainInternalCopy = GL_FALSE;
+ return GL_TRUE;
}
-/*
- * Return true if texture is resident, false otherwise.
- */
-GLboolean
-tdfxDDIsTextureResident(GLcontext *ctx, struct gl_texture_object *tObj)
+static GLboolean
+tdfxDDTexSubImage2D( GLcontext *ctx, GLenum target, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height,
+ GLenum format, GLenum type, const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage )
{
- tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj);
- return (GLboolean) (ti && ti->isInTM);
-}
+ tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
+ tdfxTexObjPtr t = TDFX_TEXTURE_DATA(texObj);
+ tdfxTexImagePtr image;
+ if ( target != GL_TEXTURE_2D )
+ return GL_FALSE;
+ if ( !t )
+ return GL_FALSE;
-/*
- * Convert a gl_color_table texture palette to Glide's format.
- */
-static void
-convertPalette(FxU32 data[256], const struct gl_color_table *table)
-{
- const GLubyte *tableUB = (const GLubyte *) table->Table;
- GLint width = table->Size;
- FxU32 r, g, b, a;
- GLint i;
-
- ASSERT(table->TableType == GL_UNSIGNED_BYTE);
-
- switch (table->Format) {
- case GL_INTENSITY:
- for (i = 0; i < width; i++) {
- r = tableUB[i];
- g = tableUB[i];
- b = tableUB[i];
- a = tableUB[i];
- data[i] = (a << 24) | (r << 16) | (g << 8) | b;
- }
- break;
- case GL_LUMINANCE:
- for (i = 0; i < width; i++) {
- r = tableUB[i];
- g = tableUB[i];
- b = tableUB[i];
- a = 255;
- data[i] = (a << 24) | (r << 16) | (g << 8) | b;
- }
- break;
- case GL_ALPHA:
- for (i = 0; i < width; i++) {
- r = g = b = 255;
- a = tableUB[i];
- data[i] = (a << 24) | (r << 16) | (g << 8) | b;
- }
- break;
- case GL_LUMINANCE_ALPHA:
- for (i = 0; i < width; i++) {
- r = g = b = tableUB[i * 2 + 0];
- a = tableUB[i * 2 + 1];
- data[i] = (a << 24) | (r << 16) | (g << 8) | b;
- }
- break;
- case GL_RGB:
- for (i = 0; i < width; i++) {
- r = tableUB[i * 3 + 0];
- g = tableUB[i * 3 + 1];
- b = tableUB[i * 3 + 2];
- a = 255;
- data[i] = (a << 24) | (r << 16) | (g << 8) | b;
- }
- break;
- case GL_RGBA:
- for (i = 0; i < width; i++) {
- r = tableUB[i * 4 + 0];
- g = tableUB[i * 4 + 1];
- b = tableUB[i * 4 + 2];
- a = tableUB[i * 4 + 3];
- data[i] = (a << 24) | (r << 16) | (g << 8) | b;
- }
- break;
- }
-}
+ if ( 0 ) {
+ fprintf( stderr, "TexSubImage id=%d lvl=%d int=0x%x format=0x%x type=0x%x x=%d y=%d w=%d h=%d fullW=%d fullH=%d\n",
+ texObj->Name, level, texImage->IntFormat, format, type,
+ xoffset, yoffset, width, height,
+ texImage->Width, texImage->Height );
+ }
+ image = &t->image[level];
+ /* Must have an existing texture image!
+ */
+ assert( image->original.data );
-void
-tdfxDDTexturePalette(GLcontext * ctx, struct gl_texture_object *tObj)
-{
- tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
-
- if (tObj) {
- /* per-texture palette */
- tdfxTexInfo *ti;
- if (!tObj->DriverData)
- tObj->DriverData = fxAllocTexObjData(fxMesa);
- ti = TDFX_TEXTURE_DATA(tObj);
- convertPalette(ti->palette.data, &tObj->Palette);
- /*tdfxTexInvalidate(ctx, tObj);*/
- }
- else {
- /* global texture palette */
- convertPalette(fxMesa->glbPalette.data, &ctx->Texture.Palette);
- }
- fxMesa->new_state |= TDFX_NEW_TEXTURE; /* XXX too heavy-handed */
+ if ( !_mesa_convert_texsubimage2d( texImage->TexFormat->IntFormat,
+ xoffset, yoffset, width, height,
+ texImage->Width,
+ format, type, packing,
+ pixels, image->original.data ) ) {
+ return GL_FALSE;
+ }
+
+ /* Rescale the original image again if we have to.
+ */
+ if ( image->wScale > 1 || image->hScale > 1 ) {
+ assert( image->rescaled.data );
+ _mesa_rescale_teximage2d( texImage->TexFormat,
+ image->original.width, image->original.height,
+ image->rescaled.width, image->rescaled.height,
+ image->original.data, image->rescaled.data );
+ }
+
+ t->reloadImages = GL_TRUE; /* signal the image needs to be reloaded */
+ fxMesa->new_state |= TDFX_NEW_TEXTURE; /* XXX this might be a bit much */
+
+ return GL_TRUE;
}
-/*
- * Given an OpenGL internal texture format, return the corresponding
- * Glide internal texture format and MesaIntTexFormat.
- * If allow32bpp is true, we'll return 32-bit texel formats when
- * appropriate.
- */
-static void
-tdfxTexGetFormat(GLenum intFormatHint, GLboolean allow32bpp,
- GrTextureFormat_t *glideFormat,
- MesaIntTexFormat *mesaFormat,
- GLint *texelSize)
-{
- switch (intFormatHint) {
- case 1:
- case GL_LUMINANCE:
- case GL_LUMINANCE4:
- case GL_LUMINANCE8:
- case GL_LUMINANCE12:
- case GL_LUMINANCE16:
- if (glideFormat)
- *glideFormat = GR_TEXFMT_INTENSITY_8;
- if (mesaFormat)
- *mesaFormat = MESA_L8;
- if (texelSize)
- *texelSize = 1;
- break;
- case 2:
- case GL_LUMINANCE_ALPHA:
- case GL_LUMINANCE4_ALPHA4:
- case GL_LUMINANCE6_ALPHA2:
- case GL_LUMINANCE8_ALPHA8:
- case GL_LUMINANCE12_ALPHA4:
- case GL_LUMINANCE12_ALPHA12:
- case GL_LUMINANCE16_ALPHA16:
- if (glideFormat)
- *glideFormat = GR_TEXFMT_ALPHA_INTENSITY_88;
- if (mesaFormat)
- *mesaFormat = MESA_A8_L8;
- if (texelSize)
- *texelSize = 2;
- break;
- case GL_INTENSITY:
- case GL_INTENSITY4:
- case GL_INTENSITY8:
- case GL_INTENSITY12:
- case GL_INTENSITY16:
- if (glideFormat)
- *glideFormat = GR_TEXFMT_ALPHA_8;
- if (mesaFormat)
- *mesaFormat = MESA_I8;
- if (texelSize)
- *texelSize = 1;
- break;
- case GL_ALPHA:
- case GL_ALPHA4:
- case GL_ALPHA8:
- case GL_ALPHA12:
- case GL_ALPHA16:
- if (glideFormat)
- *glideFormat = GR_TEXFMT_ALPHA_8;
- if (mesaFormat)
- *mesaFormat = MESA_A8;
- if (texelSize)
- *texelSize = 1;
- break;
- case GL_R3_G3_B2:
- case GL_RGB4:
- case GL_RGB5:
- if (glideFormat)
- *glideFormat = GR_TEXFMT_RGB_565;
- if (mesaFormat)
- *mesaFormat = MESA_R5_G6_B5;
- if (texelSize)
- *texelSize = 2;
- break;
- case 3:
- case GL_RGB:
- case GL_RGB8:
- case GL_RGB10:
- case GL_RGB12:
- case GL_RGB16:
- if (allow32bpp) {
- if (glideFormat)
- *glideFormat = GR_TEXFMT_ARGB_8888;
- if (mesaFormat)
- *mesaFormat = MESA_FF_R8_G8_B8;
- if (texelSize)
- *texelSize = 4;
- }
- else {
- if (glideFormat)
- *glideFormat = GR_TEXFMT_RGB_565;
- if (mesaFormat)
- *mesaFormat = MESA_R5_G6_B5;
- if (texelSize)
- *texelSize = 2;
- }
- break;
- case GL_RGBA2:
- case GL_RGBA4:
- if (glideFormat)
- *glideFormat = GR_TEXFMT_ARGB_4444;
- if (mesaFormat)
- *mesaFormat = MESA_A4_R4_G4_B4;
- if (texelSize)
- *texelSize = 2;
- break;
- case 4:
- case GL_RGBA:
- case GL_RGBA8:
- case GL_RGB10_A2:
- case GL_RGBA12:
- case GL_RGBA16:
- if (allow32bpp) {
- if (glideFormat)
- *glideFormat = GR_TEXFMT_ARGB_8888;
- if (mesaFormat)
- *mesaFormat = MESA_A8_R8_G8_B8;
- if (texelSize)
- *texelSize = 4;
- }
- else {
- if (glideFormat)
- *glideFormat = GR_TEXFMT_ARGB_4444;
- if (mesaFormat)
- *mesaFormat = MESA_A4_R4_G4_B4;
- if (texelSize)
- *texelSize = 2;
- }
- break;
- case GL_RGB5_A1:
- if (glideFormat)
- *glideFormat = GR_TEXFMT_ARGB_1555;
- if (mesaFormat)
- *mesaFormat = MESA_A1_R5_G5_B5;
- if (texelSize)
- *texelSize = 2;
- break;
- case GL_COLOR_INDEX:
- case GL_COLOR_INDEX1_EXT:
- case GL_COLOR_INDEX2_EXT:
- case GL_COLOR_INDEX4_EXT:
- case GL_COLOR_INDEX8_EXT:
- case GL_COLOR_INDEX12_EXT:
- case GL_COLOR_INDEX16_EXT:
- if (glideFormat)
- *glideFormat = GR_TEXFMT_P_8;
- if (mesaFormat)
- *mesaFormat = MESA_C8;
- if (texelSize)
- *texelSize = 1;
- break;
- case GL_COMPRESSED_RGB_FXT1_3DFX:
- if (glideFormat)
- *glideFormat = GR_TEXFMT_ARGB_CMP_FXT1;
- if (mesaFormat)
- *mesaFormat = MESA_A8_R8_G8_B8;
- if (texelSize)
- *texelSize = 4;
- break;
- case GL_COMPRESSED_RGBA_FXT1_3DFX:
- if (glideFormat)
- *glideFormat = GR_TEXFMT_ARGB_CMP_FXT1;
- if (mesaFormat)
- *mesaFormat = MESA_A8_R8_G8_B8;
- if (texelSize)
- *texelSize = 4;
- break;
- default:
- fprintf(stderr, "bad texture format in fxTexGetFormat() %d", intFormatHint);
- break;
- }
-}
+/* ================================================================
+ *
+ */
-/**********************************************************************/
-/**** NEW TEXTURE IMAGE FUNCTIONS ****/
-/**********************************************************************/
+static void tdfxDDTexEnv( GLcontext *ctx, GLenum target,
+ GLenum pname, const GLfloat *param )
+{
+ tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
-static FxBool TexusFatalError = FXFALSE;
-static FxBool TexusError = FXFALSE;
+ if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) {
+ if ( param ) {
+ fprintf( stderr, __FUNCTION__"( %x, %x )\n", pname, (GLint)(*param) );
+ } else {
+ fprintf( stderr, __FUNCTION__"( %x )\n", pname );
+ }
+ }
-#define TX_DITHER_NONE 0x00000000
+ fxMesa->new_state |= TDFX_NEW_TEXTURE;
+}
-static void
-fxTexusError(const char *string, FxBool fatal)
+static void tdfxDDTexParameter( GLcontext *ctx, GLenum target,
+ struct gl_texture_object *tObj,
+ GLenum pname, const GLfloat *params )
{
- gl_problem(NULL, string);
- /*
- * Just propagate the fatal value up.
- */
- TexusError = FXTRUE;
- TexusFatalError = fatal;
+ tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
+ GLenum param = (GLenum) (GLint) params[0];
+ tdfxTexObjPtr t;
+
+ if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) {
+ fprintf( stderr, __FUNCTION__ "( %d, %p, %x, %x )\n",
+ tObj->Name, tObj->DriverData, pname, param );
+ }
+
+ if ( target != GL_TEXTURE_2D )
+ return;
+
+ if ( !tObj->DriverData )
+ tObj->DriverData = tdfxAllocTexObj( fxMesa );
+
+ t = TDFX_TEXTURE_DATA(tObj);
+
+ switch ( pname ) {
+ case GL_TEXTURE_MIN_FILTER:
+ switch ( param ) {
+ case GL_NEAREST:
+ t->mmMode = GR_MIPMAP_DISABLE;
+ t->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED;
+ t->LODblend = FXFALSE;
+ break;
+
+ case GL_LINEAR:
+ t->mmMode = GR_MIPMAP_DISABLE;
+ t->minFilt = GR_TEXTUREFILTER_BILINEAR;
+ t->LODblend = FXFALSE;
+ break;
+
+ case GL_NEAREST_MIPMAP_LINEAR:
+ if ( TDFX_IS_NAPALM(fxMesa) ) {
+ if ( fxMesa->numTMUs > 1 ) {
+ t->mmMode = GR_MIPMAP_NEAREST;
+ t->LODblend = FXTRUE;
+ } else {
+ t->mmMode = GR_MIPMAP_NEAREST_DITHER;
+ t->LODblend = FXFALSE;
+ }
+ t->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED;
+ break;
+ }
+ /* XXX Voodoo3/Banshee mipmap blending seems to produce
+ * incorrectly filtered colors for the smallest mipmap levels.
+ * To work-around we fall-through here and use a different filter.
+ */
+ case GL_NEAREST_MIPMAP_NEAREST:
+ t->mmMode = GR_MIPMAP_NEAREST;
+ t->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED;
+ t->LODblend = FXFALSE;
+ break;
+
+ case GL_LINEAR_MIPMAP_LINEAR:
+ if ( TDFX_IS_NAPALM(fxMesa) ) {
+ if ( fxMesa->numTMUs > 1 ) {
+ t->mmMode = GR_MIPMAP_NEAREST;
+ t->LODblend = FXTRUE;
+ } else {
+ t->mmMode = GR_MIPMAP_NEAREST_DITHER;
+ t->LODblend = FXFALSE;
+ }
+ t->minFilt = GR_TEXTUREFILTER_BILINEAR;
+ break;
+ }
+ /* XXX Voodoo3/Banshee mipmap blending seems to produce
+ * incorrectly filtered colors for the smallest mipmap levels.
+ * To work-around we fall-through here and use a different filter.
+ */
+ case GL_LINEAR_MIPMAP_NEAREST:
+ t->mmMode = GR_MIPMAP_NEAREST;
+ t->minFilt = GR_TEXTUREFILTER_BILINEAR;
+ t->LODblend = FXFALSE;
+ break;
+ default:
+ break;
+ }
+ tdfxRevalidateTexture( ctx, tObj );
+ fxMesa->new_state |= TDFX_NEW_TEXTURE;
+ break;
+
+ case GL_TEXTURE_MAG_FILTER:
+ switch ( param ) {
+ case GL_NEAREST:
+ t->magFilt = GR_TEXTUREFILTER_POINT_SAMPLED;
+ break;
+ case GL_LINEAR:
+ t->magFilt = GR_TEXTUREFILTER_BILINEAR;
+ break;
+ default:
+ break;
+ }
+ fxMesa->new_state |= TDFX_NEW_TEXTURE;
+ break;
+
+ case GL_TEXTURE_WRAP_S:
+ switch ( param ) {
+ case GL_CLAMP:
+ t->sClamp = GR_TEXTURECLAMP_CLAMP;
+ break;
+ case GL_REPEAT:
+ t->sClamp = GR_TEXTURECLAMP_WRAP;
+ break;
+ default:
+ break;
+ }
+ fxMesa->new_state |= TDFX_NEW_TEXTURE;
+ break;
+
+ case GL_TEXTURE_WRAP_T:
+ switch ( param ) {
+ case GL_CLAMP:
+ t->tClamp = GR_TEXTURECLAMP_CLAMP;
+ break;
+ case GL_REPEAT:
+ t->tClamp = GR_TEXTURECLAMP_WRAP;
+ break;
+ default:
+ break;
+ }
+ fxMesa->new_state |= TDFX_NEW_TEXTURE;
+ break;
+
+ case GL_TEXTURE_BASE_LEVEL:
+ tdfxRevalidateTexture( ctx, tObj );
+ break;
+
+ case GL_TEXTURE_MAX_LEVEL:
+ tdfxRevalidateTexture( ctx, tObj );
+ break;
+
+ case GL_TEXTURE_BORDER_COLOR:
+ /* TO DO */
+ break;
+ case GL_TEXTURE_MIN_LOD:
+ /* TO DO */
+ break;
+ case GL_TEXTURE_MAX_LOD:
+ /* TO DO */
+ break;
+
+ default:
+ break;
+ }
}
-GLboolean
-tdfxDDTexImage2D(GLcontext * ctx, GLenum target, GLint level,
- GLenum format, GLenum type, const GLvoid * pixels,
- const struct gl_pixelstore_attrib * packing,
- struct gl_texture_object * texObj,
- struct gl_texture_image * texImage,
- GLboolean * retainInternalCopy)
+static void tdfxDDBindTexture( GLcontext *ctx, GLenum target,
+ struct gl_texture_object *tObj )
{
- tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
- const GLboolean allow32bpt = TDFX_IS_NAPALM(fxMesa);
- GrTextureFormat_t gldformat;
- tdfxTexInfo *ti;
- tdfxMipMapLevel *mml;
- GLint dstWidth, dstHeight, wScale, hScale, texelSize, dstStride;
- MesaIntTexFormat intFormat;
- GLboolean isCompressedFormat;
- GLint texsize;
- void *uncompressedImage;
-
- /*
- printf("TexImage id=%d int 0x%x format 0x%x type 0x%x %dx%d\n",
- texObj->Name, texImage->IntFormat, format, type,
- texImage->Width, texImage->Height);
- */
+ tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
+ tdfxTexObjPtr t;
- isCompressedFormat = texImage->IsCompressed;
- if (target != GL_TEXTURE_2D || texImage->Border > 0)
- return GL_FALSE;
-
- if (!texObj->DriverData)
- texObj->DriverData = fxAllocTexObjData(fxMesa);
-
- ti = TDFX_TEXTURE_DATA(texObj);
- mml = &ti->mipmapLevel[level];
-
- /* Determine the appropriate GL internal texel format, Mesa internal
- * texel format, and texelSize (bytes) given the user's internal
- * texture format hint.
- */
- tdfxTexGetFormat(texImage->IntFormat, allow32bpt,
- &gldformat, &intFormat, &texelSize);
-
- /* Determine width and height scale factors for texture.
- * Remember, Glide is limited to 8:1 aspect ratios.
- */
- tdfxTexGetInfo(ctx,
- texImage->Width, texImage->Height,
- NULL, /* lod level */
- NULL, /* aspect ratio */
- NULL, NULL, /* sscale, tscale */
- &wScale, &hScale);
- dstWidth = texImage->Width * wScale;
- dstHeight = texImage->Height * hScale;
- if (isCompressedFormat) {
- texsize = tdfxDDCompressedImageSize(ctx,
- texImage->IntFormat,
- 2,
- texImage->Width,
- texImage->Height,
- 1);
- }
- else {
- texsize = dstWidth * dstHeight * texelSize;
- }
-
- /*
- * If the image is not compressed, this doesn't
- * matter, but it might as well have a sensible
- * value, and it might save a failure later on.
- */
- texImage->CompressedSize = texsize;
- /* housekeeping */
- _mesa_set_teximage_component_sizes(intFormat, texImage);
-
- /*
- * allocate new storage for texture image, if needed.
- * This conditional wants to set uncompressedImage to
- * point to the uncompressed image, and mml->data to
- * the texture data. If the image is uncompressed,
- * these are identical. If the image is not compressed,
- * these are different.
- */
- if (!mml->data || mml->glideFormat != gldformat ||
- mml->width != dstWidth || mml->height != dstHeight ||
- texsize != mml->dataSize ) {
- if (mml->data) {
- FREE(mml->data);
- }
- uncompressedImage
- = (void *)MALLOC(dstWidth * dstHeight * texelSize);
- if (!uncompressedImage) {
- return GL_FALSE;
- }
- if (isCompressedFormat) {
- mml->data = MALLOC(texsize);
- if (!mml->data) {
- FREE(uncompressedImage);
- return GL_FALSE;
- }
- } else {
- mml->data = uncompressedImage;
- }
- mml->texelSize = texelSize;
- mml->glideFormat = gldformat;
- mml->width = dstWidth;
- mml->height = dstHeight;
- mml->dataSize = texsize;
- ti->info.format = gldformat;
- tdfxTMMoveOutTM(fxMesa, texObj);
- /*tdfxTexInvalidate(ctx, texObj);*/
- }
- else {
- /*
- * Here we don't have to allocate anything, but we
- * do have to point uncompressedImage to the uncompressed
- * data.
- */
- if (isCompressedFormat) {
- uncompressedImage
- = (void *)MALLOC(dstWidth * dstHeight * texelSize);
- if (!uncompressedImage) {
- return GL_FALSE;
- }
- } else {
- uncompressedImage = mml->data;
- }
- }
-
- dstStride = dstWidth * texelSize;
-
- /* store the texture image into uncompressedImage */
- if (!_mesa_convert_teximage(intFormat,
- dstWidth, dstHeight,
- uncompressedImage,
- dstStride,
- texImage->Width, texImage->Height,
- format, type, pixels, packing)) {
- /*printf("convert failed\n");*/
- return GL_FALSE; /* not necessarily an error */
- }
-
- /*
- * Now compress it if necessary.
- */
- if (isCompressedFormat) {
- TxErrorCallbackFnc_t oldErrorCallback;
- (*txErrorSetCallbackProc)(fxTexusError, &oldErrorCallback);
- (*txImgQuantizeProc)((char *)mml->data,
- (char *)uncompressedImage,
- texImage->Width,
- texImage->Height,
- gldformat,
- TX_DITHER_NONE);
- (*txErrorSetCallbackProc)(oldErrorCallback, NULL);
- if (uncompressedImage != mml->data) {
- /*
- * We do not need this any more, errors or no.
- */
- FREE(uncompressedImage);
- }
- TexusError = FXFALSE;
- if (TexusFatalError) {
- FREE(mml->data);
- mml->data = NULL;
- TexusFatalError = FXFALSE;
- return GL_FALSE;
- }
- }
-
-
- RevalidateTexture(ctx, texObj);
-
- ti->reloadImages = GL_TRUE;
- fxMesa->new_state |= TDFX_NEW_TEXTURE;
-
- *retainInternalCopy = GL_FALSE;
- return GL_TRUE;
-}
+ if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) {
+ fprintf( stderr, __FUNCTION__ "( %d, %p )\n",
+ tObj->Name, tObj->DriverData );
+ }
+ if ( target != GL_TEXTURE_2D )
+ return;
-GLboolean
-tdfxDDTexSubImage2D(GLcontext * ctx, GLenum target, GLint level,
- GLint xoffset, GLint yoffset,
- GLsizei width, GLsizei height,
- GLenum format, GLenum type, const GLvoid * pixels,
- const struct gl_pixelstore_attrib * packing,
- struct gl_texture_object * texObj,
- struct gl_texture_image * texImage)
-{
- tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
- tdfxTexInfo *ti;
- GLint wscale, hscale, dstStride = 0;
- tdfxMipMapLevel *mml;
- GLboolean result;
- void *uncompressedImage = (void *)0;
- FxU32 uncompressedSize;
- TxErrorCallbackFnc_t oldErrorCallback;
-
- if (target != GL_TEXTURE_2D)
- return GL_FALSE;
-
- if (!texObj->DriverData)
- return GL_FALSE;
-
- /*
- printf("TexSubImage id=%d lvl=%d int=0x%x format=0x%x type=0x%x x=%d y=%d w=%d h=%d fullW=%d fullH=%d\n",
- texObj->Name, level,
- texImage->IntFormat, format, type, xoffset, yoffset, width, height,
- texImage->Width, texImage->Height);
- */
+ if ( !tObj->DriverData )
+ tObj->DriverData = tdfxAllocTexObj( fxMesa );
- ti = TDFX_TEXTURE_DATA(texObj);
- mml = &ti->mipmapLevel[level];
-
- tdfxTexGetInfo(ctx, texImage->Width, texImage->Height, NULL, NULL,
- NULL, NULL, &wscale, &hscale);
-
- /*
- * Must have an existing texture image!
- */
- assert(mml->data);
-
- switch (mml->glideFormat) {
- case GR_TEXFMT_INTENSITY_8:
- dstStride = mml->width;
- result = _mesa_convert_texsubimage(MESA_I8, xoffset, yoffset,
- mml->width, mml->height, mml->data,
- dstStride, width, height,
- texImage->Width, texImage->Height,
- format, type, pixels, packing);
- break;
- case GR_TEXFMT_ALPHA_8:
- dstStride = mml->width;
- result = _mesa_convert_texsubimage(MESA_A8, xoffset, yoffset,
- mml->width, mml->height, mml->data,
- dstStride, width, height,
- texImage->Width, texImage->Height,
- format, type, pixels, packing);
- break;
- case GR_TEXFMT_P_8:
- dstStride = mml->width;
- result = _mesa_convert_texsubimage(MESA_C8, xoffset, yoffset,
- mml->width, mml->height, mml->data,
- dstStride, width, height,
- texImage->Width, texImage->Height,
- format, type, pixels, packing);
- break;
- case GR_TEXFMT_ALPHA_INTENSITY_88:
- dstStride = mml->width * 2;
- result = _mesa_convert_texsubimage(MESA_A8_L8, xoffset, yoffset,
- mml->width, mml->height, mml->data,
- dstStride, width, height,
- texImage->Width, texImage->Height,
- format, type, pixels, packing);
- break;
- case GR_TEXFMT_RGB_565:
- dstStride = mml->width * 2;
- result = _mesa_convert_texsubimage(MESA_R5_G6_B5, xoffset, yoffset,
- mml->width, mml->height, mml->data,
- dstStride, width, height,
- texImage->Width, texImage->Height,
- format, type, pixels, packing);
- break;
- case GR_TEXFMT_ARGB_4444:
- dstStride = mml->width * 2;
- result = _mesa_convert_texsubimage(MESA_A4_R4_G4_B4, xoffset, yoffset,
- mml->width, mml->height, mml->data,
- dstStride, width, height,
- texImage->Width, texImage->Height,
- format, type, pixels, packing);
- break;
- case GR_TEXFMT_ARGB_CMP_FXT1:
- /*
- * There are some special legality constraints for compressed
- * textures.
- */
- if ((xoffset != texImage->Border)
- || (yoffset != texImage->Border)) {
- gl_error( ctx,
- GL_INVALID_OPERATION,
- "glTexSubImage2D(offset)" );
- return GL_FALSE;
- }
- if ((width != texImage->Width)
- || (height != texImage->Height)) {
- gl_error( ctx,
- GL_INVALID_VALUE,
- "glTexSubImage2D(image size)" );
- return GL_FALSE;
- }
- /*
- * The width and height have to be multiples of
- * 8 and 4 respectively.
- */
- width = (mml->width + 0x7) &~ 0x7;
- height = (mml->height + 0x3) &~ 0x3;
- /*
- * A texel is 8888 for this format.
- */
- uncompressedSize = mml->width * mml->height * 4;
- uncompressedImage = (void *)MALLOC(uncompressedSize);
- /*
- * Convert the data.
- */
- dstStride = mml->width * 4;
- result = _mesa_convert_texsubimage(MESA_A8_R8_G8_B8, xoffset, yoffset,
- mml->width, mml->height, uncompressedImage,
- dstStride, width, height,
- texImage->Width, texImage->Height,
- format, type, pixels, packing);
- if (!result) {
- FREE(uncompressedImage);
- printf("TexSubImage convert failed\n");
- return GL_FALSE;
- }
- /*
- * Now that we have converted the data, then compress it.
- */
- (*txErrorSetCallbackProc)(fxTexusError, &oldErrorCallback);
- (*txImgQuantizeProc)((char *)mml->data,
- (char *)uncompressedImage,
- mml->width,
- mml->height,
- mml->glideFormat,
- TX_DITHER_NONE);
- (*txErrorSetCallbackProc)(oldErrorCallback, NULL);
- result = TexusFatalError;
- TexusFatalError = TexusError = FXFALSE;
- /*
- * We don't need this any more.
- */
- FREE(uncompressedImage);
- break;
- case GR_TEXFMT_ARGB_8888:
- {
- MesaIntTexFormat intFormat;
- if (texImage->Format == GL_RGB) {
- /* An RGB image padded out to 4 bytes/texel */
- intFormat = MESA_FF_R8_G8_B8;
- }
- else {
- intFormat = MESA_A8_R8_G8_B8;
- }
- dstStride = mml->width * 4;
- result = _mesa_convert_texsubimage(intFormat, xoffset, yoffset,
- mml->width, mml->height, mml->data,
- dstStride, width, height,
- texImage->Width, texImage->Height,
- format, type, pixels, packing);
- }
- break;
- case GR_TEXFMT_ARGB_1555:
- dstStride = mml->width * 2;
- result = _mesa_convert_texsubimage(MESA_A1_R5_G5_B5, xoffset, yoffset,
- mml->width, mml->height, mml->data,
- dstStride, width, height,
- texImage->Width, texImage->Height,
- format, type, pixels, packing);
- break;
- default:
- gl_problem(NULL, "tdfx driver: fxTexBuildSubImageMap() bad format");
- result = GL_FALSE;
- }
-
- if (!result) {
- return GL_FALSE;
- }
-
- ti->reloadImages = GL_TRUE; /* signal the image needs to be reloaded */
- fxMesa->new_state |= TDFX_NEW_TEXTURE; /* XXX this might be a bit much */
-
- return GL_TRUE;
+ t = TDFX_TEXTURE_DATA(tObj);
+ t->lastTimeUsed = fxMesa->texBindNumber++;
+
+ fxMesa->new_state |= TDFX_NEW_TEXTURE;
}
+static void tdfxDDDeleteTexture( GLcontext *ctx,
+ struct gl_texture_object *tObj )
+{
+ tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
-/**********************************************************************/
-/**** COMPRESSED TEXTURE IMAGE FUNCTIONS ****/
-/**********************************************************************/
+ LOCK_HARDWARE( fxMesa );
+ tdfxTMFreeTextureLocked( fxMesa, tObj );
+ UNLOCK_HARDWARE( fxMesa );
-GLboolean
-tdfxDDCompressedTexImage2D( GLcontext *ctx, GLenum target,
- GLint level, GLsizei imageSize,
- const GLvoid *data,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage,
- GLboolean *retainInternalCopy)
-{
- tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
- const GLboolean allow32bpt = TDFX_IS_NAPALM(fxMesa);
- GrTextureFormat_t gldformat;
- tdfxTexInfo *ti;
- tdfxMipMapLevel *mml;
- GLint dstWidth, dstHeight, wScale, hScale, texelSize;
- MesaIntTexFormat intFormat;
- GLboolean isCompressedFormat;
- GLsizei texsize;
-
- if (target != GL_TEXTURE_2D || texImage->Border > 0)
- return GL_FALSE;
-
- if (!texObj->DriverData)
- texObj->DriverData = fxAllocTexObjData(fxMesa);
-
- ti = TDFX_TEXTURE_DATA(texObj);
- mml = &ti->mipmapLevel[level];
-
- isCompressedFormat = tdfxDDIsCompressedGlideFormatMacro(texImage->IntFormat);
- if (!isCompressedFormat) {
- gl_error( ctx, GL_INVALID_ENUM, "glCompressedTexImage2D(format)" );
- return GL_FALSE;
- }
- /* Determine the apporpriate GL internal texel format, Mesa internal
- * texel format, and texelSize (bytes) given the user's internal
- * texture format hint.
- */
- tdfxTexGetFormat(texImage->IntFormat, allow32bpt,
- &gldformat, &intFormat, &texelSize);
-
- /* Determine width and height scale factors for texture.
- * Remember, Glide is limited to 8:1 aspect ratios.
- */
- tdfxTexGetInfo(ctx,
- texImage->Width, texImage->Height,
- NULL, /* lod level */
- NULL, /* aspect ratio */
- NULL, NULL, /* sscale, tscale */
- &wScale, &hScale);
- dstWidth = texImage->Width * wScale;
- dstHeight = texImage->Height * hScale;
- /* housekeeping */
- _mesa_set_teximage_component_sizes(intFormat, texImage);
-
- texsize = tdfxDDCompressedImageSize(ctx,
- texImage->IntFormat,
- 2,
- texImage->Width,
- texImage->Height,
- 1);
- if (texsize != imageSize) {
- gl_error(ctx,
- GL_INVALID_VALUE,
- "glCompressedTexImage2D(texsize)");
- return GL_FALSE;
- }
-
- /* allocate new storage for texture image, if needed */
- if (!mml->data || mml->glideFormat != gldformat ||
- mml->width != dstWidth || mml->height != dstHeight ||
- texsize != mml->dataSize) {
- if (mml->data) {
- FREE(mml->data);
- }
- mml->data = MALLOC(texsize);
- if (!mml->data) {
- return GL_FALSE;
- }
- mml->texelSize = texelSize;
- mml->glideFormat = gldformat;
- mml->width = dstWidth;
- mml->height = dstHeight;
- tdfxTMMoveOutTM(fxMesa, texObj);
- /*tdfxTexInvalidate(ctx, texObj);*/
- }
-
- /* save the texture data */
- MEMCPY(mml->data, data, imageSize);
-
- RevalidateTexture(ctx, texObj);
-
- ti->reloadImages = GL_TRUE;
- fxMesa->new_state |= TDFX_NEW_TEXTURE;
-
- *retainInternalCopy = GL_FALSE;
- return GL_TRUE;
+ fxMesa->new_state |= TDFX_NEW_TEXTURE;
}
-GLboolean
-tdfxDDCompressedTexSubImage2D( GLcontext *ctx, GLenum target,
- GLint level, GLint xoffset,
- GLint yoffset, GLsizei width,
- GLint height, GLenum format,
- GLsizei imageSize, const GLvoid *data,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage )
+static GLboolean tdfxDDIsTextureResident( GLcontext *ctx,
+ struct gl_texture_object *tObj )
{
- tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
- tdfxTexInfo *ti;
- tdfxMipMapLevel *mml;
-
- /*
- * We punt if we are not replacing the entire image. This
- * is allowed by the spec.
- */
- if ((xoffset != 0) && (yoffset != 0)
- && (width != texImage->Width)
- && (height != texImage->Height)) {
- return GL_FALSE;
- }
-
- ti = TDFX_TEXTURE_DATA(texObj);
- mml = &ti->mipmapLevel[level];
- if (imageSize != mml->dataSize) {
- return GL_FALSE;
- }
- MEMCPY(data, mml->data, imageSize);
-
- ti->reloadImages = GL_TRUE;
- fxMesa->new_state |= TDFX_NEW_TEXTURE;
-
- return GL_TRUE;
+ tdfxTexObjPtr t = TDFX_TEXTURE_DATA(tObj);
+
+ return ( t && t->isInTM );
}
-#if 0
+/* Convert a gl_color_table texture palette to Glide's format.
+ */
static void
-PrintTexture(int w, int h, int c, const GLubyte * data)
+tdfxConvertPalette( FxU32 data[256], const struct gl_color_table *table )
{
- int i, j;
- for (i = 0; i < h; i++) {
- for (j = 0; j < w; j++) {
- if (c == 2)
- printf("%02x %02x ", data[0], data[1]);
- else if (c == 3)
- printf("%02x %02x %02x ", data[0], data[1], data[2]);
- data += c;
- }
- printf("\n");
- }
+ const GLubyte *tableUB = (const GLubyte *) table->Table;
+ GLint width = table->Size;
+ FxU32 r, g, b, a;
+ GLint i;
+
+ ASSERT( table->TableType == GL_UNSIGNED_BYTE );
+
+ switch ( table->Format ) {
+ case GL_RGBA:
+ for ( i = 0 ; i < width ; i++ ) {
+ r = tableUB[i * 4 + 0];
+ g = tableUB[i * 4 + 1];
+ b = tableUB[i * 4 + 2];
+ a = tableUB[i * 4 + 3];
+ data[i] = PACK_COLOR_8888( a, r, g, b );
+ }
+ break;
+ case GL_RGB:
+ for ( i = 0 ; i < width ; i++ ) {
+ r = tableUB[i * 3 + 0];
+ g = tableUB[i * 3 + 1];
+ b = tableUB[i * 3 + 2];
+ a = 255;
+ data[i] = PACK_COLOR_8888( a, r, g, b );
+ }
+ break;
+ case GL_LUMINANCE:
+ for ( i = 0 ; i < width ; i++ ) {
+ r = tableUB[i];
+ g = tableUB[i];
+ b = tableUB[i];
+ a = 255;
+ data[i] = PACK_COLOR_8888( a, r, g, b );
+ }
+ break;
+ case GL_ALPHA:
+ for ( i = 0 ; i < width ; i++ ) {
+ r = g = b = 255;
+ a = tableUB[i];
+ data[i] = PACK_COLOR_8888( a, r, g, b );
+ }
+ break;
+ case GL_LUMINANCE_ALPHA:
+ for ( i = 0 ; i < width ; i++ ) {
+ r = g = b = tableUB[i * 2 + 0];
+ a = tableUB[i * 2 + 1];
+ data[i] = PACK_COLOR_8888( a, r, g, b );
+ }
+ break;
+ case GL_INTENSITY:
+ for ( i = 0 ; i < width ; i++ ) {
+ r = tableUB[i];
+ g = tableUB[i];
+ b = tableUB[i];
+ a = tableUB[i];
+ data[i] = PACK_COLOR_8888( a, r, g, b );
+ }
+ break;
+ }
}
-#endif
-
-GLboolean
-tdfxDDTestProxyTexImage(GLcontext *ctx, GLenum target,
- GLint level, GLint internalFormat,
- GLenum format, GLenum type,
- GLint width, GLint height,
- GLint depth, GLint border)
+static void
+tdfxDDTexturePalette( GLcontext *ctx, struct gl_texture_object *tObj )
{
- tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
- struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared;
- struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData;
-
- switch (target) {
- case GL_PROXY_TEXTURE_1D:
- return GL_TRUE; /* software rendering */
- case GL_PROXY_TEXTURE_2D:
- {
- struct gl_texture_object *tObj;
- tdfxTexInfo *ti;
- int memNeeded;
-
- tObj = ctx->Texture.Proxy2D;
- if (!tObj->DriverData)
- tObj->DriverData = fxAllocTexObjData(fxMesa);
- ti = TDFX_TEXTURE_DATA(tObj);
-
- /* assign the parameters to test against */
- tObj->Image[level]->Width = width;
- tObj->Image[level]->Height = height;
- tObj->Image[level]->Border = border;
- tObj->Image[level]->IntFormat = internalFormat;
- if (level == 0) {
- /* don't use mipmap levels > 0 */
- tObj->MinFilter = tObj->MagFilter = GL_NEAREST;
- }
- else {
- /* test with all mipmap levels */
- tObj->MinFilter = GL_LINEAR_MIPMAP_LINEAR;
- tObj->MagFilter = GL_NEAREST;
- }
- RevalidateTexture(ctx, tObj);
-
- /*
- printf("small lodlog2 0x%x\n", ti->info.smallLodLog2);
- printf("large lodlog2 0x%x\n", ti->info.largeLodLog2);
- printf("aspect ratio 0x%x\n", ti->info.aspectRatioLog2);
- printf("glide format 0x%x\n", ti->info.format);
- printf("data %p\n", ti->info.data);
- printf("lodblend %d\n", (int) ti->LODblend);
- */
-
- /* determine where texture will reside */
- if (ti->LODblend && !shared->umaTexMemory) {
- /* XXX GR_MIPMAPLEVELMASK_BOTH might not be right, but works */
- memNeeded = FX_grTexTextureMemRequired_NoLock(
- GR_MIPMAPLEVELMASK_BOTH, &(ti->info));
- }
- else {
- /* XXX GR_MIPMAPLEVELMASK_BOTH might not be right, but works */
- memNeeded = FX_grTexTextureMemRequired_NoLock(
- GR_MIPMAPLEVELMASK_BOTH, &(ti->info));
- }
- /*
- printf("Proxy test %d > %d\n", memNeeded, shared->totalTexMem[0]);
- */
- if (memNeeded > shared->totalTexMem[0])
- return GL_FALSE;
- else
- return GL_TRUE;
- }
- case GL_PROXY_TEXTURE_3D:
- return GL_TRUE; /* software rendering */
- default:
- return GL_TRUE; /* never happens, silence compiler */
- }
+ tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
+ tdfxTexObjPtr t;
+
+ if ( tObj ) {
+ /* Per-texture palette */
+ if ( !tObj->DriverData )
+ tObj->DriverData = tdfxAllocTexObj(fxMesa);
+
+ t = TDFX_TEXTURE_DATA(tObj);
+ tdfxConvertPalette( t->palette.data, &tObj->Palette );
+ /*tdfxTexInvalidate( ctx, tObj );*/
+ } else {
+ /* Global texture palette */
+ tdfxConvertPalette( fxMesa->glbPalette.data, &ctx->Texture.Palette );
+ }
+
+ fxMesa->new_state |= TDFX_NEW_TEXTURE; /* XXX too heavy-handed */
}
-/*
- * Return a texture image to Mesa. This is either to satisfy
- * a glGetTexImage() call or to prepare for software texturing.
- */
-GLvoid *
-tdfxDDGetTexImage(GLcontext * ctx, GLenum target, GLint level,
- const struct gl_texture_object *texObj,
- GLenum * formatOut, GLenum * typeOut,
- GLboolean * freeImageOut)
-{
- tdfxTexInfo *ti;
- tdfxMipMapLevel *mml;
-
- if (target != GL_TEXTURE_2D)
- return NULL;
-
- if (!texObj->DriverData)
- return NULL;
-
- ti = TDFX_TEXTURE_DATA(texObj);
- mml = &ti->mipmapLevel[level];
- if (mml->data) {
- MesaIntTexFormat mesaFormat;
- GLenum glFormat;
- struct gl_texture_image *texImage = texObj->Image[level];
- GLint srcStride;
- void *uncompressedImage = NULL;
-
- GLubyte *data =
- (GLubyte *) MALLOC(texImage->Width * texImage->Height * 4);
- if (!data)
- return NULL;
-
- uncompressedImage = (void *)mml->data;
- switch (mml->glideFormat) {
- case GR_TEXFMT_INTENSITY_8:
- mesaFormat = MESA_I8;
- glFormat = GL_INTENSITY;
- srcStride = mml->width;
- break;
- case GR_TEXFMT_ALPHA_INTENSITY_88:
- mesaFormat = MESA_A8_L8;
- glFormat = GL_LUMINANCE_ALPHA;
- srcStride = mml->width;
- break;
- case GR_TEXFMT_ALPHA_8:
- if (texImage->Format == GL_INTENSITY) {
- mesaFormat = MESA_I8;
- glFormat = GL_INTENSITY;
- }
- else {
- mesaFormat = MESA_A8;
- glFormat = GL_ALPHA;
- }
- srcStride = mml->width;
- break;
- case GR_TEXFMT_RGB_565:
- mesaFormat = MESA_R5_G6_B5;
- glFormat = GL_RGB;
- srcStride = mml->width * 2;
- break;
- case GR_TEXFMT_ARGB_8888:
- mesaFormat = MESA_A8_R8_G8_B8;
- glFormat = GL_RGBA;
- srcStride = mml->width * 4;
- break;
- case GR_TEXFMT_ARGB_4444:
- mesaFormat = MESA_A4_R4_G4_B4;
- glFormat = GL_RGBA;
- srcStride = mml->width * 2;
- break;
- case GR_TEXFMT_ARGB_1555:
- mesaFormat = MESA_A1_R5_G5_B5;
- glFormat = GL_RGBA;
- srcStride = mml->width * 2;
- break;
- case GR_TEXFMT_P_8:
- mesaFormat = MESA_C8;
- glFormat = GL_COLOR_INDEX;
- srcStride = mml->width;
- break;
- case GR_TEXFMT_ARGB_CMP_FXT1:
- mesaFormat = MESA_A8_R8_G8_B8;
- glFormat = GL_RGBA;
- srcStride = mml->width * 4;
- /*
- * Allocate data for the uncompressed image,
- * decompress the image. The data will be deallocated
- * after it is converted to the mesa format.
- */
- uncompressedImage = MALLOC(mml->width * mml->height * 4);
- if (!uncompressedImage) {
- gl_problem(NULL, "can't get memory in tdfxDDGetTexImage");
- return NULL;
- }
- (*txImgDequantizeFXT1Proc)((FxU32 *)uncompressedImage,
- (FxU32 *)mml->data,
- mml->width,
- mml->height);
- break;
- default:
- gl_problem(NULL, "Bad glideFormat in tdfxDDGetTexImage");
- return NULL;
- }
- _mesa_unconvert_teximage(mesaFormat, mml->width, mml->height,
- uncompressedImage, srcStride, texImage->Width,
- texImage->Height, glFormat, data);
- if (uncompressedImage != mml->data) {
- FREE(uncompressedImage);
- }
- *formatOut = glFormat;
- *typeOut = GL_UNSIGNED_BYTE;
- *freeImageOut = GL_TRUE;
- return data;
- }
- else {
- return NULL;
- }
-}
-/*
- * This is called from _mesa_GetCompressedTexImage. We just
- * copy out the compressed data.
- */
-void
-tdfxDDGetCompressedTexImage( GLcontext *ctx, GLenum target,
- GLint lod, void *image,
- const struct gl_texture_object *texObj,
- struct gl_texture_image *texImage )
-{
- tdfxTexInfo *ti;
- tdfxMipMapLevel *mml;
- if (target != GL_TEXTURE_2D)
- return;
+/**********************************************************************/
+/**** NEW TEXTURE IMAGE FUNCTIONS ****/
+/**********************************************************************/
- if (!texObj->DriverData)
- return;
- ti = TDFX_TEXTURE_DATA(texObj);
- mml = &ti->mipmapLevel[lod];
- if (mml->data) {
- MEMCPY(image, mml->data, mml->dataSize);
- }
-}
-/*
- * Calculate a specific texture format given a generic
- * texture format.
- */
-GLint
-tdfxDDSpecificCompressedTexFormat(GLcontext *ctx,
- GLint internalFormat,
- GLint numDimensions)
+#if 0
+static void
+PrintTexture(int w, int h, int c, const GLubyte * data)
{
- if (numDimensions != 2) {
- return internalFormat;
- }
- /*
- * If we don't have pointers to the functions, then
- * we drop back to uncompressed format. The logic
- * in Mesa proper handles this for us.
- *
- * This is just to ease the transition to a Glide with
- * the texus2 library.
- */
- if (!txImgQuantizeProc || !txImgDequantizeFXT1Proc) {
- return internalFormat;
- }
- switch (internalFormat) {
- case GL_COMPRESSED_RGB_ARB:
- return GL_COMPRESSED_RGB_FXT1_3DFX;
- case GL_COMPRESSED_RGBA_ARB:
- return GL_COMPRESSED_RGBA_FXT1_3DFX;
- }
- return internalFormat;
+ int i, j;
+ for (i = 0; i < h; i++) {
+ for (j = 0; j < w; j++) {
+ if (c == 2)
+ printf("%02x %02x ", data[0], data[1]);
+ else if (c == 3)
+ printf("%02x %02x %02x ", data[0], data[1], data[2]);
+ data += c;
+ }
+ printf("\n");
+ }
}
+#endif
-/*
- * Calculate a specific texture format given a generic
- * texture format.
- */
-GLint
-tdfxDDBaseCompressedTexFormat(GLcontext *ctx,
- GLint internalFormat)
+
+static GLboolean
+tdfxDDTestProxyTexImage( GLcontext *ctx, GLenum target,
+ GLint level, GLint internalFormat,
+ GLenum format, GLenum type,
+ GLint width, GLint height,
+ GLint depth, GLint border )
{
- switch (internalFormat) {
- case GL_COMPRESSED_RGB_FXT1_3DFX:
- return GL_RGB;
- case GL_COMPRESSED_RGBA_FXT1_3DFX:
- return GL_RGBA;
- }
- return -1;
+ tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
+ struct gl_shared_state *ss = fxMesa->glCtx->Shared;
+ tdfxSharedStatePtr tss = (tdfxSharedStatePtr)ss->DriverData;
+
+ switch (target) {
+ case GL_PROXY_TEXTURE_1D:
+ return GL_TRUE; /* software rendering */
+ case GL_PROXY_TEXTURE_2D:
+ {
+ struct gl_texture_object *tObj;
+ tdfxTexObjPtr t;
+ int memNeeded;
+
+ tObj = ctx->Texture.Proxy2D;
+ if (!tObj->DriverData)
+ tObj->DriverData = tdfxAllocTexObj(fxMesa);
+ t = TDFX_TEXTURE_DATA(tObj);
+
+ /* assign the parameters to test against */
+ tObj->Image[level]->Width = width;
+ tObj->Image[level]->Height = height;
+ tObj->Image[level]->Border = border;
+ tObj->Image[level]->IntFormat = internalFormat;
+ if (level == 0) {
+ /* don't use mipmap levels > 0 */
+ tObj->MinFilter = tObj->MagFilter = GL_NEAREST;
+ }
+ else {
+ /* test with all mipmap levels */
+ tObj->MinFilter = GL_LINEAR_MIPMAP_LINEAR;
+ tObj->MagFilter = GL_NEAREST;
+ }
+ tdfxRevalidateTexture(ctx, tObj);
+
+ /*
+ printf("small lodlog2 0x%x\n", t->info.smallLodLog2);
+ printf("large lodlog2 0x%x\n", t->info.largeLodLog2);
+ printf("aspect ratio 0x%x\n", t->info.aspectRatioLog2);
+ printf("glide format 0x%x\n", t->info.format);
+ printf("data %p\n", t->info.data);
+ printf("lodblend %d\n", (int) t->LODblend);
+ */
+
+ /* determine where texture will reside */
+ if (t->LODblend && !tss->umaTexMemory) {
+ /* XXX GR_MIPMAPLEVELMASK_BOTH might not be right, but works */
+ memNeeded = FX_grTexTextureMemRequired_NoLock(
+ GR_MIPMAPLEVELMASK_BOTH, &(t->info));
+ }
+ else {
+ /* XXX GR_MIPMAPLEVELMASK_BOTH might not be right, but works */
+ memNeeded = FX_grTexTextureMemRequired_NoLock(
+ GR_MIPMAPLEVELMASK_BOTH, &(t->info));
+ }
+ /*
+ printf("Proxy test %d > %d\n", memNeeded, tss->totalTexMem[0]);
+ */
+ if (memNeeded > tss->totalTexMem[0])
+ return GL_FALSE;
+ else
+ return GL_TRUE;
+ }
+ case GL_PROXY_TEXTURE_3D:
+ return GL_TRUE; /* software rendering */
+ default:
+ return GL_TRUE; /* never happens, silence compiler */
+ }
}
-/*
- * Tell us if an image is compressed. The real work is done
- * in a macro, but we need to have a function to create a
- * function pointer.
+
+/* Return a texture image to Mesa. This is either to satisfy
+ * a glGetTexImage() call or to prepare for software texturing.
*/
-GLboolean
-tdfxDDIsCompressedFormat(GLcontext *ctx, GLint internalFormat)
+static GLvoid *
+tdfxDDGetTexImage( GLcontext *ctx, GLenum target, GLint level,
+ const struct gl_texture_object *texObj,
+ GLenum *formatOut, GLenum *typeOut,
+ GLboolean *freeImageOut )
{
- return tdfxDDIsCompressedFormatMacro(internalFormat);
+ const struct gl_texture_image *texImage = texObj->Image[level];
+ const struct gl_texture_format *texFormat = texImage->TexFormat;
+ tdfxTexObjPtr t = TDFX_TEXTURE_DATA(texObj);
+ tdfxTexImagePtr image;
+ GLubyte *data;
+
+ if ( target != GL_TEXTURE_2D )
+ return NULL;
+ if ( !t )
+ return NULL;
+
+ image = &t->image[level];
+ if ( !image->original.data )
+ return NULL;
+
+ data = (GLubyte *) MALLOC( texImage->Width * texImage->Height * 4 );
+ if ( !data )
+ return NULL;
+
+ _mesa_unconvert_teximage2d( texFormat->IntFormat, texImage->Format,
+ texImage->Width, texImage->Height,
+ image->original.data, data );
+
+ *formatOut = texImage->Format;
+ *typeOut = GL_UNSIGNED_BYTE;
+ *freeImageOut = GL_TRUE;
+
+ return data;
}
-/*
- * Calculate the image size of a compressed texture.
- *
- * The current compressed format, the FXT1 family, all
- * map 8x32 texel blocks into 128 bits.
- *
- * We return 0 if we can't calculate the size.
- *
- * Glide would report this out to us, but we don't have
- * exactly the right parameters.
- */
-GLsizei
-tdfxDDCompressedImageSize(GLcontext *ctx,
- GLenum intFormat,
- GLuint numDimensions,
- GLuint width,
- GLuint height,
- GLuint depth)
+void tdfxDDInitTextureFuncs( GLcontext *ctx )
{
- if (numDimensions != 2) {
- return 0;
- }
- switch (intFormat) {
- case GL_COMPRESSED_RGB_FXT1_3DFX:
- case GL_COMPRESSED_RGBA_FXT1_3DFX:
- /*
- * Round height and width to multiples of 4 and 8,
- * divide the resulting product by 32 to get the number
- * of blocks, and multiply by 32 = 128/8 to get the.
- * number of bytes required. That is to say, just
- * return the product. Remember that we are returning
- * bytes, not texels, so we have shrunk the texture
- * by a factor of the texel size.
- */
- width = (width + 0x7) &~ 0x7;
- height = (height + 0x3) &~ 0x3;
- return width * height;
- }
- return 0;
+ ctx->Driver.TexImage2D = tdfxDDTexImage2D;
+ ctx->Driver.TexSubImage2D = tdfxDDTexSubImage2D;
+ ctx->Driver.GetTexImage = tdfxDDGetTexImage;
+ ctx->Driver.TexEnv = tdfxDDTexEnv;
+ ctx->Driver.TexParameter = tdfxDDTexParameter;
+ ctx->Driver.BindTexture = tdfxDDBindTexture;
+ ctx->Driver.DeleteTexture = tdfxDDDeleteTexture;
+ ctx->Driver.IsTextureResident = tdfxDDIsTextureResident;
+ ctx->Driver.UpdateTexturePalette = tdfxDDTexturePalette;
}
diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_tex.h b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_tex.h
index 95ef3b018..1132f3f35 100644
--- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_tex.h
+++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_tex.h
@@ -35,123 +35,12 @@
*
*/
-#ifndef _TDFX_TEX_H_
-#define _TDFX_TEX_H_
+#ifndef __TDFX_TEX_H__
+#define __TDFX_TEX_H__
+extern void tdfxUpdateTextureState( GLcontext *ctx );
+extern void tdfxUpdateTextureBinding( GLcontext *ctx );
-#include "texutil.h"
-
-
-#define tdfxDDIsCompressedFormatMacro(internalFormat) \
- (((internalFormat) == GL_COMPRESSED_RGB_FXT1_3DFX) || \
- ((internalFormat) == GL_COMPRESSED_RGBA_FXT1_3DFX))
-#define tdfxDDIsCompressedGlideFormatMacro(internalFormat) \
- ((internalFormat) == GR_TEXFMT_ARGB_CMP_FXT1)
-
-
-
-extern void
-tdfxTexValidate(GLcontext * ctx, struct gl_texture_object *tObj);
-
-extern void
-tdfxDDBindTexture(GLcontext * ctx, GLenum target,
- struct gl_texture_object *tObj);
-
-extern void
-tdfxDDDeleteTexture(GLcontext * ctx, struct gl_texture_object *tObj);
-
-extern GLboolean
-tdfxDDIsTextureResident(GLcontext *ctx, struct gl_texture_object *tObj);
-
-extern void
-tdfxDDTexturePalette(GLcontext * ctx, struct gl_texture_object *tObj);
-
-#if 000 /* DEAD? */
-extern void
-fxDDTexUseGlobalPalette(GLcontext * ctx, GLboolean state);
-#endif
-
-extern void
-tdfxDDTexEnv(GLcontext * ctx, GLenum target, GLenum pname,
- const GLfloat * param);
-
-extern void
-tdfxDDTexParameter(GLcontext * ctx, GLenum target,
- struct gl_texture_object *tObj,
- GLenum pname, const GLfloat * params);
-
-extern GLboolean
-tdfxDDTexImage2D(GLcontext * ctx, GLenum target, GLint level,
- GLenum format, GLenum type, const GLvoid * pixels,
- const struct gl_pixelstore_attrib * packing,
- struct gl_texture_object * texObj,
- struct gl_texture_image * texImage,
- GLboolean * retainInternalCopy);
-
-extern GLboolean
-tdfxDDTexSubImage2D(GLcontext * ctx, GLenum target, GLint level,
- GLint xoffset, GLint yoffset,
- GLsizei width, GLsizei height,
- GLenum format, GLenum type, const GLvoid * pixels,
- const struct gl_pixelstore_attrib * packing,
- struct gl_texture_object * texObj,
- struct gl_texture_image * texImage);
-
-extern GLboolean
-tdfxDDCompressedTexImage2D( GLcontext *ctx, GLenum target,
- GLint level, GLsizei imageSize,
- const GLvoid *data,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage,
- GLboolean *retainInternalCopy);
-
-extern GLboolean
-tdfxDDCompressedTexSubImage2D( GLcontext *ctx, GLenum target,
- GLint level, GLint xoffset,
- GLint yoffset, GLsizei width,
- GLint height, GLenum format,
- GLsizei imageSize, const GLvoid *data,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage );
-
-extern GLboolean
-tdfxDDTestProxyTexImage(GLcontext *ctx, GLenum target,
- GLint level, GLint internalFormat,
- GLenum format, GLenum type,
- GLint width, GLint height,
- GLint depth, GLint border);
-
-extern GLvoid *
-tdfxDDGetTexImage(GLcontext * ctx, GLenum target, GLint level,
- const struct gl_texture_object *texObj,
- GLenum * formatOut, GLenum * typeOut,
- GLboolean * freeImageOut);
-
-extern void
-tdfxDDGetCompressedTexImage( GLcontext *ctx, GLenum target,
- GLint lod, void *image,
- const struct gl_texture_object *texObj,
- struct gl_texture_image *texImage );
-
-extern GLint
-tdfxDDSpecificCompressedTexFormat(GLcontext *ctx,
- GLint internalFormat,
- GLint numDimensions);
-
-extern GLint
-tdfxDDBaseCompressedTexFormat(GLcontext *ctx,
- GLint internalFormat);
-
-extern GLboolean
-tdfxDDIsCompressedFormat(GLcontext *ctx, GLint internalFormat);
-
-extern GLsizei
-tdfxDDCompressedImageSize(GLcontext *ctx,
- GLenum intFormat,
- GLuint numDimensions,
- GLuint width,
- GLuint height,
- GLuint depth);
-
+extern void tdfxDDInitTextureFuncs( GLcontext *ctx );
#endif
diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texman.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texman.c
index 97fe9d4c6..8ca93f91a 100644
--- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texman.c
+++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texman.c
@@ -39,930 +39,882 @@
#include "tdfx_tex.h"
#include "tdfx_texman.h"
+#define BAD_ADDRESS ((FxU32) -1)
-#define BAD_ADDRESS ((FxU32) -1)
-
-
-#if 0 /* DEBUG use */
-/*
- * Verify the consistancy of the texture memory manager.
+/* Verify the consistancy of the texture memory manager.
* This involves:
* Traversing all texture objects and computing total memory used.
* Traverse the free block list and computing total memory free.
* Compare the total free and total used amounts to the total memory size.
* Make various assertions about the results.
*/
-static void
-VerifyFreeList(tdfxContextPtr fxMesa, FxU32 tmu)
+static void tdfxTMVerifyFreeList( tdfxContextPtr fxMesa, FxU32 unit )
{
- struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared;
- struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData;
- tdfxMemRange *block;
- int prevStart = -1, prevEnd = -1;
- int totalFree = 0;
- int numObj = 0, numRes = 0;
- int totalUsed = 0;
-
- for (block = shared->tmFree[tmu]; block; block = block->next) {
- assert( block->endAddr > 0 );
- assert( block->startAddr <= shared->totalTexMem[tmu] );
- assert( block->endAddr <= shared->totalTexMem[tmu] );
- assert( (int) block->startAddr > prevStart );
- assert( (int) block->startAddr >= prevEnd );
- prevStart = (int) block->startAddr;
- prevEnd = (int) block->endAddr;
- totalFree += (block->endAddr - block->startAddr);
- }
- assert(totalFree == shared->freeTexMem[tmu]);
-
- {
- struct gl_texture_object *obj;
- for (obj = mesaShared->TexObjectList; obj; obj = obj->Next) {
- tdfxTexInfo *ti = TDFX_TEXTURE_DATA(obj);
- numObj++;
- if (ti) {
- if (ti->isInTM) {
- numRes++;
- assert(ti->tm[0]);
- if (ti->tm[tmu])
- totalUsed += (ti->tm[tmu]->endAddr - ti->tm[tmu]->startAddr);
- }
- else {
- assert(!ti->tm[0]);
- }
- }
- }
- }
-
- printf("totalFree: %d totalUsed: %d totalMem: %d #objs=%d #res=%d\n",
- shared->freeTexMem[tmu], totalUsed, shared->totalTexMem[tmu],
- numObj, numRes);
-
- assert(totalUsed + totalFree == shared->totalTexMem[tmu]);
-}
+ struct gl_shared_state *ss = fxMesa->glCtx->Shared;
+ struct gl_texture_object *texObj;
+ tdfxSharedStatePtr tss = (tdfxSharedStatePtr)ss->DriverData;
+ tdfxMemRange *block;
+ int prevStart = -1, prevEnd = -1;
+ int totalFree = 0;
+ int numObj = 0, numRes = 0;
+ int totalUsed = 0;
+
+ for ( block = tss->freeRanges[unit] ; block ; block = block->next ) {
+ assert( block->endAddr > 0 );
+ assert( block->startAddr <= tss->totalTexMem[unit] );
+ assert( block->endAddr <= tss->totalTexMem[unit] );
+ assert( (int) block->startAddr > prevStart );
+ assert( (int) block->startAddr >= prevEnd );
+ prevStart = (int) block->startAddr;
+ prevEnd = (int) block->endAddr;
+ totalFree += (block->endAddr - block->startAddr);
+ }
+ assert( totalFree == tss->freeTexMem[unit] );
+
+ for ( texObj = ss->TexObjectList ; texObj ; texObj = texObj->Next ) {
+ tdfxTexObjPtr t = TDFX_TEXTURE_DATA(texObj);
+ numObj++;
+ if ( t ) {
+ if ( t->isInTM ) {
+ numRes++;
+ assert( t->range[0] );
+ if ( t->range[unit] )
+ totalUsed += (t->range[unit]->endAddr - t->range[unit]->startAddr);
+ } else {
+ assert(!t->range[0]);
+ }
+ }
+ }
+ fprintf( stderr,
+ "totalFree: %d totalUsed: %d totalMem: %d #objs=%d #res=%d\n",
+ tss->freeTexMem[unit], totalUsed, tss->totalTexMem[unit],
+ numObj, numRes );
+
+ assert( totalUsed + totalFree == tss->totalTexMem[unit] );
+}
-static void
-dump_texmem(tdfxContextPtr fxMesa)
+static void tdfxTMDumpTexMem( tdfxContextPtr fxMesa )
{
- struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared;
- struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData;
- struct gl_texture_object *oldestObj, *obj, *lowestPriorityObj;
- tdfxMemRange *r;
- FxU32 prev;
-
- printf("DUMP Objects:\n");
- for (obj = mesaShared->TexObjectList; obj; obj = obj->Next) {
- tdfxTexInfo *info = TDFX_TEXTURE_DATA(obj);
-
- if (info && info->isInTM) {
- printf("Obj %8p: %4d info = %p\n", obj, obj->Name, info);
-
- printf(" isInTM=%d whichTMU=%d lastTimeUsed=%d\n",
- info->isInTM, info->whichTMU, info->lastTimeUsed);
- printf(" tm[0] = %p", info->tm[0]);
- assert(info->tm[0]);
- if (info->tm[0]) {
- printf(" tm startAddr = %d endAddr = %d",
- info->tm[0]->startAddr,
- info->tm[0]->endAddr);
- }
- printf("\n");
- printf(" tm[1] = %p", info->tm[1]);
- if (info->tm[1]) {
- printf(" tm startAddr = %d endAddr = %d",
- info->tm[1]->startAddr,
- info->tm[1]->endAddr);
- }
- printf("\n");
- }
- }
-
- VerifyFreeList(fxMesa, 0);
- VerifyFreeList(fxMesa, 1);
-
- printf("Free memory unit 0: %d bytes\n", shared->freeTexMem[0]);
- prev = 0;
- for (r = shared->tmFree[0]; r; r = r->next) {
- printf("%8p: start %8d end %8d size %8d gap %8d\n", r, r->startAddr, r->endAddr, r->endAddr - r->startAddr, r->startAddr - prev);
- prev = r->endAddr;
- }
-
- printf("Free memory unit 1: %d bytes\n", shared->freeTexMem[1]);
- prev = 0;
- for (r = shared->tmFree[1]; r; r = r->next) {
- printf("%8p: start %8d end %8d size %8d gap %8d\n", r, r->startAddr, r->endAddr, r->endAddr - r->startAddr, r->startAddr - prev);
- prev = r->endAddr;
- }
+ struct gl_shared_state *ss = fxMesa->glCtx->Shared;
+ tdfxSharedStatePtr tss = (tdfxSharedStatePtr)ss->DriverData;
+ struct gl_texture_object *texObj;
+ tdfxMemRange *r;
+ FxU32 prev;
+
+ printf( "DUMP Objects:\n" );
+ for ( texObj = ss->TexObjectList ; texObj ; texObj = texObj->Next ) {
+ tdfxTexObjPtr t = TDFX_TEXTURE_DATA(texObj);
+
+ if ( t && t->isInTM ) {
+ printf( "Obj %8p: %4d info = %p\n", texObj, texObj->Name, t );
+
+ printf( " isInTM=%d whichTMU=%ld lastTimeUsed=%d\n",
+ t->isInTM, t->whichTMU, t->lastTimeUsed );
+ printf( " tm[0] = %p", t->range[0] );
+ assert( t->range[0] );
+ if ( t->range[0] ) {
+ printf( " tm startAddr = %ld endAddr = %ld",
+ t->range[0]->startAddr,
+ t->range[0]->endAddr );
+ }
+ printf( "\n" );
+ printf( " tm[1] = %p", t->range[1] );
+ if ( t->range[1] ) {
+ printf( " tm startAddr = %ld endAddr = %ld",
+ t->range[1]->startAddr,
+ t->range[1]->endAddr );
+ }
+ printf( "\n" );
+ }
+ }
-}
-#endif
+ tdfxTMVerifyFreeList( fxMesa, 0 );
+ tdfxTMVerifyFreeList( fxMesa, 1 );
+
+ printf( "Free memory unit 0: %d bytes\n", tss->freeTexMem[0] );
+ prev = 0;
+ for ( r = tss->freeRanges[0] ; r ; r = r->next ) {
+ printf( "%8p: start %8ld end %8ld size %8ld gap %8ld\n",
+ r, r->startAddr, r->endAddr, r->endAddr - r->startAddr,
+ r->startAddr - prev );
+ prev = r->endAddr;
+ }
+ printf( "Free memory unit 1: %d bytes\n", tss->freeTexMem[1] );
+ prev = 0;
+ for ( r = tss->freeRanges[1] ; r ; r = r->next ) {
+ printf( "%8p: start %8ld end %8ld size %8ld gap %8ld\n",
+ r, r->startAddr, r->endAddr, r->endAddr - r->startAddr,
+ r->startAddr - prev );
+ prev = r->endAddr;
+ }
+}
#ifdef TEXSANITY
-static void
-fubar(void)
+static void fubar( void )
{
+ /* GH: What am I meant to do??? */
}
-/*
- * Sanity Check
+/* Sanity Check
*/
-static void
-sanity(tdfxContextPtr fxMesa)
+static void sanity( tdfxContextPtr fxMesa )
{
- tdfxMemRange *tmp, *prev, *pos;
-
- prev = 0;
- tmp = fxMesa->tmFree[0];
- while (tmp) {
- if (!tmp->startAddr && !tmp->endAddr) {
- fprintf(stderr, "Textures fubar\n");
- fubar();
- }
- if (tmp->startAddr >= tmp->endAddr) {
- fprintf(stderr, "Node fubar\n");
- fubar();
- }
- if (prev && (prev->startAddr >= tmp->startAddr ||
- prev->endAddr > tmp->startAddr)) {
- fprintf(stderr, "Sorting fubar\n");
- fubar();
- }
- prev = tmp;
- tmp = tmp->next;
- }
- prev = 0;
- tmp = fxMesa->tmFree[1];
- while (tmp) {
- if (!tmp->startAddr && !tmp->endAddr) {
- fprintf(stderr, "Textures fubar\n");
- fubar();
- }
- if (tmp->startAddr >= tmp->endAddr) {
- fprintf(stderr, "Node fubar\n");
- fubar();
- }
- if (prev && (prev->startAddr >= tmp->startAddr ||
- prev->endAddr > tmp->startAddr)) {
- fprintf(stderr, "Sorting fubar\n");
- fubar();
- }
- prev = tmp;
- tmp = tmp->next;
- }
+ tdfxMemRange *tmp, *prev, *pos;
+
+ prev = 0;
+ tmp = fxMesa->freeRanges[0];
+ while ( tmp ) {
+ if ( !tmp->startAddr && !tmp->endAddr ) {
+ fprintf( stderr, "Textures fubar\n" );
+ fubar();
+ }
+ if ( tmp->startAddr >= tmp->endAddr ) {
+ fprintf( stderr, "Node fubar\n" );
+ fubar();
+ }
+ if ( prev && ( prev->startAddr >= tmp->startAddr ||
+ prev->endAddr > tmp->startAddr ) ) {
+ fprintf( stderr, "Sorting fubar\n" );
+ fubar();
+ }
+ prev = tmp;
+ tmp = tmp->next;
+ }
+
+ prev = 0;
+ tmp = fxMesa->freeRanges[1];
+ while ( tmp ) {
+ if ( !tmp->startAddr && !tmp->endAddr ) {
+ fprintf( stderr, "Textures fubar\n" );
+ fubar();
+ }
+ if ( tmp->startAddr >= tmp->endAddr ) {
+ fprintf( stderr, "Node fubar\n" );
+ fubar();
+ }
+ if ( prev && ( prev->startAddr >= tmp->startAddr ||
+ prev->endAddr > tmp->startAddr ) ) {
+ fprintf( stderr, "Sorting fubar\n" );
+ fubar();
+ }
+ prev = tmp;
+ tmp = tmp->next;
+ }
}
#endif
-
-
-
-/*
- * Allocate and initialize a new MemRange struct.
- * Try to allocate it from the pool of free MemRange nodes rather than malloc.
+/* Allocate and initialize a new MemRange struct. Try to allocate it
+ * from the pool of free MemRange nodes rather than malloc.
*/
static tdfxMemRange *
-NewRangeNode(tdfxContextPtr fxMesa, FxU32 start, FxU32 end)
+tdfxTMNewRangeNode( tdfxContextPtr fxMesa, FxU32 start, FxU32 end )
{
- struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared;
- struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData;
- tdfxMemRange *result;
-
- _glthread_LOCK_MUTEX(mesaShared->Mutex);
- if (shared && shared->tmPool) {
- result = shared->tmPool;
- shared->tmPool = shared->tmPool->next;
- }
- else {
- result = MALLOC(sizeof(tdfxMemRange));
-
- }
- _glthread_UNLOCK_MUTEX(mesaShared->Mutex);
-
- if (!result) {
- /*fprintf(stderr, "fxDriver: out of memory!\n");*/
- return NULL;
- }
-
- result->startAddr = start;
- result->endAddr = end;
- result->next = NULL;
-
- return result;
+ struct gl_shared_state *ss = fxMesa->glCtx->Shared;
+ tdfxSharedStatePtr tss = (tdfxSharedStatePtr)ss->DriverData;
+ tdfxMemRange *range;
+
+ _glthread_LOCK_MUTEX( ss->Mutex );
+ if ( tss && tss->rangePool ) {
+ range = tss->rangePool;
+ tss->rangePool = tss->rangePool->next;
+ } else {
+ range = MALLOC( sizeof(tdfxMemRange) );
+ }
+ _glthread_UNLOCK_MUTEX( ss->Mutex );
+
+ if ( !range ) {
+ if ( TDFX_DEBUG & DEBUG_VERBOSE_TEXTURE )
+ fprintf( stderr, __FUNCTION__ ": out of memory!\n" );
+ return NULL;
+ }
+
+ range->startAddr = start;
+ range->endAddr = end;
+ range->next = NULL;
+
+ return range;
}
-/*
- * Initialize texture memory.
- * We take care of one or both TMU's here.
+/* Initialize texture memory. We take care of one or both TMU's here.
*/
-void
-tdfxTMInit(tdfxContextPtr fxMesa)
+void tdfxTMInit( tdfxContextPtr fxMesa )
{
- if (!fxMesa->glCtx->Shared->DriverData) {
- const char *extensions;
- struct tdfxSharedState *shared = CALLOC_STRUCT(tdfxSharedState);
- if (!shared)
- return;
-
- extensions = FX_grGetString(fxMesa, GR_EXTENSION);
- if (strstr(extensions, "TEXUMA")) {
- FxU32 start, end;
- shared->umaTexMemory = GL_TRUE;
- FX_grEnable(fxMesa, GR_TEXTURE_UMA_EXT);
- start = FX_grTexMinAddress(fxMesa, 0);
- end = FX_grTexMaxAddress(fxMesa, 0);
- shared->totalTexMem[0] = end - start;
- shared->totalTexMem[1] = 0;
- shared->freeTexMem[0] = end - start;
- shared->freeTexMem[1] = 0;
- shared->tmFree[0] = NewRangeNode(fxMesa, start, end);
- shared->tmFree[1] = NULL;
- /*printf("UMA tex memory: %d\n", (int) (end - start));*/
- }
- else {
- const int numTMUs = fxMesa->haveTwoTMUs ? 2 : 1;
- int tmu;
- shared->umaTexMemory = GL_FALSE;
- for (tmu = 0; tmu < numTMUs; tmu++) {
- FxU32 start = FX_grTexMinAddress(fxMesa, tmu);
- FxU32 end = FX_grTexMaxAddress(fxMesa, tmu);
- shared->totalTexMem[tmu] = end - start;
- shared->freeTexMem[tmu] = end - start;
- shared->tmFree[tmu] = NewRangeNode(fxMesa, start, end);
- /*printf("Split tex memory: %d\n", (int) (end - start));*/
- }
- }
-
- shared->tmPool = NULL;
- fxMesa->glCtx->Shared->DriverData = shared;
- /*printf("Texture memory init UMA: %d\n", shared->umaTexMemory);*/
- }
+ GLcontext *ctx = fxMesa->glCtx;
+
+ if ( TDFX_DEBUG & DEBUG_VERBOSE_TEXTURE )
+ fprintf( stderr, __FUNCTION__ "\n" );
+
+ if ( !ctx->Shared->DriverData ) {
+ const char *extensions;
+ tdfxSharedStatePtr tss = CALLOC_STRUCT( tdfx_shared_state );
+
+ if ( !tss )
+ return;
+
+ LOCK_HARDWARE( fxMesa );
+
+ extensions = grGetString( GR_EXTENSION );
+
+ if ( strstr( extensions, " TEXUMA " ) ) {
+ FxU32 start, end;
+
+ tss->umaTexMemory = GL_TRUE;
+
+ grEnable( GR_TEXTURE_UMA_EXT );
+
+ start = grTexMinAddress( 0 );
+ end = grTexMaxAddress( 0 );
+
+ if ( TDFX_DEBUG & DEBUG_VERBOSE_TEXTURE )
+ fprintf( stderr, " UMA tex memory: %d\n", (int)(end - start) );
+
+ tss->totalTexMem[0] = end - start;
+ tss->totalTexMem[1] = 0;
+ tss->freeTexMem[0] = end - start;
+ tss->freeTexMem[1] = 0;
+ tss->freeRanges[0] = tdfxTMNewRangeNode( fxMesa, start, end );
+ tss->freeRanges[1] = NULL;
+ } else {
+ int unit;
+
+ tss->umaTexMemory = GL_FALSE;
+
+ for ( unit = 0 ; unit < fxMesa->numTMUs ; unit++ ) {
+ FxU32 start, end;
+
+ start = grTexMinAddress( unit );
+ end = grTexMaxAddress( unit );
+
+ tss->totalTexMem[unit] = end - start;
+ tss->freeTexMem[unit] = end - start;
+ tss->freeRanges[unit] = tdfxTMNewRangeNode( fxMesa, start, end );
+
+ if ( TDFX_DEBUG & DEBUG_VERBOSE_TEXTURE )
+ fprintf( stderr, " Split tex memory: %d\n",
+ (int)(end - start) );
+ }
+ }
+
+ UNLOCK_HARDWARE( fxMesa );
+
+ tss->rangePool = NULL;
+ ctx->Shared->DriverData = tss;
+
+ if ( TDFX_DEBUG & DEBUG_VERBOSE_TEXTURE )
+ fprintf( stderr, " init UMA: %d\n", tss->umaTexMemory );
+ }
}
-/*
- * Clean-up texture memory before destroying context.
+/* Clean-up texture memory before destroying context.
*/
-void
-tdfxTMClose(tdfxContextPtr fxMesa)
+void tdfxTMClose( tdfxContextPtr fxMesa )
{
- if (fxMesa->glCtx->Shared->RefCount == 1) {
- /* refcount will soon go to zero, free our 3dfx stuff */
- struct tdfxSharedState *shared = (struct tdfxSharedState *) fxMesa->glCtx->Shared->DriverData;
-
- const int numTMUs = fxMesa->haveTwoTMUs ? 2 : 1;
- int tmu;
- tdfxMemRange *tmp, *next;
-
- /* Deallocate the pool of free tdfxMemRange nodes */
- tmp = shared->tmPool;
- while (tmp) {
- next = tmp->next;
- FREE(tmp);
- tmp = next;
- }
-
- /* Delete the texture memory block tdfxMemRange nodes */
- for (tmu = 0; tmu < numTMUs; tmu++) {
- tmp = shared->tmFree[tmu];
- while (tmp) {
- next = tmp->next;
- FREE(tmp);
- tmp = next;
- }
- }
-
- FREE(shared);
- fxMesa->glCtx->Shared->DriverData = NULL;
- }
-}
+ GLcontext *ctx = fxMesa->glCtx;
+ if ( ctx->Shared->RefCount == 1 ) {
+ /* RefCount will soon go to zero, free our 3dfx stuff */
+ tdfxSharedStatePtr tss = (tdfxSharedStatePtr)ctx->Shared->DriverData;
+ int unit;
+ tdfxMemRange *tmp, *next;
+
+ /* Deallocate the pool of free tdfxMemRange nodes */
+ tmp = tss->rangePool;
+ while ( tmp ) {
+ next = tmp->next;
+ FREE( tmp );
+ tmp = next;
+ }
+ /* Delete the texture memory block tdfxMemRange nodes */
+ for ( unit = 0 ; unit < fxMesa->numTMUs ; unit++ ) {
+ tmp = tss->freeRanges[unit];
+ while ( tmp ) {
+ next = tmp->next;
+ FREE( tmp );
+ tmp = next;
+ }
+ }
-/*
- * Delete a tdfxMemRange struct.
- * We keep a linked list of free/available tdfxMemRange structs to
- * avoid extra malloc/free calls.
- */
-#if 0
-static void
-DeleteRangeNode_NoLock(struct TdfxSharedState *shared, tdfxMemRange *range)
-{
- /* insert at head of list */
- range->next = shared->tmPool;
- shared->tmPool = range;
+ FREE( tss );
+ ctx->Shared->DriverData = NULL;
+ }
}
-#endif
-#define DELETE_RANGE_NODE(shared, range) \
- (range)->next = (shared)->tmPool; \
- (shared)->tmPool = (range)
+/* Delete a tdfxMemRange struct.
+ * We keep a linked list of free/available tdfxMemRange structs to
+ * avoid extra malloc/free calls.
+ */
+#define DELETE_RANGE_NODE( tss, range ) \
+do { \
+ (range)->next = (tss)->rangePool; \
+ (tss)->rangePool = (range); \
+} while (0)
-/*
- * When we've run out of texture memory we have to throw out an
+/* When we've run out of texture memory we have to throw out an
* existing texture to make room for the new one. This function
* determins the texture to throw out.
*/
static struct gl_texture_object *
-FindOldestObject(tdfxContextPtr fxMesa, FxU32 tmu)
+tdfxTMFindOldestObject( tdfxContextPtr fxMesa, FxU32 unit )
{
- const GLuint bindnumber = fxMesa->texBindNumber;
- struct gl_texture_object *oldestObj, *obj, *lowestPriorityObj;
- GLfloat lowestPriority;
- GLuint oldestAge;
-
- oldestObj = NULL;
- oldestAge = 0;
-
- lowestPriority = 1.0F;
- lowestPriorityObj = NULL;
-
- for (obj = fxMesa->glCtx->Shared->TexObjectList; obj; obj = obj->Next) {
- tdfxTexInfo *info = TDFX_TEXTURE_DATA(obj);
-
- if (info && info->isInTM &&
- ((info->whichTMU == tmu) || (info->whichTMU == TDFX_TMU_BOTH) ||
- (info->whichTMU == TDFX_TMU_SPLIT))) {
- GLuint age, lasttime;
-
- assert(info->tm[0]);
- lasttime = info->lastTimeUsed;
-
- if (lasttime > bindnumber)
- age = bindnumber + (UINT_MAX - lasttime + 1); /* TO DO: check wrap around */
- else
- age = bindnumber - lasttime;
-
- if (age >= oldestAge) {
- oldestAge = age;
- oldestObj = obj;
- }
-
- /* examine priority */
- if (obj->Priority < lowestPriority) {
- lowestPriority = obj->Priority;
- lowestPriorityObj = obj;
- }
- }
- }
-
- if (lowestPriority < 1.0) {
- ASSERT(lowestPriorityObj);
- /*
- printf("discard %d pri=%f\n", lowestPriorityObj->Name, lowestPriority);
- */
- return lowestPriorityObj;
- }
- else {
- /*
- printf("discard %d age=%d\n", oldestObj->Name, oldestAge);
- */
- return oldestObj;
- }
-}
+ struct gl_shared_state *ss = fxMesa->glCtx->Shared;
+ const GLuint bindNumber = fxMesa->texBindNumber;
+ struct gl_texture_object *oldestObj, *texObj, *lowestPriorityObj;
+ GLfloat lowestPriority;
+ GLuint oldestAge;
+
+ if ( TDFX_DEBUG & DEBUG_VERBOSE_TEXTURE )
+ fprintf( stderr, __FUNCTION__ "\n" );
+
+ oldestObj = NULL;
+ oldestAge = 0;
+
+ lowestPriority = 1.0F;
+ lowestPriorityObj = NULL;
+
+ for ( texObj = ss->TexObjectList ; texObj ; texObj = texObj->Next ) {
+ tdfxTexObjPtr t = TDFX_TEXTURE_DATA(texObj);
+
+ if ( t && t->isInTM &&
+ ( ( t->whichTMU == unit ) ||
+ ( t->whichTMU == TDFX_TMU_BOTH ) ||
+ ( t->whichTMU == TDFX_TMU_SPLIT ) ) ) {
+ GLuint age, lastTime;
+
+ assert( t->range[0] );
+ lastTime = t->lastTimeUsed;
+
+ if ( lastTime > bindNumber ) {
+ /* TODO: check wrap around */
+ age = bindNumber + (UINT_MAX - lastTime + 1);
+ } else {
+ age = bindNumber - lastTime;
+ }
+ if ( age >= oldestAge ) {
+ oldestAge = age;
+ oldestObj = texObj;
+ }
+ /* examine priority */
+ if ( texObj->Priority < lowestPriority ) {
+ lowestPriority = texObj->Priority;
+ lowestPriorityObj = texObj;
+ }
+ }
+ }
-#if 0
-static void
-FlushTexMemory(tdfxContextPtr fxMesa)
-{
- struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared;
- struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData;
- struct gl_texture_object *obj;
-
- for (obj = mesaShared->TexObjectList; obj; obj = obj->Next) {
- if (obj->RefCount < 2) {
- /* don't flush currently bound textures */
- tdfxTMMoveOutTM_NoLock(fxMesa, obj);
- }
- }
+ if ( lowestPriority < 1.0 ) {
+ ASSERT( lowestPriorityObj );
+ if ( TDFX_DEBUG & DEBUG_VERBOSE_TEXTURE )
+ fprintf( stderr, "discard %d pri=%f\n",
+ lowestPriorityObj->Name, lowestPriority );
+ return lowestPriorityObj;
+ } else {
+ if ( TDFX_DEBUG & DEBUG_VERBOSE_TEXTURE )
+ fprintf( stderr, "discard %d age=%d\n",
+ oldestObj->Name, oldestAge );
+ return oldestObj;
+ }
}
-#endif
-/*
- * Find the address (offset?) at which we can store a new texture.
- * <tmu> is the texture unit.
+/* Find the address (offset?) at which we can store a new texture.
+ * <unit> is the texture unit.
* <size> is the texture size in bytes.
*/
-static FxU32
-FindStartAddr(tdfxContextPtr fxMesa, FxU32 tmu, FxU32 size)
+static FxU32 tdfxTMFindStartAddr( tdfxContextPtr fxMesa,
+ FxU32 unit, FxU32 size )
{
- struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared;
- struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData;
- tdfxMemRange *prev, *block;
- FxU32 result;
-#if 0
- int discardedCount = 0;
-#define MAX_DISCARDS 10
-#endif
+ struct gl_shared_state *ss = fxMesa->glCtx->Shared;
+ tdfxSharedStatePtr tss = (tdfxSharedStatePtr)ss->DriverData;
+ struct gl_texture_object *texObj;
+ tdfxMemRange *prev, *block;
+ FxU32 result;
+
+ if ( tss->umaTexMemory ) {
+ assert( unit == TDFX_TMU0 );
+ }
- if (shared->umaTexMemory) {
- assert(tmu == TDFX_TMU0);
- }
-
- _glthread_LOCK_MUTEX(mesaShared->Mutex);
- while (1) {
- prev = NULL;
- block = shared->tmFree[tmu];
- while (block) {
- if (block->endAddr - block->startAddr >= size) {
- /* The texture will fit here */
- result = block->startAddr;
- block->startAddr += size;
- if (block->startAddr == block->endAddr) {
- /* Remove this node since it's empty */
- if (prev) {
- prev->next = block->next;
- }
- else {
- shared->tmFree[tmu] = block->next;
- }
- DELETE_RANGE_NODE(shared, block);
- }
- shared->freeTexMem[tmu] -= size;
- _glthread_UNLOCK_MUTEX(mesaShared->Mutex);
- return result;
- }
- prev = block;
- block = block->next;
- }
- /* We failed to find a block large enough to accomodate <size> bytes.
- * Find the oldest texObject and free it.
- */
-#if 0
- discardedCount++;
- if (discardedCount > MAX_DISCARDS + 1) {
- gl_problem(NULL, "tdfx driver: extreme texmem fragmentation");
- _glthread_UNLOCK_MUTEX(mesaShared->Mutex);
- return BAD_ADDRESS;
- }
- else if (discardedCount > MAX_DISCARDS) {
- /* texture memory is probably really fragmented, flush it */
- FlushTexMemory(fxMesa);
- }
- else
-#endif
- {
- struct gl_texture_object *obj = FindOldestObject(fxMesa, tmu);
- if (obj) {
- tdfxTMMoveOutTM_NoLock(fxMesa, obj);
- fxMesa->stats.texSwaps++;
- }
- else {
- gl_problem(NULL, "tdfx driver: extreme texmem fragmentation");
- _glthread_UNLOCK_MUTEX(mesaShared->Mutex);
- return BAD_ADDRESS;
- }
- }
- }
-
- /* never get here, but play it safe */
- _glthread_UNLOCK_MUTEX(mesaShared->Mutex);
- return BAD_ADDRESS;
+ _glthread_LOCK_MUTEX( ss->Mutex );
+ while ( 1 ) {
+ prev = NULL;
+ block = tss->freeRanges[unit];
+
+ while ( block ) {
+ if ( block->endAddr - block->startAddr >= size ) {
+ /* The texture will fit here */
+ result = block->startAddr;
+ block->startAddr += size;
+ if ( block->startAddr == block->endAddr ) {
+ /* Remove this node since it's empty */
+ if ( prev ) {
+ prev->next = block->next;
+ } else {
+ tss->freeRanges[unit] = block->next;
+ }
+ DELETE_RANGE_NODE( tss, block );
+ }
+ tss->freeTexMem[unit] -= size;
+ _glthread_UNLOCK_MUTEX( ss->Mutex );
+ return result;
+ }
+ prev = block;
+ block = block->next;
+ }
+
+ /* We failed to find a block large enough to accomodate <size> bytes.
+ * Find the oldest texObject and free it.
+ */
+ texObj = tdfxTMFindOldestObject( fxMesa, unit );
+ if ( texObj ) {
+ tdfxTMMoveOutTMLocked( fxMesa, texObj );
+ fxMesa->stats.texSwaps++;
+ } else {
+ gl_problem( NULL, "tdfx driver: extreme texmem fragmentation" );
+ _glthread_UNLOCK_MUTEX( ss->Mutex );
+ return BAD_ADDRESS;
+ }
+ }
+
+ /* never get here, but play it safe */
+ _glthread_UNLOCK_MUTEX( ss->Mutex );
+ return BAD_ADDRESS;
}
-/*
- * Remove the given tdfxMemRange node from hardware texture memory.
+/* Remove the given tdfxMemRange node from hardware texture memory.
*/
-static void
-RemoveRange_NoLock(tdfxContextPtr fxMesa, FxU32 tmu, tdfxMemRange *range)
+static void tdfxTMRemoveRangeLocked( tdfxContextPtr fxMesa,
+ FxU32 unit, tdfxMemRange *range )
{
- struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared;
- struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData;
- tdfxMemRange *block, *prev;
-
- if (shared->umaTexMemory) {
- assert(tmu == TDFX_TMU0);
- }
-
- if (!range)
- return;
-
- if (range->startAddr == range->endAddr) {
- DELETE_RANGE_NODE(shared, range);
- return;
- }
- shared->freeTexMem[tmu] += range->endAddr - range->startAddr;
-
- /* find position in linked list to insert this tdfxMemRange node */
- prev = NULL;
- block = shared->tmFree[tmu];
- while (block) {
- assert(range->startAddr != block->startAddr);
- if (range->startAddr > block->startAddr) {
- prev = block;
- block = block->next;
- }
- else {
- break;
- }
- }
-
- /* Insert the free block, combine with adjacent blocks when possible */
- range->next = block;
- if (block) {
- if (range->endAddr == block->startAddr) {
- /* Combine */
- block->startAddr = range->startAddr;
- DELETE_RANGE_NODE(shared, range);
- range = block;
- }
- }
- if (prev) {
- if (prev->endAddr == range->startAddr) {
- /* Combine */
- prev->endAddr = range->endAddr;
- prev->next = range->next;
- DELETE_RANGE_NODE(shared, range);
- }
- else {
- prev->next = range;
- }
- }
- else {
- shared->tmFree[tmu] = range;
- }
-}
+ struct gl_shared_state *ss = fxMesa->glCtx->Shared;
+ tdfxSharedStatePtr tss = (tdfxSharedStatePtr)ss->DriverData;
+ tdfxMemRange *block, *prev;
+ if ( tss->umaTexMemory ) {
+ assert( unit == TDFX_TMU0 );
+ }
-#if 0 /* NOT USED */
-static void
-RemoveRange(tdfxContextPtr fxMesa, FxU32 tmu, tdfxMemRange *range)
-{
- struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared;
- _glthread_LOCK_MUTEX(mesaShared->Mutex);
- RemoveRange_NoLock(fxMesa, tmu, range);
- _glthread_UNLOCK_MUTEX(mesaShared->Mutex);
+ if ( !range )
+ return;
+
+ if ( range->startAddr == range->endAddr ) {
+ DELETE_RANGE_NODE( tss, range );
+ return;
+ }
+ tss->freeTexMem[unit] += range->endAddr - range->startAddr;
+
+ /* find position in linked list to insert this tdfxMemRange node */
+ prev = NULL;
+ block = tss->freeRanges[unit];
+ while ( block ) {
+ assert( range->startAddr != block->startAddr );
+ if ( range->startAddr > block->startAddr ) {
+ prev = block;
+ block = block->next;
+ } else {
+ break;
+ }
+ }
+
+ /* Insert the free block, combine with adjacent blocks when possible */
+ range->next = block;
+ if ( block ) {
+ if ( range->endAddr == block->startAddr ) {
+ /* Combine */
+ block->startAddr = range->startAddr;
+ DELETE_RANGE_NODE( tss, range );
+ range = block;
+ }
+ }
+ if ( prev ) {
+ if ( prev->endAddr == range->startAddr ) {
+ /* Combine */
+ prev->endAddr = range->endAddr;
+ prev->next = range->next;
+ DELETE_RANGE_NODE( tss, range );
+ } else {
+ prev->next = range;
+ }
+ } else {
+ tss->freeRanges[unit] = range;
+ }
}
-#endif
-/*
- * Allocate space for a texture image.
+/* Allocate space for a texture image.
* <tmu> is the texture unit
* <texmemsize> is the number of bytes to allocate
*/
static tdfxMemRange *
-AllocTexMem(tdfxContextPtr fxMesa, FxU32 tmu, FxU32 texmemsize)
+tdfxTMAllocTexMem( tdfxContextPtr fxMesa, FxU32 unit, FxU32 size )
{
- FxU32 startAddr;
- startAddr = FindStartAddr(fxMesa, tmu, texmemsize);
- if (startAddr == BAD_ADDRESS) {
- printf("AllocTexMem returned NULL! tmu=%d texmemsize=%d\n",
- tmu, texmemsize);
- return NULL;
- }
- else {
- tdfxMemRange *range;
- range = NewRangeNode(fxMesa, startAddr, startAddr + texmemsize);
- return range;
- }
+ tdfxMemRange *range = NULL;
+ FxU32 start;
+
+ start = tdfxTMFindStartAddr( fxMesa, unit, size );
+
+ if ( start != BAD_ADDRESS ) {
+ range = tdfxTMNewRangeNode( fxMesa, start, start + size );
+ } else {
+ fprintf( stderr,
+ "tdfxTMAllocTexMem returned NULL! unit=%ld size=%ld\n",
+ unit, size );
+ }
+ return range;
}
-/*
- * Download (copy) the given texture data (all mipmap levels) into the
- * Voodoo's texture memory.
- * The texture memory must have already been allocated.
+/* Download (copy) the given texture data (all mipmap levels) into the
+ * Voodoo's texture memory. The texture memory must have already been
+ * allocated.
*/
-void
-tdfxTMDownloadTexture(tdfxContextPtr fxMesa, struct gl_texture_object *tObj)
+void tdfxTMDownloadTextureLocked( tdfxContextPtr fxMesa,
+ struct gl_texture_object *tObj )
{
- tdfxTexInfo *ti;
- GLint l;
- FxU32 targetTMU;
-
- assert(tObj);
- ti = TDFX_TEXTURE_DATA(tObj);
- assert(ti);
- targetTMU = ti->whichTMU;
-
- switch (targetTMU) {
- case TDFX_TMU0:
- case TDFX_TMU1:
- if (ti->tm[targetTMU]) {
- for (l = ti->minLevel; l <= ti->maxLevel
- && ti->mipmapLevel[l].data; l++) {
- GrLOD_t glideLod = ti->info.largeLodLog2 - l + tObj->BaseLevel;
- FX_grTexDownloadMipMapLevel_NoLock(targetTMU,
- ti->tm[targetTMU]->startAddr,
- glideLod,
- ti->info.largeLodLog2,
- ti->info.aspectRatioLog2,
- ti->info.format,
- GR_MIPMAPLEVELMASK_BOTH,
- ti->mipmapLevel[l].data);
- }
- }
- break;
- case TDFX_TMU_SPLIT:
- if (ti->tm[TDFX_TMU0] && ti->tm[TDFX_TMU1]) {
- for (l = ti->minLevel; l <= ti->maxLevel
- && ti->mipmapLevel[l].data; l++) {
- GrLOD_t glideLod = ti->info.largeLodLog2 - l + tObj->BaseLevel;
- FX_grTexDownloadMipMapLevel_NoLock(GR_TMU0,
- ti->tm[TDFX_TMU0]->startAddr,
- glideLod,
- ti->info.largeLodLog2,
- ti->info.aspectRatioLog2,
- ti->info.format,
- GR_MIPMAPLEVELMASK_ODD,
- ti->mipmapLevel[l].data);
-
- FX_grTexDownloadMipMapLevel_NoLock(GR_TMU1,
- ti->tm[TDFX_TMU1]->startAddr,
- glideLod,
- ti->info.largeLodLog2,
- ti->info.aspectRatioLog2,
- ti->info.format,
- GR_MIPMAPLEVELMASK_EVEN,
- ti->mipmapLevel[l].data);
- }
- }
- break;
- case TDFX_TMU_BOTH:
- if (ti->tm[TDFX_TMU0] && ti->tm[TDFX_TMU1]) {
- for (l = ti->minLevel; l <= ti->maxLevel
- && ti->mipmapLevel[l].data; l++) {
- GrLOD_t glideLod = ti->info.largeLodLog2 - l + tObj->BaseLevel;
- FX_grTexDownloadMipMapLevel_NoLock(GR_TMU0,
- ti->tm[TDFX_TMU0]->startAddr,
- glideLod,
- ti->info.largeLodLog2,
- ti->info.aspectRatioLog2,
- ti->info.format,
- GR_MIPMAPLEVELMASK_BOTH,
- ti->mipmapLevel[l].data);
-
- FX_grTexDownloadMipMapLevel_NoLock(GR_TMU1,
- ti->tm[TDFX_TMU1]->startAddr,
- glideLod,
- ti->info.largeLodLog2,
- ti->info.aspectRatioLog2,
- ti->info.format,
- GR_MIPMAPLEVELMASK_BOTH,
- ti->mipmapLevel[l].data);
- }
- }
- break;
- default:
- gl_problem(NULL, "error in tdfxTMDownloadTexture: bad tmu");
- return;
- }
+ tdfxTexObjPtr t = TDFX_TEXTURE_DATA(tObj);
+ FxU32 targetTMU;
+ GLint l;
+
+ assert( tObj );
+ assert( t );
+
+ targetTMU = t->whichTMU;
+
+ switch ( targetTMU ) {
+ case TDFX_TMU0:
+ case TDFX_TMU1:
+ if ( t->range[targetTMU] ) {
+ for ( l = t->minLevel ; l <= t->maxLevel && t->image[l].data ; l++ ) {
+ GrLOD_t glideLod = t->info.largeLodLog2 - l + tObj->BaseLevel;
+
+ grTexDownloadMipMapLevel( targetTMU,
+ t->range[targetTMU]->startAddr,
+ glideLod,
+ t->info.largeLodLog2,
+ t->info.aspectRatioLog2,
+ t->info.format,
+ GR_MIPMAPLEVELMASK_BOTH,
+ t->image[l].data );
+ }
+ }
+ break;
+
+ case TDFX_TMU_SPLIT:
+ if ( t->range[TDFX_TMU0] && t->range[TDFX_TMU1] ) {
+ for ( l = t->minLevel ; l <= t->maxLevel && t->image[l].data ; l++ ) {
+ GrLOD_t glideLod = t->info.largeLodLog2 - l + tObj->BaseLevel;
+
+ grTexDownloadMipMapLevel( GR_TMU0,
+ t->range[TDFX_TMU0]->startAddr,
+ glideLod,
+ t->info.largeLodLog2,
+ t->info.aspectRatioLog2,
+ t->info.format,
+ GR_MIPMAPLEVELMASK_ODD,
+ t->image[l].data );
+
+ grTexDownloadMipMapLevel( GR_TMU1,
+ t->range[TDFX_TMU1]->startAddr,
+ glideLod,
+ t->info.largeLodLog2,
+ t->info.aspectRatioLog2,
+ t->info.format,
+ GR_MIPMAPLEVELMASK_EVEN,
+ t->image[l].data );
+ }
+ }
+ break;
+
+ case TDFX_TMU_BOTH:
+ if ( t->range[TDFX_TMU0] && t->range[TDFX_TMU1] ) {
+ for ( l = t->minLevel ; l <= t->maxLevel && t->image[l].data ; l++ ) {
+ GrLOD_t glideLod = t->info.largeLodLog2 - l + tObj->BaseLevel;
+
+ grTexDownloadMipMapLevel( GR_TMU0,
+ t->range[TDFX_TMU0]->startAddr,
+ glideLod,
+ t->info.largeLodLog2,
+ t->info.aspectRatioLog2,
+ t->info.format,
+ GR_MIPMAPLEVELMASK_BOTH,
+ t->image[l].data );
+
+ grTexDownloadMipMapLevel( GR_TMU1,
+ t->range[TDFX_TMU1]->startAddr,
+ glideLod,
+ t->info.largeLodLog2,
+ t->info.aspectRatioLog2,
+ t->info.format,
+ GR_MIPMAPLEVELMASK_BOTH,
+ t->image[l].data );
+ }
+ }
+ break;
+
+ default:
+ gl_problem( NULL, "error in tdfxTMDownloadTexture: bad unit" );
+ return;
+ }
}
-void
-tdfxTMReloadMipMapLevel(GLcontext *ctx, struct gl_texture_object *tObj,
- GLint level)
+void tdfxTMReloadMipMapLevelLocked( GLcontext *ctx,
+ struct gl_texture_object *tObj,
+ GLint level )
{
- tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
- tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj);
- GrLOD_t glideLod;
- FxU32 tmu;
-
- tmu = ti->whichTMU;
- glideLod = ti->info.largeLodLog2 - level + tObj->BaseLevel;
- ASSERT(ti->isInTM);
-
- switch (tmu) {
- case TDFX_TMU0:
- case TDFX_TMU1:
- FX_grTexDownloadMipMapLevel(fxMesa, tmu,
- ti->tm[tmu]->startAddr,
- glideLod,
- ti->info.largeLodLog2,
- ti->info.aspectRatioLog2,
- ti->info.format,
- GR_MIPMAPLEVELMASK_BOTH,
- ti->mipmapLevel[level].data);
- break;
- case TDFX_TMU_SPLIT:
- FX_grTexDownloadMipMapLevel(fxMesa, GR_TMU0,
- ti->tm[GR_TMU0]->startAddr,
- glideLod,
- ti->info.largeLodLog2,
- ti->info.aspectRatioLog2,
- ti->info.format,
- GR_MIPMAPLEVELMASK_ODD,
- ti->mipmapLevel[level].data);
-
- FX_grTexDownloadMipMapLevel(fxMesa, GR_TMU1,
- ti->tm[GR_TMU1]->startAddr,
- glideLod,
- ti->info.largeLodLog2,
- ti->info.aspectRatioLog2,
- ti->info.format,
- GR_MIPMAPLEVELMASK_EVEN,
- ti->mipmapLevel[level].data);
- break;
- case TDFX_TMU_BOTH:
- FX_grTexDownloadMipMapLevel(fxMesa, GR_TMU0,
- ti->tm[GR_TMU0]->startAddr,
- glideLod,
- ti->info.largeLodLog2,
- ti->info.aspectRatioLog2,
- ti->info.format,
- GR_MIPMAPLEVELMASK_BOTH,
- ti->mipmapLevel[level].data);
-
- FX_grTexDownloadMipMapLevel(fxMesa, GR_TMU1,
- ti->tm[GR_TMU1]->startAddr,
- glideLod,
- ti->info.largeLodLog2,
- ti->info.aspectRatioLog2,
- ti->info.format,
- GR_MIPMAPLEVELMASK_BOTH,
- ti->mipmapLevel[level].data);
- break;
-
- default:
- gl_problem(ctx, "error in tdfxTMReloadMipMapLevel(): wrong tmu");
- break;
- }
+ tdfxTexObjPtr t = TDFX_TEXTURE_DATA(tObj);
+ GrLOD_t glideLod;
+ FxU32 unit;
+
+ ASSERT( t->isInTM );
+
+ unit = t->whichTMU;
+ glideLod = t->info.largeLodLog2 - level + tObj->BaseLevel;
+
+ switch ( unit ) {
+ case TDFX_TMU0:
+ case TDFX_TMU1:
+ grTexDownloadMipMapLevel( unit,
+ t->range[unit]->startAddr,
+ glideLod,
+ t->info.largeLodLog2,
+ t->info.aspectRatioLog2,
+ t->info.format,
+ GR_MIPMAPLEVELMASK_BOTH,
+ t->image[level].data );
+ break;
+
+ case TDFX_TMU_SPLIT:
+ grTexDownloadMipMapLevel( GR_TMU0,
+ t->range[GR_TMU0]->startAddr,
+ glideLod,
+ t->info.largeLodLog2,
+ t->info.aspectRatioLog2,
+ t->info.format,
+ GR_MIPMAPLEVELMASK_ODD,
+ t->image[level].data );
+
+ grTexDownloadMipMapLevel( GR_TMU1,
+ t->range[GR_TMU1]->startAddr,
+ glideLod,
+ t->info.largeLodLog2,
+ t->info.aspectRatioLog2,
+ t->info.format,
+ GR_MIPMAPLEVELMASK_EVEN,
+ t->image[level].data );
+ break;
+
+ case TDFX_TMU_BOTH:
+ grTexDownloadMipMapLevel( GR_TMU0,
+ t->range[GR_TMU0]->startAddr,
+ glideLod,
+ t->info.largeLodLog2,
+ t->info.aspectRatioLog2,
+ t->info.format,
+ GR_MIPMAPLEVELMASK_BOTH,
+ t->image[level].data );
+
+ grTexDownloadMipMapLevel( GR_TMU1,
+ t->range[GR_TMU1]->startAddr,
+ glideLod,
+ t->info.largeLodLog2,
+ t->info.aspectRatioLog2,
+ t->info.format,
+ GR_MIPMAPLEVELMASK_BOTH,
+ t->image[level].data );
+ break;
+
+ default:
+ gl_problem( ctx, "error in tdfxTMReloadMipMapLevel(): wrong unit" );
+ break;
+ }
}
-/*
- * Allocate space for the given texture in texture memory then
+/* Allocate space for the given texture in texture memory then
* download (copy) it into that space.
*/
-void
-tdfxTMMoveInTM_NoLock( tdfxContextPtr fxMesa, struct gl_texture_object *tObj,
- FxU32 targetTMU )
+void tdfxTMMoveInTMLocked( tdfxContextPtr fxMesa,
+ struct gl_texture_object *tObj, FxU32 targetTMU )
{
- tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj);
- FxU32 texmemsize;
-
- fxMesa->stats.reqTexUpload++;
-
- if (ti->isInTM) {
- if (ti->whichTMU == targetTMU)
- return;
- if (targetTMU == TDFX_TMU_SPLIT || ti->whichTMU == TDFX_TMU_SPLIT) {
- tdfxTMMoveOutTM_NoLock(fxMesa, tObj);
- }
- else {
- if (ti->whichTMU == TDFX_TMU_BOTH)
- return;
- targetTMU = TDFX_TMU_BOTH;
- }
- }
-
- ti->whichTMU = targetTMU;
-
- switch (targetTMU) {
- case TDFX_TMU0:
- case TDFX_TMU1:
- texmemsize = FX_grTexTextureMemRequired_NoLock(GR_MIPMAPLEVELMASK_BOTH,
- &(ti->info));
- ti->tm[targetTMU] = AllocTexMem(fxMesa, targetTMU, texmemsize);
- break;
- case TDFX_TMU_SPLIT:
- texmemsize = FX_grTexTextureMemRequired_NoLock(GR_MIPMAPLEVELMASK_ODD,
- &(ti->info));
- ti->tm[TDFX_TMU0] = AllocTexMem(fxMesa, TDFX_TMU0, texmemsize);
- if (ti->tm[TDFX_TMU0])
- fxMesa->stats.memTexUpload += texmemsize;
-
- texmemsize = FX_grTexTextureMemRequired_NoLock(GR_MIPMAPLEVELMASK_EVEN,
- &(ti->info));
- ti->tm[TDFX_TMU1] = AllocTexMem(fxMesa, TDFX_TMU1, texmemsize);
- break;
- case TDFX_TMU_BOTH:
- texmemsize = FX_grTexTextureMemRequired_NoLock(GR_MIPMAPLEVELMASK_BOTH,
- &(ti->info));
- ti->tm[TDFX_TMU0] = AllocTexMem(fxMesa, TDFX_TMU0, texmemsize);
- if (ti->tm[TDFX_TMU0])
- fxMesa->stats.memTexUpload += texmemsize;
-
- texmemsize = FX_grTexTextureMemRequired_NoLock(GR_MIPMAPLEVELMASK_BOTH,
- &(ti->info));
- ti->tm[TDFX_TMU1] = AllocTexMem(fxMesa, TDFX_TMU1, texmemsize);
- break;
- default:
- gl_problem(NULL, "error in tdfxTMMoveInTM() -> bad tmu (%d)");
- return;
- }
-
- ti->reloadImages = GL_TRUE;
- ti->isInTM = GL_TRUE;
-
- fxMesa->stats.texUpload++;
+ tdfxTexObjPtr t = TDFX_TEXTURE_DATA(tObj);
+ FxU32 size;
+
+ fxMesa->stats.reqTexUpload++;
+
+ if ( t->isInTM ) {
+ if ( t->whichTMU == targetTMU )
+ return;
+
+ if ( targetTMU == TDFX_TMU_SPLIT || t->whichTMU == TDFX_TMU_SPLIT ) {
+ tdfxTMMoveOutTMLocked( fxMesa, tObj );
+ } else {
+ if ( t->whichTMU == TDFX_TMU_BOTH )
+ return;
+ targetTMU = TDFX_TMU_BOTH;
+ }
+ }
+
+ t->whichTMU = targetTMU;
+
+ switch ( targetTMU ) {
+ case TDFX_TMU0:
+ case TDFX_TMU1:
+ size = grTexTextureMemRequired( GR_MIPMAPLEVELMASK_BOTH, &t->info );
+ t->range[targetTMU] = tdfxTMAllocTexMem(fxMesa, targetTMU, size);
+ break;
+
+ case TDFX_TMU_SPLIT:
+ size = grTexTextureMemRequired( GR_MIPMAPLEVELMASK_ODD, &t->info );
+ t->range[TDFX_TMU0] = tdfxTMAllocTexMem( fxMesa, TDFX_TMU0, size );
+ if ( t->range[TDFX_TMU0] )
+ fxMesa->stats.memTexUpload += size;
+
+ size = grTexTextureMemRequired( GR_MIPMAPLEVELMASK_EVEN, &t->info );
+ t->range[TDFX_TMU1] = tdfxTMAllocTexMem( fxMesa, TDFX_TMU1, size );
+ break;
+
+ case TDFX_TMU_BOTH:
+ size = grTexTextureMemRequired( GR_MIPMAPLEVELMASK_BOTH, &t->info );
+ t->range[TDFX_TMU0] = tdfxTMAllocTexMem( fxMesa, TDFX_TMU0, size );
+ if ( t->range[TDFX_TMU0] )
+ fxMesa->stats.memTexUpload += size;
+
+ size = grTexTextureMemRequired( GR_MIPMAPLEVELMASK_BOTH, &t->info );
+ t->range[TDFX_TMU1] = tdfxTMAllocTexMem( fxMesa, TDFX_TMU1, size );
+ break;
+
+ default:
+ gl_problem( NULL, "error in tdfxTMMoveInTM() -> bad unit (%d)" );
+ return;
+ }
+
+ t->reloadImages = GL_TRUE;
+ t->isInTM = GL_TRUE;
+
+ fxMesa->stats.texUpload++;
}
-/*
- * Move the given texture out of hardware texture memory.
+/* Move the given texture out of hardware texture memory.
* This deallocates the texture's memory space.
*/
-void
-tdfxTMMoveOutTM_NoLock( tdfxContextPtr fxMesa, struct gl_texture_object *tObj )
+void tdfxTMMoveOutTMLocked( tdfxContextPtr fxMesa,
+ struct gl_texture_object *tObj )
{
- struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared;
- struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData;
- tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj);
-
- if (MESA_VERBOSE & VERBOSE_DRIVER) {
- fprintf(stderr, "fxmesa: fxTMMoveOutTM(%p (%d))\n", tObj, tObj->Name);
- }
-
- /*
- VerifyFreeList(fxMesa, 0);
- VerifyFreeList(fxMesa, 1);
- */
-
- if (!ti || !ti->isInTM)
- return;
-
- switch (ti->whichTMU) {
- case TDFX_TMU0:
- case TDFX_TMU1:
- RemoveRange_NoLock(fxMesa, ti->whichTMU, ti->tm[ti->whichTMU]);
- break;
- case TDFX_TMU_SPLIT:
- case TDFX_TMU_BOTH:
- assert(!shared->umaTexMemory);
- RemoveRange_NoLock(fxMesa, TDFX_TMU0, ti->tm[TDFX_TMU0]);
- RemoveRange_NoLock(fxMesa, TDFX_TMU1, ti->tm[TDFX_TMU1]);
- break;
- default:
- gl_problem(NULL, "tdfx driver: bad tmu in tdfxTMMOveOutTM()");
- return;
- }
-
- ti->isInTM = GL_FALSE;
- ti->tm[0] = NULL;
- ti->tm[1] = NULL;
- ti->whichTMU = TDFX_TMU_NONE;
-
- /*
- VerifyFreeList(fxMesa, 0);
- VerifyFreeList(fxMesa, 1);
- */
+ struct gl_shared_state *ss = fxMesa->glCtx->Shared;
+ tdfxSharedStatePtr tss = (tdfxSharedStatePtr)ss->DriverData;
+ tdfxTexObjPtr t = TDFX_TEXTURE_DATA(tObj);
+
+ if ( TDFX_DEBUG & DEBUG_VERBOSE_TEXTURE ) {
+ fprintf( stderr, __FUNCTION__ "( %p (%d) )\n", tObj, tObj->Name );
+ tdfxTMVerifyFreeList( fxMesa, 0 );
+ tdfxTMVerifyFreeList( fxMesa, 1 );
+ }
+
+ if ( !t || !t->isInTM )
+ return;
+
+ switch ( t->whichTMU ) {
+ case TDFX_TMU0:
+ case TDFX_TMU1:
+ tdfxTMRemoveRangeLocked( fxMesa, t->whichTMU, t->range[t->whichTMU] );
+ break;
+
+ case TDFX_TMU_SPLIT:
+ case TDFX_TMU_BOTH:
+ assert( !tss->umaTexMemory );
+ tdfxTMRemoveRangeLocked( fxMesa, TDFX_TMU0, t->range[TDFX_TMU0] );
+ tdfxTMRemoveRangeLocked( fxMesa, TDFX_TMU1, t->range[TDFX_TMU1] );
+ break;
+
+ default:
+ gl_problem( NULL, "tdfx driver: bad unit in tdfxTMMOveOutTM()" );
+ return;
+ }
+
+ t->isInTM = GL_FALSE;
+ t->range[0] = NULL;
+ t->range[1] = NULL;
+ t->whichTMU = TDFX_TMU_NONE;
+
+ if ( TDFX_DEBUG & DEBUG_VERBOSE_TEXTURE ) {
+ tdfxTMVerifyFreeList( fxMesa, 0 );
+ tdfxTMVerifyFreeList( fxMesa, 1 );
+ }
}
-/*
- * Called via glDeleteTexture to delete a texture object.
- */
-void
-tdfxTMFreeTexture(tdfxContextPtr fxMesa, struct gl_texture_object *tObj)
+void tdfxTMFreeTextureLocked( tdfxContextPtr fxMesa,
+ struct gl_texture_object *tObj )
{
- tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj);
- if (ti) {
- int i;
- tdfxTMMoveOutTM(fxMesa, tObj);
- for (i = 0; i < MAX_TEXTURE_LEVELS; i++) {
- if (ti->mipmapLevel[i].data) {
- FREE(ti->mipmapLevel[i].data);
- ti->mipmapLevel[i].data = NULL;
- }
- }
- FREE(ti);
- tObj->DriverData = NULL;
- }
- /*
- VerifyFreeList(fxMesa, 0);
- VerifyFreeList(fxMesa, 1);
- */
-}
+ tdfxTexObjPtr t = TDFX_TEXTURE_DATA(tObj);
+
+ if ( t ) {
+ int i;
+ tdfxTMMoveOutTMLocked( fxMesa, tObj );
+ for ( i = 0 ; i < MAX_TEXTURE_LEVELS ; i++ ) {
+ if ( t->image[i].original.data ) {
+ FREE( t->image[i].original.data );
+ t->image[i].original.data = NULL;
+ t->image[i].original.width = 0;
+ t->image[i].original.height = 0;
+ t->image[i].original.size = 0;
+ }
+ if ( t->image[i].rescaled.data ) {
+ FREE( t->image[i].rescaled.data );
+ t->image[i].rescaled.data = NULL;
+ t->image[i].rescaled.width = 0;
+ t->image[i].rescaled.height = 0;
+ t->image[i].rescaled.size = 0;
+ }
+ }
+ FREE( t );
+ tObj->DriverData = NULL;
+ }
+ if ( TDFX_DEBUG & DEBUG_VERBOSE_TEXTURE ) {
+ tdfxTMVerifyFreeList( fxMesa, 0 );
+ tdfxTMVerifyFreeList( fxMesa, 1 );
+ }
+}
-/*
- * After a context switch this function will be called to restore
+/* After a context switch this function will be called to restore
* texture memory for the new context.
*/
-void tdfxTMRestoreTextures_NoLock( tdfxContextPtr fxMesa )
+void tdfxTMRestoreTexturesLocked( tdfxContextPtr fxMesa )
{
GLcontext *ctx = fxMesa->glCtx;
struct gl_texture_object *tObj;
int i;
for ( tObj = ctx->Shared->TexObjectList ; tObj ; tObj = tObj->Next ) {
- tdfxTexInfo *ti = TDFX_TEXTURE_DATA( tObj );
- if ( ti && ti->isInTM ) {
+ tdfxTexObjPtr t = TDFX_TEXTURE_DATA( tObj );
+ if ( t && t->isInTM ) {
for ( i = 0 ; i < MAX_TEXTURE_UNITS ; i++ ) {
if ( ctx->Texture.Unit[i].Current == tObj ) {
- tdfxTMDownloadTexture( fxMesa, tObj );
+ tdfxTMDownloadTextureLocked( fxMesa, tObj );
break;
}
}
if ( i == MAX_TEXTURE_UNITS ) {
- tdfxTMMoveOutTM_NoLock( fxMesa, tObj );
+ tdfxTMMoveOutTMLocked( fxMesa, tObj );
}
}
}
- /*
- VerifyFreeList(fxMesa, 0);
- VerifyFreeList(fxMesa, 1);
- */
+
+ if ( TDFX_DEBUG & DEBUG_VERBOSE_TEXTURE ) {
+ tdfxTMVerifyFreeList( fxMesa, 0 );
+ tdfxTMVerifyFreeList( fxMesa, 1 );
+ }
}
diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texman.h b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texman.h
index 1965aaa84..6979367a0 100644
--- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texman.h
+++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texman.h
@@ -38,47 +38,39 @@
#ifndef __TDFX_TEXMAN_H__
#define __TDFX_TEXMAN_H__
-
#include "tdfx_lock.h"
-
extern void tdfxTMInit( tdfxContextPtr fxMesa );
-
extern void tdfxTMClose( tdfxContextPtr fxMesa );
-extern void tdfxTMDownloadTexture(tdfxContextPtr fxMesa,
- struct gl_texture_object *tObj);
-
-extern void tdfxTMReloadMipMapLevel( GLcontext *ctx,
- struct gl_texture_object *tObj,
- GLint level );
-
-extern void tdfxTMMoveInTM_NoLock( tdfxContextPtr fxMesa,
- struct gl_texture_object *tObj,
- FxU32 targetTMU );
-
-extern void tdfxTMMoveOutTM_NoLock( tdfxContextPtr fxMesa,
- struct gl_texture_object *tObj );
-
-extern void tdfxTMFreeTexture( tdfxContextPtr fxMesa,
- struct gl_texture_object *tObj );
-
-extern void tdfxTMRestoreTextures_NoLock( tdfxContextPtr fxMesa );
-
-
-#define tdfxTMMoveInTM( fxMesa, tObj, targetTMU ) \
- do { \
- LOCK_HARDWARE( fxMesa ); \
- tdfxTMMoveInTM_NoLock( fxMesa, tObj, targetTMU ); \
- UNLOCK_HARDWARE( fxMesa ); \
- } while (0)
-
-#define tdfxTMMoveOutTM( fxMesa, tObj ) \
- do { \
- LOCK_HARDWARE( fxMesa ); \
- tdfxTMMoveOutTM_NoLock( fxMesa, tObj ); \
- UNLOCK_HARDWARE( fxMesa ); \
- } while (0)
-
+extern void tdfxTMDownloadTextureLocked( tdfxContextPtr fxMesa,
+ struct gl_texture_object *tObj );
+extern void tdfxTMReloadMipMapLevelLocked( GLcontext *ctx,
+ struct gl_texture_object *tObj,
+ GLint level );
+extern void tdfxTMMoveInTMLocked( tdfxContextPtr fxMesa,
+ struct gl_texture_object *tObj,
+ FxU32 targetTMU );
+extern void tdfxTMMoveOutTMLocked( tdfxContextPtr fxMesa,
+ struct gl_texture_object *tObj );
+extern void tdfxTMRestoreTexturesLocked( tdfxContextPtr fxMesa );
+
+extern void tdfxTMFreeTextureLocked( tdfxContextPtr fxMesa,
+ struct gl_texture_object *tObj );
+
+
+#define tdfxTMMoveInTM( fxMesa, tObj, targetTMU ) \
+do { \
+ LOCK_HARDWARE( fxMesa ); \
+ tdfxTMMoveInTMLocked( fxMesa, tObj, targetTMU ); \
+ UNLOCK_HARDWARE( fxMesa ); \
+} while (0)
+
+#define tdfxTMMoveOutTM( fxMesa, tObj ) \
+do { \
+ LOCK_HARDWARE( fxMesa ); \
+ tdfxTMMoveOutTMLocked( fxMesa, tObj ); \
+ UNLOCK_HARDWARE( fxMesa ); \
+} while (0)
#endif
diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texstate.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texstate.c
index 5493eea8a..368f051a3 100644
--- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texstate.c
+++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texstate.c
@@ -38,7 +38,6 @@
#include "tdfx_state.h"
#include "tdfx_tex.h"
#include "tdfx_texman.h"
-#include "tdfx_texstate.h"
/* =============================================================
@@ -1270,105 +1269,105 @@ SetupDoubleTexEnvVoodoo3(GLcontext *ctx, int tmu0,
static void
setupSingleTMU(tdfxContextPtr fxMesa, struct gl_texture_object *tObj)
{
- struct tdfxSharedState *shared = (struct tdfxSharedState *) fxMesa->glCtx->Shared->DriverData;
- tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj);
const GLcontext *ctx = fxMesa->glCtx;
+ tdfxSharedStatePtr tss = (tdfxSharedStatePtr)ctx->Shared->DriverData;
+ tdfxTexObjPtr t = TDFX_TEXTURE_DATA(tObj);
/* Make sure we're not loaded incorrectly */
- if (ti->isInTM && !shared->umaTexMemory) {
+ if (t->isInTM && !tss->umaTexMemory) {
/* if doing filtering between mipmap levels, alternate mipmap levels
* must be in alternate TMUs.
*/
- if (ti->LODblend) {
- if (ti->whichTMU != TDFX_TMU_SPLIT)
- tdfxTMMoveOutTM_NoLock(fxMesa, tObj);
+ if (t->LODblend) {
+ if (t->whichTMU != TDFX_TMU_SPLIT)
+ tdfxTMMoveOutTMLocked(fxMesa, tObj);
}
else {
- if (ti->whichTMU == TDFX_TMU_SPLIT)
- tdfxTMMoveOutTM_NoLock(fxMesa, tObj);
+ if (t->whichTMU == TDFX_TMU_SPLIT)
+ tdfxTMMoveOutTMLocked(fxMesa, tObj);
}
}
/* Make sure we're loaded correctly */
- if (!ti->isInTM) {
+ if (!t->isInTM) {
/* Have to download the texture */
- if (shared->umaTexMemory) {
- tdfxTMMoveInTM_NoLock(fxMesa, tObj, TDFX_TMU0);
+ if (tss->umaTexMemory) {
+ tdfxTMMoveInTMLocked(fxMesa, tObj, TDFX_TMU0);
}
else {
/* Voodoo3 (split texture memory) */
- if (ti->LODblend) {
- tdfxTMMoveInTM_NoLock(fxMesa, tObj, TDFX_TMU_SPLIT);
+ if (t->LODblend) {
+ tdfxTMMoveInTMLocked(fxMesa, tObj, TDFX_TMU_SPLIT);
}
else {
#if 0
/* XXX putting textures into the second memory bank when the
* first bank is full is not working at this time.
*/
- if (fxMesa->haveTwoTMUs) {
- GLint memReq = FX_grTexTextureMemRequired_NoLock(
- GR_MIPMAPLEVELMASK_BOTH, &(ti->info));
- if (shared->freeTexMem[TDFX_TMU0] > memReq) {
- tdfxTMMoveInTM_NoLock(fxMesa, tObj, TDFX_TMU0);
+ if (fxMesa->numTMUs > 1) {
+ GLint memReq =
+ grTexTextureMemRequired( GR_MIPMAPLEVELMASK_BOTH, &t->info );
+ if (tss->freeTexMem[TDFX_TMU0] > memReq) {
+ tdfxTMMoveInTMLocked(fxMesa, tObj, TDFX_TMU0);
}
else {
- tdfxTMMoveInTM_NoLock(fxMesa, tObj, TDFX_TMU1);
+ tdfxTMMoveInTMLocked(fxMesa, tObj, TDFX_TMU1);
}
}
else
#endif
{
- tdfxTMMoveInTM_NoLock(fxMesa, tObj, TDFX_TMU0);
+ tdfxTMMoveInTMLocked( fxMesa, tObj, TDFX_TMU0 );
}
}
}
}
- if (ti->LODblend && ti->whichTMU == TDFX_TMU_SPLIT) {
+ if (t->LODblend && t->whichTMU == TDFX_TMU_SPLIT) {
/* mipmap levels split between texture banks */
GLint u;
- if (ti->info.format == GR_TEXFMT_P_8 && !ctx->Texture.SharedPalette) {
+ if (t->info.format == GR_TEXFMT_P_8 && !ctx->Texture.SharedPalette) {
fxMesa->TexPalette.Type = GR_TEXTABLE_PALETTE_6666_EXT;
- fxMesa->TexPalette.Data = &(ti->palette);
+ fxMesa->TexPalette.Data = &(t->palette);
fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_PALETTE;
}
for (u = 0; u < 2; u++) {
- fxMesa->TexParams[u].sClamp = ti->sClamp;
- fxMesa->TexParams[u].tClamp = ti->tClamp;
- fxMesa->TexParams[u].minFilt = ti->minFilt;
- fxMesa->TexParams[u].magFilt = ti->magFilt;
- fxMesa->TexParams[u].mmMode = ti->mmMode;
- fxMesa->TexParams[u].LODblend = ti->LODblend;
+ fxMesa->TexParams[u].sClamp = t->sClamp;
+ fxMesa->TexParams[u].tClamp = t->tClamp;
+ fxMesa->TexParams[u].minFilt = t->minFilt;
+ fxMesa->TexParams[u].magFilt = t->magFilt;
+ fxMesa->TexParams[u].mmMode = t->mmMode;
+ fxMesa->TexParams[u].LODblend = t->LODblend;
fxMesa->TexParams[u].LodBias = ctx->Texture.Unit[u].LodBias;
}
fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_PARAMS;
- fxMesa->TexSource[0].StartAddress = ti->tm[TDFX_TMU0]->startAddr;
+ fxMesa->TexSource[0].StartAddress = t->range[TDFX_TMU0]->startAddr;
fxMesa->TexSource[0].EvenOdd = GR_MIPMAPLEVELMASK_ODD;
- fxMesa->TexSource[0].Info = &(ti->info);
- fxMesa->TexSource[1].StartAddress = ti->tm[TDFX_TMU1]->startAddr;
+ fxMesa->TexSource[0].Info = &(t->info);
+ fxMesa->TexSource[1].StartAddress = t->range[TDFX_TMU1]->startAddr;
fxMesa->TexSource[1].EvenOdd = GR_MIPMAPLEVELMASK_EVEN;
- fxMesa->TexSource[1].Info = &(ti->info);
+ fxMesa->TexSource[1].Info = &(t->info);
fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_SOURCE;
}
else {
FxU32 tmu;
- if (ti->whichTMU == TDFX_TMU_BOTH)
+ if (t->whichTMU == TDFX_TMU_BOTH)
tmu = TDFX_TMU0;
else
- tmu = ti->whichTMU;
+ tmu = t->whichTMU;
- if (shared->umaTexMemory) {
- assert(ti->whichTMU == TDFX_TMU0);
+ if (tss->umaTexMemory) {
+ assert(t->whichTMU == TDFX_TMU0);
assert(tmu == TDFX_TMU0);
}
- if (ti->info.format == GR_TEXFMT_P_8 && !ctx->Texture.SharedPalette) {
+ if (t->info.format == GR_TEXFMT_P_8 && !ctx->Texture.SharedPalette) {
fxMesa->TexPalette.Type = GR_TEXTABLE_PALETTE_6666_EXT;
- fxMesa->TexPalette.Data = &(ti->palette);
+ fxMesa->TexPalette.Data = &(t->palette);
fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_PALETTE;
}
@@ -1377,18 +1376,18 @@ setupSingleTMU(tdfxContextPtr fxMesa, struct gl_texture_object *tObj)
* texture memory, so perhaps it's not a good idea.
*/
- if (fxMesa->TexParams[tmu].sClamp != ti->sClamp ||
- fxMesa->TexParams[tmu].tClamp != ti->tClamp ||
- fxMesa->TexParams[tmu].minFilt != ti->minFilt ||
- fxMesa->TexParams[tmu].magFilt != ti->magFilt ||
- fxMesa->TexParams[tmu].mmMode != ti->mmMode ||
+ if (fxMesa->TexParams[tmu].sClamp != t->sClamp ||
+ fxMesa->TexParams[tmu].tClamp != t->tClamp ||
+ fxMesa->TexParams[tmu].minFilt != t->minFilt ||
+ fxMesa->TexParams[tmu].magFilt != t->magFilt ||
+ fxMesa->TexParams[tmu].mmMode != t->mmMode ||
fxMesa->TexParams[tmu].LODblend != FXFALSE ||
fxMesa->TexParams[tmu].LodBias != ctx->Texture.Unit[tmu].LodBias) {
- fxMesa->TexParams[tmu].sClamp = ti->sClamp;
- fxMesa->TexParams[tmu].tClamp = ti->tClamp;
- fxMesa->TexParams[tmu].minFilt = ti->minFilt;
- fxMesa->TexParams[tmu].magFilt = ti->magFilt;
- fxMesa->TexParams[tmu].mmMode = ti->mmMode;
+ fxMesa->TexParams[tmu].sClamp = t->sClamp;
+ fxMesa->TexParams[tmu].tClamp = t->tClamp;
+ fxMesa->TexParams[tmu].minFilt = t->minFilt;
+ fxMesa->TexParams[tmu].magFilt = t->magFilt;
+ fxMesa->TexParams[tmu].mmMode = t->mmMode;
fxMesa->TexParams[tmu].LODblend = FXFALSE;
fxMesa->TexParams[tmu].LodBias = ctx->Texture.Unit[tmu].LodBias;
fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_PARAMS;
@@ -1397,16 +1396,16 @@ setupSingleTMU(tdfxContextPtr fxMesa, struct gl_texture_object *tObj)
/* Glide texture source info */
fxMesa->TexSource[0].Info = NULL;
fxMesa->TexSource[1].Info = NULL;
- if (ti->tm[tmu]) {
- fxMesa->TexSource[tmu].StartAddress = ti->tm[tmu]->startAddr;
+ if (t->range[tmu]) {
+ fxMesa->TexSource[tmu].StartAddress = t->range[tmu]->startAddr;
fxMesa->TexSource[tmu].EvenOdd = GR_MIPMAPLEVELMASK_BOTH;
- fxMesa->TexSource[tmu].Info = &(ti->info);
+ fxMesa->TexSource[tmu].Info = &(t->info);
fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_SOURCE;
}
}
- fxMesa->sScale0 = ti->sScale;
- fxMesa->tScale0 = ti->tScale;
+ fxMesa->sScale0 = t->sScale;
+ fxMesa->tScale0 = t->tScale;
}
static void
@@ -1420,12 +1419,12 @@ selectSingleTMUSrc(tdfxContextPtr fxMesa, GLint tmu, FxBool LODblend)
fxMesa->TexCombine[0].InvertRGB = FXFALSE;
fxMesa->TexCombine[0].InvertAlpha = FXFALSE;
- if (fxMesa->haveTwoTMUs) {
- const struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared;
- const struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData;
+ if ( fxMesa->numTMUs > 1 ) {
+ const struct gl_shared_state *ss = fxMesa->glCtx->Shared;
+ const tdfxSharedStatePtr tss = (tdfxSharedStatePtr)ss->DriverData;
int tmu;
- if (shared->umaTexMemory)
+ if (tss->umaTexMemory)
tmu = GR_TMU0;
else
tmu = GR_TMU1;
@@ -1447,7 +1446,7 @@ selectSingleTMUSrc(tdfxContextPtr fxMesa, GLint tmu, FxBool LODblend)
fxMesa->TexCombine[0].FactorAlpha = GR_COMBINE_FACTOR_NONE;
fxMesa->TexCombine[0].InvertRGB = FXFALSE;
fxMesa->TexCombine[0].InvertAlpha = FXFALSE;
- if (fxMesa->haveTwoTMUs) {
+ if ( fxMesa->numTMUs > 1 ) {
fxMesa->TexCombine[1].FunctionRGB = GR_COMBINE_FUNCTION_ZERO;
fxMesa->TexCombine[1].FactorRGB = GR_COMBINE_FACTOR_NONE;
fxMesa->TexCombine[1].FunctionAlpha = GR_COMBINE_FUNCTION_ZERO;
@@ -1511,7 +1510,7 @@ static void print_state(tdfxContextPtr fxMesa)
static void setupTextureSingleTMU(GLcontext * ctx, GLuint unit)
{
tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
- tdfxTexInfo *ti;
+ tdfxTexObjPtr t;
struct gl_texture_object *tObj;
int tmu;
GLenum envMode, baseFormat;
@@ -1530,17 +1529,17 @@ static void setupTextureSingleTMU(GLcontext * ctx, GLuint unit)
setupSingleTMU(fxMesa, tObj);
- ti = TDFX_TEXTURE_DATA(tObj);
- if (ti->whichTMU == TDFX_TMU_BOTH)
+ t = TDFX_TEXTURE_DATA(tObj);
+ if (t->whichTMU == TDFX_TMU_BOTH)
tmu = TDFX_TMU0;
else
- tmu = ti->whichTMU;
+ tmu = t->whichTMU;
if (fxMesa->tmuSrc != tmu) {
- selectSingleTMUSrc(fxMesa, tmu, ti->LODblend);
+ selectSingleTMUSrc(fxMesa, tmu, t->LODblend);
}
- if (ti->reloadImages)
+ if (t->reloadImages)
fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_IMAGES;
/* Some texture environments not supported */
@@ -1627,35 +1626,35 @@ setupDoubleTMU(tdfxContextPtr fxMesa,
#define T0_IN_TMU1 0x10
#define T1_IN_TMU1 0x20
- const struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared;
- const struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData;
+ const struct gl_shared_state *ss = fxMesa->glCtx->Shared;
+ const tdfxSharedStatePtr tss = (tdfxSharedStatePtr)ss->DriverData;
const GLcontext *ctx = fxMesa->glCtx;
- tdfxTexInfo *ti0 = TDFX_TEXTURE_DATA(tObj0);
- tdfxTexInfo *ti1 = TDFX_TEXTURE_DATA(tObj1);
+ tdfxTexObjPtr t0 = TDFX_TEXTURE_DATA(tObj0);
+ tdfxTexObjPtr t1 = TDFX_TEXTURE_DATA(tObj1);
GLuint tstate = 0;
int tmu0 = 0, tmu1 = 1;
- if (shared->umaTexMemory) {
- if (!ti0->isInTM) {
- tdfxTMMoveInTM_NoLock(fxMesa, tObj0, TDFX_TMU0);
- assert(ti0->isInTM);
+ if (tss->umaTexMemory) {
+ if (!t0->isInTM) {
+ tdfxTMMoveInTMLocked(fxMesa, tObj0, TDFX_TMU0);
+ assert(t0->isInTM);
}
- if (!ti1->isInTM) {
- tdfxTMMoveInTM_NoLock(fxMesa, tObj1, TDFX_TMU0);
- assert(ti1->isInTM);
+ if (!t1->isInTM) {
+ tdfxTMMoveInTMLocked(fxMesa, tObj1, TDFX_TMU0);
+ assert(t1->isInTM);
}
}
else {
/* We shouldn't need to do this. There is something wrong with
multitexturing when the TMUs are swapped. So, we're forcing
them to always be loaded correctly. !!! */
- if (ti0->whichTMU == TDFX_TMU1)
- tdfxTMMoveOutTM_NoLock(fxMesa, tObj0);
- if (ti1->whichTMU == TDFX_TMU0)
- tdfxTMMoveOutTM_NoLock(fxMesa, tObj1);
+ if (t0->whichTMU == TDFX_TMU1)
+ tdfxTMMoveOutTMLocked(fxMesa, tObj0);
+ if (t1->whichTMU == TDFX_TMU0)
+ tdfxTMMoveOutTMLocked(fxMesa, tObj1);
- if (ti0->isInTM) {
- switch (ti0->whichTMU) {
+ if (t0->isInTM) {
+ switch (t0->whichTMU) {
case TDFX_TMU0:
tstate |= T0_IN_TMU0;
break;
@@ -1673,8 +1672,8 @@ setupDoubleTMU(tdfxContextPtr fxMesa,
else
tstate |= T0_NOT_IN_TMU;
- if (ti1->isInTM) {
- switch (ti1->whichTMU) {
+ if (t1->isInTM) {
+ switch (t1->whichTMU) {
case TDFX_TMU0:
tstate |= T1_IN_TMU0;
break;
@@ -1697,7 +1696,7 @@ setupDoubleTMU(tdfxContextPtr fxMesa,
if (!(((tstate & T0_IN_TMU0) && (tstate & T1_IN_TMU1)) ||
((tstate & T0_IN_TMU1) && (tstate & T1_IN_TMU0)))) {
if (tObj0 == tObj1) {
- tdfxTMMoveInTM_NoLock(fxMesa, tObj1, TDFX_TMU_BOTH);
+ tdfxTMMoveInTMLocked(fxMesa, tObj1, TDFX_TMU_BOTH);
}
else {
/* Find the minimal way to correct the situation */
@@ -1705,10 +1704,10 @@ setupDoubleTMU(tdfxContextPtr fxMesa,
/* We have one in the standard order, setup the other */
if (tstate & T0_IN_TMU0) {
/* T0 is in TMU0, put T1 in TMU1 */
- tdfxTMMoveInTM_NoLock(fxMesa, tObj1, TDFX_TMU1);
+ tdfxTMMoveInTMLocked(fxMesa, tObj1, TDFX_TMU1);
}
else {
- tdfxTMMoveInTM_NoLock(fxMesa, tObj0, TDFX_TMU0);
+ tdfxTMMoveInTMLocked(fxMesa, tObj0, TDFX_TMU0);
}
/* tmu0 and tmu1 are setup */
}
@@ -1716,36 +1715,36 @@ setupDoubleTMU(tdfxContextPtr fxMesa,
/* we have one in the reverse order, setup the other */
if (tstate & T1_IN_TMU0) {
/* T1 is in TMU0, put T0 in TMU1 */
- tdfxTMMoveInTM_NoLock(fxMesa, tObj0, TDFX_TMU1);
+ tdfxTMMoveInTMLocked(fxMesa, tObj0, TDFX_TMU1);
}
else {
- tdfxTMMoveInTM_NoLock(fxMesa, tObj1, TDFX_TMU0);
+ tdfxTMMoveInTMLocked(fxMesa, tObj1, TDFX_TMU0);
}
tmu0 = 1;
tmu1 = 0;
}
else { /* Nothing is loaded */
- tdfxTMMoveInTM_NoLock(fxMesa, tObj0, TDFX_TMU0);
- tdfxTMMoveInTM_NoLock(fxMesa, tObj1, TDFX_TMU1);
+ tdfxTMMoveInTMLocked(fxMesa, tObj0, TDFX_TMU0);
+ tdfxTMMoveInTMLocked(fxMesa, tObj1, TDFX_TMU1);
/* tmu0 and tmu1 are setup */
}
}
}
}
- ti0->lastTimeUsed = fxMesa->texBindNumber;
- ti1->lastTimeUsed = fxMesa->texBindNumber;
+ t0->lastTimeUsed = fxMesa->texBindNumber;
+ t1->lastTimeUsed = fxMesa->texBindNumber;
if (!ctx->Texture.SharedPalette) {
- if (ti0->info.format == GR_TEXFMT_P_8) {
+ if (t0->info.format == GR_TEXFMT_P_8) {
fxMesa->TexPalette.Type = GR_TEXTABLE_PALETTE_6666_EXT;
- fxMesa->TexPalette.Data = &(ti0->palette);
+ fxMesa->TexPalette.Data = &(t0->palette);
fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_PALETTE;
}
- else if (ti1->info.format == GR_TEXFMT_P_8) {
+ else if (t1->info.format == GR_TEXFMT_P_8) {
fxMesa->TexPalette.Type = GR_TEXTABLE_PALETTE_6666_EXT;
- fxMesa->TexPalette.Data = &(ti1->palette);
+ fxMesa->TexPalette.Data = &(t1->palette);
fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_PALETTE;
}
else {
@@ -1756,25 +1755,25 @@ setupDoubleTMU(tdfxContextPtr fxMesa,
/*
* Setup Unit 0
*/
- assert(ti0->isInTM);
- assert(ti0->tm[tmu0]);
- fxMesa->TexSource[tmu0].StartAddress = ti0->tm[tmu0]->startAddr;
+ assert(t0->isInTM);
+ assert(t0->range[tmu0]);
+ fxMesa->TexSource[tmu0].StartAddress = t0->range[tmu0]->startAddr;
fxMesa->TexSource[tmu0].EvenOdd = GR_MIPMAPLEVELMASK_BOTH;
- fxMesa->TexSource[tmu0].Info = &(ti0->info);
+ fxMesa->TexSource[tmu0].Info = &(t0->info);
fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_SOURCE;
- if (fxMesa->TexParams[tmu0].sClamp != ti0->sClamp ||
- fxMesa->TexParams[tmu0].tClamp != ti0->tClamp ||
- fxMesa->TexParams[tmu0].minFilt != ti0->minFilt ||
- fxMesa->TexParams[tmu0].magFilt != ti0->magFilt ||
- fxMesa->TexParams[tmu0].mmMode != ti0->mmMode ||
+ if (fxMesa->TexParams[tmu0].sClamp != t0->sClamp ||
+ fxMesa->TexParams[tmu0].tClamp != t0->tClamp ||
+ fxMesa->TexParams[tmu0].minFilt != t0->minFilt ||
+ fxMesa->TexParams[tmu0].magFilt != t0->magFilt ||
+ fxMesa->TexParams[tmu0].mmMode != t0->mmMode ||
fxMesa->TexParams[tmu0].LODblend != FXFALSE ||
fxMesa->TexParams[tmu0].LodBias != ctx->Texture.Unit[tmu0].LodBias) {
- fxMesa->TexParams[tmu0].sClamp = ti0->sClamp;
- fxMesa->TexParams[tmu0].tClamp = ti0->tClamp;
- fxMesa->TexParams[tmu0].minFilt = ti0->minFilt;
- fxMesa->TexParams[tmu0].magFilt = ti0->magFilt;
- fxMesa->TexParams[tmu0].mmMode = ti0->mmMode;
+ fxMesa->TexParams[tmu0].sClamp = t0->sClamp;
+ fxMesa->TexParams[tmu0].tClamp = t0->tClamp;
+ fxMesa->TexParams[tmu0].minFilt = t0->minFilt;
+ fxMesa->TexParams[tmu0].magFilt = t0->magFilt;
+ fxMesa->TexParams[tmu0].mmMode = t0->mmMode;
fxMesa->TexParams[tmu0].LODblend = FXFALSE;
fxMesa->TexParams[tmu0].LodBias = ctx->Texture.Unit[tmu0].LodBias;
fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_PARAMS;
@@ -1783,42 +1782,42 @@ setupDoubleTMU(tdfxContextPtr fxMesa,
/*
* Setup Unit 1
*/
- if (shared->umaTexMemory) {
- ASSERT(ti1->isInTM);
- ASSERT(ti1->tm[0]);
- fxMesa->TexSource[tmu1].StartAddress = ti1->tm[0]->startAddr;
+ if (tss->umaTexMemory) {
+ ASSERT(t1->isInTM);
+ ASSERT(t1->range[0]);
+ fxMesa->TexSource[tmu1].StartAddress = t1->range[0]->startAddr;
fxMesa->TexSource[tmu1].EvenOdd = GR_MIPMAPLEVELMASK_BOTH;
- fxMesa->TexSource[tmu1].Info = &(ti1->info);
+ fxMesa->TexSource[tmu1].Info = &(t1->info);
}
else {
- ASSERT(ti1->isInTM);
- ASSERT(ti1->tm[tmu1]);
- fxMesa->TexSource[tmu1].StartAddress = ti1->tm[tmu1]->startAddr;
+ ASSERT(t1->isInTM);
+ ASSERT(t1->range[tmu1]);
+ fxMesa->TexSource[tmu1].StartAddress = t1->range[tmu1]->startAddr;
fxMesa->TexSource[tmu1].EvenOdd = GR_MIPMAPLEVELMASK_BOTH;
- fxMesa->TexSource[tmu1].Info = &(ti1->info);
+ fxMesa->TexSource[tmu1].Info = &(t1->info);
}
- if (fxMesa->TexParams[tmu1].sClamp != ti1->sClamp ||
- fxMesa->TexParams[tmu1].tClamp != ti1->tClamp ||
- fxMesa->TexParams[tmu1].minFilt != ti1->minFilt ||
- fxMesa->TexParams[tmu1].magFilt != ti1->magFilt ||
- fxMesa->TexParams[tmu1].mmMode != ti1->mmMode ||
+ if (fxMesa->TexParams[tmu1].sClamp != t1->sClamp ||
+ fxMesa->TexParams[tmu1].tClamp != t1->tClamp ||
+ fxMesa->TexParams[tmu1].minFilt != t1->minFilt ||
+ fxMesa->TexParams[tmu1].magFilt != t1->magFilt ||
+ fxMesa->TexParams[tmu1].mmMode != t1->mmMode ||
fxMesa->TexParams[tmu1].LODblend != FXFALSE ||
fxMesa->TexParams[tmu1].LodBias != ctx->Texture.Unit[tmu1].LodBias) {
- fxMesa->TexParams[tmu1].sClamp = ti1->sClamp;
- fxMesa->TexParams[tmu1].tClamp = ti1->tClamp;
- fxMesa->TexParams[tmu1].minFilt = ti1->minFilt;
- fxMesa->TexParams[tmu1].magFilt = ti1->magFilt;
- fxMesa->TexParams[tmu1].mmMode = ti1->mmMode;
+ fxMesa->TexParams[tmu1].sClamp = t1->sClamp;
+ fxMesa->TexParams[tmu1].tClamp = t1->tClamp;
+ fxMesa->TexParams[tmu1].minFilt = t1->minFilt;
+ fxMesa->TexParams[tmu1].magFilt = t1->magFilt;
+ fxMesa->TexParams[tmu1].mmMode = t1->mmMode;
fxMesa->TexParams[tmu1].LODblend = FXFALSE;
fxMesa->TexParams[tmu1].LodBias = ctx->Texture.Unit[tmu1].LodBias;
fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_PARAMS;
}
- fxMesa->sScale0 = ti0->sScale;
- fxMesa->tScale0 = ti0->tScale;
- fxMesa->sScale1 = ti1->sScale;
- fxMesa->tScale1 = ti1->tScale;
+ fxMesa->sScale0 = t0->sScale;
+ fxMesa->tScale0 = t0->tScale;
+ fxMesa->sScale1 = t1->sScale;
+ fxMesa->tScale1 = t1->tScale;
#undef T0_NOT_IN_TMU
#undef T1_NOT_IN_TMU
@@ -1833,8 +1832,8 @@ static void setupTextureDoubleTMU(GLcontext * ctx)
tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
struct gl_texture_object *tObj0 = ctx->Texture.Unit[0].CurrentD[2];
struct gl_texture_object *tObj1 = ctx->Texture.Unit[1].CurrentD[2];
- tdfxTexInfo *ti0 = TDFX_TEXTURE_DATA(tObj0);
- tdfxTexInfo *ti1 = TDFX_TEXTURE_DATA(tObj1);
+ tdfxTexObjPtr t0 = TDFX_TEXTURE_DATA(tObj0);
+ tdfxTexObjPtr t1 = TDFX_TEXTURE_DATA(tObj1);
struct gl_texture_image *baseImage0 = tObj0->Image[tObj0->BaseLevel];
struct gl_texture_image *baseImage1 = tObj1->Image[tObj1->BaseLevel];
const GLenum envMode0 = ctx->Texture.Unit[0].EnvMode;
@@ -1847,7 +1846,7 @@ static void setupTextureDoubleTMU(GLcontext * ctx)
setupDoubleTMU(fxMesa, tObj0, tObj1);
- if (ti0->reloadImages || ti1->reloadImages)
+ if (t0->reloadImages || t1->reloadImages)
fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_IMAGES;
fxMesa->tmuSrc = TDFX_TMU_BOTH;
@@ -1893,7 +1892,7 @@ static void setupTextureDoubleTMU(GLcontext * ctx)
}
else {
int unit0, unit1;
- if ((ti0->whichTMU == TDFX_TMU1) || (ti1->whichTMU == TDFX_TMU0))
+ if ((t0->whichTMU == TDFX_TMU1) || (t1->whichTMU == TDFX_TMU0))
unit0 = 1;
else
unit0 = 0;
@@ -1924,34 +1923,34 @@ static void setupTextureDoubleTMU(GLcontext * ctx)
}
-void
-tdfxUpdateTextureState( GLcontext *ctx )
+void tdfxUpdateTextureState( GLcontext *ctx )
{
tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
- GLuint tex2Denabled = ctx->Texture.ReallyEnabled;
+ GLuint enabled = ctx->Texture.ReallyEnabled;
- if (!fxMesa->haveTwoTMUs)
- tex2Denabled &= TEXTURE0_2D;
+ if ( fxMesa->numTMUs == 1 )
+ enabled &= TEXTURE0_2D;
- switch (tex2Denabled) {
+ switch ( enabled ) {
case TEXTURE0_2D:
LOCK_HARDWARE( fxMesa ); /* XXX remove locking eventually */
- setupTextureSingleTMU(ctx, 0);
+ setupTextureSingleTMU( ctx, 0 );
UNLOCK_HARDWARE( fxMesa );
break;
case TEXTURE1_2D:
LOCK_HARDWARE( fxMesa );
- setupTextureSingleTMU(ctx, 1);
+ setupTextureSingleTMU( ctx, 1 );
UNLOCK_HARDWARE( fxMesa );
break;
- case (TEXTURE0_2D | TEXTURE1_2D):
+ case TEXTURE0_2D | TEXTURE1_2D:
LOCK_HARDWARE( fxMesa );
- setupTextureDoubleTMU(ctx);
+ setupTextureDoubleTMU( ctx );
UNLOCK_HARDWARE( fxMesa );
break;
+
default:
- /* disable hardware texturing */
- if (TDFX_IS_NAPALM(fxMesa)) {
+ /* Disable hardware texturing */
+ if ( TDFX_IS_NAPALM( fxMesa ) ) {
fxMesa->ColorCombineExt.SourceA = GR_CMBX_ITRGB;
fxMesa->ColorCombineExt.ModeA = GR_FUNC_MODE_X;
fxMesa->ColorCombineExt.SourceB = GR_CMBX_ZERO;
@@ -1972,9 +1971,8 @@ tdfxUpdateTextureState( GLcontext *ctx )
fxMesa->AlphaCombineExt.InvertD = FXFALSE;
fxMesa->AlphaCombineExt.Shift = 0;
fxMesa->AlphaCombineExt.Invert = FXFALSE;
- }
- else {
- /* Voodoo 3*/
+ } else {
+ /* Voodoo 3 */
fxMesa->ColorCombine.Function = GR_COMBINE_FUNCTION_LOCAL;
fxMesa->ColorCombine.Factor = GR_COMBINE_FACTOR_NONE;
fxMesa->ColorCombine.Local = GR_COMBINE_LOCAL_ITERATED;
@@ -1997,106 +1995,103 @@ tdfxUpdateTextureState( GLcontext *ctx )
}
-
-/*
- * This is a special case of texture state update.
+/* This is a special case of texture state update.
* It's used when we've simply bound a new texture to a texture
* unit and the new texture has the exact same attributes as the
* previously bound texture.
* This is very common in Quake3.
*/
-void
-tdfxUpdateTextureBinding( GLcontext *ctx )
+void tdfxUpdateTextureBinding( GLcontext *ctx )
{
tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
+ const struct gl_shared_state *ss = fxMesa->glCtx->Shared;
+ const tdfxSharedStatePtr tss = (tdfxSharedStatePtr)ss->DriverData;
struct gl_texture_object *tObj0 = ctx->Texture.Unit[0].CurrentD[2];
struct gl_texture_object *tObj1 = ctx->Texture.Unit[1].CurrentD[2];
- tdfxTexInfo *ti0 = TDFX_TEXTURE_DATA(tObj0);
- tdfxTexInfo *ti1 = TDFX_TEXTURE_DATA(tObj1);
-
- const struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared;
- const struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData;
+ tdfxTexObjPtr t0 = TDFX_TEXTURE_DATA(tObj0);
+ tdfxTexObjPtr t1 = TDFX_TEXTURE_DATA(tObj1);
- if (ti0) {
- fxMesa->sScale0 = ti0->sScale;
- fxMesa->tScale0 = ti0->tScale;
- if (ti0->info.format == GR_TEXFMT_P_8) {
+ if ( t0 ) {
+ fxMesa->sScale0 = t0->sScale;
+ fxMesa->tScale0 = t0->tScale;
+ if ( t0->info.format == GR_TEXFMT_P_8 ) {
fxMesa->TexPalette.Type = GR_TEXTABLE_PALETTE_6666_EXT;
- fxMesa->TexPalette.Data = &(ti0->palette);
+ fxMesa->TexPalette.Data = &t0->palette;
fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_PALETTE;
- }
- else if (ti1 && ti1->info.format == GR_TEXFMT_P_8) {
+ } else if ( t1 && t1->info.format == GR_TEXFMT_P_8 ) {
fxMesa->TexPalette.Type = GR_TEXTABLE_PALETTE_6666_EXT;
- fxMesa->TexPalette.Data = &(ti1->palette);
+ fxMesa->TexPalette.Data = &t1->palette;
fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_PALETTE;
}
}
- if (ti1) {
- fxMesa->sScale1 = ti1->sScale;
- fxMesa->tScale1 = ti1->tScale;
+ if ( t1 ) {
+ fxMesa->sScale1 = t1->sScale;
+ fxMesa->tScale1 = t1->tScale;
}
- if (ctx->Texture.ReallyEnabled == TEXTURE0_2D) {
- if (shared->umaTexMemory) {
- fxMesa->TexSource[0].StartAddress = ti0->tm[0]->startAddr;
+ switch ( ctx->Texture.ReallyEnabled ) {
+ case TEXTURE0_2D:
+ if ( tss->umaTexMemory ) {
+ fxMesa->TexSource[0].StartAddress = t0->range[0]->startAddr;
fxMesa->TexSource[0].EvenOdd = GR_MIPMAPLEVELMASK_BOTH;
- fxMesa->TexSource[0].Info = &(ti0->info);
- }
- else {
- if (ti0->LODblend && ti0->whichTMU == TDFX_TMU_SPLIT) {
- fxMesa->TexSource[0].StartAddress = ti0->tm[TDFX_TMU0]->startAddr;
+ fxMesa->TexSource[0].Info = &(t0->info);
+ } else {
+ if ( t0->LODblend && t0->whichTMU == TDFX_TMU_SPLIT ) {
+ fxMesa->TexSource[0].StartAddress = t0->range[TDFX_TMU0]->startAddr;
fxMesa->TexSource[0].EvenOdd = GR_MIPMAPLEVELMASK_ODD;
- fxMesa->TexSource[0].Info = &(ti0->info);
- fxMesa->TexSource[1].StartAddress = ti0->tm[TDFX_TMU1]->startAddr;
+ fxMesa->TexSource[0].Info = &t0->info;
+ fxMesa->TexSource[1].StartAddress = t0->range[TDFX_TMU1]->startAddr;
fxMesa->TexSource[1].EvenOdd = GR_MIPMAPLEVELMASK_EVEN;
- fxMesa->TexSource[1].Info = &(ti0->info);
- }
- else {
- FxU32 tmu;
- if (ti0->whichTMU == TDFX_TMU_BOTH)
- tmu = TDFX_TMU0;
- else
- tmu = ti0->whichTMU;
+ fxMesa->TexSource[1].Info = &t0->info;
+ } else {
+ FxU32 unit;
+ if ( t0->whichTMU == TDFX_TMU_BOTH ) {
+ unit = TDFX_TMU0;
+ } else {
+ unit = t0->whichTMU;
+ }
fxMesa->TexSource[0].Info = NULL;
fxMesa->TexSource[1].Info = NULL;
- if (ti0->tm[tmu]) {
- fxMesa->TexSource[tmu].StartAddress = ti0->tm[tmu]->startAddr;
- fxMesa->TexSource[tmu].EvenOdd = GR_MIPMAPLEVELMASK_BOTH;
- fxMesa->TexSource[tmu].Info = &(ti0->info);
+ if ( t0->range[unit] ) {
+ fxMesa->TexSource[unit].StartAddress = t0->range[unit]->startAddr;
+ fxMesa->TexSource[unit].EvenOdd = GR_MIPMAPLEVELMASK_BOTH;
+ fxMesa->TexSource[unit].Info = &t0->info;
}
}
}
- }
- else if (ctx->Texture.ReallyEnabled == TEXTURE1_2D) {
- if (shared->umaTexMemory) {
- fxMesa->TexSource[0].StartAddress = ti1->tm[0]->startAddr;
+ break;
+
+ case TEXTURE1_2D:
+ if ( tss->umaTexMemory ) {
+ fxMesa->TexSource[0].StartAddress = t1->range[0]->startAddr;
fxMesa->TexSource[0].EvenOdd = GR_MIPMAPLEVELMASK_BOTH;
- fxMesa->TexSource[0].Info = &(ti1->info);
+ fxMesa->TexSource[0].Info = &t1->info;
}
- }
- else if (ctx->Texture.ReallyEnabled == (TEXTURE0_2D | TEXTURE1_2D)) {
- if (shared->umaTexMemory) {
+ break;
+
+ case TEXTURE0_2D | TEXTURE1_2D:
+ if ( tss->umaTexMemory ) {
const FxU32 tmu0 = 0, tmu1 = 1;
- fxMesa->TexSource[tmu0].StartAddress = ti0->tm[0]->startAddr;
+ fxMesa->TexSource[tmu0].StartAddress = t0->range[0]->startAddr;
fxMesa->TexSource[tmu0].EvenOdd = GR_MIPMAPLEVELMASK_BOTH;
- fxMesa->TexSource[tmu0].Info = &(ti0->info);
+ fxMesa->TexSource[tmu0].Info = &t0->info;
- fxMesa->TexSource[tmu1].StartAddress = ti1->tm[0]->startAddr;
+ fxMesa->TexSource[tmu1].StartAddress = t1->range[0]->startAddr;
fxMesa->TexSource[tmu1].EvenOdd = GR_MIPMAPLEVELMASK_BOTH;
- fxMesa->TexSource[tmu1].Info = &(ti1->info);
+ fxMesa->TexSource[tmu1].Info = &t1->info;
}
else {
const FxU32 tmu0 = 0, tmu1 = 1;
- fxMesa->TexSource[tmu0].StartAddress = ti0->tm[tmu0]->startAddr;
+ fxMesa->TexSource[tmu0].StartAddress = t0->range[tmu0]->startAddr;
fxMesa->TexSource[tmu0].EvenOdd = GR_MIPMAPLEVELMASK_BOTH;
- fxMesa->TexSource[tmu0].Info = &(ti0->info);
+ fxMesa->TexSource[tmu0].Info = &t0->info;
- fxMesa->TexSource[tmu1].StartAddress = ti1->tm[tmu1]->startAddr;
+ fxMesa->TexSource[tmu1].StartAddress = t1->range[tmu1]->startAddr;
fxMesa->TexSource[tmu1].EvenOdd = GR_MIPMAPLEVELMASK_BOTH;
- fxMesa->TexSource[tmu1].Info = &(ti1->info);
+ fxMesa->TexSource[tmu1].Info = &t1->info;
}
+ break;
}
-
fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_SOURCE;
}
diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texstate.h b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texstate.h
deleted file mode 100644
index 0c0d4adcb..000000000
--- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texstate.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* -*- mode: c; c-basic-offset: 3 -*-
- *
- * Copyright 2000 VA Linux Systems Inc., Fremont, California.
- *
- * 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 (including the next
- * paragraph) 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
- * VA LINUX SYSTEMS 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.
- */
-/* $XFree86$ */
-
-/*
- * Original rewrite:
- * Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000
- *
- * Authors:
- * Gareth Hughes <gareth@valinux.com>
- * Brian Paul <brianp@valinux.com>
- *
- */
-
-#ifndef __TDFX_TEXSTATE_H__
-#define __TDFX_TEXSTATE_H__
-
-extern void tdfxUpdateTextureState( GLcontext *ctx );
-extern void tdfxUpdateTextureBinding( GLcontext *ctx );
-
-#endif
diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_wrapper.h b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_wrapper.h
index 20e5530c5..0adb85b41 100644
--- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_wrapper.h
+++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_wrapper.h
@@ -552,8 +552,6 @@ extern FxBool FX_grLfbLock(tdfxContextPtr fxMesa,
UNLOCK_HARDWARE(fxMesa); \
} while (0)
-#define FX_grTexDownloadMipMapLevel_NoLock grTexDownloadMipMapLevel
-
#define FX_grTexDownloadMipMapLevelPartial(fxMesa, t, sa, tlod, llod, ar, f, eo, d, s, e); \
do { \
LOCK_HARDWARE(fxMesa); \
diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_xmesa.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_xmesa.c
index 06930691d..ef0c580ae 100644
--- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_xmesa.c
+++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_xmesa.c
@@ -52,19 +52,6 @@
#include "tdfx_texman.h"
-#ifndef TDFX_DEBUG
-int TDFX_DEBUG = (0
-/* | DEBUG_ALWAYS_SYNC */
-/* | DEBUG_VERBOSE_API */
-/* | DEBUG_VERBOSE_MSG */
-/* | DEBUG_VERBOSE_LRU */
-/* | DEBUG_VERBOSE_DRI */
-/* | DEBUG_VERBOSE_IOCTL */
-/* | DEBUG_VERBOSE_2D */
- );
-#endif
-
-
GLboolean
XMesaInitDriver( __DRIscreenPrivate *sPriv )
{
diff --git a/xc/programs/Xserver/GL/mesa/src/Imakefile b/xc/programs/Xserver/GL/mesa/src/Imakefile
index c2ead442c..05f2cfe1f 100644
--- a/xc/programs/Xserver/GL/mesa/src/Imakefile
+++ b/xc/programs/Xserver/GL/mesa/src/Imakefile
@@ -147,6 +147,8 @@ LinkSourceFile(state.c,$(MESASRCDIR)/src)
LinkSourceFile(state.h,$(MESASRCDIR)/src)
LinkSourceFile(stencil.c,$(MESASRCDIR)/src)
LinkSourceFile(stencil.h,$(MESASRCDIR)/src)
+LinkSourceFile(texformat.c, $(MESASRCDIR)/src)
+LinkSourceFile(texformat.h, $(MESASRCDIR)/src)
LinkSourceFile(texgen_tmp.h,$(MESASRCDIR)/src)
LinkSourceFile(teximage.c,$(MESASRCDIR)/src)
LinkSourceFile(teximage.h,$(MESASRCDIR)/src)
@@ -245,6 +247,7 @@ LinkSourceFile(zoom.h,$(MESASRCDIR)/src)
stages.c \
state.c \
stencil.c \
+ texformat.c \
teximage.c \
texobj.c \
texstate.c \
@@ -321,6 +324,7 @@ LinkSourceFile(zoom.h,$(MESASRCDIR)/src)
stages.o \
state.o \
stencil.o \
+ texformat.o \
teximage.o \
texobj.o \
texstate.o \
@@ -384,4 +388,3 @@ InstallDriverSDKLibraryModule(GLcore,$(DRIVERSDKMODULEDIR),extensions)
DependSubdirs($(SUBDIRS))
MakeLintLibSubdirs($(SUBDIRS))
LintSubdirs($(SUBDIRS))
-
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h
index c29db273b..20ad35cbc 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h
@@ -1068,36 +1068,36 @@
#define RADEON_PP_TXFORMAT_0 0x1c58
#define RADEON_PP_TXFORMAT_1 0x1c70
#define RADEON_PP_TXFORMAT_2 0x1c88
-# define RADEON_TXF_8BPP_I (0 << 0)
-# define RADEON_TXF_16BPP_AI88 (1 << 0)
-# define RADEON_TXF_8BPP_RGB332 (2 << 0)
-# define RADEON_TXF_16BPP_ARGB1555 (3 << 0)
-# define RADEON_TXF_16BPP_RGB565 (4 << 0)
-# define RADEON_TXF_16BPP_ARGB4444 (5 << 0)
-# define RADEON_TXF_32BPP_ARGB8888 (6 << 0)
-# define RADEON_TXF_32BPP_RGBA8888 (7 << 0)
-# define RADEON_TXF_8BPP_Y (8 << 0)
-# define RADEON_TXF_FORMAT_MASK (31 << 0)
-# define RADEON_TXF_FORMAT_SHIFT 0
-# define RADEON_TXF_APPLE_YUV_MODE (1 << 5)
-# define RADEON_TXF_ALPHA_IN_MAP (1 << 6)
-# define RADEON_TXF_NON_POWER2 (1 << 7)
-# define RADEON_TXF_WIDTH_MASK (15 << 8)
-# define RADEON_TXF_WIDTH_SHIFT 8
-# define RADEON_TXF_HEIGHT_MASK (15 << 12)
-# define RADEON_TXF_HEIGHT_SHIFT 12
-# define RADEON_TXF_ST_ROUTE_STQ0 (0 << 24)
-# define RADEON_TXF_ST_ROUTE_MASK (3 << 24)
-# define RADEON_TXF_ST_ROUTE_STQ1 (1 << 24)
-# define RADEON_TXF_ST_ROUTE_STQ2 (2 << 24)
-# define RADEON_TXF_ENDIAN_NO_SWAP (0 << 26)
-# define RADEON_TXF_ENDIAN_16BPP_SWAP (1 << 26)
-# define RADEON_TXF_ENDIAN_32BPP_SWAP (2 << 26)
-# define RADEON_TXF_ENDIAN_HALFDW_SWAP (3 << 26)
-# define RADEON_TXF_ALPHA_MASK_ENABLE (1 << 28)
-# define RADEON_TXF_CHROMA_KEY_ENABLE (1 << 29)
-# define RADEON_TXF_CUBIC_MAP_ENABLE (1 << 30)
-# define RADEON_TXF_PERSPECTIVE_ENABLE (1 << 31)
+# define RADEON_TXFORMAT_I8 (0 << 0)
+# define RADEON_TXFORMAT_AI88 (1 << 0)
+# define RADEON_TXFORMAT_RGB332 (2 << 0)
+# define RADEON_TXFORMAT_ARGB1555 (3 << 0)
+# define RADEON_TXFORMAT_RGB565 (4 << 0)
+# define RADEON_TXFORMAT_ARGB4444 (5 << 0)
+# define RADEON_TXFORMAT_ARGB8888 (6 << 0)
+# define RADEON_TXFORMAT_RGBA8888 (7 << 0)
+# define RADEON_TXFORMAT_Y8 (8 << 0)
+# define RADEON_TXFORMAT_FORMAT_MASK (31 << 0)
+# define RADEON_TXFORMAT_FORMAT_SHIFT 0
+# define RADEON_TXFORMAT_APPLE_YUV_MODE (1 << 5)
+# define RADEON_TXFORMAT_ALPHA_IN_MAP (1 << 6)
+# define RADEON_TXFORMAT_NON_POWER2 (1 << 7)
+# define RADEON_TXFORMAT_WIDTH_MASK (15 << 8)
+# define RADEON_TXFORMAT_WIDTH_SHIFT 8
+# define RADEON_TXFORMAT_HEIGHT_MASK (15 << 12)
+# define RADEON_TXFORMAT_HEIGHT_SHIFT 12
+# define RADEON_TXFORMAT_ST_ROUTE_STQ0 (0 << 24)
+# define RADEON_TXFORMAT_ST_ROUTE_MASK (3 << 24)
+# define RADEON_TXFORMAT_ST_ROUTE_STQ1 (1 << 24)
+# define RADEON_TXFORMAT_ST_ROUTE_STQ2 (2 << 24)
+# define RADEON_TXFORMAT_ENDIAN_NO_SWAP (0 << 26)
+# define RADEON_TXFORMAT_ENDIAN_16BPP_SWAP (1 << 26)
+# define RADEON_TXFORMAT_ENDIAN_32BPP_SWAP (2 << 26)
+# define RADEON_TXFORMAT_ENDIAN_HALFDW_SWAP (3 << 26)
+# define RADEON_TXFORMAT_ALPHA_MASK_ENABLE (1 << 28)
+# define RADEON_TXFORMAT_CHROMA_KEY_ENABLE (1 << 29)
+# define RADEON_TXFORMAT_CUBIC_MAP_ENABLE (1 << 30)
+# define RADEON_TXFORMAT_PERSPECTIVE_ENABLE (1 << 31)
#define RADEON_PP_TXOFFSET_0 0x1c5c
#define RADEON_PP_TXOFFSET_1 0x1c74
#define RADEON_PP_TXOFFSET_2 0x1c8c
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_sarea.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_sarea.h
index 14cb002fd..b80f35e52 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_sarea.h
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_sarea.h
@@ -81,7 +81,7 @@
/* Vertex/indirect buffer size
*/
-#define RADEON_BUFFER_SIZE 16384
+#define RADEON_BUFFER_SIZE 65536
/* Byte offsets for indirect buffer data
*/
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h
index 40a85875b..30b75e1e3 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h
@@ -439,7 +439,7 @@ typedef struct drm_agp_info {
#define DRM_IOCTL_RADEON_CLEAR DRM_IOW( 0x48, drm_radeon_clear_t)
#define DRM_IOCTL_RADEON_VERTEX DRM_IOW( 0x49, drm_radeon_vertex_t)
#define DRM_IOCTL_RADEON_INDICES DRM_IOW( 0x4a, drm_radeon_indices_t)
-#define DRM_IOCTL_RADEON_BLIT DRM_IOW( 0x4b, drm_radeon_blit_t)
+#define DRM_IOCTL_RADEON_TEXTURE DRM_IOWR(0x4b, drm_radeon_texture_t)
#define DRM_IOCTL_RADEON_STIPPLE DRM_IOW( 0x4c, drm_radeon_stipple_t)
#define DRM_IOCTL_RADEON_INDIRECT DRM_IOWR(0x4d, drm_radeon_indirect_t)
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_cp.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_cp.c
index 2f20806c9..3feb4b240 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_cp.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_cp.c
@@ -843,11 +843,8 @@ int radeon_cp_start( struct inode *inode, struct file *filp,
drm_radeon_private_t *dev_priv = dev->dev_private;
DRM_DEBUG( "%s\n", __FUNCTION__ );
- if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
- dev->lock.pid != current->pid ) {
- DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
- return -EINVAL;
- }
+ LOCK_TEST_WITH_RETURN( dev );
+
if ( dev_priv->cp_running ) {
DRM_DEBUG( "%s while CP running\n", __FUNCTION__ );
return 0;
@@ -876,11 +873,7 @@ int radeon_cp_stop( struct inode *inode, struct file *filp,
int ret;
DRM_DEBUG( "%s\n", __FUNCTION__ );
- if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
- dev->lock.pid != current->pid ) {
- DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
- return -EINVAL;
- }
+ LOCK_TEST_WITH_RETURN( dev );
if ( copy_from_user( &stop, (drm_radeon_init_t *)arg, sizeof(stop) ) )
return -EFAULT;
@@ -922,11 +915,8 @@ int radeon_cp_reset( struct inode *inode, struct file *filp,
drm_radeon_private_t *dev_priv = dev->dev_private;
DRM_DEBUG( "%s\n", __FUNCTION__ );
- if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
- dev->lock.pid != current->pid ) {
- DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
- return -EINVAL;
- }
+ LOCK_TEST_WITH_RETURN( dev );
+
if ( !dev_priv ) {
DRM_DEBUG( "%s called before init done\n", __FUNCTION__ );
return -EINVAL;
@@ -948,11 +938,7 @@ int radeon_cp_idle( struct inode *inode, struct file *filp,
drm_radeon_private_t *dev_priv = dev->dev_private;
DRM_DEBUG( "%s\n", __FUNCTION__ );
- if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
- dev->lock.pid != current->pid ) {
- DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
- return -EINVAL;
- }
+ LOCK_TEST_WITH_RETURN( dev );
return radeon_do_cp_idle( dev_priv );
}
@@ -964,11 +950,7 @@ int radeon_engine_reset( struct inode *inode, struct file *filp,
drm_device_t *dev = priv->dev;
DRM_DEBUG( "%s\n", __FUNCTION__ );
- if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
- dev->lock.pid != current->pid ) {
- DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
- return -EINVAL;
- }
+ LOCK_TEST_WITH_RETURN( dev );
return radeon_do_engine_reset( dev );
}
@@ -1018,11 +1000,7 @@ int radeon_fullscreen( struct inode *inode, struct file *filp,
drm_device_t *dev = priv->dev;
drm_radeon_fullscreen_t fs;
- if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
- dev->lock.pid != current->pid ) {
- DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
- return -EINVAL;
- }
+ LOCK_TEST_WITH_RETURN( dev );
if ( copy_from_user( &fs, (drm_radeon_fullscreen_t *)arg,
sizeof(fs) ) )
@@ -1246,14 +1224,10 @@ int radeon_cp_buffers( struct inode *inode, struct file *filp,
int ret = 0;
drm_dma_t d;
- if ( copy_from_user( &d, (drm_dma_t *) arg, sizeof(d) ) )
- return -EFAULT;
+ LOCK_TEST_WITH_RETURN( dev );
- if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
- dev->lock.pid != current->pid ) {
- DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
- return -EINVAL;
- }
+ if ( copy_from_user( &d, (drm_dma_t *)arg, sizeof(d) ) )
+ return -EFAULT;
/* Please don't send us buffers.
*/
@@ -1277,7 +1251,7 @@ int radeon_cp_buffers( struct inode *inode, struct file *filp,
ret = radeon_cp_get_buffers( dev, &d );
}
- if ( copy_to_user( (drm_dma_t *) arg, &d, sizeof(d) ) )
+ if ( copy_to_user( (drm_dma_t *)arg, &d, sizeof(d) ) )
return -EFAULT;
return ret;
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drm.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drm.h
index a7d7a71bb..50a7d6ed8 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drm.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drm.h
@@ -73,7 +73,7 @@
/* Vertex/indirect buffer size
*/
-#define RADEON_BUFFER_SIZE 16384
+#define RADEON_BUFFER_SIZE 65536
/* Byte offsets for indirect buffer data
*/
@@ -304,14 +304,20 @@ typedef struct drm_radeon_indices {
int discard; /* Client finished with buffer? */
} drm_radeon_indices_t;
-typedef struct drm_radeon_blit {
- int idx;
- int pitch;
+typedef struct drm_radeon_tex_image {
+ unsigned int x, y; /* Blit coordinates */
+ unsigned int width, height;
+ const void *data;
+} drm_radeon_tex_image_t;
+
+typedef struct drm_radeon_texture {
int offset;
+ int pitch;
int format;
- unsigned short x, y;
- unsigned short width, height;
-} drm_radeon_blit_t;
+ int width; /* Texture image coordinates */
+ int height;
+ drm_radeon_tex_image_t *image;
+} drm_radeon_texture_t;
typedef struct drm_radeon_stipple {
unsigned int *mask;
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.c
index cf59f866a..1aa889aee 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.c
@@ -36,7 +36,7 @@
#define DRIVER_NAME "radeon"
#define DRIVER_DESC "ATI Radeon"
-#define DRIVER_DATE "20010216"
+#define DRIVER_DATE "20010305"
#define DRIVER_MAJOR 1
#define DRIVER_MINOR 0
@@ -55,7 +55,7 @@
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_CLEAR)] = { radeon_cp_clear, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_VERTEX)] = { radeon_cp_vertex, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDICES)] = { radeon_cp_indices, 1, 0 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_BLIT)] = { radeon_cp_blit, 1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_TEXTURE)] = { radeon_cp_texture, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_STIPPLE)] = { radeon_cp_stipple, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDIRECT)] = { radeon_cp_indirect, 1, 1 },
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.h
index e67a610fb..d279b0467 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.h
@@ -161,8 +161,8 @@ extern int radeon_cp_vertex( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int radeon_cp_indices( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
-extern int radeon_cp_blit( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg );
+extern int radeon_cp_texture( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg );
extern int radeon_cp_stipple( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int radeon_cp_indirect( struct inode *inode, struct file *filp,
@@ -478,14 +478,14 @@ extern int radeon_cp_indirect( struct inode *inode, struct file *filp,
#define RADEON_COLOR_FORMAT_RGB8 9
#define RADEON_COLOR_FORMAT_ARGB4444 15
-#define RADEON_TXF_8BPP_I 0
-#define RADEON_TXF_16BPP_AI88 1
-#define RADEON_TXF_8BPP_RGB332 2
-#define RADEON_TXF_16BPP_ARGB1555 3
-#define RADEON_TXF_16BPP_RGB565 4
-#define RADEON_TXF_16BPP_ARGB4444 5
-#define RADEON_TXF_32BPP_ARGB8888 6
-#define RADEON_TXF_32BPP_RGBA8888 7
+#define RADEON_TXFORMAT_I8 0
+#define RADEON_TXFORMAT_AI88 1
+#define RADEON_TXFORMAT_RGB332 2
+#define RADEON_TXFORMAT_ARGB1555 3
+#define RADEON_TXFORMAT_RGB565 4
+#define RADEON_TXFORMAT_ARGB4444 5
+#define RADEON_TXFORMAT_ARGB8888 6
+#define RADEON_TXFORMAT_RGBA8888 7
/* Constants */
#define RADEON_MAX_USEC_TIMEOUT 100000 /* 100 ms */
@@ -586,6 +586,16 @@ extern int RADEON_READ_PLL( drm_device_t *dev, int addr );
* Misc helper macros
*/
+#define LOCK_TEST_WITH_RETURN( dev ) \
+do { \
+ if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || \
+ dev->lock.pid != current->pid ) { \
+ DRM_ERROR( "%s called without lock held\n", \
+ __FUNCTION__ ); \
+ return -EINVAL; \
+ } \
+} while (0)
+
#define RING_SPACE_TEST_WITH_RETURN( dev_priv ) \
do { \
drm_radeon_ring_buffer_t *ring = &dev_priv->ring; int i; \
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_state.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_state.c
index 9b84a7397..ff1b3512f 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_state.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_state.c
@@ -972,50 +972,67 @@ static void radeon_cp_dispatch_indices( drm_device_t *dev,
sarea_priv->nbox = 0;
}
-static int radeon_cp_dispatch_blit( drm_device_t *dev,
- drm_radeon_blit_t *blit )
+#define RADEON_MAX_TEXTURE_SIZE (RADEON_BUFFER_SIZE - 8 * sizeof(u32))
+
+static int radeon_cp_dispatch_texture( drm_device_t *dev,
+ drm_radeon_texture_t *tex,
+ drm_radeon_tex_image_t *image )
{
drm_radeon_private_t *dev_priv = dev->dev_private;
- drm_device_dma_t *dma = dev->dma;
drm_buf_t *buf;
drm_radeon_buf_priv_t *buf_priv;
u32 format;
- u32 *data;
- int dword_shift, dwords;
+ u32 *buffer;
+ u8 *data;
+ int size, dwords, tex_width, blit_width;
+ u32 y, height;
+ int ret = 0, i;
RING_LOCALS;
- DRM_DEBUG( "blit: ofs=0x%x p=%d f=%d x=%hd y=%hd w=%hd h=%hd\n",
- blit->offset >> 10, blit->pitch, blit->format,
- blit->x, blit->y, blit->width, blit->height );
- radeon_update_ring_snapshot( dev_priv );
+ /* FIXME: Be smarter about this...
+ */
+ buf = radeon_freelist_get( dev );
+ if ( !buf ) return -EAGAIN;
+
+ DRM_DEBUG( "tex: ofs=0x%x p=%d f=%d x=%hd y=%hd w=%hd h=%hd\n",
+ tex->offset >> 10, tex->pitch, tex->format,
+ image->x, image->y, image->width, image->height );
+
+ buf_priv = buf->dev_private;
/* The compiler won't optimize away a division by a variable,
* even if the only legal values are powers of two. Thus, we'll
* use a shift instead.
*/
- switch ( blit->format ) {
- case RADEON_TXF_32BPP_ARGB8888:
- case RADEON_TXF_32BPP_RGBA8888:
+ switch ( tex->format ) {
+ case RADEON_TXFORMAT_ARGB8888:
+ case RADEON_TXFORMAT_RGBA8888:
format = RADEON_COLOR_FORMAT_ARGB8888;
- dword_shift = 0;
+ tex_width = tex->width * 4;
+ blit_width = image->width * 4;
break;
- case RADEON_TXF_16BPP_AI88:
- case RADEON_TXF_16BPP_ARGB1555:
- case RADEON_TXF_16BPP_RGB565:
- case RADEON_TXF_16BPP_ARGB4444:
+ case RADEON_TXFORMAT_AI88:
+ case RADEON_TXFORMAT_ARGB1555:
+ case RADEON_TXFORMAT_RGB565:
+ case RADEON_TXFORMAT_ARGB4444:
format = RADEON_COLOR_FORMAT_RGB565;
- dword_shift = 1;
+ tex_width = tex->width * 2;
+ blit_width = image->width * 2;
break;
- case RADEON_TXF_8BPP_I:
- case RADEON_TXF_8BPP_RGB332:
+ case RADEON_TXFORMAT_I8:
+ case RADEON_TXFORMAT_RGB332:
format = RADEON_COLOR_FORMAT_CI8;
- dword_shift = 2;
+ tex_width = tex->width * 1;
+ blit_width = image->width * 1;
break;
default:
- DRM_ERROR( "invalid blit format %d\n", blit->format );
+ DRM_ERROR( "invalid texture format %d\n", tex->format );
return -EINVAL;
}
+ DRM_DEBUG( " tex=%dx%d blit=%d\n",
+ tex_width, tex->height, blit_width );
+
/* Flush the pixel cache. This ensures no pixel data gets mixed
* up with the texture data from the host data blit, otherwise
* part of the texture image may be corrupted.
@@ -1027,46 +1044,81 @@ static int radeon_cp_dispatch_blit( drm_device_t *dev,
ADVANCE_RING();
- /* Dispatch the indirect buffer.
+ /* Make a copy of the parameters in case we have to update them
+ * for a multi-pass texture blit.
*/
- buf = dma->buflist[blit->idx];
- buf_priv = buf->dev_private;
+ y = image->y;
+ height = image->height;
+ data = (u8 *)image->data;
- if ( buf->pid != current->pid ) {
- DRM_ERROR( "process %d using buffer owned by %d\n",
- current->pid, buf->pid );
- return -EINVAL;
- }
- if ( buf->pending ) {
- DRM_ERROR( "sending pending buffer %d\n", blit->idx );
- return -EINVAL;
- }
+ size = height * blit_width;
- buf_priv->discard = 1;
+ if ( size > RADEON_MAX_TEXTURE_SIZE ) {
+ /* Texture image is too large, do a multipass upload */
+ ret = -EAGAIN;
- dwords = (blit->width * blit->height) >> dword_shift;
- if ( !dwords ) dwords = 1;
+ /* Adjust the blit size to fit the indirect buffer */
+ height = RADEON_MAX_TEXTURE_SIZE / blit_width;
+ size = height * blit_width;
- data = (u32 *)((char *)dev_priv->buffers->handle + buf->offset);
+ /* Update the input parameters for next time */
+ image->y += height;
+ image->height -= height;
+ image->data = (char *)image->data + size;
- data[0] = CP_PACKET3( RADEON_CNTL_HOSTDATA_BLT, dwords + 6 );
- data[1] = (RADEON_GMC_DST_PITCH_OFFSET_CNTL |
- RADEON_GMC_BRUSH_NONE |
- (format << 8) |
- RADEON_GMC_SRC_DATATYPE_COLOR |
- RADEON_ROP3_S |
- RADEON_DP_SRC_SOURCE_HOST_DATA |
- RADEON_GMC_CLR_CMP_CNTL_DIS |
- RADEON_GMC_WR_MSK_DIS);
+ if ( copy_to_user( tex->image, image, sizeof(*image) ) )
+ return -EFAULT;
+ } else if ( size < 4 ) {
+ size = 4;
+ }
- data[2] = (blit->pitch << 22) | (blit->offset >> 10);
- data[3] = 0xffffffff;
- data[4] = 0xffffffff;
- data[5] = (blit->y << 16) | blit->x;
- data[6] = (blit->height << 16) | blit->width;
- data[7] = dwords;
+ dwords = size / 4;
+
+ /* Dispatch the indirect buffer.
+ */
+ buffer = (u32 *)((char *)dev_priv->buffers->handle + buf->offset);
+
+ buffer[0] = CP_PACKET3( RADEON_CNTL_HOSTDATA_BLT, dwords + 6 );
+ buffer[1] = (RADEON_GMC_DST_PITCH_OFFSET_CNTL |
+ RADEON_GMC_BRUSH_NONE |
+ (format << 8) |
+ RADEON_GMC_SRC_DATATYPE_COLOR |
+ RADEON_ROP3_S |
+ RADEON_DP_SRC_SOURCE_HOST_DATA |
+ RADEON_GMC_CLR_CMP_CNTL_DIS |
+ RADEON_GMC_WR_MSK_DIS);
+
+ buffer[2] = (tex->pitch << 22) | (tex->offset >> 10);
+ buffer[3] = 0xffffffff;
+ buffer[4] = 0xffffffff;
+ buffer[5] = (y << 16) | image->x;
+ buffer[6] = (height << 16) | image->width;
+ buffer[7] = dwords;
+
+ buffer += 8;
+
+ if ( tex_width >= 32 ) {
+ /* Texture image width is larger than the minimum, so we
+ * can upload it directly.
+ */
+ if ( copy_from_user( buffer, data, dwords * sizeof(u32) ) )
+ return -EFAULT;
+ } else {
+ /* Texture image width is less than the minimum, so we
+ * need to pad out each image scanline to the minimum
+ * width.
+ */
+ for ( i = 0 ; i < tex->height ; i++ ) {
+ if ( copy_from_user( buffer, data, tex_width ) )
+ return -EFAULT;
+ buffer += 8;
+ data += tex_width;
+ }
+ }
+ buf->pid = current->pid;
buf->used = (dwords + 8) * sizeof(u32);
+ buf_priv->discard = 1;
radeon_cp_dispatch_indirect( dev, buf, 0, buf->used );
@@ -1081,7 +1133,7 @@ static int radeon_cp_dispatch_blit( drm_device_t *dev,
ADVANCE_RING();
- return 0;
+ return ret;
}
static void radeon_cp_dispatch_stipple( drm_device_t *dev, u32 *stipple )
@@ -1122,11 +1174,7 @@ int radeon_cp_clear( struct inode *inode, struct file *filp,
drm_radeon_clear_rect_t depth_boxes[RADEON_NR_SAREA_CLIPRECTS];
DRM_DEBUG( "%s\n", __FUNCTION__ );
- if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
- dev->lock.pid != current->pid ) {
- DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
- return -EINVAL;
- }
+ LOCK_TEST_WITH_RETURN( dev );
if ( copy_from_user( &clear, (drm_radeon_clear_t *)arg,
sizeof(clear) ) )
@@ -1156,11 +1204,7 @@ int radeon_cp_swap( struct inode *inode, struct file *filp,
drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
DRM_DEBUG( "%s\n", __FUNCTION__ );
- if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
- dev->lock.pid != current->pid ) {
- DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
- return -EINVAL;
- }
+ LOCK_TEST_WITH_RETURN( dev );
RING_SPACE_TEST_WITH_RETURN( dev_priv );
@@ -1189,11 +1233,8 @@ int radeon_cp_vertex( struct inode *inode, struct file *filp,
drm_radeon_buf_priv_t *buf_priv;
drm_radeon_vertex_t vertex;
- if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
- dev->lock.pid != current->pid ) {
- DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
- return -EINVAL;
- }
+ LOCK_TEST_WITH_RETURN( dev );
+
if ( !dev_priv || dev_priv->is_pci ) {
DRM_ERROR( "%s called with a PCI card\n", __FUNCTION__ );
return -EINVAL;
@@ -1255,11 +1296,8 @@ int radeon_cp_indices( struct inode *inode, struct file *filp,
drm_radeon_indices_t elts;
int count;
- if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
- dev->lock.pid != current->pid ) {
- DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
- return -EINVAL;
- }
+ LOCK_TEST_WITH_RETURN( dev );
+
if ( !dev_priv || dev_priv->is_pci ) {
DRM_ERROR( "%s called with a PCI card\n", __FUNCTION__ );
return -EINVAL;
@@ -1321,38 +1359,34 @@ int radeon_cp_indices( struct inode *inode, struct file *filp,
return 0;
}
-int radeon_cp_blit( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg )
+int radeon_cp_texture( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg )
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_radeon_private_t *dev_priv = dev->dev_private;
- drm_device_dma_t *dma = dev->dma;
- drm_radeon_blit_t blit;
+ drm_radeon_texture_t tex;
+ drm_radeon_tex_image_t image;
- if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
- dev->lock.pid != current->pid ) {
- DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
- return -EINVAL;
- }
+ LOCK_TEST_WITH_RETURN( dev );
- if ( copy_from_user( &blit, (drm_radeon_blit_t *)arg,
- sizeof(blit) ) )
+ if ( copy_from_user( &tex, (drm_radeon_texture_t *)arg, sizeof(tex) ) )
return -EFAULT;
- DRM_DEBUG( "%s: pid=%d index=%d\n",
- __FUNCTION__, current->pid, blit.idx );
-
- if ( blit.idx < 0 || blit.idx > dma->buf_count ) {
- DRM_ERROR( "sending %d buffers (of %d max)\n",
- blit.idx, dma->buf_count );
+ if ( tex.image == NULL ) {
+ DRM_ERROR( "null texture image!\n" );
return -EINVAL;
}
+ if ( copy_from_user( &image,
+ (drm_radeon_tex_image_t *)tex.image,
+ sizeof(image) ) )
+ return -EFAULT;
+
RING_SPACE_TEST_WITH_RETURN( dev_priv );
VB_AGE_TEST_WITH_RETURN( dev_priv );
- return radeon_cp_dispatch_blit( dev, &blit );
+ return radeon_cp_dispatch_texture( dev, &tex, &image );
}
int radeon_cp_stipple( struct inode *inode, struct file *filp,
@@ -1364,18 +1398,13 @@ int radeon_cp_stipple( struct inode *inode, struct file *filp,
drm_radeon_stipple_t stipple;
u32 mask[32];
- if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
- dev->lock.pid != current->pid ) {
- DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
- return -EINVAL;
- }
+ LOCK_TEST_WITH_RETURN( dev );
if ( copy_from_user( &stipple, (drm_radeon_stipple_t *)arg,
sizeof(stipple) ) )
return -EFAULT;
- if ( copy_from_user( &mask, stipple.mask,
- 32 * sizeof(u32) ) )
+ if ( copy_from_user( &mask, stipple.mask, 32 * sizeof(u32) ) )
return -EFAULT;
RING_SPACE_TEST_WITH_RETURN( dev_priv );
@@ -1397,11 +1426,8 @@ int radeon_cp_indirect( struct inode *inode, struct file *filp,
drm_radeon_indirect_t indirect;
RING_LOCALS;
- if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
- dev->lock.pid != current->pid ) {
- DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
- return -EINVAL;
- }
+ LOCK_TEST_WITH_RETURN( dev );
+
if ( !dev_priv || dev_priv->is_pci ) {
DRM_ERROR( "%s called with a PCI card\n", __FUNCTION__ );
return -EINVAL;
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmRadeon.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmRadeon.c
index 62caddadc..944a030ff 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmRadeon.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmRadeon.c
@@ -311,25 +311,32 @@ int drmRadeonFlushIndices( int fd, int prim, int index,
}
}
-int drmRadeonTextureBlit( int fd, int index,
- int offset, int pitch, int format,
- int x, int y, int width, int height )
+int drmRadeonLoadTexture( int fd, int offset, int pitch, int format,
+ int width, int height, drmRadeonTexImage *image )
{
- drm_radeon_blit_t blit;
-
- blit.idx = index;
- blit.offset = offset;
- blit.pitch = pitch;
- blit.format = format;
- blit.x = x;
- blit.y = y;
- blit.width = width;
- blit.height = height;
-
- if ( ioctl( fd, DRM_IOCTL_RADEON_BLIT, &blit ) < 0 ) {
- return -errno;
- } else {
+ drm_radeon_texture_t tex;
+ drm_radeon_tex_image_t tmp;
+ int ret;
+
+ tex.offset = offset;
+ tex.pitch = pitch;
+ tex.format = format;
+ tex.width = width;
+ tex.height = height;
+ tex.image = &tmp;
+
+ /* This gets updated by the kernel when a multipass blit is needed.
+ */
+ memcpy( &tmp, image, sizeof(drm_radeon_tex_image_t) );
+
+ do {
+ ret = ioctl( fd, DRM_IOCTL_RADEON_TEXTURE, &tex );
+ } while ( ret && errno == EAGAIN );
+
+ if ( ret == 0 ) {
return 0;
+ } else {
+ return -errno;
}
}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/drm.h b/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/drm.h
index 40a85875b..30b75e1e3 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/drm.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/drm.h
@@ -439,7 +439,7 @@ typedef struct drm_agp_info {
#define DRM_IOCTL_RADEON_CLEAR DRM_IOW( 0x48, drm_radeon_clear_t)
#define DRM_IOCTL_RADEON_VERTEX DRM_IOW( 0x49, drm_radeon_vertex_t)
#define DRM_IOCTL_RADEON_INDICES DRM_IOW( 0x4a, drm_radeon_indices_t)
-#define DRM_IOCTL_RADEON_BLIT DRM_IOW( 0x4b, drm_radeon_blit_t)
+#define DRM_IOCTL_RADEON_TEXTURE DRM_IOWR(0x4b, drm_radeon_texture_t)
#define DRM_IOCTL_RADEON_STIPPLE DRM_IOW( 0x4c, drm_radeon_stipple_t)
#define DRM_IOCTL_RADEON_INDIRECT DRM_IOWR(0x4d, drm_radeon_indirect_t)
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/xf86drmRadeon.h b/xc/programs/Xserver/hw/xfree86/os-support/xf86drmRadeon.h
index 87f70590d..e3bf83fdd 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/xf86drmRadeon.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/xf86drmRadeon.h
@@ -43,27 +43,35 @@
#define DRM_RADEON_DEPTH 0x4
typedef struct {
- int sarea_priv_offset;
- int is_pci;
- int cp_mode;
- int agp_size;
- int ring_size;
- int usec_timeout;
-
- unsigned int fb_bpp;
- unsigned int front_offset, front_pitch;
- unsigned int back_offset, back_pitch;
- unsigned int depth_bpp;
- unsigned int depth_offset, depth_pitch;
-
- unsigned int fb_offset;
- unsigned int mmio_offset;
- unsigned int ring_offset;
- unsigned int ring_rptr_offset;
- unsigned int buffers_offset;
- unsigned int agp_textures_offset;
+ int sarea_priv_offset;
+ int is_pci;
+ int cp_mode;
+ int agp_size;
+ int ring_size;
+ int usec_timeout;
+
+ unsigned int fb_bpp;
+ unsigned int front_offset, front_pitch;
+ unsigned int back_offset, back_pitch;
+ unsigned int depth_bpp;
+ unsigned int depth_offset, depth_pitch;
+
+ unsigned int fb_offset;
+ unsigned int mmio_offset;
+ unsigned int ring_offset;
+ unsigned int ring_rptr_offset;
+ unsigned int buffers_offset;
+ unsigned int agp_textures_offset;
} drmRadeonInit;
+typedef struct {
+ unsigned int x;
+ unsigned int y;
+ unsigned int width;
+ unsigned int height;
+ void *data;
+} drmRadeonTexImage;
+
extern int drmRadeonInitCP( int fd, drmRadeonInit *info );
extern int drmRadeonCleanupCP( int fd );
@@ -87,9 +95,9 @@ extern int drmRadeonFlushVertexBuffer( int fd, int prim, int index,
extern int drmRadeonFlushIndices( int fd, int prim, int index,
int start, int end, int discard );
-extern int drmRadeonTextureBlit( int fd, int index,
- int offset, int pitch, int format,
- int x, int y, int width, int height );
+extern int drmRadeonLoadTexture( int fd, int offset, int pitch, int format,
+ int width, int height,
+ drmRadeonTexImage *image );
extern int drmRadeonPolygonStipple( int fd, unsigned int *mask );