diff options
author | kem <kem> | 2001-03-07 21:47:11 +0000 |
---|---|---|
committer | kem <kem> | 2001-03-07 21:47:11 +0000 |
commit | bbfdc489c17ab69c7071acd8f94ce0c9b2a15abb (patch) | |
tree | 052a9299a68f44afdc002196de62837b617d0ee4 | |
parent | 38baaad074b69a17801ab41e8edb1c033f270650 (diff) |
- Merge from trunk into branchsarea-1-0-0-20010307
121 files changed, 9005 insertions, 8920 deletions
diff --git a/xc/config/cf/host.def b/xc/config/cf/host.def index 99628a34a..bdf4e48e4 100644 --- a/xc/config/cf/host.def +++ b/xc/config/cf/host.def @@ -7,7 +7,7 @@ #define LibraryCDebugFlags -O2 #endif #define BuildServersOnly YES -#define XF86CardDrivers vga i810 mga ati glint +#define XF86CardDrivers vga tdfx i810 mga ati glint #define LinuxDistribution LinuxRedHat #define GccWarningOptions -Wall -Wpointer-arith -Wstrict-prototypes \ -Wmissing-prototypes -Wmissing-declarations \ @@ -16,7 +16,7 @@ #define NormalLibGlx NO #define BuildXF86DRI YES -#define HasGlide3 NO +#define HasGlide3 YES #ifdef i386Architecture #define MesaUse3DNow YES @@ -45,11 +45,11 @@ /* #define DoLoadableServer NO */ /* Optionally turn this on to change the place where you install the build */ -#define ProjectRoot /mnt/src/work/binary/ +/* #define ProjectRoot /usr/X11R6-DRI */ /* Optionally turn this on to force the kernel modules to build */ +/* #define BuildXF86DRM YES */ -#define BuildXF86DRM NO #define XnestServer NO #define XVirtualFramebufferServer NO #define XprtServer NO 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/stencil.c b/xc/extras/Mesa/src/stencil.c index 74e03af38..77755c313 100644 --- a/xc/extras/Mesa/src/stencil.c +++ b/xc/extras/Mesa/src/stencil.c @@ -1,9 +1,9 @@ /* * Mesa 3-D graphics library - * Version: 3.4 + * Version: 3.4.2 * - * Copyright (C) 1999-2000 Brian Paul All Rights Reserved. + * 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"), @@ -1038,47 +1038,45 @@ _mesa_stencil_and_ztest_pixels( GLcontext *ctx, if (ctx->Driver.WriteStencilPixels) { /*** Hardware stencil buffer ***/ GLstencil stencil[PB_SIZE]; - GLubyte mask[PB_SIZE]; + GLubyte origMask[PB_SIZE]; ASSERT(ctx->Driver.ReadStencilPixels); (*ctx->Driver.ReadStencilPixels)(ctx, n, x, y, stencil); + MEMCPY(origMask, mask, n * sizeof(GLubyte)); - if (do_stencil_test( ctx, n, stencil, mask ) == GL_FALSE) { - /* all fragments failed the stencil test, we're done. */ - return GL_FALSE; - } + (void) do_stencil_test( ctx, n, stencil, mask ); if (ctx->Depth.Test == GL_FALSE) { apply_stencil_op( ctx, ctx->Stencil.ZPassFunc, n, stencil, mask ); } else { - GLubyte passmask[PB_SIZE], failmask[PB_SIZE], oldmask[PB_SIZE]; - GLuint i; - - MEMCPY(oldmask, mask, n * sizeof(GLubyte)); - _mesa_depth_test_pixels(ctx, n, x, y, z, mask); - for (i=0;i<n;i++) { - ASSERT(mask[i] == 0 || mask[i] == 1); - passmask[i] = oldmask[i] & mask[i]; - failmask[i] = oldmask[i] & (mask[i] ^ 1); - } - if (ctx->Stencil.ZFailFunc != GL_KEEP) { - apply_stencil_op( ctx, ctx->Stencil.ZFailFunc, n, stencil, failmask ); + GLubyte failmask[PB_SIZE]; + GLuint i; + for (i = 0; i < n; i++) { + ASSERT(mask[i] == 0 || mask[i] == 1); + failmask[i] = origMask[i] & (mask[i] ^ 1); + } + apply_stencil_op(ctx, ctx->Stencil.ZFailFunc, n, stencil, failmask); } if (ctx->Stencil.ZPassFunc != GL_KEEP) { - apply_stencil_op( ctx, ctx->Stencil.ZPassFunc, n, stencil, passmask ); + GLubyte passmask[PB_SIZE]; + GLuint i; + for (i = 0; i < n; i++) { + ASSERT(mask[i] == 0 || mask[i] == 1); + passmask[i] = origMask[i] & mask[i]; + } + apply_stencil_op(ctx, ctx->Stencil.ZPassFunc, n, stencil, passmask); } } /* Write updated stencil values into hardware stencil buffer */ - (ctx->Driver.WriteStencilPixels)(ctx, n, x, y, stencil, mask ); + (ctx->Driver.WriteStencilPixels)(ctx, n, x, y, stencil, origMask ); return GL_TRUE; - } else { /*** Software stencil buffer ***/ @@ -1088,7 +1086,6 @@ _mesa_stencil_and_ztest_pixels( GLcontext *ctx, return GL_FALSE; } - if (ctx->Depth.Test==GL_FALSE) { apply_stencil_op_to_pixels( ctx, n, x, y, ctx->Stencil.ZPassFunc, mask ); } 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..e1d676dbb 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; } @@ -1994,11 +1878,10 @@ void _mesa_GetTexImage( GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels ) { - GET_CURRENT_CONTEXT(ctx); const struct gl_texture_object *texObj; struct gl_texture_image *texImage; GLboolean discardImage; - + GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetTexImage"); if (level < 0 || level >= ctx->Const.MaxTextureLevels) { @@ -2174,11 +2057,12 @@ _mesa_TexSubImage1D( GLenum target, GLint level, GLenum format, GLenum type, const GLvoid *pixels ) { - GET_CURRENT_CONTEXT(ctx); struct gl_texture_unit *texUnit; struct gl_texture_object *texObj; struct gl_texture_image *texImage; GLboolean success = GL_FALSE; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glTexSubImage1D"); if (subtexture_error_check(ctx, 1, target, level, xoffset, 0, 0, width, 1, 1, format, type)) { @@ -2257,11 +2141,12 @@ _mesa_TexSubImage2D( GLenum target, GLint level, GLenum format, GLenum type, const GLvoid *pixels ) { - GET_CURRENT_CONTEXT(ctx); struct gl_texture_unit *texUnit; struct gl_texture_object *texObj; struct gl_texture_image *texImage; GLboolean success = GL_FALSE; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glTexSubImage2D"); if (subtexture_error_check(ctx, 2, target, level, xoffset, yoffset, 0, width, height, 1, format, type)) { @@ -2370,11 +2255,12 @@ _mesa_TexSubImage3D( GLenum target, GLint level, GLenum format, GLenum type, const GLvoid *pixels ) { - GET_CURRENT_CONTEXT(ctx); struct gl_texture_unit *texUnit; struct gl_texture_object *texObj; struct gl_texture_image *texImage; GLboolean success = GL_FALSE; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glTexSubImage3D"); if (subtexture_error_check(ctx, 3, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type)) { @@ -2521,7 +2407,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 +2502,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 +2554,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 +2599,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); } } @@ -3116,11 +3002,12 @@ _mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data) { - GET_CURRENT_CONTEXT(ctx); struct gl_texture_unit *texUnit; struct gl_texture_object *texObj; struct gl_texture_image *texImage; GLboolean success = GL_FALSE; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glCompressedTexSubImage1DARB"); if (subtexture_error_check(ctx, 1, target, level, xoffset, 0, 0, width, 1, 1, format, GL_NONE)) { @@ -3153,11 +3040,12 @@ _mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset, GLenum format, GLsizei imageSize, const GLvoid *data) { - GET_CURRENT_CONTEXT(ctx); struct gl_texture_unit *texUnit; struct gl_texture_object *texObj; struct gl_texture_image *texImage; GLboolean success = GL_FALSE; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glCompressedTexSubImage2DARB"); if (subtexture_error_check(ctx, 2, target, level, xoffset, yoffset, 0, width, height, 1, format, GL_NONE)) { @@ -3191,11 +3079,12 @@ _mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data) { - GET_CURRENT_CONTEXT(ctx); struct gl_texture_unit *texUnit; struct gl_texture_object *texObj; struct gl_texture_image *texImage; GLboolean success = GL_FALSE; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glCompressedTexSubImage3DARB"); if (subtexture_error_check(ctx, 3, target, level, xoffset, yoffset, zoffset, width, height, depth, format, GL_NONE)) { @@ -3226,10 +3115,9 @@ _mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset, void _mesa_GetCompressedTexImageARB(GLenum target, GLint level, GLvoid *img) { - GET_CURRENT_CONTEXT(ctx); const struct gl_texture_object *texObj; struct gl_texture_image *texImage; - + GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetCompressedTexImageARB"); if (level < 0 || level >= ctx->Const.MaxTextureLevels) { 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/i810_3d_reg.h b/xc/lib/GL/mesa/src/drv/i810/i810_3d_reg.h index a7200f1b8..cad45626d 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810_3d_reg.h +++ b/xc/lib/GL/mesa/src/drv/i810/i810_3d_reg.h @@ -113,8 +113,8 @@ #define LCS_LINEWIDTH_2_0 (0x4<<12) #define LCS_LINEWIDTH_3_0 (0x6<<12) #define LCS_UPDATE_ALPHA_INTERP (0x1<<11) -#define LCS_ALPHA_FLAT (0x0<<10) -#define LCS_ALPHA_INTERP (0x1<<10) +#define LCS_ALPHA_FLAT (0x1<<10) +#define LCS_ALPHA_INTERP (0x0<<10) #define LCS_UPDATE_FOG_INTERP (0x1<<9) #define LCS_FOG_INTERP (0x0<<8) #define LCS_FOG_FLAT (0x1<<8) diff --git a/xc/lib/GL/mesa/src/drv/i810/i810ioctl.c b/xc/lib/GL/mesa/src/drv/i810/i810ioctl.c index 2f16e33d7..146b6c1b9 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810ioctl.c +++ b/xc/lib/GL/mesa/src/drv/i810/i810ioctl.c @@ -200,7 +200,6 @@ void i810DmaFinish( i810ContextPtr imesa ) FLUSH_BATCH( imesa ); if (imesa->sarea->last_quiescent != imesa->sarea->last_enqueue) { - if (I810_DEBUG&DEBUG_VERBOSE_IOCTL) fprintf(stderr, "i810DmaFinish\n"); @@ -214,14 +213,22 @@ void i810DmaFinish( i810ContextPtr imesa ) void i810RegetLockQuiescent( i810ContextPtr imesa ) { + /* XXX I disabled this conditional. Doing so fixes all the readpixels + * problems. The problem was that we'd sometimes read from the frame + * buffer (via the span functions) before rendering was completed. + * Taking out this conditional solves that problem. (BrianP) + * if (imesa->sarea->last_quiescent != imesa->sarea->last_enqueue) { + */ if (I810_DEBUG&DEBUG_VERBOSE_IOCTL) fprintf(stderr, "i810RegetLockQuiescent\n"); drmUnlock(imesa->driFd, imesa->hHWContext); i810GetLock( imesa, DRM_LOCK_QUIESCENT ); imesa->sarea->last_quiescent = imesa->sarea->last_enqueue; + /* } + */ } void i810WaitAgeLocked( i810ContextPtr imesa, int age ) diff --git a/xc/lib/GL/mesa/src/drv/i810/i810span.c b/xc/lib/GL/mesa/src/drv/i810/i810span.c index 9e86e9b68..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) @@ -50,6 +50,8 @@ #define HW_LOCK() \ i810ContextPtr imesa = I810_CONTEXT(ctx); \ + FLUSH_BATCH(imesa); \ + i810DmaFinish(imesa); \ LOCK_HARDWARE_QUIESCENT(imesa); #define HW_CLIPLOOP() \ @@ -85,9 +87,9 @@ #define READ_RGBA( rgba, _x, _y ) \ do { \ GLushort p = *(GLushort *)(read_buf + _x*2 + _y*pitch); \ - rgba[0] = (p >> 8) & 0xf8; \ - rgba[1] = (p >> 3) & 0xfc; \ - rgba[2] = (p << 3) & 0xf8; \ + rgba[0] = (((p >> 11) & 0x1f) * 255) / 31; \ + rgba[1] = (((p >> 5) & 0x3f) * 255) / 63; \ + rgba[2] = (((p >> 0) & 0x1f) * 255) / 31; \ rgba[3] = 255; \ } while(0) @@ -128,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; */ @@ -144,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/i810/i810state.c b/xc/lib/GL/mesa/src/drv/i810/i810state.c index cdccbd5ec..50a916fb7 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810state.c +++ b/xc/lib/GL/mesa/src/drv/i810/i810state.c @@ -182,6 +182,7 @@ static void i810DDPolygonStipple( GLcontext *ctx, const GLubyte *mask ) GLubyte p[4]; int i,j,k; int active = (ctx->Polygon.StippleFlag && ctx->PB->primitive == GL_POLYGON); + GLuint newMask; FLUSH_BATCH(imesa); ctx->Driver.TriangleCaps |= DD_TRI_STIPPLE; @@ -191,10 +192,10 @@ static void i810DDPolygonStipple( GLcontext *ctx, const GLubyte *mask ) imesa->Setup[I810_CTXREG_ST1] &= ~ST1_ENABLE; } - p[0] = mask[0] & 0xf; p[0] |= p[0] << 4; - p[1] = mask[4] & 0xf; p[1] |= p[1] << 4; - p[2] = mask[8] & 0xf; p[2] |= p[2] << 4; - p[3] = mask[12] & 0xf; p[3] |= p[3] << 4; + p[0] = mask[12] & 0xf; p[0] |= p[0] << 4; + p[1] = mask[8] & 0xf; p[1] |= p[1] << 4; + p[2] = mask[4] & 0xf; p[2] |= p[2] << 4; + p[3] = mask[0] & 0xf; p[3] |= p[3] << 4; for (k = 0 ; k < 8 ; k++) for (j = 0 ; j < 4; j++) @@ -203,12 +204,19 @@ static void i810DDPolygonStipple( GLcontext *ctx, const GLubyte *mask ) ctx->Driver.TriangleCaps &= ~DD_TRI_STIPPLE; return; } - + + newMask = ((p[0] & 0xf) << 0) | + ((p[1] & 0xf) << 4) | + ((p[2] & 0xf) << 8) | + ((p[3] & 0xf) << 12); + if (newMask == 0xffff) { + /* do opaque stipple in software for conformance */ + ctx->Driver.TriangleCaps &= ~DD_TRI_STIPPLE; + return; + } + imesa->Setup[I810_CTXREG_ST1] &= ~0xffff; - imesa->Setup[I810_CTXREG_ST1] |= ( ((p[0] & 0xf) << 0) | - ((p[1] & 0xf) << 4) | - ((p[2] & 0xf) << 8) | - ((p[3] & 0xf) << 12) ); + imesa->Setup[I810_CTXREG_ST1] |= newMask; if (active) imesa->Setup[I810_CTXREG_ST1] |= ST1_ENABLE; @@ -439,26 +447,23 @@ static GLboolean i810DDColorMask(GLcontext *ctx, GLboolean b, GLboolean a ) { i810ContextPtr imesa = I810_CONTEXT( ctx ); - GLuint tmp = 0; - GLuint rv = 1; - - imesa->Fallback &= ~I810_FALLBACK_COLORMASK; + GLuint tmp; - if (r && g && b) { - tmp = imesa->Setup[I810_CTXREG_B2] | B2_FB_WRITE_ENABLE; - } else if (!r && !g && !b) { - tmp = imesa->Setup[I810_CTXREG_B2] & ~B2_FB_WRITE_ENABLE; - } else { - rv = 0; + if (r && g && b) + imesa->Fallback &= ~I810_FALLBACK_COLORMASK; + else imesa->Fallback |= I810_FALLBACK_COLORMASK; - } - + + tmp = imesa->Setup[I810_CTXREG_B2] | + (B2_FB_WRITE_ENABLE | B2_UPDATE_FB_WRITE_ENABLE); + if (tmp != imesa->Setup[I810_CTXREG_B2]) { FLUSH_BATCH(imesa); imesa->Setup[I810_CTXREG_B2] = tmp; + imesa->dirty |= I810_UPLOAD_CTX; } - return rv; + return GL_FALSE; /* makes s/w path always do s/w masking */ } /* Seperate specular not fully implemented in hardware... Needs @@ -625,16 +630,6 @@ static void i810DDEnable(GLcontext *ctx, GLenum cap, GLboolean state) case GL_TEXTURE_2D: FLUSH_BATCH(imesa); imesa->new_state |= I810_NEW_TEXTURE; - imesa->dirty |= I810_UPLOAD_CTX; - if (ctx->Texture.CurrentUnit == 0) { - imesa->Setup[I810_CTXREG_MT] &= ~MT_TEXEL0_ENABLE; - if (state) - imesa->Setup[I810_CTXREG_MT] |= MT_TEXEL0_ENABLE; - } else { - imesa->Setup[I810_CTXREG_MT] &= ~MT_TEXEL1_ENABLE; - if (state) - imesa->Setup[I810_CTXREG_MT] |= MT_TEXEL1_ENABLE; - } break; case GL_COLOR_LOGIC_OP: FLUSH_BATCH( imesa ); @@ -995,8 +990,8 @@ void i810DDInitState( i810ContextPtr imesa ) #define INTERESTED (~(NEW_MODELVIEW|NEW_PROJECTION|\ NEW_TEXTURE_MATRIX|\ - NEW_USER_CLIP|NEW_CLIENT_STATE|\ - NEW_TEXTURE_ENABLE)) + NEW_USER_CLIP|NEW_CLIENT_STATE)) + void i810DDUpdateState( GLcontext *ctx ) { diff --git a/xc/lib/GL/mesa/src/drv/i810/i810tex.c b/xc/lib/GL/mesa/src/drv/i810/i810tex.c index 5c1615128..ff537aece 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810tex.c +++ b/xc/lib/GL/mesa/src/drv/i810/i810tex.c @@ -705,44 +705,50 @@ static void i810UpdateTex0State( GLcontext *ctx ) struct gl_texture_object *tObj; i810TextureObjectPtr t; int ma_modulate_op; + int format; - - tObj = ctx->Texture.Unit[0].Current; - - if ( tObj != ctx->Texture.Unit[0].CurrentD[2] ) - tObj = 0; - - + /* disable */ + imesa->Setup[I810_CTXREG_MT] &= ~MT_TEXEL0_ENABLE; imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES | - MC_STAGE_0 | - MC_UPDATE_DEST | - MC_DEST_CURRENT | - MC_UPDATE_ARG1 | - MC_ARG1_ITERATED_COLOR | - MC_UPDATE_ARG2 | - MC_ARG2_ONE | - MC_UPDATE_OP | - MC_OP_ARG1 ); - + MC_STAGE_0 | + MC_UPDATE_DEST | + MC_DEST_CURRENT | + MC_UPDATE_ARG1 | + MC_ARG1_ITERATED_COLOR | + MC_UPDATE_ARG2 | + MC_ARG2_ONE | + MC_UPDATE_OP | + MC_OP_ARG1 ); imesa->Setup[I810_CTXREG_MA0] = ( GFX_OP_MAP_ALPHA_STAGES | - MA_STAGE_0 | - MA_UPDATE_ARG1 | - MA_ARG1_ITERATED_ALPHA | - MA_UPDATE_ARG2 | - MA_ARG2_TEX0_ALPHA | - MA_UPDATE_OP | - MA_OP_ARG1 ); - + MA_STAGE_0 | + MA_UPDATE_ARG1 | + MA_ARG1_ITERATED_ALPHA | + MA_UPDATE_ARG2 | + MA_ARG2_TEX0_ALPHA | + MA_UPDATE_OP | + MA_OP_ARG1 ); + + if (ctx->Texture.Unit[0].ReallyEnabled == 0) { + return; + } - if (!(ctx->Texture.ReallyEnabled & 0xf) || !tObj || !tObj->Complete) { + tObj = ctx->Texture.Unit[0].Current; + if (ctx->Texture.Unit[0].ReallyEnabled != TEXTURE0_2D || + tObj->Image[tObj->BaseLevel]->Border > 0) { + /* 1D or 3D texturing enabled, or texture border - fallback */ + imesa->Fallback |= I810_FALLBACK_TEXTURE; return; } + /* Do 2D texture setup */ + + imesa->Setup[I810_CTXREG_MT] |= MT_TEXEL0_ENABLE; + t = tObj->DriverData; - if (!t) { t = i810CreateTexObj( imesa, tObj ); - if (!t) return; + if (!t) + return; } if (t->current_unit != 0) @@ -757,9 +763,11 @@ static void i810UpdateTex0State( GLcontext *ctx ) if (t->MemBlock) i810UpdateTexLRU( imesa, t ); + format = t->image[0].internalFormat; + switch (ctx->Texture.Unit[0].EnvMode) { case GL_REPLACE: - if (t->image[0].internalFormat == GL_ALPHA) + if (format == GL_ALPHA) imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES | MC_STAGE_0 | MC_UPDATE_DEST | @@ -782,7 +790,7 @@ static void i810UpdateTex0State( GLcontext *ctx ) MC_UPDATE_OP | MC_OP_ARG1 ); - if (t->image[0].internalFormat == GL_RGB) { + if (format == GL_RGB) { ma_modulate_op = MA_OP_ARG1; } else { ma_modulate_op = MA_OP_ARG2; @@ -809,7 +817,7 @@ static void i810UpdateTex0State( GLcontext *ctx ) MC_UPDATE_OP | MC_OP_MODULATE ); - if (t->image[0].internalFormat == GL_RGB) { + if (format == GL_RGB) { ma_modulate_op = MA_OP_ARG1; } else { ma_modulate_op = MA_OP_MODULATE; @@ -826,30 +834,74 @@ static void i810UpdateTex0State( GLcontext *ctx ) break; case GL_ADD: - imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES | - MC_STAGE_0 | - MC_UPDATE_DEST | - MC_DEST_CURRENT | - MC_UPDATE_ARG1 | - MC_ARG1_TEX0_COLOR | - MC_UPDATE_ARG2 | - MC_ARG2_ITERATED_COLOR | - MC_UPDATE_OP | - MC_OP_ADD ); + if (format == GL_ALPHA) { + /* Cv = Cf */ + imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES | + MC_STAGE_0 | + MC_UPDATE_DEST | + MC_DEST_CURRENT | + MC_UPDATE_ARG1 | + MC_ARG1_TEX0_COLOR | + MC_UPDATE_ARG2 | + MC_ARG2_ITERATED_COLOR | + MC_UPDATE_OP | + MC_OP_ARG2 ); + } + else { + /* Cv = Cf + Ct */ + imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES | + MC_STAGE_0 | + MC_UPDATE_DEST | + MC_DEST_CURRENT | + MC_UPDATE_ARG1 | + MC_ARG1_TEX0_COLOR | + MC_UPDATE_ARG2 | + MC_ARG2_ITERATED_COLOR | + MC_UPDATE_OP | + MC_OP_ADD ); + } - imesa->Setup[I810_CTXREG_MA0] = ( GFX_OP_MAP_ALPHA_STAGES | - MA_STAGE_0 | - MA_UPDATE_ARG1 | - MA_ARG1_ITERATED_ALPHA | - MA_UPDATE_ARG2 | - MA_ARG2_TEX0_ALPHA | - MA_UPDATE_OP | - MA_OP_ADD ); + /* alpha */ + if (format == GL_ALPHA || + format == GL_LUMINANCE_ALPHA || + format == GL_RGBA) { + /* Av = Af * At */ + imesa->Setup[I810_CTXREG_MA0] = ( GFX_OP_MAP_ALPHA_STAGES | + MA_STAGE_0 | + MA_UPDATE_ARG1 | + MA_ARG1_ITERATED_ALPHA | + MA_UPDATE_ARG2 | + MA_ARG2_TEX0_ALPHA | + MA_UPDATE_OP | + MA_OP_MODULATE ); + } + else if (format == GL_LUMINANCE || format == GL_RGB) { + /* Av = Af */ + imesa->Setup[I810_CTXREG_MA0] = ( GFX_OP_MAP_ALPHA_STAGES | + MA_STAGE_0 | + MA_UPDATE_ARG1 | + MA_ARG1_ITERATED_ALPHA | + MA_UPDATE_ARG2 | + MA_ARG2_ITERATED_ALPHA | + MA_UPDATE_OP | + MA_OP_ARG1 ); + } + else { + /* Av = Af + At */ + imesa->Setup[I810_CTXREG_MA0] = ( GFX_OP_MAP_ALPHA_STAGES | + MA_STAGE_0 | + MA_UPDATE_ARG1 | + MA_ARG1_ITERATED_ALPHA | + MA_UPDATE_ARG2 | + MA_ARG2_TEX0_ALPHA | + MA_UPDATE_OP | + MA_OP_ADD ); + } break; case GL_DECAL: - - if (t->image[0].internalFormat == GL_RGB) { + if (format == GL_RGB) { + /* C = Ct */ imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES | MC_STAGE_0 | MC_UPDATE_DEST | @@ -862,29 +914,32 @@ static void i810UpdateTex0State( GLcontext *ctx ) MC_OP_ARG2 ); } else { + /* RGBA or undefined result */ + /* C = Cf*(1-At)+Ct*At */ imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES | MC_STAGE_0 | MC_UPDATE_DEST | MC_DEST_CURRENT | MC_UPDATE_ARG1 | - MC_ARG1_COLOR_FACTOR | + MC_ARG1_TEX0_COLOR | MC_UPDATE_ARG2 | - MC_ARG2_TEX0_COLOR | + MC_ARG2_ITERATED_COLOR | MC_UPDATE_OP | MC_OP_LIN_BLEND_TEX0_ALPHA ); } + /* Av = Af */ imesa->Setup[I810_CTXREG_MA0] = ( GFX_OP_MAP_ALPHA_STAGES | MA_STAGE_0 | MA_UPDATE_ARG1 | - MA_ARG1_ALPHA_FACTOR | + MA_ARG1_ITERATED_ALPHA | MA_UPDATE_ARG2 | - MA_ARG2_ALPHA_FACTOR | + MA_ARG2_ITERATED_ALPHA | MA_UPDATE_OP | MA_OP_ARG1 ); break; case GL_BLEND: - if (t->image[0].internalFormat == GL_ALPHA) + if (format == GL_ALPHA) imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES | MC_STAGE_0 | MC_UPDATE_DEST | @@ -907,7 +962,20 @@ static void i810UpdateTex0State( GLcontext *ctx ) MC_UPDATE_OP | MC_OP_LIN_BLEND_TEX0_COLOR ); - if (t->image[0].internalFormat == GL_RGB) { + /* alpha */ + if (format == GL_LUMINANCE || format == GL_RGB) { + /* Av = Af */ + imesa->Setup[I810_CTXREG_MA0] = ( GFX_OP_MAP_ALPHA_STAGES | + MA_STAGE_0 | + MA_UPDATE_ARG1 | + MA_ARG1_ITERATED_ALPHA | + MA_UPDATE_ARG2 | + MA_ARG2_ITERATED_ALPHA | + MA_UPDATE_OP | + MA_OP_ARG1 ); + } + else if (format == GL_INTENSITY) { + /* Av = Af(1-It)+AcIt */ imesa->Setup[I810_CTXREG_MA0] = ( GFX_OP_MAP_ALPHA_STAGES | MA_STAGE_0 | MA_UPDATE_ARG1 | @@ -915,16 +983,17 @@ static void i810UpdateTex0State( GLcontext *ctx ) MA_UPDATE_ARG2 | MA_ARG2_ITERATED_ALPHA | MA_UPDATE_OP | - MA_OP_ARG1 ); + MA_OP_LIN_BLEND_TEX0_ALPHA ); } else { + /* Av = AfAt */ imesa->Setup[I810_CTXREG_MA0] = ( GFX_OP_MAP_ALPHA_STAGES | MA_STAGE_0 | MA_UPDATE_ARG1 | - MA_ARG1_ALPHA_FACTOR | + MA_ARG1_TEX0_ALPHA | MA_UPDATE_ARG2 | MA_ARG2_ITERATED_ALPHA | MA_UPDATE_OP | - MA_OP_LIN_BLEND_TEX0_ALPHA ); + MA_OP_MODULATE ); } break; @@ -942,50 +1011,56 @@ static void i810UpdateTex1State( GLcontext *ctx ) i810ContextPtr imesa = I810_CONTEXT(ctx); struct gl_texture_object *tObj; i810TextureObjectPtr t; - int ma_modulate_op; - - - tObj = ctx->Texture.Unit[1].Current; - - if ( tObj != ctx->Texture.Unit[1].CurrentD[2] ) - tObj = 0; - + int ma_modulate_op, format; + /* disable */ + imesa->Setup[I810_CTXREG_MT] &= ~MT_TEXEL1_ENABLE; imesa->Setup[I810_CTXREG_MC1] = ( GFX_OP_MAP_COLOR_STAGES | - MC_STAGE_1 | - MC_UPDATE_DEST | - MC_DEST_CURRENT | - MC_UPDATE_ARG1 | - MC_ARG1_ONE | - MC_ARG1_DONT_REPLICATE_ALPHA | - MC_ARG1_DONT_INVERT | - MC_UPDATE_ARG2 | - MC_ARG2_ONE | - MC_ARG2_DONT_REPLICATE_ALPHA | - MC_ARG2_DONT_INVERT | - MC_UPDATE_OP | - MC_OP_DISABLE ); - + MC_STAGE_1 | + MC_UPDATE_DEST | + MC_DEST_CURRENT | + MC_UPDATE_ARG1 | + MC_ARG1_ONE | + MC_ARG1_DONT_REPLICATE_ALPHA | + MC_ARG1_DONT_INVERT | + MC_UPDATE_ARG2 | + MC_ARG2_ONE | + MC_ARG2_DONT_REPLICATE_ALPHA | + MC_ARG2_DONT_INVERT | + MC_UPDATE_OP | + MC_OP_DISABLE ); imesa->Setup[I810_CTXREG_MA1] = ( GFX_OP_MAP_ALPHA_STAGES | - MA_STAGE_1 | - MA_UPDATE_ARG1 | - MA_ARG1_CURRENT_ALPHA | - MA_ARG1_DONT_INVERT | - MA_UPDATE_ARG2 | - MA_ARG2_CURRENT_ALPHA | - MA_ARG2_DONT_INVERT | - MA_UPDATE_OP | - MA_OP_ARG1 ); - - if (!(ctx->Texture.ReallyEnabled & 0xf0) || !tObj || !tObj->Complete) { + MA_STAGE_1 | + MA_UPDATE_ARG1 | + MA_ARG1_CURRENT_ALPHA | + MA_ARG1_DONT_INVERT | + MA_UPDATE_ARG2 | + MA_ARG2_CURRENT_ALPHA | + MA_ARG2_DONT_INVERT | + MA_UPDATE_OP | + MA_OP_ARG1 ); + + if (ctx->Texture.Unit[1].ReallyEnabled == 0) { + return; + } + + tObj = ctx->Texture.Unit[1].Current; + if (ctx->Texture.Unit[1].ReallyEnabled != TEXTURE0_2D || + tObj->Image[tObj->BaseLevel]->Border > 0) { + /* 1D or 3D texturing enabled, or texture border - fallback */ + imesa->Fallback |= I810_FALLBACK_TEXTURE; return; } + /* Do 2D texture setup */ + + imesa->Setup[I810_CTXREG_MT] |= MT_TEXEL1_ENABLE; + t = tObj->DriverData; - if (!t) { t = i810CreateTexObj( imesa, tObj ); - if (!t) return; + if (!t) + return; } if (t->current_unit != 1) @@ -1000,6 +1075,8 @@ static void i810UpdateTex1State( GLcontext *ctx ) if (t->MemBlock) i810UpdateTexLRU( imesa, t ); + format = t->image[0].internalFormat; + switch (ctx->Texture.Unit[1].EnvMode) { case GL_REPLACE: imesa->Setup[I810_CTXREG_MC1] = ( GFX_OP_MAP_COLOR_STAGES | @@ -1013,7 +1090,7 @@ static void i810UpdateTex1State( GLcontext *ctx ) MC_UPDATE_OP | MC_OP_ARG1 ); - if (t->image[0].internalFormat == GL_RGB) { + if (format == GL_RGB) { ma_modulate_op = MA_OP_ARG1; } else { ma_modulate_op = MA_OP_ARG2; @@ -1040,7 +1117,7 @@ static void i810UpdateTex1State( GLcontext *ctx ) MC_UPDATE_OP | MC_OP_MODULATE ); - if (t->image[0].internalFormat == GL_RGB) { + if (format == GL_RGB) { ma_modulate_op = MA_OP_ARG1; } else { ma_modulate_op = MA_OP_MODULATE; @@ -1068,7 +1145,7 @@ static void i810UpdateTex1State( GLcontext *ctx ) MC_UPDATE_OP | MC_OP_ADD ); - if (t->image[0].internalFormat == GL_RGB) { + if (format == GL_RGB) { ma_modulate_op = MA_OP_ARG1; } else { ma_modulate_op = MA_OP_ADD; @@ -1086,7 +1163,7 @@ static void i810UpdateTex1State( GLcontext *ctx ) case GL_DECAL: - if (t->image[0].internalFormat == GL_RGB) { + if (format == GL_RGB) { imesa->Setup[I810_CTXREG_MC1] = ( GFX_OP_MAP_COLOR_STAGES | MC_STAGE_1 | MC_UPDATE_DEST | @@ -1133,7 +1210,7 @@ static void i810UpdateTex1State( GLcontext *ctx ) MC_UPDATE_OP | MC_OP_LIN_BLEND_TEX1_COLOR ); - if (t->image[0].internalFormat == GL_RGB) { + if (format == GL_RGB) { imesa->Setup[I810_CTXREG_MA1] = ( GFX_OP_MAP_ALPHA_STAGES | MA_STAGE_1 | MA_UPDATE_ARG1 | @@ -1169,11 +1246,12 @@ void i810UpdateTextureState( GLcontext *ctx ) if (imesa->CurrentTexObj[1]) imesa->CurrentTexObj[1]->bound = 0; imesa->CurrentTexObj[0] = 0; imesa->CurrentTexObj[1] = 0; + imesa->Fallback &= ~I810_FALLBACK_TEXTURE; i810UpdateTex0State( ctx ); i810UpdateTex1State( ctx ); I810_CONTEXT( ctx )->dirty |= (I810_UPLOAD_CTX | - I810_UPLOAD_TEX0 | - I810_UPLOAD_TEX1); + I810_UPLOAD_TEX0 | + I810_UPLOAD_TEX1); } @@ -1196,13 +1274,17 @@ static void i810TexEnv( GLcontext *ctx, GLenum target, struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; - GLfloat *fc = texUnit->EnvColor; - GLuint col; - - col = ((((GLubyte)fc[3])<<24) | - (((GLubyte)fc[0])<<16) | - (((GLubyte)fc[1])<<8) | - (((GLubyte)fc[2])<<0)); + const GLfloat *fc = texUnit->EnvColor; + GLuint r, g, b, a, col; + FLOAT_COLOR_TO_UBYTE_COLOR(r, fc[0]); + FLOAT_COLOR_TO_UBYTE_COLOR(g, fc[1]); + FLOAT_COLOR_TO_UBYTE_COLOR(b, fc[2]); + FLOAT_COLOR_TO_UBYTE_COLOR(a, fc[3]); + + col = ((a << 24) | + (r << 16) | + (g << 8) | + (b << 0)); if (imesa->Setup[I810_CTXREG_CF1] != col) { FLUSH_BATCH(imesa); diff --git a/xc/lib/GL/mesa/src/drv/i810/i810tris.h b/xc/lib/GL/mesa/src/drv/i810/i810tris.h index a83adad95..a416f82dc 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810tris.h +++ b/xc/lib/GL/mesa/src/drv/i810/i810tris.h @@ -87,40 +87,42 @@ static __inline__ void i810_draw_point( i810ContextPtr imesa, { int vertsize = imesa->vertsize; GLuint *vb = i810AllocDwordsInline( imesa, 6 * vertsize ); + const GLfloat x = tmp->v.x + 0.125; + const GLfloat y = tmp->v.y - 0.5F; int j; - *(float *)&vb[0] = tmp->v.x - sz; - *(float *)&vb[1] = tmp->v.y - sz; + *(float *)&vb[0] = x - sz; + *(float *)&vb[1] = y - sz; for (j = 2 ; j < vertsize ; j++) vb[j] = tmp->ui[j]; vb += vertsize; - *(float *)&vb[0] = tmp->v.x + sz; - *(float *)&vb[1] = tmp->v.y - sz; + *(float *)&vb[0] = x + sz; + *(float *)&vb[1] = y - sz; for (j = 2 ; j < vertsize ; j++) vb[j] = tmp->ui[j]; vb += vertsize; - *(float *)&vb[0] = tmp->v.x + sz; - *(float *)&vb[1] = tmp->v.y + sz; + *(float *)&vb[0] = x + sz; + *(float *)&vb[1] = y + sz; for (j = 2 ; j < vertsize ; j++) vb[j] = tmp->ui[j]; vb += vertsize; - *(float *)&vb[0] = tmp->v.x + sz; - *(float *)&vb[1] = tmp->v.y + sz; + *(float *)&vb[0] = x + sz; + *(float *)&vb[1] = y + sz; for (j = 2 ; j < vertsize ; j++) vb[j] = tmp->ui[j]; vb += vertsize; - *(float *)&vb[0] = tmp->v.x - sz; - *(float *)&vb[1] = tmp->v.y + sz; + *(float *)&vb[0] = x - sz; + *(float *)&vb[1] = y + sz; for (j = 2 ; j < vertsize ; j++) vb[j] = tmp->ui[j]; vb += vertsize; - *(float *)&vb[0] = tmp->v.x - sz; - *(float *)&vb[1] = tmp->v.y - sz; + *(float *)&vb[0] = x - sz; + *(float *)&vb[1] = y - sz; for (j = 2 ; j < vertsize ; j++) vb[j] = tmp->ui[j]; } @@ -143,13 +145,33 @@ static __inline__ void i810_draw_line( i810ContextPtr imesa, : "=%c" (j) : "0" (vertsize), "S" ((long)v1) : "memory" ); +#elif 0 + for (j = 0 ; j < vertsize ; j++) + vb[j] = v0->ui[j]; + + vb += vertsize; + for (j = 0 ; j < vertsize ; j++) + vb[j] = v1->ui[j]; #else + const GLfloat dx = -0.5; + const GLfloat dy = -0.5; + + v0->v.x += dx; + v0->v.y += dy; + v1->v.x += dx; + v1->v.y += dy; + for (j = 0 ; j < vertsize ; j++) vb[j] = v0->ui[j]; vb += vertsize; for (j = 0 ; j < vertsize ; j++) vb[j] = v1->ui[j]; + + v0->v.x -= dx; + v0->v.y -= dy; + v1->v.x -= dx; + v1->v.y -= dy; #endif } diff --git a/xc/lib/GL/mesa/src/drv/i810/i810vb.c b/xc/lib/GL/mesa/src/drv/i810/i810vb.c index a6ad760a6..5ecc3e2af 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810vb.c +++ b/xc/lib/GL/mesa/src/drv/i810/i810vb.c @@ -87,15 +87,18 @@ #define COORD \ GLfloat *win = VB->Win.data[i]; \ - v->v.x = win[0]; \ - v->v.y = i810height - win[1]; \ - v->v.z = (1.0/0x10000) * win[2]; \ + v->v.x = xoffset + win[0]; \ + v->v.y = yoffset - win[1]; \ + v->v.z = (1.0/0x10000) * win[2]; \ v->v.oow = win[3]; #define NOP +#define SUBPIXEL_X -0.5 +#define SUBPIXEL_Y -0.375 + #define SETUPFUNC(name,win,col,tex0,tex1,tex0_4,spec,fog) \ static void name(struct vertex_buffer *VB, GLuint start, GLuint end) \ @@ -105,9 +108,12 @@ static void name(struct vertex_buffer *VB, GLuint start, GLuint end) \ i810VertexPtr v; \ GLfloat (*tc0)[4]; \ GLfloat (*tc1)[4]; \ - GLfloat i810height = dPriv->h; \ + const GLfloat xoffset = SUBPIXEL_X; \ + const GLfloat yoffset = dPriv->h + SUBPIXEL_Y; \ int i; \ - (void) i810height; (void) imesa; \ + (void) xoffset; \ + (void) yoffset; \ + (void) imesa; \ \ \ gl_import_client_data( VB, VB->ctx->RenderFlags, \ @@ -269,7 +275,7 @@ void i810ChooseRasterSetupFunc(GLcontext *ctx) funcindex |= I810_TEX0_BIT; if (ctx->Texture.ReallyEnabled & 0xf0) { - funcindex |= I810_TEX1_BIT; + funcindex |= (I810_TEX0_BIT | I810_TEX1_BIT); imesa->vertsize = 10; imesa->Setup[I810_CTXREG_VF] = I810_VFMT_T0T1; } 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/mga_xmesa.c b/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c index f428614f0..8e7bb0f24 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c +++ b/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c @@ -314,6 +314,7 @@ GLboolean XMesaCreateContext( Display *dpy, GLvisual *mesaVis, mmesa->hHWContext = driContextPriv->hHWContext; mmesa->driFd = sPriv->fd; mmesa->driHwLock = &sPriv->pSAREA->lock; + mmesa->mgaScreen = mgaScreen; mmesa->driScreen = sPriv; mmesa->sarea = saPriv; @@ -374,7 +375,7 @@ GLboolean XMesaCreateContext( Display *dpy, GLvisual *mesaVis, break; }; - + mmesa->canDoStipple = GL_FALSE; mmesa->renderindex = -1; /* impossible value */ mmesa->new_state = ~0; mmesa->dirty = ~0; @@ -444,14 +445,16 @@ GLframebuffer *XMesaCreateWindowBuffer( Display *dpy, __DRIdrawablePrivate *driDrawPriv, GLvisual *mesaVis) { + GLboolean swStencil = mesaVis->StencilBits > 0 && mesaVis->DepthBits != 24; + if (MGA_DEBUG&DEBUG_VERBOSE_DRI) fprintf(stderr, "XMesaCreateWindowBuffer\n"); return gl_create_framebuffer(mesaVis, GL_FALSE, /* software depth buffer? */ - mesaVis->StencilBits > 0, + swStencil, mesaVis->AccumRedBits > 0, - mesaVis->AlphaBits > 0 + GL_FALSE /* software alpha buffer/ */ ); } diff --git a/xc/lib/GL/mesa/src/drv/mga/mgacontext.h b/xc/lib/GL/mesa/src/drv/mga/mgacontext.h index 1ae30deec..e1aacb193 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgacontext.h +++ b/xc/lib/GL/mesa/src/drv/mga/mgacontext.h @@ -57,11 +57,13 @@ * - texture env GL_BLEND -- can be fixed * - 1D and 3D textures * - incomplete textures + * - GL_DEPTH_FUNC == GL_NEVER not in h/w */ #define MGA_FALLBACK_TEXTURE 0x1 #define MGA_FALLBACK_BUFFER 0x2 #define MGA_FALLBACK_LOGICOP 0x4 #define MGA_FALLBACK_STENCIL 0x8 +#define MGA_FALLBACK_DEPTH 0x10 /* For mgaCtx->new_state. @@ -191,6 +193,7 @@ struct mga_context_t { GLuint depth_clear_mask; GLuint stencil_clear_mask; GLuint hw_stencil; + GLboolean canDoStipple; /* Dma buffers */ @@ -220,7 +223,6 @@ struct mga_context_t { */ unsigned int texAge[MGA_NR_TEX_HEAPS];/* texture LRU age */ unsigned int dirtyAge; /* buffer age for synchronization */ - unsigned int lastSwap; /* throttling runaway apps */ GLuint *status; GLuint status_offset; diff --git a/xc/lib/GL/mesa/src/drv/mga/mgadd.c b/xc/lib/GL/mesa/src/drv/mga/mgadd.c index dced4235b..6f055c5be 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgadd.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgadd.c @@ -51,7 +51,7 @@ #include "X86/common_x86_asm.h" #endif -#define MGA_DATE "20010215" +#define MGA_DATE "20010306" diff --git a/xc/lib/GL/mesa/src/drv/mga/mgaioctl.c b/xc/lib/GL/mesa/src/drv/mga/mgaioctl.c index c803ac5b5..c31d23eca 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgaioctl.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgaioctl.c @@ -28,7 +28,7 @@ static void mga_iload_dma_ioctl(mgaContextPtr mmesa, if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL) fprintf(stderr, "DRM_IOCTL_MGA_ILOAD idx %d dst %x length %d\n", - buf->idx, dest, length); + buf->idx, (int) dest, length); ret = drmMGATextureLoad( mmesa->driFd, buf->idx, dest, length ); if ( ret < 0 ) { @@ -156,8 +156,9 @@ drmBufPtr mga_get_buffer_ioctl( mgaContextPtr mmesa ) -GLbitfield mgaDDClear( GLcontext *ctx, GLbitfield mask, GLboolean all, - GLint cx, GLint cy, GLint cw, GLint ch ) +static GLbitfield +mgaDDClear( GLcontext *ctx, GLbitfield mask, GLboolean all, + GLint cx, GLint cy, GLint cw, GLint ch ) { mgaContextPtr mmesa = MGA_CONTEXT(ctx); __DRIdrawablePrivate *dPriv = mmesa->driDrawable; @@ -290,7 +291,6 @@ void mgaSwapBuffers( mgaContextPtr mmesa ) int nbox; int ret; int i; - int tmp; GLuint last_frame, last_wrap; FLUSH_BATCH( mmesa ); @@ -300,6 +300,16 @@ void mgaSwapBuffers( mgaContextPtr mmesa ) last_frame = mmesa->sarea->last_frame.head; last_wrap = mmesa->sarea->last_frame.wrap; + /* FIXME: Add a timeout to this loop... + */ + while ( 1 ) { + if ( last_wrap < mmesa->sarea->last_wrap || + ( last_wrap == mmesa->sarea->last_wrap && + last_frame <= *mmesa->status - mmesa->status_offset ) ) { + break; + } + } + /* Use the frontbuffer cliprects */ if (mmesa->dirty_cliprects & MGA_FRONT) @@ -329,32 +339,8 @@ void mgaSwapBuffers( mgaContextPtr mmesa ) } } - if ( 0 ) { - fprintf( stderr, "waiting...\n" ); - } - - while ( 1 ) { - if ( last_wrap < mmesa->sarea->last_wrap || - ( last_wrap == mmesa->sarea->last_wrap && - last_frame <= *mmesa->status - mmesa->status_offset ) ) { - break; - } - if ( 0 ) { - fprintf( stderr, " head=0x%06x wrap=%d\n", - *mmesa->status - mmesa->status_offset, - mmesa->sarea->last_wrap ); - fprintf( stderr, " frame=0x%06x wrap=%d\n\n", - last_frame, last_wrap ); - } - } - - if ( 0 ) - fprintf( stderr, "waiting... done.\n" ); - UNLOCK_HARDWARE( mmesa ); - - mmesa->lastSwap = tmp; mmesa->dirty |= MGA_UPLOAD_CLIPRECTS; } @@ -408,8 +394,8 @@ static int intersect_rect( XF86DRIClipRectPtr out, if (b->y1 > out->y1) out->y1 = b->y1; if (b->x2 < out->x2) out->x2 = b->x2; if (b->y2 < out->y2) out->y2 = b->y2; - if (out->x1 >= out->x2) return 0; - if (out->y1 >= out->y2) return 0; + if (out->x1 > out->x2) return 0; + if (out->y1 > out->y2) return 0; return 1; } 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/mgaspan.c b/xc/lib/GL/mesa/src/drv/mga/mgaspan.c index b707bc406..83a78f2dc 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgaspan.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgaspan.c @@ -25,7 +25,6 @@ dPriv->y * pitch); \ GLuint p = MGA_CONTEXT( ctx )->MonoColor; \ (void) read_buf; (void) buf; (void) p - #define LOCAL_DEPTH_VARS \ @@ -59,8 +58,10 @@ #define HW_LOCK() \ mgaContextPtr mmesa = MGA_CONTEXT(ctx); \ + FLUSH_BATCH(mmesa); \ LOCK_HARDWARE_QUIESCENT(mmesa); + #define HW_CLIPLOOP() \ do { \ int _nc = mmesa->numClipRects; \ @@ -97,9 +98,9 @@ #define READ_RGBA( rgba, _x, _y ) \ do { \ GLushort p = *(GLushort *)(read_buf + _x*2 + _y*pitch); \ - rgba[0] = (p >> 8) & 0xf8; \ - rgba[1] = (p >> 3) & 0xfc; \ - rgba[2] = (p << 3) & 0xf8; \ + rgba[0] = (((p >> 11) & 0x1f) * 255) / 31; \ + rgba[1] = (((p >> 5) & 0x3f) * 255) / 63; \ + rgba[2] = (((p >> 0) & 0x1f) * 255) / 31; \ rgba[3] = 255; \ } while(0) @@ -127,7 +128,7 @@ do { \ rgba[0] = (p >> 16) & 0xff; \ rgba[1] = (p >> 8) & 0xff; \ rgba[2] = (p >> 0) & 0xff; \ - rgba[3] = (p >> 24) & 0xff; \ + rgba[3] = 0xff; \ } while (0) #define TAG(x) mga##x##_8888 @@ -168,13 +169,13 @@ do { \ #define WRITE_DEPTH( _x, _y, d ) { \ GLuint tmp = *(GLuint *)(buf + _x*4 + _y*pitch); \ tmp &= 0xff; \ - tmp |= (d) & 0xffffff00; \ + tmp |= (d) << 8; \ *(GLuint *)(buf + _x*4 + _y*pitch) = tmp; \ } -#define READ_DEPTH( d, _x, _y ) \ - d = *(GLuint *)(buf + _x*4 + _y*pitch) & ~0xff; - +#define READ_DEPTH( d, _x, _y ) { \ + d = (*(GLuint *)(buf + _x*4 + _y*pitch) & ~0xff) >> 8; \ +} #define TAG(x) mga##x##_24_8 #include "depthtmp.h" diff --git a/xc/lib/GL/mesa/src/drv/mga/mgastate.c b/xc/lib/GL/mesa/src/drv/mga/mgastate.c index eb45233e0..54cc4de29 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgastate.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgastate.c @@ -190,7 +190,9 @@ static void mgaUpdateZMode(const GLcontext *ctx) if (ctx->Depth.Test) { switch(ctx->Depth.Func) { case GL_NEVER: - zmode = DC_zmode_nozcmp; break; + /* can't do this in h/w, we'll use a s/w fallback */ + zmode = DC_zmode_nozcmp; + break; case GL_ALWAYS: zmode = DC_zmode_nozcmp; break; case GL_LESS: @@ -208,15 +210,17 @@ static void mgaUpdateZMode(const GLcontext *ctx) default: break; } - } else { + + if (ctx->Depth.Mask) + zmode |= DC_atype_zi; + else + zmode |= DC_atype_i; + } + else { zmode |= DC_zmode_nozcmp; + zmode |= DC_atype_i; /* don't write to zbuffer */ } - if (ctx->Depth.Mask) - zmode |= DC_atype_zi; - else - zmode |= DC_atype_i; - #if defined(ACCEL_ROP) mmesa->setup.dwgctl &= DC_bop_MASK; if (ctx->Color.ColorLogicOpEnabled) @@ -287,6 +291,10 @@ static void mgaDDDepthFunc(GLcontext *ctx, GLenum func) { FLUSH_BATCH( MGA_CONTEXT(ctx) ); MGA_CONTEXT(ctx)->new_state |= MGA_NEW_DEPTH; + if (func == GL_NEVER && ctx->Depth.Test) + MGA_CONTEXT(ctx)->Fallback |= MGA_FALLBACK_DEPTH; + else + MGA_CONTEXT(ctx)->Fallback &= ~MGA_FALLBACK_DEPTH; } static void mgaDDDepthMask(GLcontext *ctx, GLboolean flag) @@ -439,7 +447,10 @@ static void mgaUpdateAlphaMode(GLcontext *ctx) a |= AC_src_zero; break; case GL_SRC_ALPHA_SATURATE: - a |= AC_src_src_alpha_sat; + if (ctx->Visual->AlphaBits > 0) + a |= AC_src_src_alpha_sat; + else + a |= AC_src_zero; break; default: /* never happens */ break; @@ -499,10 +510,10 @@ void mgaUpdateClipping(const GLcontext *ctx) if (mmesa->driDrawable) { int x1 = mmesa->driDrawable->x + ctx->Scissor.X; - int y1 = mmesa->driDrawable->y + mmesa->driDrawable->h - (ctx->Scissor.Y+ - ctx->Scissor.Height); - int x2 = mmesa->driDrawable->x + ctx->Scissor.X+ctx->Scissor.Width; - int y2 = mmesa->driDrawable->y + mmesa->driDrawable->h - ctx->Scissor.Y; + int y1 = mmesa->driDrawable->y + mmesa->driDrawable->h + - (ctx->Scissor.Y + ctx->Scissor.Height); + int x2 = x1 + ctx->Scissor.Width - 1; + int y2 = y1 + ctx->Scissor.Height - 1; if (x1 < 0) x1 = 0; if (y1 < 0) y1 = 0; @@ -636,7 +647,7 @@ static GLboolean mgaDDColorMask(GLcontext *ctx, mmesa->dirty |= MGA_UPLOAD_CONTEXT; } - return 1; + return 0; /* Kind of a hack */ } /* ============================================================= @@ -644,9 +655,12 @@ static GLboolean mgaDDColorMask(GLcontext *ctx, * * The mga supports a subset of possible 4x4 stipples natively, GL * wants 32x32. Fortunately stipple is usually a repeating pattern. + * + * Note: the fully opaque pattern (0xffff) has been disabled in order + * to work around a conformance issue. */ static int mgaStipples[16] = { - 0xffff, + 0xffff1, /* See above note */ 0xa5a5, 0x5a5a, 0xa0a0, @@ -674,7 +688,12 @@ static void mgaDDPolygonStipple( GLcontext *ctx, const GLubyte *mask ) GLuint stipple; FLUSH_BATCH(mmesa); - ctx->Driver.TriangleCaps |= DD_TRI_STIPPLE; + + /* Turn off flags. We'll turn them on below if this stipple pattern + * works in h/w. + */ + ctx->Driver.TriangleCaps &= ~DD_TRI_STIPPLE; + mmesa->canDoStipple = GL_FALSE; if (active) { mmesa->dirty |= MGA_UPLOAD_CONTEXT; @@ -690,7 +709,6 @@ static void mgaDDPolygonStipple( GLcontext *ctx, const GLubyte *mask ) for (j = 0 ; j < 4; j++) for (i = 0 ; i < 4 ; i++) if (*m++ != p[j]) { - ctx->Driver.TriangleCaps &= ~DD_TRI_STIPPLE; return; } @@ -706,13 +724,15 @@ static void mgaDDPolygonStipple( GLcontext *ctx, const GLubyte *mask ) } if (i == 16) { - ctx->Driver.TriangleCaps &= ~DD_TRI_STIPPLE; return; } + mmesa->canDoStipple = GL_TRUE; + if (active) { mmesa->setup.dwgctl &= ~(0xf<<20); mmesa->setup.dwgctl |= mmesa->poly_stipple; + ctx->Driver.TriangleCaps |= DD_TRI_STIPPLE; } } @@ -778,6 +798,16 @@ void mgaEmitHwStateLocked( mgaContextPtr mmesa ) mmesa->sarea->dirty |= mmesa->dirty; mmesa->dirty &= (MGA_UPLOAD_CLIPRECTS|MGA_WAIT_AGE); + + /* This is a bit of a hack but seems to be the best place to ensure + * that separate specular is disabled when not needed. + */ + if (mmesa->glCtx->Texture.ReallyEnabled == 0 || + !mmesa->glCtx->Light.Enabled || + mmesa->glCtx->Light.Model.ColorControl == GL_SINGLE_COLOR) { + sarea->TexState[0].texctl2 &= ~TMC_specen_enable; + sarea->TexState[1].texctl2 &= ~TMC_specen_enable; + } } @@ -808,6 +838,10 @@ static void mgaDDEnable(GLcontext *ctx, GLenum cap, GLboolean state) case GL_DEPTH_TEST: FLUSH_BATCH( mmesa ); mmesa->new_state |= MGA_NEW_DEPTH; + if (ctx->Depth.Func == GL_NEVER && ctx->Depth.Test) + mmesa->Fallback |= MGA_FALLBACK_DEPTH; + else + mmesa->Fallback &= ~MGA_FALLBACK_DEPTH; break; case GL_SCISSOR_TEST: FLUSH_BATCH( mmesa ); @@ -829,14 +863,20 @@ static void mgaDDEnable(GLcontext *ctx, GLenum cap, GLboolean state) mmesa->new_state |= (MGA_NEW_TEXTURE|MGA_NEW_ALPHA); break; case GL_POLYGON_STIPPLE: - if ((ctx->Driver.TriangleCaps & DD_TRI_STIPPLE) && - ctx->PB->primitive == GL_POLYGON) - { - FLUSH_BATCH(mmesa); - mmesa->dirty |= MGA_UPLOAD_CONTEXT; - mmesa->setup.dwgctl &= ~(0xf<<20); - if (state) + FLUSH_BATCH(mmesa); + mmesa->dirty |= MGA_UPLOAD_CONTEXT; + mmesa->setup.dwgctl &= ~(0xf<<20); + if (state) { + if (mmesa->canDoStipple && ctx->PB->primitive == GL_POLYGON) { mmesa->setup.dwgctl |= mmesa->poly_stipple; + ctx->Driver.TriangleCaps |= DD_TRI_STIPPLE; + } + else { + ctx->Driver.TriangleCaps &= ~DD_TRI_STIPPLE; + } + } + else { + ctx->Driver.TriangleCaps &= ~DD_TRI_STIPPLE; } break; case GL_COLOR_LOGIC_OP: @@ -948,11 +988,6 @@ void mgaDDUpdateHwState( GLcontext *ctx ) } - - - - - void mgaDDReducedPrimitiveChange( GLcontext *ctx, GLenum prim ) { mgaContextPtr mmesa = MGA_CONTEXT(ctx); @@ -960,20 +995,24 @@ void mgaDDReducedPrimitiveChange( GLcontext *ctx, GLenum prim ) FLUSH_BATCH( mmesa ); mgaUpdateCull(ctx); - if (ctx->Polygon.StippleFlag && (ctx->Driver.TriangleCaps & DD_TRI_STIPPLE)) - { + if (ctx->Polygon.StippleFlag) { mmesa->dirty |= MGA_UPLOAD_CONTEXT; mmesa->setup.dwgctl &= ~(0xf<<20); - if (ctx->PB->primitive == GL_POLYGON) + ctx->Driver.TriangleCaps &= ~DD_TRI_STIPPLE; + if (ctx->PB->primitive == GL_POLYGON && mmesa->canDoStipple) { mmesa->setup.dwgctl |= mmesa->poly_stipple; + ctx->Driver.TriangleCaps |= DD_TRI_STIPPLE; + } + } + else { + ctx->Driver.TriangleCaps &= ~DD_TRI_STIPPLE; } } #define INTERESTED (~(NEW_MODELVIEW|NEW_PROJECTION|\ NEW_TEXTURE_MATRIX|\ - NEW_USER_CLIP|NEW_CLIENT_STATE|\ - NEW_TEXTURE_ENABLE)) + NEW_USER_CLIP|NEW_CLIENT_STATE)) void mgaDDUpdateState( GLcontext *ctx ) { @@ -999,6 +1038,9 @@ void mgaDDUpdateState( GLcontext *ctx ) ctx->Driver.TriangleFunc=mmesa->TriangleFunc; ctx->Driver.QuadFunc=mmesa->QuadFunc; } + else { + ctx->IndirectTriangles |= mmesa->IndirectTriangles; + } } diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatex.c b/xc/lib/GL/mesa/src/drv/mga/mgatex.c index 03f1e39f4..35945224a 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgatex.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgatex.c @@ -37,9 +37,11 @@ #include "mgaregs.h" #include "mgaioctl.h" +#include "context.h" #include "enums.h" #include "simple_list.h" #include "mem.h" +#include "texutil.h" #define TEX_0 1 #define TEX_1 2 @@ -144,11 +146,166 @@ 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 will report incorrect component sizes... */ + SET_FORMAT( TMC_tformat_tw12, _mesa_texformat_argb4444 ); + break; + + case 1: + case GL_LUMINANCE: + case GL_LUMINANCE4: + case GL_LUMINANCE8: + case GL_LUMINANCE12: + case GL_LUMINANCE16: + /* FIXME: This will report incorrect component sizes... */ + SET_FORMAT( TMC_tformat_tw16, _mesa_texformat_rgb565 ); + 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 will report incorrect component sizes... */ + SET_FORMAT( TMC_tformat_tw12, _mesa_texformat_argb4444 ); + break; + case GL_INTENSITY: + case GL_INTENSITY4: + case GL_INTENSITY8: + case GL_INTENSITY12: + case GL_INTENSITY16: + /* FIXME: This will report incorrect component sizes... */ + SET_FORMAT( TMC_tformat_tw12, _mesa_texformat_argb4444 ); + 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; +} /* @@ -160,60 +317,27 @@ static void mgaSetTexBorderColor(mgaTextureObjectPtr t, GLubyte color[4]) static void mgaCreateTexObj(mgaContextPtr mmesa, struct gl_texture_object *tObj) { - const struct gl_texture_image *image = tObj->Image[ 0 ]; + const GLint baseLevel = tObj->BaseLevel; + struct gl_texture_image *image = tObj->Image[baseLevel]; mgaTextureObjectPtr t; int i, ofs; int LastLevel; int s, s2; - int textureFormat; - + int tformat; if (!image) return; - tObj->DriverData = t = CALLOC( sizeof( *t ) ); if (!t) { fprintf(stderr, "mgaCreateTexObj: Failed to malloc mgaTextureObject\n" ); return; } - switch( image->Format ) { - case GL_RGB: - case GL_LUMINANCE: - if ( image->IntFormat != GL_RGB5 && ( image->IntFormat == GL_RGB8 || - mmesa->default32BitTextures ) ) { - t->texelBytes = 4; - textureFormat = TMC_tformat_tw32; - } else { - t->texelBytes = 2; - textureFormat = TMC_tformat_tw16; - } - break; - case GL_ALPHA: - case GL_LUMINANCE_ALPHA: - case GL_INTENSITY: - case GL_RGBA: - if ( image->IntFormat != GL_RGBA4 && ( image->IntFormat == GL_RGBA8 || - mmesa->default32BitTextures ) ) { - t->texelBytes = 4; - textureFormat = TMC_tformat_tw32; - } else { - t->texelBytes = 2; - textureFormat = TMC_tformat_tw12; - } - break; - case GL_COLOR_INDEX: - textureFormat = TMC_tformat_tw8; - t->texelBytes = 1; - break; - default: - fprintf(stderr, "mgaCreateTexObj: bad image->Format %x/%s\n", - image->Format, - gl_lookup_enum_by_nr(image->Format)); - FREE( t ); - tObj->DriverData = 0; - return; - } + /* FIXME: Use the real DD interface... + */ + tformat = mgaChooseTexFormat( mmesa, image, image->Format, + GL_UNSIGNED_BYTE ); + t->texelBytes = image->TexFormat->TexelBytes; /* We are going to upload all levels that are present, even if * later levels wouldn't be used by the current filtering mode. This @@ -236,7 +360,6 @@ static void mgaCreateTexObj(mgaContextPtr mmesa, MAX2( tObj->Image[i]->Height, 8 ) * t->texelBytes) + 31) & ~31; } - t->totalSize = ofs; t->lastLevel = LastLevel; t->tObj = tObj; @@ -249,9 +372,7 @@ static void mgaCreateTexObj(mgaContextPtr mmesa, /* 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); @@ -331,6 +452,7 @@ static void mgaUpdateTextureEnvG400( GLcontext *ctx, int unit ) GLuint *reg = ((GLuint *)&mmesa->setup.tdualstage0 + unit); GLuint source = mmesa->tmu_source[unit]; struct gl_texture_object *tObj = ctx->Texture.Unit[source].Current; + GLenum format; if ( tObj != ctx->Texture.Unit[source].CurrentD[2] || !tObj || @@ -338,95 +460,183 @@ static void mgaUpdateTextureEnvG400( GLcontext *ctx, int unit ) ((ctx->Enabled>>(source*4))&TEXTURE0_ANY) != TEXTURE0_2D ) return; + format = tObj->Image[tObj->BaseLevel]->Format; switch (ctx->Texture.Unit[source].EnvMode) { case GL_REPLACE: - *reg = (TD0_color_sel_arg1 | - TD0_alpha_sel_arg1 ); + if (format == GL_RGB || format == GL_LUMINANCE) { + *reg = (TD0_color_sel_arg1 | + TD0_alpha_arg2_diffuse | + TD0_alpha_sel_arg2 ); + } + else if (format == GL_ALPHA) { + *reg = (TD0_color_sel_arg2 | + TD0_color_arg2_diffuse | + TD0_alpha_sel_arg1 ); + } + else { + *reg = (TD0_color_sel_arg1 | + TD0_alpha_sel_arg1 ); + } break; case GL_MODULATE: - if (unit == 0) + if (unit == 0) { *reg = ( TD0_color_arg2_diffuse | TD0_color_sel_mul | TD0_alpha_arg2_diffuse | TD0_alpha_sel_mul); - else + } + else { *reg = ( TD0_color_arg2_prevstage | TD0_color_alpha_prevstage | TD0_color_sel_mul | TD0_alpha_arg2_prevstage | TD0_alpha_sel_mul); + } break; case GL_DECAL: - if (tObj->Image[0]->Format == GL_RGB) - *reg = (TD0_color_sel_arg1 | - TD0_alpha_sel_arg1 ); - else if (unit == 0) - *reg = (TD0_color_arg2_diffuse | - TD0_color_alpha_currtex | - TD0_color_alpha2inv_enable | - TD0_color_arg2mul_alpha2 | - TD0_color_arg1mul_alpha1 | - TD0_color_add_add | - TD0_color_sel_add | - TD0_alpha_arg2_diffuse | - TD0_alpha_sel_arg2 ); - else - *reg = (TD0_color_arg2_prevstage | - TD0_color_alpha_currtex | - TD0_color_alpha2inv_enable | - TD0_color_arg2mul_alpha2 | - TD0_color_arg1mul_alpha1 | - TD0_color_add_add | - TD0_color_sel_add | - TD0_alpha_arg2_prevstage | - TD0_alpha_sel_arg2 ); - + if (format == GL_RGB) { + if (unit == 0) { + *reg = (TD0_color_sel_arg1 | + TD0_alpha_arg2_diffuse | + TD0_alpha_sel_arg2 ); + } + else { + *reg = (TD0_color_sel_arg1 | + TD0_alpha_arg2_prevstage | + TD0_alpha_sel_arg2 ); + } + } + else if ( format == GL_RGBA ) { +#if 0 + if (unit == 0) { + /* this doesn't work */ + *reg = (TD0_color_arg2_diffuse | + TD0_color_alpha_currtex | + TD0_color_alpha2inv_enable | + TD0_color_arg2mul_alpha2 | + TD0_color_arg1mul_alpha1 | + TD0_color_blend_enable | + TD0_color_arg1add_mulout | + TD0_color_arg2add_mulout | + TD0_color_add_add | + TD0_color_sel_mul | + TD0_alpha_arg2_diffuse | + TD0_alpha_sel_arg2 ); + } + else { + *reg = (TD0_color_arg2_prevstage | + TD0_color_alpha_currtex | + TD0_color_alpha2inv_enable | + TD0_color_arg2mul_alpha2 | + TD0_color_arg1mul_alpha1 | + TD0_color_add_add | + TD0_color_sel_add | + TD0_alpha_arg2_prevstage | + TD0_alpha_sel_arg2 ); + } +#else + /* s/w fallback, pretty sure we can't do in h/w */ + mmesa->Fallback |= MGA_FALLBACK_TEXTURE; +#endif + } + else { + if (unit == 0) { + *reg = ( TD0_color_arg2_diffuse | + TD0_color_sel_arg2 | + TD0_alpha_arg2_diffuse | + TD0_alpha_sel_arg2); + } + else { + *reg = ( TD0_color_arg2_prevstage | + TD0_color_sel_arg2 | + TD0_alpha_arg2_prevstage | + TD0_alpha_sel_arg2); + } + } break; case GL_ADD: - if (unit == 0) - *reg = ( TD0_color_arg2_diffuse | - TD0_color_add_add | - TD0_color_sel_add | - TD0_alpha_arg2_diffuse | - TD0_alpha_sel_add); - else - *reg = ( TD0_color_arg2_prevstage | - TD0_color_alpha_prevstage | - TD0_color_add_add | - TD0_color_sel_add | - TD0_alpha_arg2_prevstage | - TD0_alpha_sel_add); + if (unit == 0) { + if (format == GL_INTENSITY) + *reg = ( TD0_color_arg2_diffuse | + TD0_color_add_add | + TD0_color_sel_add | + TD0_alpha_arg2_diffuse | + TD0_alpha_add_enable | + TD0_alpha_sel_add); + else if (format == GL_ALPHA) + *reg = ( TD0_color_arg2_diffuse | + TD0_color_sel_mul | + TD0_alpha_arg2_diffuse | + TD0_alpha_sel_mul); + else + *reg = ( TD0_color_arg2_diffuse | + TD0_color_add_add | + TD0_color_sel_add | + TD0_alpha_arg2_diffuse | + TD0_alpha_sel_mul); + } + else { + if (format == GL_INTENSITY) { + *reg = ( TD0_color_arg2_prevstage | + TD0_color_add_add | + TD0_color_sel_add | + TD0_alpha_arg2_prevstage | + TD0_alpha_add_enable | + TD0_alpha_sel_add); + } + else if (format == GL_ALPHA) { + *reg = ( TD0_color_arg2_prevstage | + TD0_color_sel_mul | + TD0_alpha_arg2_prevstage | + TD0_alpha_sel_mul); + } + else { + *reg = ( TD0_color_arg2_prevstage | + TD0_color_alpha_prevstage | + TD0_color_add_add | + TD0_color_sel_add | + TD0_alpha_arg2_prevstage | + TD0_alpha_sel_mul); + } + } break; case GL_BLEND: - if (mmesa->blend_flags) - mmesa->Fallback |= MGA_FALLBACK_TEXTURE; - - /* Do singletexture GL_BLEND with 'all ones' env-color - * by using both texture units. Multitexture gl_blend - * is a fallback. - */ - if (unit == 0) { - /* Part 1: R1 = Rf ( 1 - Rt ) - * A1 = Af At - */ + if (format == GL_ALPHA) { *reg = ( TD0_color_arg2_diffuse | - TD0_color_arg1_inv_enable | TD0_color_sel_mul | TD0_alpha_arg2_diffuse | - TD0_alpha_sel_arg1); - } else { - /* Part 2: R2 = R1 + Rt - * A2 = A1 - */ - *reg = ( TD0_color_arg2_prevstage | - TD0_color_add_add | - TD0_color_sel_add | - TD0_alpha_arg2_prevstage | - TD0_alpha_sel_arg2); + TD0_alpha_sel_mul); + } + else { + mmesa->Fallback |= MGA_FALLBACK_TEXTURE; + + /* Do singletexture GL_BLEND with 'all ones' env-color + * by using both texture units. Multitexture gl_blend + * is a fallback. + */ + if (unit == 0) { + /* Part 1: R1 = Rf ( 1 - Rt ) + * A1 = Af At + */ + *reg = ( TD0_color_arg2_diffuse | + TD0_color_arg1_inv_enable | + TD0_color_sel_mul | + TD0_alpha_arg2_diffuse | + TD0_alpha_sel_arg1); + } else { + /* Part 2: R2 = R1 + Rt + * A2 = A1 + */ + *reg = ( TD0_color_arg2_prevstage | + TD0_color_add_add | + TD0_color_sel_add | + TD0_alpha_arg2_prevstage | + TD0_alpha_sel_arg2); + } } break; default: @@ -459,6 +669,11 @@ static void mgaUpdateTextureObject( GLcontext *ctx, int unit ) return; } + if (tObj->Image[tObj->BaseLevel]->Border > 0) { + mmesa->Fallback |= MGA_FALLBACK_TEXTURE; + return; + } + /* if (!tObj) tObj = ctx->Texture.Unit[0].Current; */ /* if (!tObj) return; */ @@ -597,6 +812,9 @@ static void mgaDDTexImage( GLcontext *ctx, GLenum target, { mgaContextPtr mmesa = MGA_CONTEXT( ctx ); mgaTextureObjectPtr t; + GLint tformat; + /* hack: cast-away const */ + struct gl_texture_image *img = (struct gl_texture_image *) image; /* just free the mga texture if it exists, it will be recreated at mgaUpdateTextureState time. */ @@ -608,6 +826,9 @@ static void mgaDDTexImage( GLcontext *ctx, GLenum target, mmesa->new_state |= MGA_NEW_TEXTURE; } + tformat = mgaChooseTexFormat( mmesa, img, img->Format, + GL_UNSIGNED_BYTE ); + if (0) fprintf(stderr, "mgaDDTexImage tObj %p, level %d, image %p\n", tObj, level, image); diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatris.c b/xc/lib/GL/mesa/src/drv/mga/mgatris.c index cd051bf26..4caa1bfa4 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgatris.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgatris.c @@ -38,25 +38,6 @@ #include "mgavb.h" -static void mga_null_quad( GLcontext *ctx, GLuint v0, - GLuint v1, GLuint v2, GLuint v3, GLuint pv ) -{ -} - -static void mga_null_triangle( GLcontext *ctx, GLuint v0, - GLuint v1, GLuint v2, GLuint pv ) -{ -} - -static void mga_null_line( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv ) -{ -} - -static void mga_null_points( GLcontext *ctx, GLuint first, GLuint last ) -{ -} - - #define MGA_COLOR(to, from) { \ (to)[0] = (from)[2]; \ (to)[1] = (from)[1]; \ @@ -64,6 +45,12 @@ static void mga_null_points( GLcontext *ctx, GLuint first, GLuint last ) (to)[3] = (from)[3]; \ } +#define MGA_COLOR3(to, from) { \ + (to)[0] = (from)[2]; \ + (to)[1] = (from)[1]; \ + (to)[2] = (from)[0]; \ +} + static triangle_func tri_tab[0x10]; @@ -106,9 +93,6 @@ static points_func points_tab[0x10]; void mgaDDTrifuncInit() { - int i; - - init(); init_flat(); init_offset(); @@ -117,14 +101,6 @@ void mgaDDTrifuncInit() init_twoside_flat(); init_twoside_offset(); init_twoside_offset_flat(); - - for (i = 0 ; i < 0x20 ; i++) - if (i & MGA_NODRAW_BIT) { - quad_tab[i] = mga_null_quad; - tri_tab[i] = mga_null_triangle; - line_tab[i] = mga_null_line; - points_tab[i] = mga_null_points; - } } @@ -134,7 +110,7 @@ void mgaDDTrifuncInit() #define LINE_FALLBACK (ALL_FALLBACK | DD_LINE_SMOOTH | DD_LINE_STIPPLE) #define TRI_FALLBACK (ALL_FALLBACK | DD_TRI_SMOOTH | DD_TRI_UNFILLED) #define ANY_FALLBACK (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK|DD_TRI_STIPPLE) -#define ANY_RASTER_FLAGS (DD_FLATSHADE|DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET|DD_Z_NEVER) +#define ANY_RASTER_FLAGS (DD_FLATSHADE|DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET) /* Setup the Point, Line, Triangle and Quad functions based on the current rendering state. Wherever possible, use the hardware to @@ -147,6 +123,9 @@ void mgaDDChooseRenderState(GLcontext *ctx) if (mmesa->Fallback) { mmesa->renderindex = MGA_FALLBACK_BIT; + if (flags & DD_TRI_LIGHT_TWOSIDE) { + mmesa->IndirectTriangles = DD_TRI_LIGHT_TWOSIDE; + } return; } @@ -154,7 +133,6 @@ void mgaDDChooseRenderState(GLcontext *ctx) if (flags & DD_FLATSHADE) index |= MGA_FLAT_BIT; if (flags & DD_TRI_LIGHT_TWOSIDE) index |= MGA_TWOSIDE_BIT; if (flags & DD_TRI_OFFSET) index |= MGA_OFFSET_BIT; - if (flags & DD_Z_NEVER) index |= MGA_NODRAW_BIT; } mmesa->PointsFunc = points_tab[index]; @@ -194,6 +172,9 @@ void mgaDDChooseRenderState(GLcontext *ctx) mmesa->QuadFunc = 0; mmesa->IndirectTriangles |= (DD_TRI_SW_RASTERIZE | DD_QUAD_SW_RASTERIZE); + if (flags & DD_TRI_LIGHT_TWOSIDE) { + mmesa->IndirectTriangles |= DD_TRI_LIGHT_TWOSIDE; + } } } } diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatris.h b/xc/lib/GL/mesa/src/drv/mga/mgatris.h index f50c83974..9880bbdf1 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgatris.h +++ b/xc/lib/GL/mesa/src/drv/mga/mgatris.h @@ -38,8 +38,7 @@ extern void mgaDDTrifuncInit( void ); #define MGA_FLAT_BIT 0x1 #define MGA_OFFSET_BIT 0x2 #define MGA_TWOSIDE_BIT 0x4 -#define MGA_NODRAW_BIT 0x8 -#define MGA_FALLBACK_BIT 0x10 +#define MGA_FALLBACK_BIT 0x8 static __inline void mga_draw_triangle( mgaContextPtr mmesa, mgaVertex *v0, @@ -90,40 +89,42 @@ static __inline void mga_draw_point( mgaContextPtr mmesa, { GLuint vertsize = mmesa->vertsize; GLuint *wv = mgaAllocVertexDwords( mmesa, 6*vertsize); - int j; + GLuint j; + const GLfloat x = tmp->v.x + 0.125; + const GLfloat y = tmp->v.y - 0.125; - *(float *)&wv[0] = tmp->v.x - sz; - *(float *)&wv[1] = tmp->v.y - sz; + *(float *)&wv[0] = x - sz; + *(float *)&wv[1] = y - sz; for (j = 2 ; j < vertsize ; j++) wv[j] = tmp->ui[j]; wv += vertsize; - *(float *)&wv[0] = tmp->v.x + sz; - *(float *)&wv[1] = tmp->v.y - sz; + *(float *)&wv[0] = x + sz; + *(float *)&wv[1] = y - sz; for (j = 2 ; j < vertsize ; j++) wv[j] = tmp->ui[j]; wv += vertsize; - *(float *)&wv[0] = tmp->v.x + sz; - *(float *)&wv[1] = tmp->v.y + sz; + *(float *)&wv[0] = x + sz; + *(float *)&wv[1] = y + sz; for (j = 2 ; j < vertsize ; j++) wv[j] = tmp->ui[j]; wv += vertsize; - *(float *)&wv[0] = tmp->v.x + sz; - *(float *)&wv[1] = tmp->v.y + sz; + *(float *)&wv[0] = x + sz; + *(float *)&wv[1] = y + sz; for (j = 2 ; j < vertsize ; j++) wv[j] = tmp->ui[j]; wv += vertsize; - *(float *)&wv[0] = tmp->v.x - sz; - *(float *)&wv[1] = tmp->v.y + sz; + *(float *)&wv[0] = x - sz; + *(float *)&wv[1] = y + sz; for (j = 2 ; j < vertsize ; j++) wv[j] = tmp->ui[j]; wv += vertsize; - *(float *)&wv[0] = tmp->v.x - sz; - *(float *)&wv[1] = tmp->v.y - sz; + *(float *)&wv[0] = x - sz; + *(float *)&wv[1] = y - sz; for (j = 2 ; j < vertsize ; j++) wv[j] = tmp->ui[j]; } @@ -134,55 +135,79 @@ static __inline void mga_draw_line( mgaContextPtr mmesa, const mgaVertex *tmp1, float width ) { - GLuint vertsize = mmesa->vertsize; + const GLuint vertsize = mmesa->vertsize; GLuint *wv = mgaAllocVertexDwords( mmesa, 6 * vertsize ); - float dx, dy, ix, iy; - int j; + GLuint j; + GLfloat x0 = tmp0->v.x; + GLfloat y0 = tmp0->v.y; + GLfloat x1 = tmp1->v.x; + GLfloat y1 = tmp1->v.y; + GLfloat dx, dy, ix, iy; + GLfloat hw; + + hw = 0.5F * width; + if (hw > 0.1F && hw < 0.5F) { + hw = 0.5F; + } + /* adjust vertices depending on line direction */ dx = tmp0->v.x - tmp1->v.x; dy = tmp0->v.y - tmp1->v.y; - - ix = width * .5; iy = 0; - - if ((ix<.5) && (ix>0.1)) ix = .5; /* I want to see lines with width - 0.5 also */ - if (dx * dx > dy * dy) { - iy = ix; ix = 0; + /* X-major line */ + ix = 0.0F; + iy = hw; + if (x1 < x0) { + x0 += 0.5F; + x1 += 0.5F; + } + y0 -= 0.5F; + y1 -= 0.5F; + } + else { + /* Y-major line */ + ix = hw; + iy = 0.0F; + if (y1 > y0) { + y0 -= 0.5F; + y1 -= 0.5F; + } + x0 += 0.5F; + x1 += 0.5F; } - - *(float *)&wv[0] = tmp0->v.x - ix; - *(float *)&wv[1] = tmp0->v.y - iy; + + *(float *)&wv[0] = x0 - ix; + *(float *)&wv[1] = y0 - iy; for (j = 2 ; j < vertsize ; j++) wv[j] = tmp0->ui[j]; wv += vertsize; - *(float *)&wv[0] = tmp1->v.x + ix; - *(float *)&wv[1] = tmp1->v.y + iy; + *(float *)&wv[0] = x1 + ix; + *(float *)&wv[1] = y1 + iy; for (j = 2 ; j < vertsize ; j++) wv[j] = tmp1->ui[j]; wv += vertsize; - *(float *)&wv[0] = tmp0->v.x + ix; - *(float *)&wv[1] = tmp0->v.y + iy; + *(float *)&wv[0] = x0 + ix; + *(float *)&wv[1] = y0 + iy; for (j = 2 ; j < vertsize ; j++) wv[j] = tmp0->ui[j]; wv += vertsize; - *(float *)&wv[0] = tmp0->v.x - ix; - *(float *)&wv[1] = tmp0->v.y - iy; + *(float *)&wv[0] = x0 - ix; + *(float *)&wv[1] = y0 - iy; for (j = 2 ; j < vertsize ; j++) wv[j] = tmp0->ui[j]; wv += vertsize; - *(float *)&wv[0] = tmp1->v.x - ix; - *(float *)&wv[1] = tmp1->v.y - iy; + *(float *)&wv[0] = x1 - ix; + *(float *)&wv[1] = y1 - iy; for (j = 2 ; j < vertsize ; j++) wv[j] = tmp1->ui[j]; wv += vertsize; - *(float *)&wv[0] = tmp1->v.x + ix; - *(float *)&wv[1] = tmp1->v.y + iy; + *(float *)&wv[0] = x1 + ix; + *(float *)&wv[1] = y1 + iy; for (j = 2 ; j < vertsize ; j++) wv[j] = tmp1->ui[j]; wv += vertsize; diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatritmp.h b/xc/lib/GL/mesa/src/drv/mga/mgatritmp.h index f578871ce..a041d887d 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgatritmp.h +++ b/xc/lib/GL/mesa/src/drv/mga/mgatritmp.h @@ -16,6 +16,7 @@ static __inline void TAG(triangle)(GLcontext *ctx, #if (IND & (MGA_TWOSIDE_BIT | MGA_FLAT_BIT)) GLuint c[3]; + GLuint s[3]; #endif v[0] = &mgaverts[e0]; @@ -26,6 +27,9 @@ static __inline void TAG(triangle)(GLcontext *ctx, c[0] = v[0]->ui[4]; c[1] = v[1]->ui[4]; c[2] = v[2]->ui[4]; + s[0] = v[0]->ui[5]; + s[1] = v[1]->ui[5]; + s[2] = v[2]->ui[5]; #endif @@ -41,13 +45,19 @@ static __inline void TAG(triangle)(GLcontext *ctx, { GLuint facing = (cc > 0.0) ^ ctx->Polygon.FrontBit; GLubyte (*vbcolor)[4] = VB->Color[facing]->data; + GLubyte (*vbspec)[4] = VB->Spec[facing]; if (IND & MGA_FLAT_BIT) { MGA_COLOR((char *)&v[0]->ui[4], vbcolor[pv]); v[2]->ui[4] = v[1]->ui[4] = v[0]->ui[4]; + MGA_COLOR3((char *)&v[0]->ui[5], vbspec[pv]); + v[2]->ui[5] = v[1]->ui[5] = v[0]->ui[5]; } else { MGA_COLOR((char *)&v[0]->ui[4], vbcolor[e0]); MGA_COLOR((char *)&v[1]->ui[4], vbcolor[e1]); MGA_COLOR((char *)&v[2]->ui[4], vbcolor[e2]); + MGA_COLOR3((char *)&v[0]->ui[5], vbspec[e0]); + MGA_COLOR3((char *)&v[1]->ui[5], vbspec[e1]); + MGA_COLOR3((char *)&v[2]->ui[5], vbspec[e2]); } } #endif @@ -79,9 +89,13 @@ static __inline void TAG(triangle)(GLcontext *ctx, #elif (IND & MGA_FLAT_BIT) { GLuint color = mgaverts[pv].ui[4]; + GLuint spec = mgaverts[pv].ui[5]; v[0]->ui[4] = color; v[1]->ui[4] = color; v[2]->ui[4] = color; + v[0]->ui[5] = spec; + v[1]->ui[5] = spec; + v[2]->ui[5] = spec; } #endif @@ -97,6 +111,9 @@ static __inline void TAG(triangle)(GLcontext *ctx, v[0]->ui[4] = c[0]; v[1]->ui[4] = c[1]; v[2]->ui[4] = c[2]; + v[0]->ui[5] = s[0]; + v[1]->ui[5] = s[1]; + v[2]->ui[5] = s[2]; #endif } @@ -120,25 +137,34 @@ static void TAG(line)( GLcontext *ctx, GLuint v0, GLuint v1, GLuint pv ) float width = ctx->Line.Width; GLfloat z0, z1; GLuint c0, c1; + GLuint s0, s1; mgaVertex *vert0 = &mgaVB[v0]; mgaVertex *vert1 = &mgaVB[v1]; - if (IND & MGA_TWOSIDE_BIT) { GLubyte (*vbcolor)[4] = ctx->VB->ColorPtr->data; + GLubyte (*vbspec)[4] = ctx->VB->Specular; if (IND & MGA_FLAT_BIT) { MGA_COLOR((char *)&vert0->v.color,vbcolor[pv]); *(int *)&vert1->v.color = *(int *)&vert0->v.color; + MGA_COLOR3((char *)&vert0->v.specular, vbspec[pv]); + *(int *)&vert1->v.specular = *(int *)&vert0->v.specular; } else { MGA_COLOR((char *)&vert0->v.color,vbcolor[v0]); MGA_COLOR((char *)&vert1->v.color,vbcolor[v1]); + MGA_COLOR3((char *)&vert0->v.specular, vbspec[v0]); + MGA_COLOR3((char *)&vert1->v.specular, vbspec[v1]); } } else if (IND & MGA_FLAT_BIT) { c0 = *(GLuint *) &(vert0->v.color); c1 = *(GLuint *) &(vert1->v.color); *(int *)&vert0->v.color = *(int *)&vert1->v.color = *(int *)&mgaVB[pv].v.color; + s0 = *(GLuint *) &(vert0->v.specular); + s1 = *(GLuint *) &(vert1->v.specular); + *(int *)&vert0->v.specular = + *(int *)&vert1->v.specular = *(int *)&mgaVB[pv].v.specular; } if (IND & MGA_OFFSET_BIT) { @@ -159,6 +185,8 @@ static void TAG(line)( GLcontext *ctx, GLuint v0, GLuint v1, GLuint pv ) if ((IND & MGA_FLAT_BIT) && !(IND & MGA_TWOSIDE_BIT)) { *(GLuint *) &(vert0->v.color) = c0; *(GLuint *) &(vert1->v.color) = c1; + *(GLuint *) &(vert0->v.specular) = s0; + *(GLuint *) &(vert1->v.specular) = s1; } } diff --git a/xc/lib/GL/mesa/src/drv/mga/mgavb.c b/xc/lib/GL/mesa/src/drv/mga/mgavb.c index ae6316fc8..1dfc89d2b 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgavb.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgavb.c @@ -35,34 +35,34 @@ #include <stdio.h> #include <stdlib.h> -#define TEX0 { \ +#define TEX0 { \ v->v.tu0 = tc0[i][0]; \ v->v.tv0 = tc0[i][1]; \ } -#define TEX1 { \ +#define TEX1 { \ v->v.tu1 = tc1[i][0]; \ v->v.tv1 = tc1[i][1]; \ } -#define SPC { \ - GLubyte *spec = &(VB->Spec[0][i][0]); \ +#define SPC { \ + GLubyte *spec = &(VB->Spec[0][i][0]); \ v->v.specular.red = spec[0]; \ - v->v.specular.green = spec[1]; \ + v->v.specular.green = spec[1]; \ v->v.specular.blue = spec[2]; \ } -#define FOG { \ - GLubyte *spec = &(VB->Spec[0][i][0]); \ - v->v.specular.alpha = spec[3]; \ +#define FOG { \ + GLubyte *spec = &(VB->Spec[0][i][0]); \ + v->v.specular.alpha = spec[3]; \ } #define COL { \ GLubyte *col = &(VB->Color[0]->data[i][0]); \ - v->v.color.blue = col[2]; \ - v->v.color.green = col[1]; \ - v->v.color.red = col[0]; \ - v->v.color.alpha = col[3]; \ + v->v.color.blue = col[2]; \ + v->v.color.green = col[1]; \ + v->v.color.red = col[0]; \ + v->v.color.alpha = col[3]; \ } /* The v code we have doesn't seem to support projective texturing @@ -70,14 +70,13 @@ * second set of texcoords). This may be a problem for the g400. */ #define TEX0_4 \ - if (VB->TexCoordPtr[0]->size == 4) \ - { \ + if (VB->TexCoordPtr[0]->size == 4) { \ GLfloat (*tc)[4] = VB->TexCoordPtr[0]->data; \ v = &(MGA_DRIVER_DATA(VB)->verts[start]); \ mmesa->setupdone &= ~MGA_WIN_BIT; \ - for (i=start; i < end; i++, v++) { \ - float oow = 1.0 / tc[i][3]; \ - v->v.rhw *= tc[i][3]; \ + for (i = start; i < end; i++, v++) { \ + GLfloat oow = 1.0 / tc[i][3]; \ + v->v.rhw *= tc[i][3]; \ v->v.tu0 *= oow; \ v->v.tv0 *= oow; \ } \ @@ -138,7 +137,7 @@ static void name(struct vertex_buffer *VB, GLuint start, GLuint end) \ spec; \ fog; \ } \ - col; \ + col; \ } \ tex0_4; \ } 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 9b2c5b2f1..172e0f62a 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_context.c +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_context.c @@ -163,16 +163,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 d82013338..d80004dd6 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_state.c +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_state.c @@ -511,7 +511,8 @@ static void radeonDDLightModelfv( GLcontext *ctx, GLenum pname, FLUSH_BATCH( rmesa ); - if ( ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR ) { + if ( ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR && + ctx->Light.Enabled && ctx->Texture.ReallyEnabled) { p |= RADEON_SPECULAR_ENABLE; } else { p &= ~RADEON_SPECULAR_ENABLE; @@ -805,6 +806,22 @@ static void radeonDDEnable( GLcontext *ctx, GLenum cap, GLboolean state ) } break; + case GL_LIGHTING: + { + GLuint p = rmesa->setup.pp_cntl; + if ( ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR && + ctx->Light.Enabled && ctx->Texture.ReallyEnabled) { + p |= RADEON_SPECULAR_ENABLE; + } else { + p &= ~RADEON_SPECULAR_ENABLE; + } + if ( rmesa->setup.pp_cntl != p ) { + rmesa->setup.pp_cntl = p; + rmesa->dirty |= RADEON_UPLOAD_CONTEXT; + } + break; + } + case GL_SCISSOR_TEST: FLUSH_BATCH( rmesa ); rmesa->scissor = state; @@ -919,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..a77a7f154 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,701 @@ 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 ) -{ -#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. - */ -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 ) +static GLint radeonChooseTexFormat( radeonContextPtr rmesa, + struct gl_texture_image *texImage, + GLenum format, GLenum type ) { - 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]; - } -} + const GLboolean do32bpt = ( rmesa->radeonScreen->cpp == 4 ); + 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 ) ); -/* ================================================================ - * 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 unit = ctx->Texture.CurrentUnit; + 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, %d )\n", __FUNCTION__, texObj, level ); } - /* 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; + txformat = radeonChooseTexFormat( rmesa, texImage, format, type ); + if ( txformat < 0 ) + return GL_FALSE; - 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 ); - } + texFormat = texImage->TexFormat; + texSize = texImage->Width * texFormat->TexelBytes; - /* Grab the indirect buffer for the texture blit */ - buffer = radeonGetBufferLocked( rmesa ); + /* 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; + } - dst = (CARD32 *)((char *)buffer->address + RADEON_HOSTDATA_BLIT_OFFSET); + data = (GLubyte *) MALLOC( texSize ); + if ( !data ) + return GL_FALSE; - /* 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 ); + if ( !_mesa_convert_texsubimage1d( texFormat->IntFormat, + 0, texImage->Width, + format, type, packing, + pixels, data ) ) { + /*fprintf( stderr, " *** convert failed!\n" );*/ + FREE( data ); + return GL_FALSE; } - rmesa->new_state |= RADEON_NEW_CONTEXT; - rmesa->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_MASKS; -} + t->image[level].data = data; + t->dirty_images |= (1 << level); -/* 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; + /* Format-specific hardware state: + */ + t->pp_txformat &= ~(RADEON_TXFORMAT_FORMAT_MASK | + RADEON_TXFORMAT_ALPHA_IN_MAP); + t->pp_txformat |= txformat; - if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { - fprintf( stderr, "%s( %p, %p )\n", - __FUNCTION__, rmesa->glCtx, t ); + 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; } - 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; + /* If we don't have a texture bound, bind this one. + */ + if ( !rmesa->CurrentTexObj[unit] ) { + rmesa->CurrentTexObj[unit] = t; + t->bound |= unit + 1; } -#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; + 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 unit = ctx->Texture.CurrentUnit; + 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, %d )\n", __FUNCTION__, texObj, level ); } - /* 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; + + 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; } -}; -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: + /* If we don't have a texture bound, bind this one. */ - { - /* 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 ( !rmesa->CurrentTexObj[unit] ) { + rmesa->CurrentTexObj[unit] = t; + t->bound |= unit + 1; } -}; + 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[] = -{ - 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[] = +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_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 -}; + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + radeonTexObjPtr t = (radeonTexObjPtr)texObj->DriverData; + const struct gl_texture_format *texFormat; + GLuint unit = ctx->Texture.CurrentUnit; + GLuint texSize; + GLint txformat; + GLubyte *data; -/* 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 -}; + if ( target != GL_TEXTURE_3D ) + return GL_FALSE; -static GLuint radeon_primary_alpha[] = -{ - RADEON_ALPHA_ARG_A_DIFFUSE_ALPHA, - RADEON_ALPHA_ARG_A_DIFFUSE_ALPHA | RADEON_COMP_ARG_A -}; + if ( t ) { + if ( t->bound ) FLUSH_BATCH( rmesa ); + radeonSwapOutTexObj( rmesa, t ); + } else { + t = radeonAllocTexObj( texObj ); + texObj->DriverData = t; + } -static GLuint radeon_previous_alpha[] = -{ - RADEON_ALPHA_ARG_A_CURRENT_ALPHA, - RADEON_ALPHA_ARG_A_CURRENT_ALPHA | RADEON_COMP_ARG_A -}; + txformat = radeonChooseTexFormat( rmesa, texImage, format, type ); + if ( txformat < 0 ) + return GL_FALSE; + texFormat = texImage->TexFormat; + texSize = (texImage->Width * texImage->Height * + texImage->Depth * texFormat->TexelBytes); -/* 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) + /* 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; -/* ================================================================ - * Texture unit state management - */ + 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; + } -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; + t->image[level].data = data; + t->dirty_images |= (1 << level); - if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { - fprintf( stderr, "%s( %p, %d )\n", - __FUNCTION__, ctx, unit ); + /* If we don't have a texture bound, bind this one. + */ + if ( !rmesa->CurrentTexObj[unit] ) { + rmesa->CurrentTexObj[unit] = t; + t->bound |= unit + 1; } - enabled = (ctx->Texture.ReallyEnabled >> (source * 4)) & TEXTURE0_ANY; - if ( enabled != TEXTURE0_2D && enabled != TEXTURE0_1D ) - return; + rmesa->new_state |= RADEON_NEW_TEXTURE; - /* 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; + *retainInternalCopy = GL_FALSE; + return GL_TRUE; +} - 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; +/* ================================================================ + * Texture subimage callbacks + */ - 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; +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); + radeonTexObjPtr t = (radeonTexObjPtr)texObj->DriverData; + const struct gl_texture_format *texFormat; - 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; + if ( target != GL_TEXTURE_1D ) + return GL_FALSE; - 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; + /* FIXME: Can this ever be NULL??? + */ + ASSERT( t ); - 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_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_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; + 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 ) { - 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; - - if ( ( tObj != ctx->Texture.Unit[source].CurrentD[2] ) && - ( tObj != ctx->Texture.Unit[source].CurrentD[1] ) ) - return; + ASSERT( t ); - 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 +805,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 +821,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,34 +857,51 @@ 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; + if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, __FUNCTION__ "( %p )\n", tObj ); + } + 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 +922,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..13f6d4b59 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_texmem.c @@ -0,0 +1,508 @@ +/* $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. + */ +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/radeon/radeon_tris.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_tris.c index 71ed6910b..e4b6394ee 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_tris.c +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_tris.c @@ -55,6 +55,13 @@ do { \ *(GLuint *)(to) = *(GLuint *)(from); \ } while (0) +#define RADEON_COLOR3( to, from ) \ +do { \ + (to)[0] = (from)[2]; \ + (to)[1] = (from)[1]; \ + (to)[2] = (from)[0]; \ +} while (0) + static void radeon_null_quad( GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3, GLuint pv ) @@ -162,6 +169,10 @@ void radeonDDChooseRenderState( GLcontext *ctx ) if ( rmesa->Fallback ) { rmesa->RenderIndex = RADEON_FALLBACK_BIT; + /* fixes vorder.c failure: */ + if (flags & DD_TRI_LIGHT_TWOSIDE) { + rmesa->IndirectTriangles = DD_TRI_LIGHT_TWOSIDE; + } return; } @@ -200,6 +211,11 @@ void radeonDDChooseRenderState( GLcontext *ctx ) rmesa->IndirectTriangles |= (DD_TRI_SW_RASTERIZE | DD_QUAD_SW_RASTERIZE); } + + /* fixes vorder.c failure: */ + if (flags & DD_TRI_LIGHT_TWOSIDE) { + rmesa->IndirectTriangles |= DD_TRI_LIGHT_TWOSIDE; + } } if ( 0 ) { diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_tritmp.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_tritmp.h index ed5006ea2..a53512a30 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_tritmp.h +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_tritmp.h @@ -247,7 +247,8 @@ static void TAG(line)( GLcontext *ctx, GLfloat z[2]; #endif #if (IND & RADEON_TWOSIDE_BIT) - int c[2]; + GLuint c[2]; + GLuint s[2]; #endif v[0] = &verts[e0]; @@ -256,17 +257,24 @@ static void TAG(line)( GLcontext *ctx, #if (IND & RADEON_TWOSIDE_BIT) c[0] = v[0]->ui[4]; c[1] = v[1]->ui[4]; + s[0] = v[0]->ui[5]; + s[1] = v[1]->ui[5]; #endif #if (IND & RADEON_TWOSIDE_BIT) { GLubyte (*vbcolor)[4] = ctx->VB->ColorPtr->data; + GLubyte (*vbspec)[4] = ctx->VB->Specular; if ( IND & RADEON_FLAT_BIT ) { RADEON_COLOR( (char *)&v[0]->ui[4], vbcolor[pv] ); v[1]->ui[4] = v[0]->ui[4]; + RADEON_COLOR3( (char *)&v[0]->ui[5], vbspec[pv] ); + v[1]->ui[5] = v[0]->ui[5]; } else { RADEON_COLOR( (char *)&v[0]->ui[4], vbcolor[e0] ); RADEON_COLOR( (char *)&v[1]->ui[4], vbcolor[e1] ); + RADEON_COLOR3( (char *)&v[0]->ui[5], vbspec[e0] ); + RADEON_COLOR3( (char *)&v[1]->ui[5], vbspec[e1] ); } } #endif @@ -289,6 +297,8 @@ static void TAG(line)( GLcontext *ctx, #if (IND & RADEON_TWOSIDE_BIT) v[0]->ui[4] = c[0]; v[1]->ui[4] = c[1]; + v[0]->ui[5] = s[0]; + v[1]->ui[5] = s[1]; #endif } @@ -309,7 +319,10 @@ static void TAG(points)( GLcontext *ctx, if ( IND & RADEON_TWOSIDE_BIT ) { GLubyte (*vbcolor)[4] = VB->ColorPtr->data; + GLubyte (*vbspec)[4] = VB->Specular; RADEON_COLOR( (char *)&tmp0.v.color, vbcolor[i] ); + if (vbspec) + RADEON_COLOR3( (char *)&tmp0.v.specular, vbspec[i] ); } if ( IND & RADEON_OFFSET_BIT ) { GLfloat offset = ctx->PointZoffset * rmesa->depth_scale; 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 4cb7efaba..293c42fd7 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 d630184bd..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(tObj) ((tdfxTexObjPtr)((tObj)->DriverData)) -#define TDFX_TEXTURE_DATA(mesaObj) ((tdfxTexInfo *)((mesaObj)->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; @@ -516,6 +513,11 @@ struct tdfx_depth { FxBool Mask; /* Write enable flag */ }; +#ifndef GR_STIPPLE_PATTERN +#error "You MUST upgrade your Glide3 libraries and headers." +#error "Get the latest from http://dri.sourceforge.net/resources.html" +#endif + struct tdfx_stipple { GrStippleMode_t Mode; /* Stipple enable/disable */ FxU32 Pattern; /* 8x4 Stipple Pattern */ @@ -630,6 +632,7 @@ struct tdfx_context { GLuint tmu_source[TDFX_NUM_TMU]; GLuint tex_dest[MAX_TEXTURE_UNITS]; + GLuint numTMUs; GLuint SetupIndex; GLuint SetupDone; @@ -641,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; @@ -652,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; @@ -768,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 a0b4304e4..00935e2de 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 ) { @@ -393,11 +380,12 @@ XMesaMakeCurrent( __DRIcontextPrivate *driContextPriv, GLboolean XMesaOpenFullScreen(__DRIcontextPrivate *driContextPriv) { - fprintf(stderr,"***** XMesaOpenFullScreen *****\n"); + if ( 0 ) + fprintf( stderr, "***** XMesaOpenFullScreen *****\n" ); #if 0 /* When new glide3 calls exist */ - return((GLboolean)grDRISetupFullScreen(GL_TRUE)); + return (GLboolean)grDRISetupFullScreen( GL_TRUE ); #else - return GL_TRUE; + return GL_TRUE; #endif } @@ -405,11 +393,12 @@ XMesaOpenFullScreen(__DRIcontextPrivate *driContextPriv) GLboolean XMesaCloseFullScreen(__DRIcontextPrivate *driContextPriv) { - fprintf(stderr,"***** XMesaCloseFullScreen *****\n"); + if ( 0 ) + fprintf( stderr, "***** XMesaCloseFullScreen *****\n" ); #if 0 /* When new glide3 calls exist */ - return((GLboolean)grDRISetupFullScreen(GL_FALSE)); + return (GLboolean)grDRISetupFullScreen( GL_FALSE ); #else - return GL_TRUE; + return GL_TRUE; #endif } 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/r128_dri.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.h index 5651f0d59..01857a0e3 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.h @@ -45,7 +45,7 @@ /* DRI Driver defaults */ #define R128_DEFAULT_CCE_PIO_MODE R128_PM4_64PIO_64VCBM_64INDBM #define R128_DEFAULT_CCE_BM_MODE R128_PM4_64BM_64VCBM_64INDBM -#define R128_DEFAULT_AGP_MODE 2 +#define R128_DEFAULT_AGP_MODE 1 #define R128_DEFAULT_AGP_SIZE 8 /* MB (must be a power of 2 and > 4MB) */ #define R128_DEFAULT_RING_SIZE 1 /* MB (must be page aligned) */ #define R128_DEFAULT_BUFFER_SIZE 2 /* MB (must be page aligned) */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.h index 11e8a3e09..bfbc07b40 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.h @@ -43,7 +43,7 @@ /* DRI Driver defaults */ #define RADEON_DEFAULT_CP_PIO_MODE RADEON_CSQ_PRIPIO_INDPIO #define RADEON_DEFAULT_CP_BM_MODE RADEON_CSQ_PRIBM_INDBM -#define RADEON_DEFAULT_AGP_MODE 2 +#define RADEON_DEFAULT_AGP_MODE 1 #define RADEON_DEFAULT_AGP_SIZE 8 /* MB (must be a power of 2 and > 4MB) */ #define RADEON_DEFAULT_RING_SIZE 1 /* MB (must be page aligned) */ #define RADEON_DEFAULT_BUFFER_SIZE 2 /* MB (must be page aligned) */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dripriv.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dripriv.h index 852027c17..ffbd869c5 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dripriv.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dripriv.h @@ -52,8 +52,13 @@ typedef struct { } RADEONConfigPrivRec, *RADEONConfigPrivPtr; typedef struct { +#ifdef PER_CONTEXT_SAREA drmContext ctx_id; drmHandle sarea_handle; +#else + /* Nothing here yet */ + int dummy; +#endif } RADEONDRIContextRec, *RADEONDRIContextPtr; #endif 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/drivers/mga/mga_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c index cb17e0533..3b34acf08 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c @@ -251,7 +251,7 @@ static Bool MGAInitVisualConfigs( ScreenPtr pScreen ) pConfigs[i].redSize = 8; pConfigs[i].greenSize = 8; pConfigs[i].blueSize = 8; - pConfigs[i].alphaSize = 0; + pConfigs[i].alphaSize = 8; pConfigs[i].redMask = 0x00FF0000; pConfigs[i].greenMask = 0x0000FF00; pConfigs[i].blueMask = 0x000000FF; @@ -736,6 +736,8 @@ static Bool MGADRIAgpInit(ScreenPtr pScreen) "[drm] Added %d %d byte DMA buffers\n", count, MGA_BUFFER_SIZE ); + xf86EnableBusMaster( pMga->PciTag ); + return TRUE; } @@ -845,8 +847,7 @@ static Bool MGADRIKernelInit( ScreenPtr pScreen ) /* FIXME: This is just here to clean up after the engine reset test * in the kernel module. Please remove it later... */ - pMga->haveQuiescense = 0; - CHECK_DMA_QUIESCENT( pMGA, pScrn ); + pMga->GetQuiescence( pScrn ); #endif return TRUE; diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.h b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.h index ab39b1701..56069492f 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.h @@ -34,7 +34,7 @@ #include <xf86drm.h> #include <xf86drmMga.h> -#define MGA_DEFAULT_AGP_MODE 2 +#define MGA_DEFAULT_AGP_MODE 1 #define MGA_MAX_AGP_MODE 4 /* Buffer are aligned on 4096 byte boundaries. @@ -61,7 +61,7 @@ typedef struct { unsigned int depthPitch; unsigned int textureOffset; - unsigned int textureSize; + int textureSize; drmRegion agp; diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dri.c index c70cb35e5..5d160998d 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dri.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dri.c @@ -16,20 +16,20 @@ static char TDFXKernelDriverName[] = "tdfx"; static char TDFXClientDriverName[] = "tdfx"; -static Bool TDFXCreateContext(ScreenPtr pScreen, VisualPtr visual, +static Bool TDFXCreateContext(ScreenPtr pScreen, VisualPtr visual, drmContext hwContext, void *pVisualConfigPriv, DRIContextType contextStore); static void TDFXDestroyContext(ScreenPtr pScreen, drmContext hwContext, DRIContextType contextStore); -static void TDFXDRISwapContext(ScreenPtr pScreen, DRISyncType syncType, - DRIContextType readContextType, +static void TDFXDRISwapContext(ScreenPtr pScreen, DRISyncType syncType, + DRIContextType readContextType, void *readContextStore, - DRIContextType writeContextType, + DRIContextType writeContextType, void *writeContextStore); static Bool TDFXDRIOpenFullScreen(ScreenPtr pScreen); static Bool TDFXDRICloseFullScreen(ScreenPtr pScreen); static void TDFXDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index); -static void TDFXDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, +static void TDFXDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, RegionPtr prgnSrc, CARD32 index); static void TDFXDRITransitionTo2d(ScreenPtr pScreen); static void TDFXDRITransitionTo3d(ScreenPtr pScreen); @@ -65,7 +65,7 @@ TDFXInitVisualConfigs(ScreenPtr pScreen) xfree(pTDFXConfigs); return FALSE; } - for (i=0; i<numConfigs; i++) + for (i=0; i<numConfigs; i++) pTDFXConfigPtrs[i] = &pTDFXConfigs[i]; i=0; @@ -104,7 +104,7 @@ TDFXInitVisualConfigs(ScreenPtr pScreen) if (depth) { if (pTDFX->cpp>2) pConfigs[i].depthSize = 24; - else + else pConfigs[i].depthSize = 16; } else { pConfigs[i].depthSize = 0; @@ -158,7 +158,7 @@ TDFXInitVisualConfigs(ScreenPtr pScreen) return FALSE; } - for (i = 0; i < numConfigs; i++) + for (i = 0; i < numConfigs; i++) pTDFXConfigPtrs[i] = &pTDFXConfigs[i]; i=0; @@ -199,7 +199,7 @@ TDFXInitVisualConfigs(ScreenPtr pScreen) if (depth) { if (pTDFX->cpp > 2) pConfigs[i].depthSize = 24; - else + else pConfigs[i].depthSize = 16; } else { pConfigs[i].depthSize = 0; @@ -249,7 +249,7 @@ TDFXDoWakeupHandler(int screenNum, pointer wakeupData, unsigned long result, TDFXNeedSync(pScrn); } -static void +static void TDFXDoBlockHandler(int screenNum, pointer blockData, pointer pTimeout, pointer pReadmask) { @@ -343,10 +343,10 @@ Bool TDFXDRIScreenInit(ScreenPtr pScreen) pDRIInfo->maxDrawableTableEntry = TDFX_MAX_DRAWABLES; #ifdef NOT_DONE - /* FIXME need to extend DRI protocol to pass this size back to client + /* FIXME need to extend DRI protocol to pass this size back to client * for SAREA mapping that includes a device private record */ - pDRIInfo->SAREASize = + pDRIInfo->SAREASize = ((sizeof(XF86DRISAREARec) + 0xfff) & 0x1000); /* round to page */ /* + shared memory device private rec */ #else @@ -415,7 +415,7 @@ Bool TDFXDRIScreenInit(ScreenPtr pScreen) } pTDFXDRI->regsSize=TDFXIOMAPSIZE; - if (drmAddMap(pTDFX->drmSubFD, (drmHandle)pTDFX->MMIOAddr[0], + if (drmAddMap(pTDFX->drmSubFD, (drmHandle)pTDFX->MMIOAddr[0], pTDFXDRI->regsSize, DRM_REGISTERS, 0, &pTDFXDRI->regs)<0) { TDFXDRICloseScreen(pScreen); xf86DrvMsg(pScreen->myNum, X_ERROR, "drmAddMap failed, disabling DRI.\n"); @@ -455,7 +455,7 @@ TDFXDRICloseScreen(ScreenPtr pScreen) } static Bool -TDFXCreateContext(ScreenPtr pScreen, VisualPtr visual, +TDFXCreateContext(ScreenPtr pScreen, VisualPtr visual, drmContext hwContext, void *pVisualConfigPriv, DRIContextType contextStore) { @@ -463,7 +463,7 @@ TDFXCreateContext(ScreenPtr pScreen, VisualPtr visual, } static void -TDFXDestroyContext(ScreenPtr pScreen, drmContext hwContext, +TDFXDestroyContext(ScreenPtr pScreen, drmContext hwContext, DRIContextType contextStore) { } @@ -496,7 +496,7 @@ TDFXDRIFinishScreenInit(ScreenPtr pScreen) } static void -TDFXDRISwapContext(ScreenPtr pScreen, DRISyncType syncType, +TDFXDRISwapContext(ScreenPtr pScreen, DRISyncType syncType, DRIContextType oldContextType, void *oldContext, DRIContextType newContextType, void *newContext) { @@ -518,10 +518,10 @@ TDFXDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index) TDFXSetupForSolidFill(pScrn, 0, GXcopy, -1); while (nbox--) { TDFXSelectBuffer(pTDFX, TDFX_BACK); - TDFXSubsequentSolidFillRect(pScrn, pbox->x1, pbox->y1, + TDFXSubsequentSolidFillRect(pScrn, pbox->x1, pbox->y1, pbox->x2-pbox->x1, pbox->y2-pbox->y1); TDFXSelectBuffer(pTDFX, TDFX_DEPTH); - TDFXSubsequentSolidFillRect(pScrn, pbox->x1, pbox->y1, + TDFXSubsequentSolidFillRect(pScrn, pbox->x1, pbox->y1, pbox->x2-pbox->x1, pbox->y2-pbox->y1); pbox++; } @@ -537,7 +537,7 @@ TDFXDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index) are reversed. */ static void -TDFXDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, +TDFXDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, RegionPtr prgnSrc, CARD32 index) { ScreenPtr pScreen = pParent->drawable.pScreen; @@ -684,11 +684,11 @@ TDFXDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, static Bool TDFXDRIOpenFullScreen(ScreenPtr pScreen) { +#if 0 ScrnInfoPtr pScrn; TDFXPtr pTDFX; xf86DrvMsg(pScreen->myNum, X_INFO, "OpenFullScreen\n"); -#if 0 pScrn = xf86Screens[pScreen->myNum]; pTDFX=TDFXPTR(pScrn); if (pTDFX->numChips>1) { @@ -701,10 +701,10 @@ TDFXDRIOpenFullScreen(ScreenPtr pScreen) static Bool TDFXDRICloseFullScreen(ScreenPtr pScreen) { +#if 0 ScrnInfoPtr pScrn; xf86DrvMsg(pScreen->myNum, X_INFO, "CloseFullScreen\n"); -#if 0 pScrn = xf86Screens[pScreen->myNum]; TDFXDisableSLI(pScrn); #endif @@ -718,7 +718,7 @@ TDFXDRITransitionTo2d(ScreenPtr pScreen) ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; TDFXPtr pTDFX = TDFXPTR(pScrn); - xf86FreeOffscreenArea(pTDFX->reservedArea); + xf86FreeOffscreenArea(pTDFX->reservedArea); } @@ -740,7 +740,7 @@ TDFXDRITransitionTo3d(ScreenPtr pScreen) } xf86PurgeUnlockedOffscreenAreas(pScreen); - + /* this is an ugly hack! isnt there a resize? */ pArea = xf86AllocateOffscreenArea(pScreen, pScrn->displayWidth, pTDFX->pixmapCacheLinesMin, diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.linux b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.linux index 26eed9a5f..d022557d8 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.linux +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.linux @@ -47,38 +47,34 @@ # **** End of SMP/MODVERSIONS detection -#MODS= gamma.o tdfx.o -MODS= tdfx.o -LIBS= +MODS = gamma.o tdfx.o +LIBS = -#DRMOBJS= init.o memory.o proc.o auth.o context.o drawable.o bufs.o \ -# lists.o lock.o ioctl.o fops.o vm.o dma.o ctxbitmap.o -DRMOBS= -DRMTEMPLATES= drm_init.h drm_memory.h drm_proc.h drm_auth.h drm_context.h \ - drm_drawable.h drm_bufs.h drm_lists.h drm_lock.h drm_ioctl.h \ - drm_fops.h drm_vm.h drm_dma.h drm_stub.h -DRMHEADERS= drm.h drmP.h compat-pre24.h +DRMTEMPLATES = drm_auth.h drm_bufs.h drm_context.h drm_dma.h drm_drawable.h \ + drm_drv.h drm_fops.h drm_init.h drm_ioctl.h drm_lists.h \ + drm_lock.h drm_memory.h drm_proc.h drm_stub.h drm_vm.h +DRMHEADERS = drm.h drmP.h compat-pre24.h -#GAMMAOBJS= gamma_drv.o gamma_drm.o gamma_dma.o gamma_context.o -#GAMMAHEADERS= gamma_drv.h $(DRMHEADERS) $(DRMTEMPLATES) +GAMMAOBJS = gamma_drv.o gamma_dma.o +GAMMAHEADERS = gamma_drv.h $(DRMHEADERS) $(DRMTEMPLATES) -TDFXOBJS= tdfx_drv.o -TDFXHEADERS= tdfx.h $(DRMHEADERS) +TDFXOBJS = tdfx_drv.o +TDFXHEADERS = tdfx.h $(DRMHEADERS) -INC= /usr/include +INC = /usr/include -CFLAGS= -O2 $(WARNINGS) -WARNINGS= -Wall -Wwrite-strings -Wpointer-arith -Wcast-align \ +CFLAGS = -O2 $(WARNINGS) +WARNINGS = -Wall -Wwrite-strings -Wpointer-arith -Wcast-align \ -Wstrict-prototypes -Wnested-externs \ -Wpointer-arith # -Wshadow -Winline -- make output too noisy -MODCFLAGS= $(CFLAGS) -D__KERNEL__ -DMODULE -fomit-frame-pointer -PRGCFLAGS= $(CFLAGS) -g -ansi -pedantic -DPOSIX_C_SOURCE=199309L \ +MODCFLAGS = $(CFLAGS) -D__KERNEL__ -DMODULE -fomit-frame-pointer +PRGCFLAGS = $(CFLAGS) -g -ansi -pedantic -DPOSIX_C_SOURCE=199309L \ -D_POSIX_SOURCE -D_XOPEN_SOURCE -D_BSD_SOURCE -D_SVID_SOURCE \ -I../../../../../../include -I../../../../../../../../include \ -I../../../../../../../../programs/Xserver/hw/xfree86/common \ -I. -I../../.. -I../../../../../../../../lib/X11 -PRGLIBS= +PRGLIBS = # **** Start of SMP/MODVERSIONS detection @@ -134,7 +130,8 @@ endif ifeq ($(AGP),1) MODCFLAGS += -DCONFIG_AGP -DCONFIG_AGP_MODULE -#DRMOBJS += agpsupport.o +DRMTEMPLATES += drm_agpsupport.h +DRMHEADERS += agpsupport-pre24.h MODS += mga.o r128.o radeon.o ifeq ($(MACHINE),i386) MODS += i810.o @@ -144,17 +141,17 @@ MODS += i810.o endif -MGAOBJS= mga_drv.o mga_dma.o mga_state.o mga_warp.o -MGAHEADERS= mga.h mga_drv.h $(DRMHEADERS) $(DRMTEMPLATES) +MGAOBJS = mga_drv.o mga_dma.o mga_state.o mga_warp.o +MGAHEADERS = mga.h mga_drv.h mga_drm.h $(DRMHEADERS) $(DRMTEMPLATES) -I810OBJS= i810_drv.o i810_dma.o -I810HEADERS= i810.h i810_drv.h $(DRMHEADERS) $(DRMTEMPLATES) +I810OBJS = i810_drv.o i810_dma.o +I810HEADERS = i810.h i810_drv.h i810_drm.h $(DRMHEADERS) $(DRMTEMPLATES) -R128OBJS= r128_drv.o r128_cce.o r128_state.o -R128HEADERS= r128.h r128_drv.h r128_drm.h $(DRMHEADERS) $(DRMTEMPLATES) +R128OBJS = r128_drv.o r128_cce.o r128_state.o +R128HEADERS = r128.h r128_drv.h r128_drm.h $(DRMHEADERS) $(DRMTEMPLATES) -RADEONOBJS= radeon_drv.o radeon_cp.o radeon_state.o -RADEONHEADERS= radeon.h radeon_drv.h radeon_drm.h $(DRMHEADERS) \ +RADEONOBJS = radeon_drv.o radeon_cp.o radeon_state.o +RADEONHEADERS = radeon.h radeon_drv.h radeon_drm.h $(DRMHEADERS) \ $(DRMTEMPLATES) endif @@ -177,7 +174,7 @@ all::;@echo === SMP=${SMP} MODULES=${MODULES} MODVERSIONS=${MODVERSIONS} AGP=${A all::;@echo === kill_fasync has $(PARAMS) parameters all::;@echo === Compiling for machine $(MACHINE) all::;@echo === WARNING -all::;@echo === WARNING 2.4.0 kernels before test11 DONT WORK +all::;@echo === WARNING 2.4.0 kernels before 2.4.0-test11 DO NOT WORK all::;@echo === WARNING ifeq ($(MODULES),0) @@ -205,17 +202,13 @@ endif # **** End of configuration -libdrm.a: $(DRMOBJS) - -$(RM) -f $@ - $(AR) rcs $@ $(DRMOBJS) - dristat: dristat.c $(CC) $(PRGCFLAGS) $< -o $@ -#gamma_drv.o: gamma_drv.c -# $(CC) $(MODCFLAGS) -DEXPORT_SYMTAB -I$(TREE) -c $< -o $@ -#gamma.o: $(GAMMAOBJS) -# $(LD) -r $^ -o $@ +gamma_drv.o: gamma_drv.c + $(CC) $(MODCFLAGS) -DEXPORT_SYMTAB -I$(TREE) -c $< -o $@ +gamma.o: $(GAMMAOBJS) + $(LD) -r $^ -o $@ tdfx_drv.o: tdfx_drv.c $(CC) $(MODCFLAGS) -DEXPORT_SYMTAB -I$(TREE) -c $< -o $@ @@ -260,8 +253,7 @@ ChangeLog: %.o: %.c $(CC) $(MODCFLAGS) -I$(TREE) -c $< -o $@ -$(DRMOBJS): $(DRMHEADERS) -#$(GAMMAOBJS): $(GAMMAHEADERS) +$(GAMMAOBJS): $(GAMMAHEADERS) $(TDFXOBJS): $(TDFXHEADERS) ifeq ($(AGP),1) $(MGAOBJS): $(MGAHEADERS) diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/compat-pre24.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/compat-pre24.h index f6dae008d..0ad96b12a 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/compat-pre24.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/compat-pre24.h @@ -45,6 +45,7 @@ /* This is a hack that only works for this code base -- because we always call this with dev->tq.* */ +#undef INIT_LIST_HEAD #define INIT_LIST_HEAD(pointer) dev->tq.next = NULL #endif diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/dristat.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/dristat.c index f429efd3f..47193ab46 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/dristat.c +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/dristat.c @@ -35,28 +35,11 @@ #include "../xf86drmHash.c" #include "../xf86drm.c" -#define DRM_DIR_NAME "/dev/dri" -#define DRM_DEV_NAME "%s/card%d" - #define DRM_VERSION 0x00000001 #define DRM_MEMORY 0x00000002 #define DRM_CLIENTS 0x00000004 #define DRM_STATS 0x00000008 - -typedef struct drmStatsS { - unsigned long count; - struct { - unsigned long value; - const char *long_format; - const char *long_name; - const char *rate_format; - const char *rate_name; - int isvalue; - const char *mult_names; - int mult; - int verbose; - } data[15]; -} drmStatsT; +#define DRM_BUSID 0x00000010 static void getversion(int fd) { @@ -78,6 +61,15 @@ static void getversion(int fd) } } +static void getbusid(int fd) +{ + const char *busid = drmGetBusid(fd); + + printf(" Busid: %s\n", *busid ? busid : "(not set)"); + drmFreeBusid(busid); +} + +#if 0 typedef struct { unsigned long offset; /* Requested physical address (0 for SAREA)*/ unsigned long size; /* Requested physical size (bytes) */ @@ -88,160 +80,7 @@ typedef struct { int mtrr; /* MTRR slot used */ /* Private data */ } drmVmRec, *drmVmPtr; - -int drmGetMap(int fd, int idx, drmHandle *offset, drmSize *size, - drmMapType *type, drmMapFlags *flags, drmHandle *handle, - int *mtrr) -{ - drm_map_t map; - - map.offset = idx; - if (ioctl(fd, DRM_IOCTL_GET_MAP, &map)) return -errno; - *offset = map.offset; - *size = map.size; - *type = map.type; - *flags = map.flags; - *handle = (unsigned long)map.handle; - *mtrr = map.mtrr; - return 0; -} - -int drmGetClient(int fd, int idx, int *auth, int *pid, int *uid, - unsigned long *magic, unsigned long *iocs) -{ - drm_client_t client; - - client.idx = idx; - if (ioctl(fd, DRM_IOCTL_GET_CLIENT, &client)) return -errno; - *auth = client.auth; - *pid = client.pid; - *uid = client.uid; - *magic = client.magic; - *iocs = client.iocs; - return 0; -} - -int drmGetStats(int fd, drmStatsT *stats) -{ - drm_stats_t s; - int i; - - if (ioctl(fd, DRM_IOCTL_GET_STATS, &s)) return -errno; - - stats->count = 0; - memset(stats, 0, sizeof(*stats)); - if (s.count > sizeof(stats->data)/sizeof(stats->data[0])) - return -1; - -#define SET_VALUE \ - stats->data[i].long_format = "%-20.20s"; \ - stats->data[i].rate_format = "%8.8s"; \ - stats->data[i].isvalue = 1; \ - stats->data[i].verbose = 0 - -#define SET_COUNT \ - stats->data[i].long_format = "%-20.20s"; \ - stats->data[i].rate_format = "%5.5s"; \ - stats->data[i].isvalue = 0; \ - stats->data[i].mult_names = "kgm"; \ - stats->data[i].mult = 1000; \ - stats->data[i].verbose = 0 - -#define SET_BYTE \ - stats->data[i].long_format = "%-9.9s"; \ - stats->data[i].rate_format = "%5.5s"; \ - stats->data[i].isvalue = 0; \ - stats->data[i].mult_names = "KGM"; \ - stats->data[i].mult = 1024; \ - stats->data[i].verbose = 0 - - - stats->count = s.count; - for (i = 0; i < s.count; i++) { - stats->data[i].value = s.data[i].value; - switch (s.data[i].type) { - case _DRM_STAT_LOCK: - stats->data[i].long_name = "Lock"; - stats->data[i].rate_name = "Lock"; - SET_VALUE; - break; - case _DRM_STAT_OPENS: - stats->data[i].long_name = "Opens"; - stats->data[i].rate_name = "O"; - SET_COUNT; - stats->data[i].verbose = 1; - break; - case _DRM_STAT_CLOSES: - stats->data[i].long_name = "Closes"; - stats->data[i].rate_name = "Lock"; - SET_COUNT; - stats->data[i].verbose = 1; - break; - case _DRM_STAT_IOCTLS: - stats->data[i].long_name = "Ioctls"; - stats->data[i].rate_name = "Ioc/s"; - SET_COUNT; - break; - case _DRM_STAT_LOCKS: - stats->data[i].long_name = "Locks"; - stats->data[i].rate_name = "Lck/s"; - SET_COUNT; - break; - case _DRM_STAT_UNLOCKS: - stats->data[i].long_name = "Unlocks"; - stats->data[i].rate_name = "Unl/s"; - SET_COUNT; - break; - case _DRM_STAT_IRQ: - stats->data[i].long_name = "IRQs"; - stats->data[i].rate_name = "IRQ/s"; - SET_COUNT; - break; - case _DRM_STAT_PRIMARY: - stats->data[i].long_name = "Primary Bytes"; - stats->data[i].rate_name = "PB/s"; - SET_BYTE; - break; - case _DRM_STAT_SECONDARY: - stats->data[i].long_name = "Secondary Bytes"; - stats->data[i].rate_name = "SB/s"; - SET_BYTE; - break; - case _DRM_STAT_DMA: - stats->data[i].long_name = "DMA"; - stats->data[i].rate_name = "DMA/s"; - SET_COUNT; - break; - case _DRM_STAT_SPECIAL: - stats->data[i].long_name = "Special DMA"; - stats->data[i].rate_name = "dma/s"; - SET_COUNT; - break; - case _DRM_STAT_MISSED: - stats->data[i].long_name = "Miss"; - stats->data[i].rate_name = "Ms/s"; - SET_COUNT; - break; - case _DRM_STAT_VALUE: - stats->data[i].long_name = "Value"; - stats->data[i].rate_name = "Value"; - SET_VALUE; - break; - case _DRM_STAT_BYTE: - stats->data[i].long_name = "Bytes"; - stats->data[i].rate_name = "B/s"; - SET_BYTE; - break; - case _DRM_STAT_COUNT: - default: - stats->data[i].long_name = "Count"; - stats->data[i].rate_name = "Cnt/s"; - SET_COUNT; - break; - } - } - return 0; -} +#endif static void getvm(int fd) { @@ -255,7 +94,7 @@ static void getvm(int fd) drmHandle handle; int mtrr; - printf(" VM map information:\n"); + printf(" VM map information (Restricted locked kernel WC Lock):\n"); printf(" slot offset size type flags address mtrr\n"); for (i = 0; @@ -298,7 +137,7 @@ static void getclients(int fd) int procfd; printf(" DRI client information:\n"); - printf(" a pid uid magic ioctls prog\n"); + printf(" a pid uid magic ioctls prog\n"); for (i = 0; !drmGetClient(fd, i, &auth, &pid, &uid, &magic, &iocs); i++) { sprintf(buf, "/proc/%d/cmdline", pid); @@ -307,12 +146,16 @@ static void getclients(int fd) read(procfd, cmd, sizeof(cmd)-1); close(procfd); } - if (*cmd) + if (*cmd) { + char *pt; + + for (pt = cmd; *pt; pt++) if (!isprint(*pt)) *pt = ' '; printf(" %c %5d %5d %10lu %10lu %s\n", auth ? 'y' : 'n', pid, uid, magic, iocs, cmd); - else + } else { printf(" %c %5d %5d %10lu %10lu\n", auth ? 'y' : 'n', pid, uid, magic, iocs); + } } } @@ -394,44 +237,6 @@ static void getstats(int fd, int i) } -static int drmOpenMinor(int minor, uid_t user, gid_t group, - mode_t dirmode, mode_t devmode, int force) -{ - struct stat st; - char buf[64]; - long dev = makedev(DRM_MAJOR, minor); - int setdir = 0; - int setdev = 0; - int fd; - - if (stat(DRM_DIR_NAME, &st) || !S_ISDIR(st.st_mode)) { - remove(DRM_DIR_NAME); - mkdir(DRM_DIR_NAME, dirmode); - ++setdir; - } - - if (force || setdir) { - chown(DRM_DIR_NAME, user, group); - chmod(DRM_DIR_NAME, dirmode); - } - - sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, minor); - if (stat(buf, &st) || st.st_rdev != dev) { - remove(buf); - mknod(buf, S_IFCHR, dev); - ++setdev; - } - - if (force || setdev) { - chown(buf, user, group); - chmod(buf, devmode); - } - - if ((fd = open(buf, O_RDWR, 0)) >= 0) return fd; - if (setdev) remove(buf); - return -errno; -} - int main(int argc, char **argv) { int c; @@ -442,13 +247,14 @@ int main(int argc, char **argv) char buf[64]; int i; - while ((c = getopt(argc, argv, "avmcsM:i:")) != EOF) + while ((c = getopt(argc, argv, "avmcsbM:i:")) != EOF) switch (c) { case 'a': mask = ~0; break; case 'v': mask |= DRM_VERSION; break; case 'm': mask |= DRM_MEMORY; break; case 'c': mask |= DRM_CLIENTS; break; case 's': mask |= DRM_STATS; break; + case 'b': mask |= DRM_BUSID; break; case 'i': interval = strtol(optarg, NULL, 0); break; case 'M': minor = strtol(optarg, NULL, 0); break; default: @@ -458,9 +264,10 @@ int main(int argc, char **argv) for (i = 0; i < 16; i++) if (!minor || i == minor) { sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, i); - fd = drmOpenMinor(i, 0, 0, 0700, 0600, 0); + fd = drmOpenMinor(i, 1); if (fd >= 0) { printf("%s\n", buf); + if (mask & DRM_BUSID) getbusid(fd); if (mask & DRM_VERSION) getversion(fd); if (mask & DRM_MEMORY) getvm(fd); if (mask & DRM_CLIENTS) getclients(fd); 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 7c65f5fc3..ddabc2771 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 @@ -44,11 +44,8 @@ #define DRM_IOCTL_NR(n) ((n) & 0xff) #endif -#define DRM_DEV_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) -#define DRM_DEV_UID 0 -#define DRM_DEV_GID 0 - #define DRM_MAJOR 226 +#define DRM_MAX_MINOR 15 #define DRM_NAME "drm" /* Name in kernel, /dev, and /proc */ #define DRM_MIN_ORDER 5 /* At least 2^5 bytes = 32 bytes */ #define DRM_MAX_ORDER 22 /* Up to 2^22 bytes = 4MB */ @@ -453,7 +450,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/drmP.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h index 804df4095..a7e4d5732 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h @@ -84,15 +84,24 @@ #ifndef __HAVE_MTRR #define __HAVE_MTRR 0 #endif +#ifndef __HAVE_CTX_BITMAP +#define __HAVE_CTX_BITMAP 0 +#endif #ifndef __HAVE_DMA #define __HAVE_DMA 0 #endif +#ifndef __HAVE_DMA_IRQ +#define __HAVE_DMA_IRQ 0 +#endif #ifndef __HAVE_DMA_WAITLIST #define __HAVE_DMA_WAITLIST 0 #endif #ifndef __HAVE_DMA_FREELIST #define __HAVE_DMA_FREELIST 0 #endif +#ifndef __HAVE_DMA_HISTOGRAM +#define __HAVE_DMA_HISTOGRAM 0 +#endif #define __REALLY_HAVE_AGP (__HAVE_AGP && (defined(CONFIG_AGP) || \ defined(CONFIG_AGP_MODULE))) @@ -104,7 +113,6 @@ #define DRM_DEBUG_CODE 2 /* Include debugging code (if > 1, then also include looping detection. */ -#define DRM_DMA_HISTOGRAM 1 /* Make histogram of DMA latency. */ #define DRM_HASH_SIZE 16 /* Size of key hash table */ #define DRM_KERNEL_CONTEXT 0 /* Change drm_resctx if changed */ @@ -643,7 +651,7 @@ typedef struct drm_device { struct tq_struct tq; cycles_t ctx_start; cycles_t lck_start; -#if DRM_DMA_HISTOGRAM +#if __HAVE_DMA_HISTOGRAM drm_histogram_t histo; #endif @@ -667,9 +675,11 @@ typedef struct drm_device { } drm_device_t; - /* Internal function definitions */ +/* ================================================================ + * Internal function definitions + */ - /* Misc. support (init.c) */ + /* Misc. support (drm_init.h) */ extern int DRM(flags); extern void DRM(parse_options)( char *s ); extern int DRM(cpu_valid)( void ); @@ -686,7 +696,7 @@ extern int DRM(lock)(struct inode *inode, struct file *filp, extern int DRM(unlock)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); - /* Device support (fops.c) */ + /* Device support (drm_fops.h) */ extern int DRM(open_helper)(struct inode *inode, struct file *filp, drm_device_t *dev); extern int DRM(flush)(struct file *filp); @@ -698,7 +708,7 @@ extern int DRM(write_string)(drm_device_t *dev, const char *s); extern unsigned int DRM(poll)(struct file *filp, struct poll_table_struct *wait); - /* Mapping support (vm.c) */ + /* Mapping support (drm_vm.h) */ #if LINUX_VERSION_CODE < 0x020317 extern unsigned long DRM(vm_nopage)(struct vm_area_struct *vma, unsigned long address, @@ -728,17 +738,7 @@ extern int DRM(mmap_dma)(struct file *filp, struct vm_area_struct *vma); extern int DRM(mmap)(struct file *filp, struct vm_area_struct *vma); - - /* Proc support (proc.c) */ -extern struct proc_dir_entry *drm_proc_init(drm_device_t *dev, - int minor, - struct proc_dir_entry *root, - struct proc_dir_entry **dev_root); -extern int drm_proc_cleanup(int minor, - struct proc_dir_entry *root, - struct proc_dir_entry *dev_root); - - /* Memory management support (memory.c) */ + /* Memory management support (drm_memory.h) */ extern void DRM(mem_init)(void); extern int DRM(mem_info)(char *buf, char **start, off_t offset, int request, int *eof, void *data); @@ -761,7 +761,7 @@ extern int DRM(bind_agp)(agp_memory *handle, unsigned int start); extern int DRM(unbind_agp)(agp_memory *handle); #endif - /* Misc. IOCTL support (ioctl.c) */ + /* Misc. IOCTL support (drm_ioctl.h) */ extern int DRM(irq_busid)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int DRM(getunique)(struct inode *inode, struct file *filp, @@ -775,7 +775,7 @@ extern int DRM(getclient)(struct inode *inode, struct file *filp, extern int DRM(getstats)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); - /* Context IOCTL support (context.c) */ + /* Context IOCTL support (drm_context.h) */ extern int DRM(resctx)( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ); extern int DRM(addctx)( struct inode *inode, struct file *filp, @@ -794,14 +794,24 @@ extern int DRM(rmctx)( struct inode *inode, struct file *filp, extern int DRM(context_switch)(drm_device_t *dev, int old, int new); extern int DRM(context_switch_complete)(drm_device_t *dev, int new); - /* Drawable IOCTL support (drawable.c) */ +#if __HAVE_CTX_BITMAP +extern int DRM(ctxbitmap_init)( drm_device_t *dev ); +extern void DRM(ctxbitmap_cleanup)( drm_device_t *dev ); +#endif + +extern int DRM(setsareactx)( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); +extern int DRM(getsareactx)( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); + + /* Drawable IOCTL support (drm_drawable.h) */ extern int DRM(adddraw)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int DRM(rmdraw)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); - /* Authentication IOCTL support (auth.c) */ + /* Authentication IOCTL support (drm_auth.h) */ extern int DRM(add_magic)(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic); extern int DRM(remove_magic)(drm_device_t *dev, drm_magic_t magic); @@ -811,7 +821,7 @@ extern int DRM(authmagic)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); - /* Locking IOCTL support (lock.c) */ + /* Locking IOCTL support (drm_lock.h) */ extern int DRM(block)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int DRM(unblock)(struct inode *inode, struct file *filp, @@ -832,20 +842,13 @@ extern int DRM(flush_block_and_flush)(drm_device_t *dev, int context, drm_lock_flags_t flags); extern int DRM(notifier)(void *priv); - /* Context Bitmap support (ctxbitmap.c) */ -extern int DRM(ctxbitmap_init)( drm_device_t *dev ); -extern void DRM(ctxbitmap_cleanup)( drm_device_t *dev ); -extern int DRM(setsareactx)( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern int DRM(getsareactx)( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); - - /* Buffer management support (bufs.c) */ + /* Buffer management support (drm_bufs.h) */ extern int DRM(order)( unsigned long size ); extern int DRM(addmap)( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ); extern int DRM(rmmap)( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ); +#if __HAVE_DMA extern int DRM(addbufs)( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ); extern int DRM(infobufs)( struct inode *inode, struct file *filp, @@ -857,27 +860,37 @@ extern int DRM(freebufs)( struct inode *inode, struct file *filp, extern int DRM(mapbufs)( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ); - -#if __HAVE_DMA - /* DMA support (dma.c) */ + /* DMA support (drm_dma.h) */ extern int DRM(dma_setup)(drm_device_t *dev); extern void DRM(dma_takedown)(drm_device_t *dev); extern void DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf); extern void DRM(reclaim_buffers)(drm_device_t *dev, pid_t pid); +#if __HAVE_OLD_DMA +/* GH: This is a dirty hack for now... + */ extern void DRM(clear_next_buffer)(drm_device_t *dev); extern int DRM(select_queue)(drm_device_t *dev, void (*wrapper)(unsigned long)); extern int DRM(dma_enqueue)(drm_device_t *dev, drm_dma_t *dma); -#if 0 extern int DRM(dma_get_buffers)(drm_device_t *dev, drm_dma_t *dma); #endif +#if __HAVE_DMA_IRQ +extern int DRM(control)( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); +extern int DRM(irq_install)( drm_device_t *dev, int irq ); +extern int DRM(irq_uninstall)( drm_device_t *dev ); +extern void DRM(dma_service)( int irq, void *device, + struct pt_regs *regs ); +#if __HAVE_DMA_IRQ_BH +extern void DRM(dma_immediate_bh)( void *dev ); +#endif +#endif #if DRM_DMA_HISTOGRAM extern int DRM(histogram_slot)(unsigned long count); extern void DRM(histogram_compute)(drm_device_t *dev, drm_buf_t *buf); #endif -#endif - /* Buffer list management support (lists.c) */ + /* Buffer list support (drm_lists.h) */ #if __HAVE_DMA_WAITLIST extern int DRM(waitlist_create)(drm_waitlist_t *bl, int count); extern int DRM(waitlist_destroy)(drm_waitlist_t *bl); @@ -891,9 +904,10 @@ extern int DRM(freelist_put)(drm_device_t *dev, drm_freelist_t *bl, drm_buf_t *buf); extern drm_buf_t *DRM(freelist_get)(drm_freelist_t *bl, int block); #endif +#endif /* __HAVE_DMA */ #if __REALLY_HAVE_AGP - /* AGP/GART support (agpsupport.c) */ + /* AGP/GART support (drm_agpsupport.h) */ extern drm_agp_head_t *DRM(agp_init)(void); extern void DRM(agp_uninit)(void); extern int DRM(agp_acquire)(struct inode *inode, struct file *filp, @@ -917,6 +931,7 @@ extern agp_memory *DRM(agp_allocate_memory)(size_t pages, u32 type); extern int DRM(agp_free_memory)(agp_memory *handle); extern int DRM(agp_bind_memory)(agp_memory *handle, off_t start); extern int DRM(agp_unbind_memory)(agp_memory *handle); +#endif /* Stub support (drm_stub.h) */ int DRM(stub_register)(const char *name, @@ -924,6 +939,14 @@ int DRM(stub_register)(const char *name, drm_device_t *dev); int DRM(stub_unregister)(int minor); -#endif -#endif + /* Proc support (drm_proc.h) */ +extern struct proc_dir_entry *DRM(proc_init)(drm_device_t *dev, + int minor, + struct proc_dir_entry *root, + struct proc_dir_entry **dev_root); +extern int DRM(proc_cleanup)(int minor, + struct proc_dir_entry *root, + struct proc_dir_entry *dev_root); + +#endif /* __KERNEL__ */ #endif diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_agpsupport.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_agpsupport.h index b070a59e6..dfd0d8fc2 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_agpsupport.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_agpsupport.h @@ -77,7 +77,7 @@ int DRM(agp_acquire)(struct inode *inode, struct file *filp, drm_device_t *dev = priv->dev; int retcode; - if (dev->agp->acquired || !drm_agp->acquire) return -EINVAL; + if (!dev->agp|| dev->agp->acquired || !drm_agp->acquire) return -EINVAL; if ((retcode = drm_agp->acquire())) return retcode; dev->agp->acquired = 1; return 0; diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_bufs.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_bufs.h index 02694f46d..1d5403225 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_bufs.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_bufs.h @@ -135,6 +135,7 @@ int DRM(addmap)( struct inode *inode, struct file *filp, #if __REALLY_HAVE_AGP case _DRM_AGP: map->offset = map->offset + dev->agp->base; + map->mtrr = dev->agp->agp_mtrr; /* for getmap */ break; #endif default: @@ -332,7 +333,7 @@ int DRM(addbufs_agp)( struct inode *inode, struct file *filp, buf->order = order; buf->used = 0; - buf->offset = (dma->byte_count + offset); /* ******** */ + buf->offset = (dma->byte_count + offset); buf->bus_address = agp_offset + offset; buf->address = (void *)(agp_offset + offset); buf->next = NULL; @@ -346,7 +347,7 @@ int DRM(addbufs_agp)( struct inode *inode, struct file *filp, DRM_MEM_BUFS ); memset( buf->dev_private, 0, buf->dev_priv_size ); -#if DRM_DMA_HISTOGRAM +#if __HAVE_DMA_HISTOGRAM buf->time_queued = 0; buf->time_dispatched = 0; buf->time_completed = 0; @@ -377,17 +378,12 @@ int DRM(addbufs_agp)( struct inode *inode, struct file *filp, DRM_DEBUG( "dma->buf_count : %d\n", dma->buf_count ); DRM_DEBUG( "entry->buf_count : %d\n", entry->buf_count ); -/* GH: Please leave this disabled for now. I need to fix this properly... - */ -#if 0 - /* FIXME: work this mess out... - */ +#if __HAVE_DMA_FREELIST DRM(freelist_create)( &entry->freelist, entry->buf_count ); for ( i = 0 ; i < entry->buf_count ; i++ ) { DRM(freelist_put)( dev, &entry->freelist, &entry->buflist[i] ); } #endif - up( &dev->struct_sem ); request.count = entry->buf_count; @@ -523,11 +519,11 @@ int DRM(addbufs_pci)( struct inode *inode, struct file *filp, buf->pending = 0; init_waitqueue_head( &buf->dma_wait ); buf->pid = 0; -#if DRM_DMA_HISTOGRAM +#if __HAVE_DMA_HISTOGRAM buf->time_queued = 0; buf->time_dispatched = 0; buf->time_completed = 0; - buf->time_freed = 0; + buf->time_freed = 0; #endif DRM_DEBUG( "buffer %d @ %p\n", entry->buf_count, buf->address ); @@ -549,17 +545,12 @@ int DRM(addbufs_pci)( struct inode *inode, struct file *filp, dma->page_count += entry->seg_count << page_order; dma->byte_count += PAGE_SIZE * (entry->seg_count << page_order); -/* GH: Please leave this disabled for now. I need to fix this properly... - */ -#if 0 - /* FIXME: work this mess out... - */ +#if __HAVE_DMA_FREELIST DRM(freelist_create)( &entry->freelist, entry->buf_count ); for ( i = 0 ; i < entry->buf_count ; i++ ) { DRM(freelist_put)( dev, &entry->freelist, &entry->buflist[i] ); } #endif - up( &dev->struct_sem ); request.count = entry->buf_count; diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_context.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_context.h index 8f891fd2a..4ac896ef5 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_context.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_context.h @@ -29,6 +29,11 @@ * Gareth Hughes <gareth@valinux.com> */ +#define __NO_VERSION__ +#include "drmP.h" + +#if __HAVE_CTX_BITMAP + /* ================================================================ * Context bitmap support */ @@ -210,7 +215,7 @@ int DRM(context_switch)( drm_device_t *dev, int old, int new ) return -EBUSY; } -#if DRM_DMA_HISTOGRAM +#if __HAVE_DMA_HISTOGRAM dev->ctx_start = get_cycles(); #endif @@ -243,7 +248,7 @@ int DRM(context_switch_complete)( drm_device_t *dev, int new ) /* If a context switch is ever initiated when the kernel holds the lock, release that lock here. */ -#if DRM_DMA_HISTOGRAM +#if __HAVE_DMA_HISTOGRAM atomic_inc( &dev->histo.ctx[DRM(histogram_slot)(get_cycles() - dev->ctx_start)] ); @@ -380,3 +385,376 @@ int DRM(rmctx)( struct inode *inode, struct file *filp, return 0; } + + +#else /* __HAVE_CTX_BITMAP */ + +/* ================================================================ + * Old-style context support + */ + + +int DRM(context_switch)(drm_device_t *dev, int old, int new) +{ + char buf[64]; + drm_queue_t *q; + +#if 0 + atomic_inc(&dev->total_ctx); +#endif + + if (test_and_set_bit(0, &dev->context_flag)) { + DRM_ERROR("Reentering -- FIXME\n"); + return -EBUSY; + } + +#if __HAVE_DMA_HISTOGRAM + dev->ctx_start = get_cycles(); +#endif + + DRM_DEBUG("Context switch from %d to %d\n", old, new); + + if (new >= dev->queue_count) { + clear_bit(0, &dev->context_flag); + return -EINVAL; + } + + if (new == dev->last_context) { + clear_bit(0, &dev->context_flag); + return 0; + } + + q = dev->queuelist[new]; + atomic_inc(&q->use_count); + if (atomic_read(&q->use_count) == 1) { + atomic_dec(&q->use_count); + clear_bit(0, &dev->context_flag); + return -EINVAL; + } + + if (DRM(flags) & DRM_FLAG_NOCTX) { + DRM(context_switch_complete)(dev, new); + } else { + sprintf(buf, "C %d %d\n", old, new); + DRM(write_string)(dev, buf); + } + + atomic_dec(&q->use_count); + + return 0; +} + +int DRM(context_switch_complete)(drm_device_t *dev, int new) +{ + drm_device_dma_t *dma = dev->dma; + + dev->last_context = new; /* PRE/POST: This is the _only_ writer. */ + dev->last_switch = jiffies; + + if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("Lock isn't held after context switch\n"); + } + + if (!dma || !(dma->next_buffer && dma->next_buffer->while_locked)) { + if (DRM(lock_free)(dev, &dev->lock.hw_lock->lock, + DRM_KERNEL_CONTEXT)) { + DRM_ERROR("Cannot free lock\n"); + } + } + +#if __HAVE_DMA_HISTOGRAM + atomic_inc(&dev->histo.ctx[DRM(histogram_slot)(get_cycles() + - dev->ctx_start)]); + +#endif + clear_bit(0, &dev->context_flag); + wake_up_interruptible(&dev->context_wait); + + return 0; +} + +static int DRM(init_queue)(drm_device_t *dev, drm_queue_t *q, drm_ctx_t *ctx) +{ + DRM_DEBUG("\n"); + + if (atomic_read(&q->use_count) != 1 + || atomic_read(&q->finalization) + || atomic_read(&q->block_count)) { + DRM_ERROR("New queue is already in use: u%d f%d b%d\n", + atomic_read(&q->use_count), + atomic_read(&q->finalization), + atomic_read(&q->block_count)); + } + + atomic_set(&q->finalization, 0); + atomic_set(&q->block_count, 0); + atomic_set(&q->block_read, 0); + atomic_set(&q->block_write, 0); + atomic_set(&q->total_queued, 0); + atomic_set(&q->total_flushed, 0); + atomic_set(&q->total_locks, 0); + + init_waitqueue_head(&q->write_queue); + init_waitqueue_head(&q->read_queue); + init_waitqueue_head(&q->flush_queue); + + q->flags = ctx->flags; + + DRM(waitlist_create)(&q->waitlist, dev->dma->buf_count); + + return 0; +} + + +/* drm_alloc_queue: +PRE: 1) dev->queuelist[0..dev->queue_count] is allocated and will not + disappear (so all deallocation must be done after IOCTLs are off) + 2) dev->queue_count < dev->queue_slots + 3) dev->queuelist[i].use_count == 0 and + dev->queuelist[i].finalization == 0 if i not in use +POST: 1) dev->queuelist[i].use_count == 1 + 2) dev->queue_count < dev->queue_slots */ + +static int DRM(alloc_queue)(drm_device_t *dev) +{ + int i; + drm_queue_t *queue; + int oldslots; + int newslots; + /* Check for a free queue */ + for (i = 0; i < dev->queue_count; i++) { + atomic_inc(&dev->queuelist[i]->use_count); + if (atomic_read(&dev->queuelist[i]->use_count) == 1 + && !atomic_read(&dev->queuelist[i]->finalization)) { + DRM_DEBUG("%d (free)\n", i); + return i; + } + atomic_dec(&dev->queuelist[i]->use_count); + } + /* Allocate a new queue */ + down(&dev->struct_sem); + + queue = gamma_alloc(sizeof(*queue), DRM_MEM_QUEUES); + memset(queue, 0, sizeof(*queue)); + atomic_set(&queue->use_count, 1); + + ++dev->queue_count; + if (dev->queue_count >= dev->queue_slots) { + oldslots = dev->queue_slots * sizeof(*dev->queuelist); + if (!dev->queue_slots) dev->queue_slots = 1; + dev->queue_slots *= 2; + newslots = dev->queue_slots * sizeof(*dev->queuelist); + + dev->queuelist = DRM(realloc)(dev->queuelist, + oldslots, + newslots, + DRM_MEM_QUEUES); + if (!dev->queuelist) { + up(&dev->struct_sem); + DRM_DEBUG("out of memory\n"); + return -ENOMEM; + } + } + dev->queuelist[dev->queue_count-1] = queue; + + up(&dev->struct_sem); + DRM_DEBUG("%d (new)\n", dev->queue_count - 1); + return dev->queue_count - 1; +} + +int DRM(resctx)(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_ctx_res_t res; + drm_ctx_t ctx; + int i; + + DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS); + if (copy_from_user(&res, (drm_ctx_res_t *)arg, sizeof(res))) + return -EFAULT; + if (res.count >= DRM_RESERVED_CONTEXTS) { + memset(&ctx, 0, sizeof(ctx)); + for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) { + ctx.handle = i; + if (copy_to_user(&res.contexts[i], + &i, + sizeof(i))) + return -EFAULT; + } + } + res.count = DRM_RESERVED_CONTEXTS; + if (copy_to_user((drm_ctx_res_t *)arg, &res, sizeof(res))) + return -EFAULT; + return 0; +} + +int DRM(addctx)(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_ctx_t ctx; + + if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) + return -EFAULT; + if ((ctx.handle = DRM(alloc_queue)(dev)) == DRM_KERNEL_CONTEXT) { + /* Init kernel's context and get a new one. */ + DRM(init_queue)(dev, dev->queuelist[ctx.handle], &ctx); + ctx.handle = DRM(alloc_queue)(dev); + } + DRM(init_queue)(dev, dev->queuelist[ctx.handle], &ctx); + DRM_DEBUG("%d\n", ctx.handle); + if (copy_to_user((drm_ctx_t *)arg, &ctx, sizeof(ctx))) + return -EFAULT; + return 0; +} + +int DRM(modctx)(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_ctx_t ctx; + drm_queue_t *q; + + if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) + return -EFAULT; + + DRM_DEBUG("%d\n", ctx.handle); + + if (ctx.handle < 0 || ctx.handle >= dev->queue_count) return -EINVAL; + q = dev->queuelist[ctx.handle]; + + atomic_inc(&q->use_count); + if (atomic_read(&q->use_count) == 1) { + /* No longer in use */ + atomic_dec(&q->use_count); + return -EINVAL; + } + + if (DRM_BUFCOUNT(&q->waitlist)) { + atomic_dec(&q->use_count); + return -EBUSY; + } + + q->flags = ctx.flags; + + atomic_dec(&q->use_count); + return 0; +} + +int DRM(getctx)(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_ctx_t ctx; + drm_queue_t *q; + + if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) + return -EFAULT; + + DRM_DEBUG("%d\n", ctx.handle); + + if (ctx.handle >= dev->queue_count) return -EINVAL; + q = dev->queuelist[ctx.handle]; + + atomic_inc(&q->use_count); + if (atomic_read(&q->use_count) == 1) { + /* No longer in use */ + atomic_dec(&q->use_count); + return -EINVAL; + } + + ctx.flags = q->flags; + atomic_dec(&q->use_count); + + if (copy_to_user((drm_ctx_t *)arg, &ctx, sizeof(ctx))) + return -EFAULT; + + return 0; +} + +int DRM(switchctx)(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_ctx_t ctx; + + if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) + return -EFAULT; + DRM_DEBUG("%d\n", ctx.handle); + return DRM(context_switch)(dev, dev->last_context, ctx.handle); +} + +int DRM(newctx)(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_ctx_t ctx; + + if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) + return -EFAULT; + DRM_DEBUG("%d\n", ctx.handle); + DRM(context_switch_complete)(dev, ctx.handle); + + return 0; +} + +int DRM(rmctx)(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_ctx_t ctx; + drm_queue_t *q; + drm_buf_t *buf; + + if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) + return -EFAULT; + DRM_DEBUG("%d\n", ctx.handle); + + if (ctx.handle >= dev->queue_count) return -EINVAL; + q = dev->queuelist[ctx.handle]; + + atomic_inc(&q->use_count); + if (atomic_read(&q->use_count) == 1) { + /* No longer in use */ + atomic_dec(&q->use_count); + return -EINVAL; + } + + atomic_inc(&q->finalization); /* Mark queue in finalization state */ + atomic_sub(2, &q->use_count); /* Mark queue as unused (pending + finalization) */ + + while (test_and_set_bit(0, &dev->interrupt_flag)) { + schedule(); + if (signal_pending(current)) { + clear_bit(0, &dev->interrupt_flag); + return -EINTR; + } + } + /* Remove queued buffers */ + while ((buf = DRM(waitlist_get)(&q->waitlist))) { + DRM(free_buffer)(dev, buf); + } + clear_bit(0, &dev->interrupt_flag); + + /* Wakeup blocked processes */ + wake_up_interruptible(&q->read_queue); + wake_up_interruptible(&q->write_queue); + wake_up_interruptible(&q->flush_queue); + + /* Finalization over. Queue is made + available when both use_count and + finalization become 0, which won't + happen until all the waiting processes + stop waiting. */ + atomic_dec(&q->finalization); + return 0; +} + +#endif /* __HAVE_CTX_BITMAP */ diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_dma.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_dma.h index 35eb896e2..e715bd416 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_dma.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_dma.h @@ -118,7 +118,7 @@ void DRM(dma_takedown)(drm_device_t *dev) } -#if DRM_DMA_HISTOGRAM +#if __HAVE_DMA_HISTOGRAM /* This is slow, but is useful for debugging. */ int DRM(histogram_slot)(unsigned long count) { @@ -182,7 +182,7 @@ void DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf) buf->pending = 0; buf->pid = 0; buf->used = 0; -#if DRM_DMA_HISTOGRAM +#if __HAVE_DMA_HISTOGRAM buf->time_completed = get_cycles(); #endif @@ -231,85 +231,6 @@ void DRM(reclaim_buffers)(drm_device_t *dev, pid_t pid) */ #if __HAVE_OLD_DMA -int drm_context_switch(drm_device_t *dev, int old, int new) -{ - char buf[64]; - drm_queue_t *q; - -#if 0 - atomic_inc(&dev->total_ctx); -#endif - - if (test_and_set_bit(0, &dev->context_flag)) { - DRM_ERROR("Reentering -- FIXME\n"); - return -EBUSY; - } - -#if DRM_DMA_HISTOGRAM - dev->ctx_start = get_cycles(); -#endif - - DRM_DEBUG("Context switch from %d to %d\n", old, new); - - if (new >= dev->queue_count) { - clear_bit(0, &dev->context_flag); - return -EINVAL; - } - - if (new == dev->last_context) { - clear_bit(0, &dev->context_flag); - return 0; - } - - q = dev->queuelist[new]; - atomic_inc(&q->use_count); - if (atomic_read(&q->use_count) == 1) { - atomic_dec(&q->use_count); - clear_bit(0, &dev->context_flag); - return -EINVAL; - } - - if (DRM(flags) & DRM_FLAG_NOCTX) { - drm_context_switch_complete(dev, new); - } else { - sprintf(buf, "C %d %d\n", old, new); - DRM(write_string)(dev, buf); - } - - atomic_dec(&q->use_count); - - return 0; -} - -int drm_context_switch_complete(drm_device_t *dev, int new) -{ - drm_device_dma_t *dma = dev->dma; - - dev->last_context = new; /* PRE/POST: This is the _only_ writer. */ - dev->last_switch = jiffies; - - if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { - DRM_ERROR("Lock isn't held after context switch\n"); - } - - if (!dma || !(dma->next_buffer && dma->next_buffer->while_locked)) { - if (DRM(lock_free)(dev, &dev->lock.hw_lock->lock, - DRM_KERNEL_CONTEXT)) { - DRM_ERROR("Cannot free lock\n"); - } - } - -#if DRM_DMA_HISTOGRAM - atomic_inc(&dev->histo.ctx[DRM(histogram_slot)(get_cycles() - - dev->ctx_start)]); - -#endif - clear_bit(0, &dev->context_flag); - wake_up_interruptible(&dev->context_wait); - - return 0; -} - void DRM(clear_next_buffer)(drm_device_t *dev) { drm_device_dma_t *dma = dev->dma; @@ -571,6 +492,103 @@ int DRM(dma_get_buffers)(drm_device_t *dev, drm_dma_t *dma) return 0; } -#endif +#endif /* __HAVE_OLD_DMA */ + + +#if __HAVE_DMA_IRQ + +int DRM(irq_install)( drm_device_t *dev, int irq ) +{ + int ret; + + if ( !irq ) + return -EINVAL; + + down( &dev->struct_sem ); + if ( dev->irq ) { + up( &dev->struct_sem ); + return -EBUSY; + } + dev->irq = irq; + up( &dev->struct_sem ); + + DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, irq ); + + dev->context_flag = 0; + dev->interrupt_flag = 0; + dev->dma_flag = 0; + + dev->dma->next_buffer = NULL; + dev->dma->next_queue = NULL; + dev->dma->this_buffer = NULL; +#if __HAVE_DMA_IRQ_BH + INIT_LIST_HEAD( &dev->tq.list ); + dev->tq.sync = 0; + dev->tq.routine = DRM(dma_immediate_bh); + dev->tq.data = dev; #endif + + /* Before installing handler */ + DRIVER_PREINSTALL(); + + /* Install handler */ + ret = request_irq( dev->irq, DRM(dma_service), + 0, dev->devname, dev ); + if ( ret < 0 ) { + down( &dev->struct_sem ); + dev->irq = 0; + up( &dev->struct_sem ); + return ret; + } + + /* After installing handler */ + DRIVER_POSTINSTALL(); + + return 0; +} + +int DRM(irq_uninstall)( drm_device_t *dev ) +{ + int irq; + + down( &dev->struct_sem ); + irq = dev->irq; + dev->irq = 0; + up( &dev->struct_sem ); + + if ( !irq ) + return -EINVAL; + + DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, irq ); + + DRIVER_UNINSTALL(); + + free_irq( irq, dev ); + + return 0; +} + +int DRM(control)( 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_control_t ctl; + + if ( copy_from_user( &ctl, (drm_control_t *)arg, sizeof(ctl) ) ) + return -EFAULT; + + switch ( ctl.func ) { + case DRM_INST_HANDLER: + return DRM(irq_install)( dev, ctl.irq ); + case DRM_UNINST_HANDLER: + return DRM(irq_uninstall)( dev ); + default: + return -EINVAL; + } +} + +#endif /* __HAVE_DMA_IRQ */ + +#endif /* __HAVE_DMA */ diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_drv.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_drv.h index 05923b50b..7447ca6d4 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_drv.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_drv.h @@ -492,7 +492,8 @@ static int __init drm_init( void ) } #endif #if __REALLY_HAVE_MTRR - dev->agp->agp_mtrr = mtrr_add( dev->agp->agp_info.aper_base, + if (dev->agp) + dev->agp->agp_mtrr = mtrr_add( dev->agp->agp_info.aper_base, dev->agp->agp_info.aper_size*1024*1024, MTRR_TYPE_WRCOMB, 1 ); @@ -646,7 +647,7 @@ int DRM(release)( struct inode *inode, struct file *filp ) if ( dev->lock.hw_lock && _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) && dev->lock.pid == current->pid ) { - DRM_ERROR( "Process %d dead, freeing lock for context %d\n", + DRM_DEBUG( "Process %d dead, freeing lock for context %d\n", current->pid, _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) ); #if __HAVE_RELEASE @@ -697,7 +698,7 @@ int DRM(release)( struct inode *inode, struct file *filp ) DRM_KERNEL_CONTEXT ); } } -#else +#elif __HAVE_DMA DRM(reclaim_buffers)( dev, priv->pid ); #endif @@ -804,7 +805,7 @@ int DRM(lock)( struct inode *inode, struct file *filp, #if __HAVE_MULTIPLE_DMA_QUEUES drm_queue_t *q; #endif -#if DRM_DMA_HISTOGRAM +#if __HAVE_DMA_HISTOGRAM cycles_t start; dev->lck_start = start = get_cycles(); @@ -892,7 +893,7 @@ int DRM(lock)( struct inode *inode, struct file *filp, DRM_DEBUG( "%d %s\n", lock.context, ret ? "interrupted" : "has lock" ); -#if DRM_DMA_HISTOGRAM +#if __HAVE_DMA_HISTOGRAM atomic_inc(&dev->histo.lacq[DRM(histogram_slot)(get_cycles()-start)]); #endif return ret; diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_fops.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_fops.h index d646f3188..dd5747669 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_fops.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_fops.h @@ -83,50 +83,6 @@ int DRM(flush)(struct file *filp) return 0; } -#if 0 -/* drm_release is called whenever a process closes /dev/drm*. Linux calls - this only if any mappings have been closed. */ - -int drm_release(struct inode *inode, struct file *filp) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - - DRM_DEBUG("pid = %d, device = 0x%x, open_count = %d\n", - current->pid, dev->device, dev->open_count); - - if (dev->lock.hw_lock - && _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) - && dev->lock.pid == current->pid) { - DRM_ERROR("Process %d dead, freeing lock for context %d\n", - current->pid, - _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); - drm_lock_free(dev, - &dev->lock.hw_lock->lock, - _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); - - /* FIXME: may require heavy-handed reset of - hardware at this point, possibly - processed via a callback to the X - server. */ - } - drm_reclaim_buffers(dev, priv->pid); - - drm_fasync(-1, filp, 0); - - down(&dev->struct_sem); - if (priv->prev) priv->prev->next = priv->next; - else dev->file_first = priv->next; - if (priv->next) priv->next->prev = priv->prev; - else dev->file_last = priv->prev; - up(&dev->struct_sem); - - drm_free(priv, sizeof(*priv), DRM_MEM_FILES); - - return 0; -} -#endif - int DRM(fasync)(int fd, struct file *filp, int on) { drm_file_t *priv = filp->private_data; diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_lists.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_lists.h index b597ef770..f8dbaaa71 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_lists.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_lists.h @@ -74,7 +74,7 @@ int DRM(waitlist_put)(drm_waitlist_t *bl, drm_buf_t *buf) buf->idx, buf->pid); return -EINVAL; } -#if DRM_DMA_HISTOGRAM +#if __HAVE_DMA_HISTOGRAM buf->time_queued = get_cycles(); #endif buf->list = DRM_LIST_WAIT; @@ -106,6 +106,7 @@ drm_buf_t *DRM(waitlist_get)(drm_waitlist_t *bl) #endif /* __HAVE_DMA_WAITLIST */ + #if __HAVE_DMA_FREELIST int DRM(freelist_create)(drm_freelist_t *bl, int count) @@ -142,7 +143,7 @@ int DRM(freelist_put)(drm_device_t *dev, drm_freelist_t *bl, drm_buf_t *buf) buf->idx, buf->waiting, buf->pending, buf->list); } if (!bl) return 1; -#if DRM_DMA_HISTOGRAM +#if __HAVE_DMA_HISTOGRAM buf->time_freed = get_cycles(); DRM(histogram_compute)(dev, buf); #endif diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_memory.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_memory.h index caf053943..1763d9b41 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_memory.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_memory.h @@ -351,8 +351,7 @@ void DRM(ioremapfree)(void *pt, unsigned long size) } } -#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) -#if __MUST_HAVE_AGP +#if __REALLY_HAVE_AGP agp_memory *DRM(alloc_agp)(int pages, u32 type) { @@ -457,4 +456,3 @@ int DRM(unbind_agp)(agp_memory *handle) return retcode; } #endif -#endif /* defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) */ diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_proc.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_proc.h index 606286607..f65f42b71 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_proc.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_proc.h @@ -50,7 +50,7 @@ static int DRM(bufs_info)(char *buf, char **start, off_t offset, static int DRM(vma_info)(char *buf, char **start, off_t offset, int request, int *eof, void *data); #endif -#if DRM_DMA_HISTOGRAM +#if __HAVE_DMA_HISTOGRAM static int DRM(histo_info)(char *buf, char **start, off_t offset, int request, int *eof, void *data); #endif @@ -68,7 +68,7 @@ struct drm_proc_list { #if DRM_DEBUG_CODE { "vma", DRM(vma_info) }, #endif -#if DRM_DMA_HISTOGRAM +#if __HAVE_DMA_HISTOGRAM { "histo", DRM(histo_info) }, #endif }; @@ -488,7 +488,7 @@ static int DRM(vma_info)(char *buf, char **start, off_t offset, int request, #endif -#if DRM_DMA_HISTOGRAM +#if __HAVE_DMA_HISTOGRAM static int DRM(_histo_info)(char *buf, char **start, off_t offset, int request, int *eof, void *data) { diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_stub.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_stub.h index ed37af4da..bc9587963 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_stub.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_stub.h @@ -1,4 +1,4 @@ -/* drm_stub.c -- -*- linux-c -*- +/* drm_stub.h -- -*- linux-c -*- * Created: Fri Jan 19 10:48:35 2001 by faith@acm.org * * Copyright 2001 VA Linux Systems, Inc., Sunnyvale, California. @@ -28,6 +28,13 @@ * */ +#define __NO_VERSION__ +#include "drmP.h" + +#if LINUX_VERSION_CODE < 0x020400 +#include "stubsupport-pre24.h" +#endif + #define DRM_STUB_MAXCARDS 16 /* Enough for one machine */ static struct drm_stub_list { @@ -58,7 +65,7 @@ static int DRM(stub_open)(struct inode *inode, struct file *filp) filp->f_op = fops_get(old_fops); } fops_put(old_fops); - + return err; } @@ -73,7 +80,7 @@ static int DRM(stub_getminor)(const char *name, struct file_operations *fops, drm_device_t *dev) { int i; - + if (!DRM(stub_list)) { DRM(stub_list) = DRM(alloc)(sizeof(*DRM(stub_list)) * DRM_STUB_MAXCARDS, DRM_MEM_STUB); @@ -117,10 +124,13 @@ static int DRM(stub_putminor)(int minor) int DRM(stub_register)(const char *name, struct file_operations *fops, drm_device_t *dev) { - if (register_chrdev(DRM_MAJOR, "drm", &DRM(stub_fops))) { - /* Already registered */ - struct drm_stub_info *i; + struct drm_stub_info *i = NULL; + + if (register_chrdev(DRM_MAJOR, "drm", &DRM(stub_fops))) i = (struct drm_stub_info *)inter_module_get("drm"); + + if (i) { + /* Already registered */ DRM(stub_info).info_register = i->info_register; DRM(stub_info).info_unregister = i->info_unregister; } else { diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma.h index 5ca1f7451..232ed018b 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma.h @@ -1,3 +1,32 @@ +/* gamma.c -- 3dlabs GMX 2000 driver -*- linux-c -*- + * Created: Mon Jan 4 08:58:31 1999 by gareth@valinux.com + * + * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, 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 + * PRECISION INSIGHT AND/OR ITS 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: + * Gareth Hughes <gareth@valinux.com> + */ + #ifndef __GAMMA_H__ #define __GAMMA_H__ @@ -5,18 +34,60 @@ */ #define DRM(x) gamma_##x -#define __HAVE_MTRR 1 -#define __HAVE_PCI_DMA 1 -#define __HAVE_CTX_BITMAP 0 +/* General customization: + */ +#define __HAVE_MTRR 1 + +/* DMA customization: + */ +#define __HAVE_DMA 1 +#define __HAVE_OLD_DMA 1 +#define __HAVE_PCI_DMA 1 + #define __HAVE_MULTIPLE_DMA_QUEUES 1 +#define __HAVE_DMA_WAITQUEUE 1 + +#define __HAVE_DMA_WAITLIST 1 +#define __HAVE_DMA_FREELIST 1 + #define __HAVE_DMA_FLUSH 1 -#define __HAVE_DMA_QUEUE 0 #define __HAVE_DMA_SCHEDULE 1 -#define __HAVE_DMA_WAITQUEUE 1 -#define __HAVE_DMA_WAITLIST 1 -#define __HAVE_DMA_FREELIST 1 -#define __HAVE_DMA 1 -#define __HAVE_OLD_DMA 1 -#define __HAVE_DMA_IRQ 1 -#endif +#define __HAVE_DMA_READY 1 +#define DRIVER_DMA_READY() do { \ + gamma_dma_ready(dev); \ +} while (0) + +#define __HAVE_DMA_QUIESCENT 1 +#define DRIVER_DMA_QUIESCENT() do { \ + /* FIXME ! */ \ + gamma_dma_quiescent_dual(dev); \ + return 0; \ +} while (0) + +#define __HAVE_DMA_IRQ 1 +#define __HAVE_DMA_IRQ_BH 1 +#define DRIVER_PREINSTALL() do { \ + drm_gamma_private_t *dev_priv = \ + (drm_gamma_private_t *)dev->dev_private;\ + GAMMA_WRITE( GAMMA_GCOMMANDMODE, 0x00000000 ); \ + GAMMA_WRITE( GAMMA_GDMACONTROL, 0x00000000 ); \ +} while (0) + +#define DRIVER_POSTINSTALL() do { \ + drm_gamma_private_t *dev_priv = \ + (drm_gamma_private_t *)dev->dev_private;\ + GAMMA_WRITE( GAMMA_GINTENABLE, 0x00002001 ); \ + GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000008 ); \ + GAMMA_WRITE( GAMMA_GDELAYTIMER, 0x00039090 ); \ +} while (0) + +#define DRIVER_UNINSTALL() do { \ + drm_gamma_private_t *dev_priv = \ + (drm_gamma_private_t *)dev->dev_private;\ + GAMMA_WRITE( GAMMA_GDELAYTIMER, 0x00000000 ); \ + GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000000 ); \ + GAMMA_WRITE( GAMMA_GINTENABLE, 0x00000000 ); \ +} while (0) + +#endif /* __GAMMA_H__ */ diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_context.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_context.c deleted file mode 100644 index d94054a29..000000000 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_context.c +++ /dev/null @@ -1,319 +0,0 @@ -/* context.c -- IOCTLs for contexts and DMA queues -*- linux-c -*- - * Created: Tue Feb 2 08:37:54 1999 by faith@precisioninsight.com - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, 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 - * PRECISION INSIGHT AND/OR ITS 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: - * Rickard E. (Rik) Faith <faith@valinux.com> - * - */ - -#define __NO_VERSION__ -#include "gamma.h" -#include "drmP.h" - -static int drm_init_queue(drm_device_t *dev, drm_queue_t *q, drm_ctx_t *ctx) -{ - DRM_DEBUG("\n"); - - if (atomic_read(&q->use_count) != 1 - || atomic_read(&q->finalization) - || atomic_read(&q->block_count)) { - DRM_ERROR("New queue is already in use: u%d f%d b%d\n", - atomic_read(&q->use_count), - atomic_read(&q->finalization), - atomic_read(&q->block_count)); - } - - atomic_set(&q->finalization, 0); - atomic_set(&q->block_count, 0); - atomic_set(&q->block_read, 0); - atomic_set(&q->block_write, 0); - atomic_set(&q->total_queued, 0); - atomic_set(&q->total_flushed, 0); - atomic_set(&q->total_locks, 0); - - init_waitqueue_head(&q->write_queue); - init_waitqueue_head(&q->read_queue); - init_waitqueue_head(&q->flush_queue); - - q->flags = ctx->flags; - - gamma_waitlist_create(&q->waitlist, dev->dma->buf_count); - - return 0; -} - - -/* drm_alloc_queue: -PRE: 1) dev->queuelist[0..dev->queue_count] is allocated and will not - disappear (so all deallocation must be done after IOCTLs are off) - 2) dev->queue_count < dev->queue_slots - 3) dev->queuelist[i].use_count == 0 and - dev->queuelist[i].finalization == 0 if i not in use -POST: 1) dev->queuelist[i].use_count == 1 - 2) dev->queue_count < dev->queue_slots */ - -static int drm_alloc_queue(drm_device_t *dev) -{ - int i; - drm_queue_t *queue; - int oldslots; - int newslots; - /* Check for a free queue */ - for (i = 0; i < dev->queue_count; i++) { - atomic_inc(&dev->queuelist[i]->use_count); - if (atomic_read(&dev->queuelist[i]->use_count) == 1 - && !atomic_read(&dev->queuelist[i]->finalization)) { - DRM_DEBUG("%d (free)\n", i); - return i; - } - atomic_dec(&dev->queuelist[i]->use_count); - } - /* Allocate a new queue */ - down(&dev->struct_sem); - - queue = gamma_alloc(sizeof(*queue), DRM_MEM_QUEUES); - memset(queue, 0, sizeof(*queue)); - atomic_set(&queue->use_count, 1); - - ++dev->queue_count; - if (dev->queue_count >= dev->queue_slots) { - oldslots = dev->queue_slots * sizeof(*dev->queuelist); - if (!dev->queue_slots) dev->queue_slots = 1; - dev->queue_slots *= 2; - newslots = dev->queue_slots * sizeof(*dev->queuelist); - - dev->queuelist = gamma_realloc(dev->queuelist, - oldslots, - newslots, - DRM_MEM_QUEUES); - if (!dev->queuelist) { - up(&dev->struct_sem); - DRM_DEBUG("out of memory\n"); - return -ENOMEM; - } - } - dev->queuelist[dev->queue_count-1] = queue; - - up(&dev->struct_sem); - DRM_DEBUG("%d (new)\n", dev->queue_count - 1); - return dev->queue_count - 1; -} - -int gamma_resctx(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) -{ - drm_ctx_res_t res; - drm_ctx_t ctx; - int i; - - DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS); - if (copy_from_user(&res, (drm_ctx_res_t *)arg, sizeof(res))) - return -EFAULT; - if (res.count >= DRM_RESERVED_CONTEXTS) { - memset(&ctx, 0, sizeof(ctx)); - for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) { - ctx.handle = i; - if (copy_to_user(&res.contexts[i], - &i, - sizeof(i))) - return -EFAULT; - } - } - res.count = DRM_RESERVED_CONTEXTS; - if (copy_to_user((drm_ctx_res_t *)arg, &res, sizeof(res))) - return -EFAULT; - return 0; -} - - -int gamma_addctx(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_ctx_t ctx; - - if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) - return -EFAULT; - if ((ctx.handle = drm_alloc_queue(dev)) == DRM_KERNEL_CONTEXT) { - /* Init kernel's context and get a new one. */ - drm_init_queue(dev, dev->queuelist[ctx.handle], &ctx); - ctx.handle = drm_alloc_queue(dev); - } - drm_init_queue(dev, dev->queuelist[ctx.handle], &ctx); - DRM_DEBUG("%d\n", ctx.handle); - if (copy_to_user((drm_ctx_t *)arg, &ctx, sizeof(ctx))) - return -EFAULT; - return 0; -} - -int gamma_modctx(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_ctx_t ctx; - drm_queue_t *q; - - if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) - return -EFAULT; - - DRM_DEBUG("%d\n", ctx.handle); - - if (ctx.handle < 0 || ctx.handle >= dev->queue_count) return -EINVAL; - q = dev->queuelist[ctx.handle]; - - atomic_inc(&q->use_count); - if (atomic_read(&q->use_count) == 1) { - /* No longer in use */ - atomic_dec(&q->use_count); - return -EINVAL; - } - - if (DRM_BUFCOUNT(&q->waitlist)) { - atomic_dec(&q->use_count); - return -EBUSY; - } - - q->flags = ctx.flags; - - atomic_dec(&q->use_count); - return 0; -} - -int gamma_getctx(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_ctx_t ctx; - drm_queue_t *q; - - if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) - return -EFAULT; - - DRM_DEBUG("%d\n", ctx.handle); - - if (ctx.handle >= dev->queue_count) return -EINVAL; - q = dev->queuelist[ctx.handle]; - - atomic_inc(&q->use_count); - if (atomic_read(&q->use_count) == 1) { - /* No longer in use */ - atomic_dec(&q->use_count); - return -EINVAL; - } - - ctx.flags = q->flags; - atomic_dec(&q->use_count); - - if (copy_to_user((drm_ctx_t *)arg, &ctx, sizeof(ctx))) - return -EFAULT; - - return 0; -} - -int gamma_switchctx(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_ctx_t ctx; - - if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) - return -EFAULT; - DRM_DEBUG("%d\n", ctx.handle); - return drm_context_switch(dev, dev->last_context, ctx.handle); -} - -int gamma_newctx(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_ctx_t ctx; - - if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) - return -EFAULT; - DRM_DEBUG("%d\n", ctx.handle); - drm_context_switch_complete(dev, ctx.handle); - - return 0; -} - -int gamma_rmctx(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_ctx_t ctx; - drm_queue_t *q; - drm_buf_t *buf; - - if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) - return -EFAULT; - DRM_DEBUG("%d\n", ctx.handle); - - if (ctx.handle >= dev->queue_count) return -EINVAL; - q = dev->queuelist[ctx.handle]; - - atomic_inc(&q->use_count); - if (atomic_read(&q->use_count) == 1) { - /* No longer in use */ - atomic_dec(&q->use_count); - return -EINVAL; - } - - atomic_inc(&q->finalization); /* Mark queue in finalization state */ - atomic_sub(2, &q->use_count); /* Mark queue as unused (pending - finalization) */ - - while (test_and_set_bit(0, &dev->interrupt_flag)) { - schedule(); - if (signal_pending(current)) { - clear_bit(0, &dev->interrupt_flag); - return -EINTR; - } - } - /* Remove queued buffers */ - while ((buf = gamma_waitlist_get(&q->waitlist))) { - gamma_free_buffer(dev, buf); - } - clear_bit(0, &dev->interrupt_flag); - - /* Wakeup blocked processes */ - wake_up_interruptible(&q->read_queue); - wake_up_interruptible(&q->write_queue); - wake_up_interruptible(&q->flush_queue); - - /* Finalization over. Queue is made - available when both use_count and - finalization become 0, which won't - happen until all the waiting processes - stop waiting. */ - atomic_dec(&q->finalization); - return 0; -} diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_dma.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_dma.c index e2ac60616..d3a9414d7 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_dma.c +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_dma.c @@ -11,11 +11,11 @@ * 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 @@ -23,7 +23,7 @@ * 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: * Rickard E. (Rik) Faith <faith@valinux.com> * @@ -37,76 +37,13 @@ #include <linux/interrupt.h> /* For task queue support */ #include <linux/delay.h> -#if 0 -#define DO_IOREMAP( _map ) \ -do { \ - (_map)->handle = DRM(ioremap)( (_map)->offset, (_map)->size ); \ -} while (0) - -#define DO_IOREMAPFREE( _map ) \ -do { \ - if ( (_map)->handle && (_map)->size ) \ - DRM(ioremapfree)( (_map)->handle, (_map)->size ); \ -} while (0) - -#define DO_FIND_MAP( _map, _offset ) \ -do { \ - int _i; \ - for ( _i = 0 ; _i < dev->map_count ; _i++ ) { \ - if ( dev->maplist[_i]->offset == _offset ) { \ - _map = dev->maplist[_i]; \ - break; \ - } \ - } \ -} while (0) -#endif - -/* WARNING!!! MAGIC NUMBER!!! The number of regions already added to the - kernel must be specified here. Currently, the number is 2. This must - match the order the X server uses for instantiating register regions , - or must be passed in a new ioctl. */ -#define GAMMA_REG(reg) \ - (2 \ - + ((reg < 0x1000) \ - ? 0 \ - : ((reg < 0x10000) ? 1 : ((reg < 0x11000) ? 2 : 3)))) - -#define GAMMA_OFF(reg) \ - ((reg < 0x1000) \ - ? reg \ - : ((reg < 0x10000) \ - ? (reg - 0x1000) \ - : ((reg < 0x11000) \ - ? (reg - 0x10000) \ - : (reg - 0x11000)))) - -#define GAMMA_BASE(reg) ((unsigned long)dev->maplist[GAMMA_REG(reg)]->handle) -#define GAMMA_ADDR(reg) (GAMMA_BASE(reg) + GAMMA_OFF(reg)) -#define GAMMA_DEREF(reg) *(__volatile__ int *)GAMMA_ADDR(reg) -#define GAMMA_READ(reg) GAMMA_DEREF(reg) -#define GAMMA_WRITE(reg,val) do { GAMMA_DEREF(reg) = val; } while (0) - -#define GAMMA_BROADCASTMASK 0x9378 -#define GAMMA_COMMANDINTENABLE 0x0c48 -#define GAMMA_DMAADDRESS 0x0028 -#define GAMMA_DMACOUNT 0x0030 -#define GAMMA_FILTERMODE 0x8c00 -#define GAMMA_GCOMMANDINTFLAGS 0x0c50 -#define GAMMA_GCOMMANDMODE 0x0c40 -#define GAMMA_GCOMMANDSTATUS 0x0c60 -#define GAMMA_GDELAYTIMER 0x0c38 -#define GAMMA_GDMACONTROL 0x0060 -#define GAMMA_GINTENABLE 0x0808 -#define GAMMA_GINTFLAGS 0x0810 -#define GAMMA_INFIFOSPACE 0x0018 -#define GAMMA_OUTFIFOWORDS 0x0020 -#define GAMMA_OUTPUTFIFO 0x2000 -#define GAMMA_SYNC 0x8c40 -#define GAMMA_SYNC_TAG 0x0188 static inline void gamma_dma_dispatch(drm_device_t *dev, unsigned long address, unsigned long length) { + drm_gamma_private_t *dev_priv = + (drm_gamma_private_t *)dev->dev_private; + GAMMA_WRITE(GAMMA_DMAADDRESS, virt_to_phys((void *)address)); while (GAMMA_READ(GAMMA_GCOMMANDSTATUS) != 4) ; @@ -115,6 +52,9 @@ static inline void gamma_dma_dispatch(drm_device_t *dev, unsigned long address, void gamma_dma_quiescent_single(drm_device_t *dev) { + drm_gamma_private_t *dev_priv = + (drm_gamma_private_t *)dev->dev_private; + while (GAMMA_READ(GAMMA_DMACOUNT)) ; while (GAMMA_READ(GAMMA_INFIFOSPACE) < 3) @@ -122,7 +62,7 @@ void gamma_dma_quiescent_single(drm_device_t *dev) GAMMA_WRITE(GAMMA_FILTERMODE, 1 << 10); GAMMA_WRITE(GAMMA_SYNC, 0); - + do { while (!GAMMA_READ(GAMMA_OUTFIFOWORDS)) ; @@ -131,6 +71,9 @@ void gamma_dma_quiescent_single(drm_device_t *dev) void gamma_dma_quiescent_dual(drm_device_t *dev) { + drm_gamma_private_t *dev_priv = + (drm_gamma_private_t *)dev->dev_private; + while (GAMMA_READ(GAMMA_DMACOUNT)) ; while (GAMMA_READ(GAMMA_INFIFOSPACE) < 3) @@ -140,13 +83,13 @@ void gamma_dma_quiescent_dual(drm_device_t *dev) GAMMA_WRITE(GAMMA_FILTERMODE, 1 << 10); GAMMA_WRITE(GAMMA_SYNC, 0); - + /* Read from first MX */ do { while (!GAMMA_READ(GAMMA_OUTFIFOWORDS)) ; } while (GAMMA_READ(GAMMA_OUTPUTFIFO) != GAMMA_SYNC_TAG); - + /* Read from second MX */ do { while (!GAMMA_READ(GAMMA_OUTFIFOWORDS + 0x10000)) @@ -156,20 +99,28 @@ void gamma_dma_quiescent_dual(drm_device_t *dev) void gamma_dma_ready(drm_device_t *dev) { + drm_gamma_private_t *dev_priv = + (drm_gamma_private_t *)dev->dev_private; + while (GAMMA_READ(GAMMA_DMACOUNT)) ; } static inline int gamma_dma_is_ready(drm_device_t *dev) { + drm_gamma_private_t *dev_priv = + (drm_gamma_private_t *)dev->dev_private; + return !GAMMA_READ(GAMMA_DMACOUNT); } -static void gamma_dma_service(int irq, void *device, struct pt_regs *regs) +void gamma_dma_service(int irq, void *device, struct pt_regs *regs) { - drm_device_t *dev = (drm_device_t *)device; - drm_device_dma_t *dma = dev->dma; - + drm_device_t *dev = (drm_device_t *)device; + drm_device_dma_t *dma = dev->dma; + drm_gamma_private_t *dev_priv = + (drm_gamma_private_t *)dev->dev_private; + atomic_inc(&dev->counts[6]); /* _DRM_STAT_IRQ */ GAMMA_WRITE(GAMMA_GDELAYTIMER, 0xc350/2); /* 0x05S */ GAMMA_WRITE(GAMMA_GCOMMANDINTFLAGS, 8); @@ -202,7 +153,7 @@ static int gamma_do_dma(drm_device_t *dev, int locked) #endif if (test_and_set_bit(0, &dev->dma_flag)) return -EBUSY; - + #if DRM_DMA_HISTOGRAM dma_start = get_cycles(); #endif @@ -234,7 +185,7 @@ static int gamma_do_dma(drm_device_t *dev, int locked) clear_bit(0, &dev->dma_flag); return 0; } - + if (!gamma_dma_is_ready(dev)) { clear_bit(0, &dev->dma_flag); return -EBUSY; @@ -258,13 +209,14 @@ static int gamma_do_dma(drm_device_t *dev, int locked) && !(dev->queuelist[buf->context]->flags & _DRM_CONTEXT_PRESERVED)) { /* PRE: dev->last_context != buf->context */ - if (drm_context_switch(dev, dev->last_context, buf->context)) { - gamma_clear_next_buffer(dev); - gamma_free_buffer(dev, buf); + if (DRM(context_switch)(dev, dev->last_context, + buf->context)) { + DRM(clear_next_buffer)(dev); + DRM(free_buffer)(dev, buf); } retcode = -EBUSY; goto cleanup; - + /* POST: we will wait for the context switch and will dispatch on a later call when dev->last_context == buf->context. @@ -305,12 +257,12 @@ cleanup: return retcode; } -static void gamma_dma_schedule_timer_wrapper(unsigned long dev) +static void gamma_dma_timer_bh(unsigned long dev) { gamma_dma_schedule((drm_device_t *)dev, 0); } -static void gamma_dma_schedule_tq_wrapper(void *dev) +void gamma_dma_immediate_bh(void *dev) { gamma_dma_schedule(dev, 0); } @@ -354,8 +306,7 @@ again: if (!(retcode = gamma_do_dma(dev, locked))) ++processed; } else { do { - next = gamma_select_queue(dev, - gamma_dma_schedule_timer_wrapper); + next = gamma_select_queue(dev, gamma_dma_timer_bh); if (next >= 0) { q = dev->queuelist[next]; buf = gamma_waitlist_get(&q->waitlist); @@ -383,9 +334,9 @@ again: goto again; } } - + clear_bit(0, &dev->interrupt_flag); - + #if DRM_DMA_HISTOGRAM atomic_inc(&dev->histo.schedule[gamma_histogram_slot(get_cycles() - schedule_start)]); @@ -472,15 +423,15 @@ static int gamma_dma_priority(drm_device_t *dev, drm_dma_t *d) goto cleanup; } buf->pending = 1; - + if (dev->last_context != buf->context && !(dev->queuelist[buf->context]->flags & _DRM_CONTEXT_PRESERVED)) { add_wait_queue(&dev->context_wait, &entry); current->state = TASK_INTERRUPTIBLE; /* PRE: dev->last_context != buf->context */ - drm_context_switch(dev, dev->last_context, - buf->context); + DRM(context_switch)(dev, dev->last_context, + buf->context); /* POST: we will wait for the context switch and will dispatch on a later call when dev->last_context == buf->context. @@ -507,7 +458,7 @@ static int gamma_dma_priority(drm_device_t *dev, drm_dma_t *d) gamma_dma_dispatch(dev, address, length); atomic_inc(&dev->counts[9]); /* _DRM_STAT_SPECIAL */ atomic_add(length, &dev->counts[8]); /* _DRM_STAT_PRIMARY */ - + if (last_buf) { gamma_free_buffer(dev, last_buf); } @@ -520,7 +471,7 @@ cleanup: gamma_dma_ready(dev); gamma_free_buffer(dev, last_buf); } - + if (must_free && !dev->context_flag) { if (gamma_lock_free(dev, &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT)) { @@ -542,15 +493,15 @@ static int gamma_dma_send_buffers(drm_device_t *dev, drm_dma_t *d) last_buf = dma->buflist[d->send_indices[d->send_count-1]]; add_wait_queue(&last_buf->dma_wait, &entry); } - + if ((retcode = gamma_dma_enqueue(dev, d))) { if (d->flags & _DRM_DMA_BLOCK) remove_wait_queue(&last_buf->dma_wait, &entry); return retcode; } - + gamma_dma_schedule(dev, 0); - + if (d->flags & _DRM_DMA_BLOCK) { DRM_DEBUG("%d waiting\n", current->pid); for (;;) { @@ -618,7 +569,7 @@ int gamma_dma(struct inode *inode, struct file *filp, unsigned int cmd, if (d.send_count) { if (d.flags & _DRM_DMA_PRIORITY) retcode = gamma_dma_priority(dev, &d); - else + else retcode = gamma_dma_send_buffers(dev, &d); } @@ -635,105 +586,3 @@ int gamma_dma(struct inode *inode, struct file *filp, unsigned int cmd, return retcode; } - -int gamma_irq_install(drm_device_t *dev, int irq) -{ - int retcode; - - if (!irq) return -EINVAL; - - down(&dev->struct_sem); - if (dev->irq) { - up(&dev->struct_sem); - return -EBUSY; - } - dev->irq = irq; - up(&dev->struct_sem); - - DRM_DEBUG("%d\n", irq); - - dev->context_flag = 0; - dev->interrupt_flag = 0; - dev->dma_flag = 0; - - dev->dma->next_buffer = NULL; - dev->dma->next_queue = NULL; - dev->dma->this_buffer = NULL; - - INIT_LIST_HEAD(&dev->tq.list); - dev->tq.sync = 0; - dev->tq.routine = gamma_dma_schedule_tq_wrapper; - dev->tq.data = dev; - - - /* Before installing handler */ - GAMMA_WRITE(GAMMA_GCOMMANDMODE, 0); - GAMMA_WRITE(GAMMA_GDMACONTROL, 0); - - /* Install handler */ - if ((retcode = request_irq(dev->irq, - gamma_dma_service, - 0, - dev->devname, - dev))) { - down(&dev->struct_sem); - dev->irq = 0; - up(&dev->struct_sem); - return retcode; - } - - /* After installing handler */ - GAMMA_WRITE(GAMMA_GINTENABLE, 0x2001); - GAMMA_WRITE(GAMMA_COMMANDINTENABLE, 0x0008); - GAMMA_WRITE(GAMMA_GDELAYTIMER, 0x39090); - - return 0; -} - -int gamma_irq_uninstall(drm_device_t *dev) -{ - int irq; - - down(&dev->struct_sem); - irq = dev->irq; - dev->irq = 0; - up(&dev->struct_sem); - - if (!irq) return -EINVAL; - - DRM_DEBUG("%d\n", irq); - - GAMMA_WRITE(GAMMA_GDELAYTIMER, 0); - GAMMA_WRITE(GAMMA_COMMANDINTENABLE, 0); - GAMMA_WRITE(GAMMA_GINTENABLE, 0); - free_irq(irq, dev); - - return 0; -} - - -int gamma_control(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_control_t ctl; - int retcode; - - if (copy_from_user(&ctl, (drm_control_t *)arg, sizeof(ctl))) - return -EFAULT; - - switch (ctl.func) { - case DRM_INST_HANDLER: - if ((retcode = gamma_irq_install(dev, ctl.irq))) - return retcode; - break; - case DRM_UNINST_HANDLER: - if ((retcode = gamma_irq_uninstall(dev))) - return retcode; - break; - default: - return -EINVAL; - } - return 0; -} diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_drm.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_drm.c deleted file mode 100644 index 4b12d8c47..000000000 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_drm.c +++ /dev/null @@ -1,33 +0,0 @@ -#define __NO_VERSION__ -#include "gamma.h" -#include "drmP.h" -#include "gamma_drv.h" - -#define DRIVER_DEV_PRIV_T drm_gamma_private_t -#define DRIVER_AGP_BUFFER_MAP dev_priv->buffers - -#include "drm_auth.h" - -#include "drm_bufs.h" - -#include "drm_dma.h" - -#include "drm_drawable.h" - -#include "drm_fops.h" - -#include "drm_init.h" - -#include "drm_ioctl.h" - -#include "drm_lists.h" - -#include "drm_lock.h" - -#include "drm_memory.h" - -#include "drm_proc.h" - -#include "drm_vm.h" - -#include "drm_stub.h" diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_drv.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_drv.c index c24d5a33c..98916bc53 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_drv.c +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_drv.c @@ -26,7 +26,7 @@ * * Authors: * Rickard E. (Rik) Faith <faith@valinux.com> - * + * Gareth Hughes <gareth@valinux.com> */ #include <linux/config.h> @@ -38,29 +38,15 @@ #define DRIVER_NAME "gamma" #define DRIVER_DESC "3DLabs gamma" -#define DRIVER_DATE "20010215" +#define DRIVER_DATE "20010216" #define DRIVER_MAJOR 1 #define DRIVER_MINOR 0 #define DRIVER_PATCHLEVEL 0 - #define DRIVER_IOCTLS \ [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { gamma_dma, 1, 0 } -#define __HAVE_MTRR 1 -#define __HAVE_CTX_BITMAP 0 -#define __HAVE_PCI_DMA 1 -#define __HAVE_MULTIPLE_DMA_QUEUES 1 -#define __HAVE_DMA_FLUSH 1 -#define __HAVE_DMA_QUEUE 0 -#define __HAVE_DMA_SCHEDULE 1 -#define __HAVE_DMA_WAITQUEUE 1 -#define __HAVE_DMA_WAITLIST 1 -#define __HAVE_DMA_FREELIST 1 -#define __HAVE_DMA 1 -#define __HAVE_OLD_DMA 1 -#define __HAVE_DMA_IRQ 1 #define __HAVE_COUNTERS 5 #define __HAVE_COUNTER6 _DRM_STAT_IRQ @@ -69,35 +55,19 @@ #define __HAVE_COUNTER9 _DRM_STAT_SPECIAL #define __HAVE_COUNTER10 _DRM_STAT_MISSED -#define __HAVE_DMA_READY 1 -#define DRIVER_DMA_READY() \ -do { \ - gamma_dma_ready(dev); \ -} while (0) - -#define __HAVE_DMA_QUIESCENT 1 -#define DRIVER_DMA_QUIESCENT() \ -do { \ - /* FIXME ! */ \ - gamma_dma_quiescent_dual(dev); \ - return 0; \ -} while (0) - -#if 0 -#define __HAVE_DRIVER_RELEASE 1 -#define DRIVER_RELEASE() do { \ - gamma_reclaim_buffers( dev, priv->pid ); \ - if ( dev->dev_private ) { \ - drm_gamma_private_t *dev_priv = dev->dev_private; \ - dev_priv->dispatch_status &= MGA_IN_DISPATCH; \ - } \ -} while (0) -#endif - -#if 0 -#define DRIVER_PRETAKEDOWN() do { \ - if ( dev->dev_private ) gamma_do_cleanup_dma( dev ); \ -} while (0) -#endif +#include "drm_auth.h" +#include "drm_bufs.h" +#include "drm_context.h" +#include "drm_dma.h" +#include "drm_drawable.h" #include "drm_drv.h" +#include "drm_fops.h" +#include "drm_init.h" +#include "drm_ioctl.h" +#include "drm_lists.h" +#include "drm_lock.h" +#include "drm_memory.h" +#include "drm_proc.h" +#include "drm_vm.h" +#include "drm_stub.h" diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_drv.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_drv.h index 1bfa26509..68b520700 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_drv.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_drv.h @@ -11,11 +11,11 @@ * 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 @@ -23,10 +23,10 @@ * 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: * Rickard E. (Rik) Faith <faith@valinux.com> - * + * */ #ifndef _GAMMA_DRV_H_ @@ -35,6 +35,10 @@ typedef struct drm_gamma_private { drm_map_t *buffers; + drm_map_t *mmio0; + drm_map_t *mmio1; + drm_map_t *mmio2; + drm_map_t *mmio3; } drm_gamma_private_t; #define LOCK_TEST_WITH_RETURN( dev ) \ @@ -47,30 +51,55 @@ do { \ } \ } while (0) + extern void gamma_dma_ready(drm_device_t *dev); extern void gamma_dma_quiescent_single(drm_device_t *dev); extern void gamma_dma_quiescent_dual(drm_device_t *dev); - /* gamma_drv.c */ -extern int gamma_version(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); -extern int gamma_open(struct inode *inode, struct file *filp); -extern int gamma_release(struct inode *inode, struct file *filp); -extern int gamma_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); -extern int gamma_lock(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); -extern int gamma_unlock(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); /* gamma_dma.c */ extern int gamma_dma_schedule(drm_device_t *dev, int locked); extern int gamma_dma(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); -extern int gamma_irq_install(drm_device_t *dev, int irq); -extern int gamma_irq_uninstall(drm_device_t *dev); -extern int gamma_control(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); extern int gamma_find_devices(void); extern int gamma_found(void); + +#define GAMMA_OFF(reg) \ + ((reg < 0x1000) \ + ? reg \ + : ((reg < 0x10000) \ + ? (reg - 0x1000) \ + : ((reg < 0x11000) \ + ? (reg - 0x10000) \ + : (reg - 0x11000)))) + +#define GAMMA_BASE(reg) ((unsigned long) \ + ((reg < 0x1000) ? dev_priv->mmio0->handle : \ + ((reg < 0x10000) ? dev_priv->mmio1->handle : \ + ((reg < 0x11000) ? dev_priv->mmio2->handle : \ + dev_priv->mmio3->handle)))) + +#define GAMMA_ADDR(reg) (GAMMA_BASE(reg) + GAMMA_OFF(reg)) +#define GAMMA_DEREF(reg) *(__volatile__ int *)GAMMA_ADDR(reg) +#define GAMMA_READ(reg) GAMMA_DEREF(reg) +#define GAMMA_WRITE(reg,val) do { GAMMA_DEREF(reg) = val; } while (0) + +#define GAMMA_BROADCASTMASK 0x9378 +#define GAMMA_COMMANDINTENABLE 0x0c48 +#define GAMMA_DMAADDRESS 0x0028 +#define GAMMA_DMACOUNT 0x0030 +#define GAMMA_FILTERMODE 0x8c00 +#define GAMMA_GCOMMANDINTFLAGS 0x0c50 +#define GAMMA_GCOMMANDMODE 0x0c40 +#define GAMMA_GCOMMANDSTATUS 0x0c60 +#define GAMMA_GDELAYTIMER 0x0c38 +#define GAMMA_GDMACONTROL 0x0060 +#define GAMMA_GINTENABLE 0x0808 +#define GAMMA_GINTFLAGS 0x0810 +#define GAMMA_INFIFOSPACE 0x0018 +#define GAMMA_OUTFIFOWORDS 0x0020 +#define GAMMA_OUTPUTFIFO 0x2000 +#define GAMMA_SYNC 0x8c40 +#define GAMMA_SYNC_TAG 0x0188 + #endif diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810.h index 021d7988c..ed25b2a99 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810.h @@ -34,17 +34,79 @@ */ #define DRM(x) i810_##x +/* General customization: + */ #define __HAVE_AGP 1 #define __MUST_HAVE_AGP 1 - #define __HAVE_MTRR 1 - #define __HAVE_CTX_BITMAP 1 +/* Driver customization: + */ +#define __HAVE_RELEASE 1 +#define DRIVER_RELEASE() do { \ + i810_reclaim_buffers( dev, priv->pid ); \ +} while (0) + +/* DMA customization: + */ #define __HAVE_DMA 1 -#define __HAVE_DMA_IRQ 1 #define __HAVE_DMA_QUEUE 1 #define __HAVE_DMA_WAITLIST 1 #define __HAVE_DMA_RECLAIM 1 +#define __HAVE_DMA_QUIESCENT 1 +#define DRIVER_DMA_QUIESCENT() do { \ + i810_dma_quiescent( dev ); \ +} while (0) + +#define __HAVE_DMA_IRQ 1 +#define __HAVE_DMA_IRQ_BH 1 +#define DRIVER_PREINSTALL() do { \ + drm_i810_private_t *dev_priv = \ + (drm_i810_private_t *)dev->dev_private; \ + u16 tmp; \ + tmp = I810_READ16( I810REG_HWSTAM ); \ + tmp = tmp & 0x6000; \ + I810_WRITE16( I810REG_HWSTAM, tmp ); \ + \ + tmp = I810_READ16( I810REG_INT_MASK_R ); \ + tmp = tmp & 0x6000; /* Unmask interrupts */ \ + I810_WRITE16( I810REG_INT_MASK_R, tmp ); \ + tmp = I810_READ16( I810REG_INT_ENABLE_R ); \ + tmp = tmp & 0x6000; /* Disable all interrupts */ \ + I810_WRITE16( I810REG_INT_ENABLE_R, tmp ); \ +} while (0) + +#define DRIVER_POSTINSTALL() do { \ + drm_i810_private_t *dev_priv = \ + (drm_i810_private_t *)dev->dev_private; \ + u16 tmp; \ + tmp = I810_READ16( I810REG_INT_ENABLE_R ); \ + tmp = tmp & 0x6000; \ + tmp = tmp | 0x0003; /* Enable bp & user interrupts */ \ + I810_WRITE16( I810REG_INT_ENABLE_R, tmp ); \ +} while (0) + +#define DRIVER_UNINSTALL() do { \ + drm_i810_private_t *dev_priv = \ + (drm_i810_private_t *)dev->dev_private; \ + u16 tmp; \ + tmp = I810_READ16( I810REG_INT_IDENTITY_R ); \ + tmp = tmp & ~(0x6000); /* Clear all interrupts */ \ + if ( tmp != 0 ) I810_WRITE16( I810REG_INT_IDENTITY_R, tmp ); \ + \ + tmp = I810_READ16( I810REG_INT_ENABLE_R ); \ + tmp = tmp & 0x6000; /* Disable all interrupts */ \ + I810_WRITE16( I810REG_INT_ENABLE_R, tmp ); \ +} while (0) + +/* Buffer customization: + */ + +#define DRIVER_BUF_PRIV_T drm_i810_buf_priv_t + +#define DRIVER_AGP_BUFFERS_MAP( dev ) \ + ((drm_i810_private_t *)((dev)->dev_private))->buffer_map + #endif diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_dma.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_dma.c index 8c50b3204..4c90496a7 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_dma.c +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_dma.c @@ -48,16 +48,6 @@ #define I810_BUF_UNMAPPED 0 #define I810_BUF_MAPPED 1 -#define I810_BASE(reg) ((unsigned long) \ - dev_priv->mmio_map->handle) -#define I810_ADDR(reg) (I810_BASE(reg) + reg) -#define I810_DEREF(reg) *(__volatile__ int *)I810_ADDR(reg) -#define I810_READ(reg) I810_DEREF(reg) -#define I810_WRITE(reg,val) do { I810_DEREF(reg) = val; } while (0) -#define I810_DEREF16(reg) *(__volatile__ u16 *)I810_ADDR(reg) -#define I810_READ16(reg) I810_DEREF16(reg) -#define I810_WRITE16(reg,val) do { I810_DEREF16(reg) = val; } while (0) - #define RING_LOCALS unsigned int outring, ringmask; volatile char *virt; #define BEGIN_LP_RING(n) do { \ @@ -875,7 +865,7 @@ static void i810_dma_dispatch_vertex(drm_device_t *dev, /* Interrupts are only for flushing */ -static void i810_dma_service(int irq, void *device, struct pt_regs *regs) +void i810_dma_service(int irq, void *device, struct pt_regs *regs) { drm_device_t *dev = (drm_device_t *)device; drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; @@ -893,7 +883,7 @@ static void i810_dma_service(int irq, void *device, struct pt_regs *regs) mark_bh(IMMEDIATE_BH); } -static void i810_dma_task_queue(void *device) +void i810_dma_immediate_bh(void *device) { drm_device_t *dev = (drm_device_t *) device; drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; @@ -902,131 +892,6 @@ static void i810_dma_task_queue(void *device) wake_up_interruptible(&dev_priv->flush_queue); } -int i810_irq_install(drm_device_t *dev, int irq) -{ - drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; - int retcode; - u16 temp; - - if (!irq) return -EINVAL; - - down(&dev->struct_sem); - if (dev->irq) { - up(&dev->struct_sem); - return -EBUSY; - } - dev->irq = irq; - up(&dev->struct_sem); - - DRM_DEBUG( "Interrupt Install : %d\n", irq); - DRM_DEBUG("%d\n", irq); - - dev->context_flag = 0; - dev->interrupt_flag = 0; - dev->dma_flag = 0; - - dev->dma->next_buffer = NULL; - dev->dma->next_queue = NULL; - dev->dma->this_buffer = NULL; - - INIT_LIST_HEAD(&dev->tq.list); - dev->tq.sync = 0; - dev->tq.routine = i810_dma_task_queue; - dev->tq.data = dev; - - /* Before installing handler */ - temp = I810_READ16(I810REG_HWSTAM); - temp = temp & 0x6000; - I810_WRITE16(I810REG_HWSTAM, temp); - - temp = I810_READ16(I810REG_INT_MASK_R); - temp = temp & 0x6000; - I810_WRITE16(I810REG_INT_MASK_R, temp); /* Unmask interrupts */ - temp = I810_READ16(I810REG_INT_ENABLE_R); - temp = temp & 0x6000; - I810_WRITE16(I810REG_INT_ENABLE_R, temp); /* Disable all interrupts */ - - /* Install handler */ - if ((retcode = request_irq(dev->irq, - i810_dma_service, - SA_SHIRQ, - dev->devname, - dev))) { - down(&dev->struct_sem); - dev->irq = 0; - up(&dev->struct_sem); - return retcode; - } - temp = I810_READ16(I810REG_INT_ENABLE_R); - temp = temp & 0x6000; - temp = temp | 0x0003; - I810_WRITE16(I810REG_INT_ENABLE_R, - temp); /* Enable bp & user interrupts */ - return 0; -} - -int i810_irq_uninstall(drm_device_t *dev) -{ - drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; - int irq; - u16 temp; - - -/* return 0; */ - - down(&dev->struct_sem); - irq = dev->irq; - dev->irq = 0; - up(&dev->struct_sem); - - if (!irq) return -EINVAL; - - DRM_DEBUG( "Interrupt UnInstall: %d\n", irq); - DRM_DEBUG("%d\n", irq); - - temp = I810_READ16(I810REG_INT_IDENTITY_R); - temp = temp & ~(0x6000); - if(temp != 0) I810_WRITE16(I810REG_INT_IDENTITY_R, - temp); /* Clear all interrupts */ - - temp = I810_READ16(I810REG_INT_ENABLE_R); - temp = temp & 0x6000; - I810_WRITE16(I810REG_INT_ENABLE_R, - temp); /* Disable all interrupts */ - - free_irq(irq, dev); - - return 0; -} - -int i810_control(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_control_t ctl; - int retcode; - - DRM_DEBUG( "i810_control\n"); - - if (copy_from_user(&ctl, (drm_control_t *)arg, sizeof(ctl))) - return -EFAULT; - - switch (ctl.func) { - case DRM_INST_HANDLER: - if ((retcode = i810_irq_install(dev, ctl.irq))) - return retcode; - break; - case DRM_UNINST_HANDLER: - if ((retcode = i810_irq_uninstall(dev))) - return retcode; - break; - default: - return -EINVAL; - } - return 0; -} - static inline void i810_dma_emit_flush(drm_device_t *dev) { drm_i810_private_t *dev_priv = dev->dev_private; diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.c index 86ab394d9..12a59dbf3 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.c +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.c @@ -56,42 +56,26 @@ [DRM_IOCTL_NR(DRM_IOCTL_I810_COPY)] = { i810_copybuf, 1, 0 }, \ [DRM_IOCTL_NR(DRM_IOCTL_I810_DOCOPY)] = { i810_docopy, 1, 0 }, + #define __HAVE_COUNTERS 4 #define __HAVE_COUNTER6 _DRM_STAT_IRQ #define __HAVE_COUNTER7 _DRM_STAT_PRIMARY #define __HAVE_COUNTER8 _DRM_STAT_SECONDARY #define __HAVE_COUNTER9 _DRM_STAT_DMA -#define __HAVE_DMA_QUIESCENT 1 -#define DRIVER_DMA_QUIESCENT() do { \ - i810_dma_quiescent( dev ); \ -} while (0) - -#define __HAVE_RELEASE 1 -#define DRIVER_RELEASE() do { \ - i810_reclaim_buffers( dev, priv->pid ); \ -} while (0) - -#include "drm_drv.h" - - -#define DRIVER_BUF_PRIV_T drm_i810_buf_priv_t - -#define DRIVER_AGP_BUFFERS_MAP( dev ) \ - ((drm_i810_private_t *)((dev)->dev_private))->buffer_map - -#include "drm_bufs.h" - #include "drm_agpsupport.h" #include "drm_auth.h" +#include "drm_bufs.h" #include "drm_context.h" #include "drm_dma.h" #include "drm_drawable.h" +#include "drm_drv.h" #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" #include "drm_lock.h" +#include "drm_lists.h" #include "drm_memory.h" #include "drm_proc.h" #include "drm_vm.h" diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.h index 1f6e14680..e1b17148e 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.h @@ -81,12 +81,6 @@ typedef struct drm_i810_private { extern int i810_dma_schedule(drm_device_t *dev, int locked); extern int i810_getbuf(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); -extern int i810_irq_install(drm_device_t *dev, int irq); -extern int i810_irq_uninstall(drm_device_t *dev); -extern int i810_control(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); -extern int i810_lock(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); extern int i810_dma_init(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int i810_flush_ioctl(struct inode *inode, struct file *filp, @@ -114,6 +108,18 @@ int i810_swap_bufs(struct inode *inode, struct file *filp, int i810_clear_bufs(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); + +#define I810_BASE(reg) ((unsigned long) \ + dev_priv->mmio_map->handle) +#define I810_ADDR(reg) (I810_BASE(reg) + reg) +#define I810_DEREF(reg) *(__volatile__ int *)I810_ADDR(reg) +#define I810_READ(reg) I810_DEREF(reg) +#define I810_WRITE(reg,val) do { I810_DEREF(reg) = val; } while (0) +#define I810_DEREF16(reg) *(__volatile__ u16 *)I810_ADDR(reg) +#define I810_READ16(reg) I810_DEREF16(reg) +#define I810_WRITE16(reg,val) do { I810_DEREF16(reg) = val; } while (0) + + #define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23)) #define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23)) #define CMD_REPORT_HEAD (7<<23) diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga.h index 9b2224048..277aa2029 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga.h @@ -34,13 +34,34 @@ */ #define DRM(x) mga_##x +/* General customization: + */ #define __HAVE_AGP 1 #define __MUST_HAVE_AGP 1 - #define __HAVE_MTRR 1 - #define __HAVE_CTX_BITMAP 1 +/* Driver customization: + */ +#define DRIVER_PRETAKEDOWN() do { \ + if ( dev->dev_private ) mga_do_cleanup_dma( dev ); \ +} while (0) + +/* DMA customization: + */ #define __HAVE_DMA 1 +#define __HAVE_DMA_QUIESCENT 1 +#define DRIVER_DMA_QUIESCENT() do { \ + drm_mga_private_t *dev_priv = dev->dev_private; \ + return mga_do_wait_for_idle( dev_priv ); \ +} while (0) + +/* Buffer customization: + */ +#define DRIVER_BUF_PRIV_T drm_mga_buf_priv_t + +#define DRIVER_AGP_BUFFERS_MAP( dev ) \ + ((drm_mga_private_t *)((dev)->dev_private))->buffers + #endif diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_dma.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_dma.c index 275495dc6..21e14f376 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_dma.c +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_dma.c @@ -57,7 +57,6 @@ int mga_do_wait_for_idle( drm_mga_private_t *dev_priv ) for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { status = MGA_READ( MGA_STATUS ) & MGA_ENGINE_IDLE_MASK; if ( status == MGA_ENDPRDMASTS ) { - /* printk("I'm not busy, flushing pixel cache\n"); */ MGA_WRITE8( MGA_CRTC_INDEX, 0 ); return 0; } @@ -273,7 +272,8 @@ static void mga_freelist_print( drm_device_t *dev ) DRM_INFO( "\n" ); DRM_INFO( "current dispatch: last=0x%x done=0x%x\n", dev_priv->sarea_priv->last_dispatch, - *dev_priv->prim.head - dev_priv->primary->offset ); + (unsigned int)(*dev_priv->prim.head - + dev_priv->primary->offset) ); DRM_INFO( "current freelist:\n" ); for ( entry = dev_priv->head->next ; entry ; entry = entry->next ) { @@ -354,7 +354,6 @@ static void mga_freelist_cleanup( drm_device_t *dev ) static void mga_freelist_reset( drm_device_t *dev ) { drm_device_dma_t *dma = dev->dma; - drm_mga_private_t *dev_priv = dev->dev_private; drm_buf_t *buf; drm_mga_buf_priv_t *buf_priv; int i; @@ -400,7 +399,7 @@ static drm_buf_t *mga_freelist_get( drm_device_t *dev ) return NULL; } -static int mga_freelist_put( drm_device_t *dev, drm_buf_t *buf ) +int mga_freelist_put( drm_device_t *dev, drm_buf_t *buf ) { drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_buf_priv_t *buf_priv = buf->dev_private; @@ -412,15 +411,17 @@ static int mga_freelist_put( drm_device_t *dev, drm_buf_t *buf ) dev_priv->primary->offset, buf_priv->list_entry->age.wrap ); - if ( buf_priv->list_entry->age.head == MGA_BUFFER_USED ) { - SET_AGE( &next->age, MGA_BUFFER_FREE, 0 ); - } - /* Put buffer on the head + 1, as the head is a sentinal. */ + next = buf_priv->list_entry; head = dev_priv->head; prev = head->next; + + if ( buf_priv->list_entry->age.head == MGA_BUFFER_USED ) { + SET_AGE( &next->age, MGA_BUFFER_FREE, 0 ); + } + head->next = next; prev->prev = next; next->prev = head; diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drv.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drv.c index 7898c744d..88fa53a6d 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drv.c +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drv.c @@ -38,7 +38,7 @@ #define DRIVER_NAME "mga" #define DRIVER_DESC "Matrox G200/G400" -#define DRIVER_DATE "20010215" +#define DRIVER_DATE "20010216" #define DRIVER_MAJOR 3 #define DRIVER_MINOR 0 @@ -56,38 +56,20 @@ [DRM_IOCTL_NR(DRM_IOCTL_MGA_ILOAD)] = { mga_dma_iload, 1, 0 }, \ [DRM_IOCTL_NR(DRM_IOCTL_MGA_BLIT)] = { mga_dma_blit, 1, 0 }, + #define __HAVE_COUNTERS 3 #define __HAVE_COUNTER6 _DRM_STAT_IRQ #define __HAVE_COUNTER7 _DRM_STAT_PRIMARY #define __HAVE_COUNTER8 _DRM_STAT_SECONDARY -#define __HAVE_DMA_QUIESCENT 1 -#define DRIVER_DMA_QUIESCENT() \ -do { \ - drm_mga_private_t *dev_priv = dev->dev_private; \ - return mga_do_wait_for_idle( dev_priv ); \ -} while (0) - -#define DRIVER_PRETAKEDOWN() do { \ - if ( dev->dev_private ) mga_do_cleanup_dma( dev ); \ -} while (0) - -#include "drm_drv.h" - - -#define DRIVER_BUF_PRIV_T drm_mga_buf_priv_t - -#define DRIVER_AGP_BUFFERS_MAP( dev ) \ - ((drm_mga_private_t *)((dev)->dev_private))->buffers - -#include "drm_bufs.h" - #include "drm_agpsupport.h" #include "drm_auth.h" +#include "drm_bufs.h" #include "drm_context.h" #include "drm_dma.h" #include "drm_drawable.h" +#include "drm_drv.h" #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drv.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drv.h index ab6d9edbb..f56186e1e 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drv.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drv.h @@ -102,18 +102,6 @@ typedef struct drm_mga_private { drm_map_t *agp_textures; } drm_mga_private_t; - /* mga_drv.c */ -extern int mga_version( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern int mga_open( struct inode *inode, struct file *filp ); -extern int mga_release( struct inode *inode, struct file *filp ); -extern int mga_ioctl( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern int mga_lock( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern int mga_unlock( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); - /* mga_dma.c */ extern int mga_dma_init( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ); @@ -121,8 +109,6 @@ extern int mga_dma_flush( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ); extern int mga_dma_reset( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ); -extern int mga_control( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); extern int mga_dma_buffers( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ); @@ -136,7 +122,8 @@ extern void mga_do_dma_flush( drm_mga_private_t *dev_priv ); extern void mga_do_dma_wrap_start( drm_mga_private_t *dev_priv ); extern void mga_do_dma_wrap_end( drm_mga_private_t *dev_priv ); -extern int mga_irq_uninstall( drm_device_t *dev ); +extern int mga_freelist_put( drm_device_t *dev, drm_buf_t *buf ); + /* mga_state.c */ extern int mga_dma_clear( struct inode *inode, struct file *filp, diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128.h index 0440501ee..83e002afa 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128.h @@ -34,13 +34,46 @@ */ #define DRM(x) r128_##x +/* General customization: + */ #define __HAVE_AGP 1 #define __MUST_HAVE_AGP 1 - #define __HAVE_MTRR 1 - #define __HAVE_CTX_BITMAP 1 +/* Driver customization: + */ +#define DRIVER_PRERELEASE() do { \ + if ( dev->dev_private ) { \ + drm_r128_private_t *dev_priv = dev->dev_private; \ + if ( dev_priv->page_flipping ) { \ + r128_do_cleanup_pageflip( dev ); \ + } \ + } \ +} while (0) + +#define DRIVER_PRETAKEDOWN() do { \ + if ( dev->dev_private ) r128_do_cleanup_cce( dev ); \ +} while (0) + +/* DMA customization: + */ #define __HAVE_DMA 1 +#if 0 +/* GH: Remove this for now... */ +#define __HAVE_DMA_QUIESCENT 1 +#define DRIVER_DMA_QUIESCENT() do { \ + drm_r128_private_t *dev_priv = dev->dev_private; \ + return r128_do_cce_idle( dev_priv ); \ +} while (0) +#endif + +/* Buffer customization: + */ +#define DRIVER_BUF_PRIV_T drm_r128_buf_priv_t + +#define DRIVER_AGP_BUFFERS_MAP( dev ) \ + ((drm_r128_private_t *)((dev)->dev_private))->buffers + #endif diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_cce.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_cce.c index 5ffc1d0e2..f4b4f0c4a 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_cce.c +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_cce.c @@ -25,7 +25,7 @@ * DEALINGS IN THE SOFTWARE. * * Authors: - * Gareth Hughes <gareth@valinux.com> + * Gareth Hughes <gareth@valinux.com> */ #define __NO_VERSION__ diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drm.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drm.h index aaf2ce3e0..86aba175f 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drm.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drm.h @@ -25,9 +25,8 @@ * DEALINGS IN THE SOFTWARE. * * Authors: - * Kevin E. Martin <martin@valinux.com> * Gareth Hughes <gareth@valinux.com> - * + * Kevin E. Martin <martin@valinux.com> */ #ifndef __R128_DRM_H__ diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drv.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drv.c index 3bd27ae7d..e42868ed6 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drv.c +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drv.c @@ -38,7 +38,7 @@ #define DRIVER_NAME "r128" #define DRIVER_DESC "ATI Rage 128" -#define DRIVER_DATE "20010215" +#define DRIVER_DATE "20010216" #define DRIVER_MAJOR 2 #define DRIVER_MINOR 1 @@ -62,6 +62,7 @@ [DRM_IOCTL_NR(DRM_IOCTL_R128_STIPPLE)] = { r128_cce_stipple, 1, 0 }, \ [DRM_IOCTL_NR(DRM_IOCTL_R128_INDIRECT)] = { r128_cce_indirect, 1, 1 }, + #if 0 /* GH: Count data sent to card via ring or vertex/indirect buffers. */ @@ -71,41 +72,14 @@ #define __HAVE_COUNTER8 _DRM_STAT_SECONDARY #endif -#define __HAVE_DMA_QUIESCENT 1 -#define DRIVER_DMA_QUIESCENT() do { \ - drm_r128_private_t *dev_priv = dev->dev_private; \ - return r128_do_cce_idle( dev_priv ); \ -} while (0) - -#define DRIVER_PRERELEASE() do { \ - if ( dev->dev_private ) { \ - drm_r128_private_t *dev_priv = dev->dev_private; \ - if ( dev_priv->page_flipping ) { \ - r128_do_cleanup_pageflip( dev ); \ - } \ - } \ -} while (0) - -#define DRIVER_PRETAKEDOWN() do { \ - if ( dev->dev_private ) r128_do_cleanup_cce( dev ); \ -} while (0) - -#include "drm_drv.h" - - -#define DRIVER_BUF_PRIV_T drm_r128_buf_priv_t - -#define DRIVER_AGP_BUFFERS_MAP( dev ) \ - ((drm_r128_private_t *)((dev)->dev_private))->buffers - -#include "drm_bufs.h" - #include "drm_agpsupport.h" #include "drm_auth.h" +#include "drm_bufs.h" #include "drm_context.h" #include "drm_dma.h" #include "drm_drawable.h" +#include "drm_drv.h" #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drv.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drv.h index 950a4711b..9f53746f8 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drv.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drv.h @@ -25,10 +25,9 @@ * DEALINGS IN THE SOFTWARE. * * Authors: - * Rickard E. (Rik) Faith <faith@valinux.com> - * Kevin E. Martin <martin@valinux.com> - * Gareth Hughes <gareth@valinux.com> - * + * Rickard E. (Rik) Faith <faith@valinux.com> + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> */ #ifndef __R128_DRV_H__ @@ -440,8 +439,7 @@ do { \ } \ } while (0) -#define R128_WAIT_UNTIL_PAGE_FLIPPED() \ -do { \ +#define R128_WAIT_UNTIL_PAGE_FLIPPED() do { \ OUT_RING( CCE_PACKET0( R128_WAIT_UNTIL, 0 ) ); \ OUT_RING( R128_EVENT_CRTC_OFFSET ); \ } while (0) @@ -456,7 +454,8 @@ do { \ #define R128_VERBOSE 0 -#define RING_LOCALS int write; unsigned int tail_mask; volatile u32 *ring; +#define RING_LOCALS \ + int write; unsigned int tail_mask; volatile u32 *ring; #define BEGIN_RING( n ) do { \ if ( R128_VERBOSE ) { \ @@ -472,11 +471,23 @@ do { \ tail_mask = dev_priv->ring.tail_mask; \ } while (0) +/* You can set this to zero if you want. If the card locks up, you'll + * need to keep this set. It works around a bug in early revs of the + * Rage 128 chipset, where the CCE would read 32 dwords past the end of + * the ring buffer before wrapping around. + */ +#define R128_BROKEN_CCE 1 + #define ADVANCE_RING() do { \ if ( R128_VERBOSE ) { \ DRM_INFO( "ADVANCE_RING() tail=0x%06x wr=0x%06x\n", \ write, dev_priv->ring.tail ); \ } \ + if ( R128_BROKEN_CCE && write < 32 ) { \ + memcpy( dev_priv->ring.end, \ + dev_priv->ring.start, \ + write * sizeof(u32) ); \ + } \ r128_flush_write_combine(); \ dev_priv->ring.tail = write; \ R128_WRITE( R128_PM4_BUFFER_DL_WPTR, write ); \ diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_state.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_state.c index a4683c4e2..fa16f3ced 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_state.c +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_state.c @@ -25,7 +25,6 @@ * * Authors: * Gareth Hughes <gareth@valinux.com> - * */ #define __NO_VERSION__ diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon.h index 6ef992775..db238b1b4 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon.h @@ -34,13 +34,46 @@ */ #define DRM(x) radeon_##x +/* General customization: + */ #define __HAVE_AGP 1 #define __MUST_HAVE_AGP 1 - #define __HAVE_MTRR 1 - #define __HAVE_CTX_BITMAP 1 +/* Driver customization: + */ +#define DRIVER_PRERELEASE() do { \ + if ( dev->dev_private ) { \ + drm_radeon_private_t *dev_priv = dev->dev_private; \ + if ( dev_priv->page_flipping ) { \ + radeon_do_cleanup_pageflip( dev ); \ + } \ + } \ +} while (0) + +#define DRIVER_PRETAKEDOWN() do { \ + if ( dev->dev_private ) radeon_do_cleanup_cp( dev ); \ +} while (0) + +/* DMA customization: + */ #define __HAVE_DMA 1 +#if 0 +/* GH: Remove this for now... */ +#define __HAVE_DMA_QUIESCENT 1 +#define DRIVER_DMA_QUIESCENT() do { \ + drm_radeon_private_t *dev_priv = dev->dev_private; \ + return radeon_do_cp_idle( dev_priv ); \ +} while (0) +#endif + +/* Buffer customization: + */ +#define DRIVER_BUF_PRIV_T drm_radeon_buf_priv_t + +#define DRIVER_AGP_BUFFERS_MAP( dev ) \ + ((drm_radeon_private_t *)((dev)->dev_private))->buffers + #endif 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 28e64284e..c80665caf 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 @@ -24,9 +24,8 @@ * DEALINGS IN THE SOFTWARE. * * Authors: - * Kevin E. Martin <martin@valinux.com> - * Gareth Hughes <gareth@valinux.com> - * + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> */ #define __NO_VERSION__ @@ -844,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; @@ -877,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; @@ -923,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; @@ -949,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 ); } @@ -965,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 ); } @@ -1019,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) ) ) @@ -1247,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. */ @@ -1278,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 643253d2f..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 @@ -26,7 +26,6 @@ * Authors: * Kevin E. Martin <martin@valinux.com> * Gareth Hughes <gareth@valinux.com> - * */ #ifndef __RADEON_DRM_H__ @@ -74,7 +73,7 @@ /* Vertex/indirect buffer size */ -#define RADEON_BUFFER_SIZE 16384 +#define RADEON_BUFFER_SIZE 65536 /* Byte offsets for indirect buffer data */ @@ -305,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 43f6e2e7b..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 "20010215" +#define DRIVER_DATE "20010305" #define DRIVER_MAJOR 1 #define DRIVER_MINOR 0 @@ -55,10 +55,11 @@ [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 }, + #if 0 /* GH: Count data sent to card via ring or vertex/indirect buffers. */ @@ -68,41 +69,14 @@ #define __HAVE_COUNTER8 _DRM_STAT_SECONDARY #endif -#define __HAVE_DMA_QUIESCENT 1 -#define DRIVER_DMA_QUIESCENT() do { \ - drm_radeon_private_t *dev_priv = dev->dev_private; \ - return radeon_do_cp_idle( dev_priv ); \ -} while (0) - -#define DRIVER_PRERELEASE() do { \ - if ( dev->dev_private ) { \ - drm_radeon_private_t *dev_priv = dev->dev_private; \ - if ( dev_priv->page_flipping ) { \ - radeon_do_cleanup_pageflip( dev ); \ - } \ - } \ -} while (0) - -#define DRIVER_PRETAKEDOWN() do { \ - if ( dev->dev_private ) radeon_do_cleanup_cp( dev ); \ -} while (0) - -#include "drm_drv.h" - - -#define DRIVER_BUF_PRIV_T drm_radeon_buf_priv_t - -#define DRIVER_AGP_BUFFERS_MAP( dev ) \ - ((drm_radeon_private_t *)((dev)->dev_private))->buffers - -#include "drm_bufs.h" - #include "drm_agpsupport.h" #include "drm_auth.h" +#include "drm_bufs.h" #include "drm_context.h" #include "drm_dma.h" #include "drm_drawable.h" +#include "drm_drv.h" #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" 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 656d6e03b..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 @@ -24,10 +24,8 @@ * DEALINGS IN THE SOFTWARE. * * Authors: - * Rickard E. (Rik) Faith <faith@valinux.com> - * Kevin E. Martin <martin@valinux.com> - * Gareth Hughes <gareth@valinux.com> - * + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> */ #ifndef __RADEON_DRV_H__ @@ -163,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, @@ -480,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 */ @@ -504,25 +502,23 @@ extern int radeon_cp_indirect( struct inode *inode, struct file *filp, #define RADEON_BASE(reg) ((u32)(dev_priv->mmio->handle)) -#define RADEON_ADDR(reg) (RADEON_BASE(reg) + reg) +#define RADEON_ADDR(reg) (RADEON_BASE( reg ) + reg) -#define RADEON_DEREF(reg) *(volatile u32 *)RADEON_ADDR(reg) -#define RADEON_READ(reg) RADEON_DEREF(reg) -#define RADEON_WRITE(reg,val) do { RADEON_DEREF(reg) = val; } while (0) +#define RADEON_DEREF(reg) *(volatile u32 *)RADEON_ADDR( reg ) +#define RADEON_READ(reg) RADEON_DEREF( reg ) +#define RADEON_WRITE(reg, val) do { RADEON_DEREF( reg ) = val; } while (0) -#define RADEON_DEREF8(reg) *(volatile u8 *)RADEON_ADDR(reg) -#define RADEON_READ8(reg) RADEON_DEREF8(reg) -#define RADEON_WRITE8(reg,val) do { RADEON_DEREF8(reg) = val; } while (0) +#define RADEON_DEREF8(reg) *(volatile u8 *)RADEON_ADDR( reg ) +#define RADEON_READ8(reg) RADEON_DEREF8( reg ) +#define RADEON_WRITE8(reg, val) do { RADEON_DEREF8( reg ) = val; } while (0) -#define RADEON_WRITE_PLL(addr,val) \ -do { \ - RADEON_WRITE8(RADEON_CLOCK_CNTL_INDEX, \ - ((addr) & 0x1f) | RADEON_PLL_WR_EN); \ - RADEON_WRITE(RADEON_CLOCK_CNTL_DATA, (val)); \ +#define RADEON_WRITE_PLL( addr, val ) do { \ + RADEON_WRITE8( RADEON_CLOCK_CNTL_INDEX, \ + ((addr) & 0x1f) | RADEON_PLL_WR_EN ); \ + RADEON_WRITE( RADEON_CLOCK_CNTL_DATA, (val) ); \ } while (0) -extern int RADEON_READ_PLL(drm_device_t *dev, int addr); - +extern int RADEON_READ_PLL( drm_device_t *dev, int addr ); #define CP_PACKET0( reg, n ) \ @@ -541,54 +537,46 @@ extern int RADEON_READ_PLL(drm_device_t *dev, int addr); * Engine control helper macros */ -#define RADEON_WAIT_UNTIL_2D_IDLE() \ -do { \ +#define RADEON_WAIT_UNTIL_2D_IDLE() do { \ OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) ); \ OUT_RING( (RADEON_WAIT_2D_IDLECLEAN | \ RADEON_WAIT_HOST_IDLECLEAN) ); \ } while (0) -#define RADEON_WAIT_UNTIL_3D_IDLE() \ -do { \ +#define RADEON_WAIT_UNTIL_3D_IDLE() do { \ OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) ); \ OUT_RING( (RADEON_WAIT_3D_IDLECLEAN | \ RADEON_WAIT_HOST_IDLECLEAN) ); \ } while (0) -#define RADEON_WAIT_UNTIL_IDLE() \ -do { \ +#define RADEON_WAIT_UNTIL_IDLE() do { \ OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) ); \ OUT_RING( (RADEON_WAIT_2D_IDLECLEAN | \ RADEON_WAIT_3D_IDLECLEAN | \ RADEON_WAIT_HOST_IDLECLEAN) ); \ } while (0) -#define RADEON_WAIT_UNTIL_PAGE_FLIPPED() \ -do { \ +#define RADEON_WAIT_UNTIL_PAGE_FLIPPED() do { \ OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) ); \ OUT_RING( RADEON_WAIT_CRTC_PFLIP ); \ } while (0) -#define RADEON_FLUSH_CACHE() \ -do { \ +#define RADEON_FLUSH_CACHE() do { \ OUT_RING( CP_PACKET0( RADEON_RB2D_DSTCACHE_CTLSTAT, 0 ) ); \ OUT_RING( RADEON_RB2D_DC_FLUSH ); \ } while (0) -#define RADEON_PURGE_CACHE() \ -do { \ +#define RADEON_PURGE_CACHE() do { \ OUT_RING( CP_PACKET0( RADEON_RB2D_DSTCACHE_CTLSTAT, 0 ) ); \ OUT_RING( RADEON_RB2D_DC_FLUSH_ALL ); \ } while (0) -#define RADEON_FLUSH_ZCACHE() \ -do { \ +#define RADEON_FLUSH_ZCACHE() do { \ OUT_RING( CP_PACKET0( RADEON_RB3D_ZCACHE_CTLSTAT, 0 ) ); \ OUT_RING( RADEON_RB3D_ZC_FLUSH ); \ } while (0) -#define RADEON_PURGE_ZCACHE() \ -do { \ +#define RADEON_PURGE_ZCACHE() do { \ OUT_RING( CP_PACKET0( RADEON_RB3D_ZCACHE_CTLSTAT, 0 ) ); \ OUT_RING( RADEON_RB3D_ZC_FLUSH_ALL ); \ } while (0) @@ -598,6 +586,16 @@ do { \ * 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; \ @@ -627,20 +625,17 @@ do { \ } \ } while (0) -#define RADEON_DISPATCH_AGE( age ) \ -do { \ +#define RADEON_DISPATCH_AGE( age ) do { \ OUT_RING( CP_PACKET0( RADEON_LAST_DISPATCH_REG, 0 ) ); \ OUT_RING( age ); \ } while (0) -#define RADEON_FRAME_AGE( age ) \ -do { \ +#define RADEON_FRAME_AGE( age ) do { \ OUT_RING( CP_PACKET0( RADEON_LAST_FRAME_REG, 0 ) ); \ OUT_RING( age ); \ } while (0) -#define RADEON_CLEAR_AGE( age ) \ -do { \ +#define RADEON_CLEAR_AGE( age ) do { \ OUT_RING( CP_PACKET0( RADEON_LAST_CLEAR_REG, 0 ) ); \ OUT_RING( age ); \ } while (0) 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/kernel/gamma_drm.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/stubsupport-pre24.h index b4acd70a8..f5046f7f9 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_drm.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/stubsupport-pre24.h @@ -1,9 +1,8 @@ -/* gamma_drm.h -- Public header for the Gamma driver -*- linux-c -*- - * Created: Tue Jan 25 01:50:01 1999 by jhartmann@precisioninsight.com +/* stubsupport.h -- -*- linux-c -*- + * Created: Fri Jan 19 10:48:35 2001 by faith@acm.org * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All rights reserved. + * Copyright 2001 VA Linux Systems, Inc., Sunnyvale, 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"), @@ -19,23 +18,27 @@ * 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 AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * PRECISION INSIGHT AND/OR ITS 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. + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. * * Authors: - * Jeff Hartmann <jhartmann@valinux.com> + * Rickard E. (Rik) Faith <faith@valinux.com> + * */ -#ifndef __GAMMA_DRM_H__ -#define __GAMMA_DRM_H__ +#ifndef _STUBSUPPORT_PRE24_H_ +#define _STUBSUPPORT_PRE24_H_ +struct drm_stub_info *DRM(_stub_pointer) = NULL; +#define inter_module_put(x) +#define inter_module_unregister(x) +#define inter_module_get(x) DRM(_stub_pointer) +#define inter_module_register(x,y,z) do { DRM(_stub_pointer) = z; } while (0) -typedef struct drm_gamma_init { - unsigned long hControlRegs0; - unsigned long hControlRegs1; - unsigned long hControlRegs2; - unsigned long hControlRegs3; -} drm_gamma_init_t; + /* This is a kludge for backward compatibility + that is only useful in DRM(stub_open) */ +#define fops_put(fops) MOD_DEC_USE_COUNT +#define fops_get(fops) (fops); MOD_INC_USE_COUNT #endif diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/tdfx.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/tdfx.h index 6af675ff6..40aba8fb2 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/tdfx.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/tdfx.h @@ -34,6 +34,8 @@ */ #define DRM(x) tdfx_##x +/* General customization: + */ #define __HAVE_MTRR 1 #define __HAVE_CTX_BITMAP 1 diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/tdfx_drv.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/tdfx_drv.c index e8d7955ca..f478395f8 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/tdfx_drv.c +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/tdfx_drv.c @@ -38,21 +38,19 @@ #define DRIVER_NAME "tdfx" #define DRIVER_DESC "3dfx Banshee/Voodoo3+" -#define DRIVER_DATE "20010215" +#define DRIVER_DATE "20010216" #define DRIVER_MAJOR 1 #define DRIVER_MINOR 0 #define DRIVER_PATCHLEVEL 0 -#include "drm_drv.h" - -#include "drm_agpsupport.h" #include "drm_auth.h" #include "drm_bufs.h" #include "drm_context.h" #include "drm_dma.h" #include "drm_drawable.h" +#include "drm_drv.h" #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c index f51840201..a640d5987 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c @@ -81,7 +81,18 @@ extern unsigned long _bus_base(void); #include "xf86drm.h" #include "drm.h" -#define DRM_FIXED_DEVICE_MAJOR 145 +#ifndef DRM_MAJOR +#define DRM_MAJOR 226 /* Linux */ +#endif + +#ifndef __linux__ +#undef DRM_MAJOR +#define DRM_MAJOR 145 /* Should set in drm.h for *BSD */ +#endif + +#ifndef DRM_MAX_MINOR +#define DRM_MAX_MINOR 16 +#endif #ifdef __linux__ #include <sys/sysmacros.h> /* for makedev() */ @@ -161,93 +172,108 @@ static drmHashEntry *drmGetEntry(int fd) return entry; } -/* drm_open is used to open the /dev/dri device */ - -static int drm_open(const char *file) -{ - int fd = open(file, O_RDWR, 0); - - if (fd >= 0) return fd; - return -errno; -} - -static int drmOpenDevice(const char *path, long dev, - mode_t mode, uid_t user, gid_t group) +static int drmOpenDevice(long dev, int minor) { #ifdef XFree86LOADER struct xf86stat st; #else struct stat st; #endif + char buf[64]; + int fd; + mode_t dirmode = DRM_DEV_DIRMODE; + mode_t devmode = DRM_DEV_MODE; + int isroot = !geteuid(); +#if defined(XFree86Server) + uid_t user = DRM_DEV_UID; + gid_t group = DRM_DEV_GID; +#endif - /* Fiddle mode to remove execute bits */ - mode &= ~(S_IXUSR|S_IXGRP|S_IXOTH); +#if defined(XFree86Server) + devmode = xf86ConfigDRI.mode ? xf86ConfigDRI.mode : DRM_DEV_MODE; + dirmode = (devmode & S_IRUSR) ? S_IXUSR : 0; + dirmode |= (devmode & S_IRGRP) ? S_IXGRP : 0; + dirmode |= (devmode & S_IROTH) ? S_IXOTH : 0; + dirmode |= devmode; + devmode &= ~(S_IXUSR|S_IXGRP|S_IXOTH); + group = (xf86ConfigDRI.group >= 0) ? xf86ConfigDRI.group : DRM_DEV_GID; +#endif - if (!stat(path, &st) && st.st_rdev == dev) { - if (!geteuid()) { - chown(path, user, group); - chmod(path, mode); - } - return drm_open(path); + if (stat(DRM_DIR_NAME, &st)) { + if (!isroot) return DRM_ERR_NOT_ROOT; + remove(DRM_DIR_NAME); + mkdir(DRM_DIR_NAME, dirmode); } +#if defined(XFree86Server) + chown(DRM_DIR_NAME, user, group); + chmod(DRM_DIR_NAME, dirmode); +#endif - if (geteuid()) return DRM_ERR_NOT_ROOT; - remove(path); - if (mknod(path, S_IFCHR, dev)) { - remove(path); - return DRM_ERR_NOT_ROOT; + sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, minor); + if (stat(buf, &st) || st.st_rdev != dev) { + if (!isroot) return DRM_ERR_NOT_ROOT; + remove(buf); + mknod(buf, S_IFCHR | devmode, dev); } - chown(path, user, group); - chmod(path, mode); - return drm_open(path); +#if defined(XFree86Server) + chown(buf, user, group); + chmod(buf, devmode); +#endif + + if ((fd = open(buf, O_RDWR, 0)) >= 0) return fd; + remove(buf); + return -errno; } -/* drmAvailable looks for /proc/dri, and returns 1 if it is present. On - OSs that do not have a Linux-like /proc, this information will not be - available, and we'll have to create a device and check if the driver is - loaded that way. */ +int drmOpenMinor(int minor, int create) +{ + int fd; + char buf[64]; + + if (create) return drmOpenDevice(makedev(DRM_MAJOR, minor), minor); + + sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, minor); + if ((fd = open(buf, O_RDWR, 0)) >= 0) return fd; + return -errno; +} + +/* drmAvailable looks for (DRM_MAJOR, 0) and returns 1 if it returns + information for DRM_IOCTL_VERSION. For backward compatibility with + older Linux implementations, /proc/dri is also checked. */ int drmAvailable(void) { - char dev_name[64]; drmVersionPtr version; int retval = 0; int fd; - if (!access("/proc/dri/0", R_OK)) return 1; - - sprintf(dev_name, "/dev/dri-temp-%d", getpid()); - - remove(dev_name); - if ((fd = drmOpenDevice(dev_name, makedev(DRM_FIXED_DEVICE_MAJOR, 0), - S_IRUSR, geteuid(), getegid())) >= 0) { - /* Read version to make sure this is - actually a DRI device. */ - if ((version = drmGetVersion(fd))) { - retval = 1; - drmFreeVersion(version); - } - close(fd); + if ((fd = drmOpenMinor(0, 1)) < 0) { + /* Try proc for backward Linux compatibility */ + if (!access("/proc/dri/0", R_OK)) return 1; + return 0; } - remove(dev_name); + + if ((version = drmGetVersion(fd))) { + retval = 1; + drmFreeVersion(version); + } + close(fd); return retval; } static int drmOpenByBusid(const char *busid) { - int i; - char dev_name[64]; - char *buf; - int fd; - - for (i = 0; i < 8; i++) { - sprintf(dev_name, "/dev/dri/card%d", i); - if ((fd = drm_open(dev_name)) >= 0) { + int i; + int fd; + const char *buf; + + for (i = 0; i < DRM_MAX_MINOR; i++) { + if ((fd = drmOpenMinor(i, 0)) >= 0) { buf = drmGetBusid(fd); if (buf && !strcmp(buf, busid)) { - drmFreeBusid(buf); - return fd; + drmFreeBusid(buf); + return fd; } if (buf) drmFreeBusid(buf); close(fd); @@ -258,54 +284,43 @@ static int drmOpenByBusid(const char *busid) static int drmOpenByName(const char *name) { - int i; - char proc_name[64]; - char dev_name[64]; - char buf[512]; - mode_t mode = DRM_DEV_MODE; - mode_t dirmode; - gid_t group = DRM_DEV_GID; - uid_t user = DRM_DEV_UID; - int fd; - char *pt; - char *driver = NULL; - char *devstring; - long dev = 0; - int retcode; - -#if defined(XFree86Server) - mode = xf86ConfigDRI.mode ? xf86ConfigDRI.mode : DRM_DEV_MODE; - group = (xf86ConfigDRI.group >= 0) ? xf86ConfigDRI.group : DRM_DEV_GID; -#endif - -#if defined(XFree86Server) + int i; + int fd; + drmVersionPtr version; + if (!drmAvailable()) { +#if !defined(XFree86Server) + return -1; +#else /* try to load the kernel module now */ if (!xf86LoadKernelModule(name)) { ErrorF("[drm] failed to load kernel module \"%s\"\n", name); return -1; } - } -#else - if (!drmAvailable()) - return -1; #endif + } - if (!geteuid()) { - dirmode = mode; - if (dirmode & S_IRUSR) dirmode |= S_IXUSR; - if (dirmode & S_IRGRP) dirmode |= S_IXGRP; - if (dirmode & S_IROTH) dirmode |= S_IXOTH; - dirmode &= ~(S_IWGRP | S_IWOTH); - mkdir("/dev/dri", 0); - chown("/dev/dri", user, group); - chmod("/dev/dri", dirmode); + for (i = 0; i < DRM_MAX_MINOR; i++) { + if ((fd = drmOpenMinor(i, 1)) >= 0) { + if ((version = drmGetVersion(fd))) { + if (!strcmp(version->name, name)) { + drmFreeVersion(version); + return fd; + } + drmFreeVersion(version); + } + } } +#ifdef __linux__ + /* Backward-compatibility /proc support */ for (i = 0; i < 8; i++) { + char proc_name[64], buf[512]; + char *driver, *pt, *devstring; + int retcode; + sprintf(proc_name, "/proc/dri/%d/name", i); - sprintf(dev_name, "/dev/dri/card%d", i); if ((fd = open(proc_name, 0, 0)) >= 0) { retcode = read(fd, buf, sizeof(buf)-1); close(fd); @@ -319,34 +334,17 @@ static int drmOpenByName(const char *name) for (devstring = ++pt; *pt && *pt != ' '; ++pt) ; if (*pt) { /* Found busid */ - return drmOpenByBusid(++pt); + return drmOpenByBusid(++pt); } else { /* No busid */ - dev = strtol(devstring, NULL, 0); - return drmOpenDevice(dev_name, dev, - mode, user, group); + return drmOpenDevice(strtol(devstring, NULL, 0),i); } } } } - } else { - drmVersionPtr version; - /* /proc/dri not available, possibly - because we aren't on a Linux system. - So, try to create the next device and - see if it's active. */ - dev = makedev(DRM_FIXED_DEVICE_MAJOR, i); - if ((fd = drmOpenDevice(dev_name, dev, mode, user, group))) { - if ((version = drmGetVersion(fd))) { - if (!strcmp(version->name, name)) { - drmFreeVersion(version); - return fd; - } - drmFreeVersion(version); - } - } - remove(dev_name); } } +#endif + return -1; } @@ -1123,6 +1121,160 @@ int drmGetContextPrivateMapping(int fd, drmContext ctx_id, drmHandlePtr handle) return 0; } +int drmGetMap(int fd, int idx, drmHandle *offset, drmSize *size, + drmMapType *type, drmMapFlags *flags, drmHandle *handle, + int *mtrr) +{ + drm_map_t map; + + map.offset = idx; + if (ioctl(fd, DRM_IOCTL_GET_MAP, &map)) return -errno; + *offset = map.offset; + *size = map.size; + *type = map.type; + *flags = map.flags; + *handle = (unsigned long)map.handle; + *mtrr = map.mtrr; + return 0; +} + +int drmGetClient(int fd, int idx, int *auth, int *pid, int *uid, + unsigned long *magic, unsigned long *iocs) +{ + drm_client_t client; + + client.idx = idx; + if (ioctl(fd, DRM_IOCTL_GET_CLIENT, &client)) return -errno; + *auth = client.auth; + *pid = client.pid; + *uid = client.uid; + *magic = client.magic; + *iocs = client.iocs; + return 0; +} + +int drmGetStats(int fd, drmStatsT *stats) +{ + drm_stats_t s; + int i; + + if (ioctl(fd, DRM_IOCTL_GET_STATS, &s)) return -errno; + + stats->count = 0; + memset(stats, 0, sizeof(*stats)); + if (s.count > sizeof(stats->data)/sizeof(stats->data[0])) + return -1; + +#define SET_VALUE \ + stats->data[i].long_format = "%-20.20s"; \ + stats->data[i].rate_format = "%8.8s"; \ + stats->data[i].isvalue = 1; \ + stats->data[i].verbose = 0 + +#define SET_COUNT \ + stats->data[i].long_format = "%-20.20s"; \ + stats->data[i].rate_format = "%5.5s"; \ + stats->data[i].isvalue = 0; \ + stats->data[i].mult_names = "kgm"; \ + stats->data[i].mult = 1000; \ + stats->data[i].verbose = 0 + +#define SET_BYTE \ + stats->data[i].long_format = "%-20.20s"; \ + stats->data[i].rate_format = "%5.5s"; \ + stats->data[i].isvalue = 0; \ + stats->data[i].mult_names = "KGM"; \ + stats->data[i].mult = 1024; \ + stats->data[i].verbose = 0 + + + stats->count = s.count; + for (i = 0; i < s.count; i++) { + stats->data[i].value = s.data[i].value; + switch (s.data[i].type) { + case _DRM_STAT_LOCK: + stats->data[i].long_name = "Lock"; + stats->data[i].rate_name = "Lock"; + SET_VALUE; + break; + case _DRM_STAT_OPENS: + stats->data[i].long_name = "Opens"; + stats->data[i].rate_name = "O"; + SET_COUNT; + stats->data[i].verbose = 1; + break; + case _DRM_STAT_CLOSES: + stats->data[i].long_name = "Closes"; + stats->data[i].rate_name = "Lock"; + SET_COUNT; + stats->data[i].verbose = 1; + break; + case _DRM_STAT_IOCTLS: + stats->data[i].long_name = "Ioctls"; + stats->data[i].rate_name = "Ioc/s"; + SET_COUNT; + break; + case _DRM_STAT_LOCKS: + stats->data[i].long_name = "Locks"; + stats->data[i].rate_name = "Lck/s"; + SET_COUNT; + break; + case _DRM_STAT_UNLOCKS: + stats->data[i].long_name = "Unlocks"; + stats->data[i].rate_name = "Unl/s"; + SET_COUNT; + break; + case _DRM_STAT_IRQ: + stats->data[i].long_name = "IRQs"; + stats->data[i].rate_name = "IRQ/s"; + SET_COUNT; + break; + case _DRM_STAT_PRIMARY: + stats->data[i].long_name = "Primary Bytes"; + stats->data[i].rate_name = "PB/s"; + SET_BYTE; + break; + case _DRM_STAT_SECONDARY: + stats->data[i].long_name = "Secondary Bytes"; + stats->data[i].rate_name = "SB/s"; + SET_BYTE; + break; + case _DRM_STAT_DMA: + stats->data[i].long_name = "DMA"; + stats->data[i].rate_name = "DMA/s"; + SET_COUNT; + break; + case _DRM_STAT_SPECIAL: + stats->data[i].long_name = "Special DMA"; + stats->data[i].rate_name = "dma/s"; + SET_COUNT; + break; + case _DRM_STAT_MISSED: + stats->data[i].long_name = "Miss"; + stats->data[i].rate_name = "Ms/s"; + SET_COUNT; + break; + case _DRM_STAT_VALUE: + stats->data[i].long_name = "Value"; + stats->data[i].rate_name = "Value"; + SET_VALUE; + break; + case _DRM_STAT_BYTE: + stats->data[i].long_name = "Bytes"; + stats->data[i].rate_name = "B/s"; + SET_BYTE; + break; + case _DRM_STAT_COUNT: + default: + stats->data[i].long_name = "Count"; + stats->data[i].rate_name = "Cnt/s"; + SET_COUNT; + break; + } + } + return 0; +} + #if defined(XFree86Server) || defined(DRM_USE_MALLOC) static void drmSIGIOHandler(int interrupt, void *closure) { diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmGlint.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmGlint.c deleted file mode 100644 index 0729c8692..000000000 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmGlint.c +++ /dev/null @@ -1,96 +0,0 @@ -/* xf86drmGlint.c -- User-level interface to Gamma DRM device - * Created: Wed Feb 21 08:31:23 2000 by jhartmann@valinux.com - * - * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas. - * 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 - * PRECISION INSIGHT AND/OR ITS 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. - * - * Author: - * Jeff Hartmann <jhartmann@valinux.com> - * - */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmMga.c,v 1.3 2000/08/24 22:20:17 tsi Exp $ */ - -#ifdef XFree86Server -# include "xf86.h" -# include "xf86_OSproc.h" -# include "xf86_ansic.h" -# include "xf86Priv.h" -# define _DRM_MALLOC xalloc -# define _DRM_FREE xfree -# ifndef XFree86LOADER -# include <sys/stat.h> -# include <sys/mman.h> -# endif -#else -# include <stdio.h> -# include <stdlib.h> -# include <unistd.h> -# include <string.h> -# include <ctype.h> -# include <fcntl.h> -# include <errno.h> -# include <signal.h> -# include <sys/types.h> -# include <sys/stat.h> -# include <sys/ioctl.h> -# include <sys/mman.h> -# include <sys/time.h> -# ifdef DRM_USE_MALLOC -# define _DRM_MALLOC malloc -# define _DRM_FREE free -extern int xf86InstallSIGIOHandler(int fd, void (*f)(int, void *), void *); -extern int xf86RemoveSIGIOHandler(int fd); -# else -# include <Xlibint.h> -# define _DRM_MALLOC Xmalloc -# define _DRM_FREE Xfree -# endif -#endif - -/* Not all systems have MAP_FAILED defined */ -#ifndef MAP_FAILED -#define MAP_FAILED ((void *)-1) -#endif - -#ifdef __linux__ -#include <sys/sysmacros.h> /* for makedev() */ -#endif -#include "xf86drm.h" -#include "xf86drmGlint.h" -#include "drm.h" - -int -drmGLINTInitDMA(int drmFD, drmGLINTInit *init) -{ - drm_gamma_init_t init; - memset(&init, 0, sizeof(drm_gamma_init_t)); - - init.hControlRegs0 = init->hControlRegs0; - init.hControlRegs1 = init->hControlRegs1; - init.hControlRegs2 = init->hControlRegs2; - init.hControlRegs3 = init->hControlRegs3; - - if (ioctl(drmFD, DRM_IOCTL_GAMMA_INIT, &init)) { - return -errno; - } - return 0; -} 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 7c65f5fc3..ddabc2771 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 @@ -44,11 +44,8 @@ #define DRM_IOCTL_NR(n) ((n) & 0xff) #endif -#define DRM_DEV_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) -#define DRM_DEV_UID 0 -#define DRM_DEV_GID 0 - #define DRM_MAJOR 226 +#define DRM_MAX_MINOR 15 #define DRM_NAME "drm" /* Name in kernel, /dev, and /proc */ #define DRM_MIN_ORDER 5 /* At least 2^5 bytes = 32 bytes */ #define DRM_MAX_ORDER 22 /* Up to 2^22 bytes = 4MB */ @@ -453,7 +450,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/xf86drm.h b/xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h index df5ddd8fb..180e15844 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h @@ -33,6 +33,16 @@ #ifndef _XF86DRM_H_ #define _XF86DRM_H_ + /* Defaults, if nothing set in xf86config */ +#define DRM_DEV_UID 0 +#define DRM_DEV_GID 0 +#define DRM_DEV_DIRMODE (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP) +#define DRM_DEV_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) + +#define DRM_DIR_NAME "/dev/dri" +#define DRM_DEV_NAME "%s/card%d" +#define DRM_PROC_NAME "/proc/dri/" /* For backware Linux compatibility */ + #define DRM_ERR_NO_DEVICE (-1001) #define DRM_ERR_NO_ACCESS (-1002) #define DRM_ERR_NOT_ROOT (-1003) @@ -58,6 +68,21 @@ typedef struct _drmVersion { char *desc; /* User-space buffer to hold desc */ } drmVersion, *drmVersionPtr; +typedef struct _drmStats { + unsigned long count; /* Number of data */ + struct { + unsigned long value; /* Value from kernel */ + const char *long_format; /* Suggested format for long_name */ + const char *long_name; /* Long name for value */ + const char *rate_format; /* Suggested format for rate_name */ + const char *rate_name; /* Short name for value per second */ + int isvalue; /* True if value (vs. counter) */ + const char *mult_names; /* Multiplier names (e.g., "KGM") */ + int mult; /* Multiplier value (e.g., 1024) */ + int verbose; /* Suggest only in verbose output */ + } data[15]; +} drmStatsT; + /* All of these enums *MUST* match with the kernel implementation -- so do *NOT* @@ -191,14 +216,7 @@ typedef struct _drmTextureRegion { unsigned int age; } drmTextureRegion, *drmTextureRegionPtr; -#if 0 - /* The kernel does this, but it doesn't - seem necessary with recent gcc's. */ -typedef struct { unsigned int a[100]; } __drm_dummy_lock_t; -#define __drm_dummy_lock(lock) (*(__volatile__ __drm_dummy_lock_t *)lock) -#else #define __drm_dummy_lock(lock) (*(__volatile__ unsigned int *)lock) -#endif #define DRM_LOCK_HELD 0x80000000 /* Hardware lock is held */ #define DRM_LOCK_CONT 0x40000000 /* Hardware lock is contended */ @@ -388,6 +406,14 @@ extern int drmGetMagic(int fd, drmMagicPtr magic); extern char *drmGetBusid(int fd); extern int drmGetInterruptFromBusID(int fd, int busnum, int devnum, int funcnum); +extern int drmGetMap(int fd, int idx, drmHandle *offset, + drmSize *size, drmMapType *type, + drmMapFlags *flags, drmHandle *handle, + int *mtrr); +extern int drmGetClient(int fd, int idx, int *auth, int *pid, + int *uid, unsigned long *magic, + unsigned long *iocs); +extern int drmGetStats(int fd, drmStatsT *stats); /* General user-level programmer's API: X server (root) only */ diff --git a/xc/programs/Xserver/hw/xfree86/os-support/xf86drmGlint.h b/xc/programs/Xserver/hw/xfree86/os-support/xf86drmGlint.h deleted file mode 100644 index 7bd0073a8..000000000 --- a/xc/programs/Xserver/hw/xfree86/os-support/xf86drmGlint.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef __XF86DRI_GLINT_H__ -#define __XF86DRI_GLINT_H__ - -typedef struct _drmGLINTInit { - drmHandle hControlRegs0; - drmHandle hControlRegs1; - drmHandle hControlRegs2; - drmHandle hControlRegs3; -} drmGLINTInit; - -extern int drmGLINTInitDMA(int drmFD, drmGLINTInit *init); - -#endif 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 ); |