diff options
author | dawes <dawes> | 2000-11-07 22:09:49 +0000 |
---|---|---|
committer | dawes <dawes> | 2000-11-07 22:09:49 +0000 |
commit | f93d27aa9ffc3e26ebb937ccd8dfe3319315c70c (patch) | |
tree | 4c21a480eb5dcca70013481c2f9e0873fa09ce6b /xc/lib/GL/mesa/src | |
parent | 0aaf69d45917298d83ad7ddf346914232987aa70 (diff) |
Import of XFree86 4.0.1dX_4_0_1d
Diffstat (limited to 'xc/lib/GL/mesa/src')
98 files changed, 20357 insertions, 2056 deletions
diff --git a/xc/lib/GL/mesa/src/Imakefile b/xc/lib/GL/mesa/src/Imakefile index 779cde990..f8232128f 100644 --- a/xc/lib/GL/mesa/src/Imakefile +++ b/xc/lib/GL/mesa/src/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/Imakefile,v 1.16 2000/08/01 20:28:38 dawes Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/Imakefile,v 1.19 2000/10/20 12:57:22 alanh Exp $ #include <Threads.tmpl> @@ -349,13 +349,19 @@ LinkSourceFile(zoom.h, $(MESASRCDIR)/src) ASM_SRCS = ASM_OBJS = #ifdef MesaUse3DNow - ASM_DEFS = -DUSE_MMX_ASM -DUSE_X86_ASM -DUSE_3DNOW_ASM -#else - ASM_DEFS = -DUSE_MMX_ASM -DUSE_X86_ASM + 3DNOW_DEFS = -DUSE_3DNOW_ASM +#endif +#ifdef MesaUseKatmai + KATMAI_DEFS = -DUSE_KATMAI_ASM +#endif + ASM_DEFS = -DUSE_MMX_ASM -DUSE_X86_ASM $(3DNOW_DEFS) $(KATMAI_DEFS) #endif + +#ifdef UseCompaqMathLibrary + MATHDEF = -DCCPML #endif - DEFINES = $(ALLOC_DEFINES) GlxDefines $(TDFX_DEFS) $(ASM_DEFS) + DEFINES = $(ALLOC_DEFINES) GlxDefines $(TDFX_DEFS) $(ASM_DEFS) $(MATHDEF) INCLUDES = -I$(XLIBSRC) -I$(EXTINCSRC) -I../include -I../../dri -I. -I../../../../include SRCS = $(CORE_SRCS) $(ASM_SRCS) OBJS = $(CORE_OBJS) $(ASM_OBJS) @@ -368,10 +374,6 @@ LinkSourceFile(zoom.h, $(MESASRCDIR)/src) #endif #if GlxBuiltInMesa || GlxDriverUsesMesa || !GlxUseBuiltInDRIDriver - MESASUBDIRS = -#ifdef i386Architecture - ASMSUBDIRS = X86 -#endif #include <Library.tmpl> @@ -380,17 +382,22 @@ LibraryObjectRule() SubdirLibraryRule($(OBJS)) NormalLintTarget($(SRCS)) -#else - -AllTarget($(OBJS)) - -#endif +#ifdef i386Architecture #define IHaveSubdirs #define PassCDebugFlags -SUBDIRS = $(MESASUBDIRS) $(ASMSUBDIRS) +SUBDIRS = X86 MakeSubdirs($(SUBDIRS)) DependSubdirs($(SUBDIRS)) + +#endif + +#else + +AllTarget($(OBJS)) + +#endif + DependTarget() diff --git a/xc/lib/GL/mesa/src/X86/Imakefile b/xc/lib/GL/mesa/src/X86/Imakefile index f97040009..a0cdc8e61 100644 --- a/xc/lib/GL/mesa/src/X86/Imakefile +++ b/xc/lib/GL/mesa/src/X86/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/X86/Imakefile,v 1.10 2000/08/01 20:28:39 dawes Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/X86/Imakefile,v 1.11 2000/09/24 13:51:02 alanh Exp $ #define DoNormalLib NormalLibGlx #define DoSharedLib SharedLibGlx @@ -40,7 +40,7 @@ ALLOC_DEFINES = -DMALLOC_0_RETURNS_NULL #endif #ifdef i386Architecture -XCOMM We'll learn at runtime whether 3dNow, MMX, etc are really present. +XCOMM Determine at runtime whether 3dNow, Katmai, MMX, etc are really present. X86_SRCS = x86a.S common_x86.c common_x86asm.S glapi_x86.S x86.c vertex.S X86_OBJS = x86a.o common_x86.o common_x86asm.o x86.o vertex.o @@ -70,13 +70,28 @@ XCOMM We'll learn at runtime whether 3dNow, MMX, etc are really present. 3DNOW_DEFS = -DUSE_3DNOW_ASM #endif +#ifdef MesaUseKatmai + KATMAI_SRCS = katmai.c katmai_norm_raw.S katmai_xform_masked1.S \ + katmai_xform_masked2.S katmai_xform_masked3.S \ + katmai_xform_masked4.S katmai_xform_raw1.S \ + katmai_xform_raw2.S katmai_xform_raw3.S katmai_xform_raw4.S \ + vertex_katmai.S + + KATMAI_OBJS = katmai.o katmai_norm_raw.o katmai_xform_masked1.o \ + katmai_xform_masked2.o katmai_xform_masked3.o \ + katmai_xform_masked4.o katmai_xform_raw1.o \ + katmai_xform_raw2.o katmai_xform_raw3.o katmai_xform_raw4.o \ + vertex_katmai.o + + KATMAI_DEFS = -DUSE_KATMAI_ASM +#endif #endif - DEFINES = $(ALLOC_DEFINES) GlxDefines -DFX $(X86_DEFS) $(MMX_DEFS) $(3DNOW_DEFS) + DEFINES = $(ALLOC_DEFINES) GlxDefines -DFX $(X86_DEFS) $(MMX_DEFS) $(3DNOW_DEFS) $(KATMAI_DEFS) INCLUDES = -I$(XLIBSRC) -I$(EXTINCSRC) -I../include -I../../include -I../../dri -I.. - SRCS = $(X86_SRCS) $(MMX_SRCS) $(3DNOW_SRCS) - OBJS = $(X86_OBJS) $(MMX_OBJS) $(3DNOW_OBJS) + SRCS = $(X86_SRCS) $(MMX_SRCS) $(3DNOW_SRCS) $(KATMAI_SRCS) + OBJS = $(X86_OBJS) $(MMX_OBJS) $(3DNOW_OBJS) $(KATMAI_OBJS) #if !GlxUseBuiltInDRIDriver #undef DoNormalLib NormalLibGlx @@ -107,6 +122,19 @@ ObjectFromAsmSource(3dnow_xform_raw4, NullParameter) ObjectFromAsmSource(vertex_3dnow, NullParameter) #endif +#ifdef MesaUseKatmai +ObjectFromAsmSource(katmai_norm_raw, NullParameter) +ObjectFromAsmSource(katmai_xform_masked1, NullParameter) +ObjectFromAsmSource(katmai_xform_masked2, NullParameter) +ObjectFromAsmSource(katmai_xform_masked3, NullParameter) +ObjectFromAsmSource(katmai_xform_masked4, NullParameter) +ObjectFromAsmSource(katmai_xform_raw1, NullParameter) +ObjectFromAsmSource(katmai_xform_raw2, NullParameter) +ObjectFromAsmSource(katmai_xform_raw3, NullParameter) +ObjectFromAsmSource(katmai_xform_raw4, NullParameter) +ObjectFromAsmSource(vertex_katmai, NullParameter) +#endif + ObjectFromAsmSource(mmx_blend, NullParameter) ObjectFromAsmSource(common_x86asm, NullParameter) diff --git a/xc/lib/GL/mesa/src/drv/common/stenciltmp.h b/xc/lib/GL/mesa/src/drv/common/stenciltmp.h new file mode 100644 index 000000000..d22f6867c --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/common/stenciltmp.h @@ -0,0 +1,134 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/common/stenciltmp.h,v 1.2 2000/09/26 15:56:46 tsi Exp $ */ + +#ifndef DBG +#define DBG 0 +#endif + + +static void TAG(WriteStencilSpan)( GLcontext *ctx, + GLuint n, GLint x, GLint y, + const GLstencil *stencil, + const GLubyte mask[] ) +{ + HW_LOCK() + { + GLint x1; + GLint n1; + LOCAL_STENCIL_VARS; + + y = Y_FLIP(y); + + HW_CLIPLOOP() + { + GLint i = 0; + CLIPSPAN(x,y,n,x1,n1,i); + + if (DBG) fprintf(stderr, "WriteStencilSpan %d..%d (x1 %d)\n", + (int)i, (int)n1, (int)x1); + + if (mask) + { + for (;i<n1;i++,x1++) + if (mask[i]) + WRITE_STENCIL( x1, y, stencil[i] ); + } + else + { + for (;i<n1;i++,x1++) + WRITE_STENCIL( x1, y, stencil[i] ); + } + } + HW_ENDCLIPLOOP(); + } + HW_UNLOCK(); +} + + +static void TAG(WriteStencilPixels)( GLcontext *ctx, + GLuint n, + const GLint x[], + const GLint y[], + const GLstencil stencil[], + const GLubyte mask[] ) +{ + HW_LOCK() + { + GLint i; + LOCAL_STENCIL_VARS; + + if (DBG) fprintf(stderr, "WriteStencilPixels\n"); + + HW_CLIPLOOP() + { + for (i=0;i<n;i++) + { + if (mask[i]) { + const int fy = Y_FLIP(y[i]); + if (CLIPPIXEL(x[i],fy)) + WRITE_STENCIL( x[i], fy, stencil[i] ); + } + } + } + HW_ENDCLIPLOOP(); + } + HW_UNLOCK(); +} + + +/* Read stencil spans and pixels + */ +static void TAG(ReadStencilSpan)( GLcontext *ctx, + GLuint n, GLint x, GLint y, + GLstencil stencil[]) +{ + HW_LOCK() + { + GLint x1,n1; + LOCAL_STENCIL_VARS; + + y = Y_FLIP(y); + + if (DBG) fprintf(stderr, "ReadStencilSpan\n"); + + HW_CLIPLOOP() + { + GLint i = 0; + CLIPSPAN(x,y,n,x1,n1,i); + for (;i<n1;i++) + READ_STENCIL( stencil[i], (x1+i), y ); + } + HW_ENDCLIPLOOP(); + } + HW_UNLOCK(); +} + +static void TAG(ReadStencilPixels)( GLcontext *ctx, GLuint n, + const GLint x[], const GLint y[], + GLstencil stencil[] ) +{ + HW_LOCK() + { + GLint i; + LOCAL_STENCIL_VARS; + + if (DBG) fprintf(stderr, "ReadStencilPixels\n"); + + HW_CLIPLOOP() + { + for (i=0;i<n;i++) { + int fy = Y_FLIP( y[i] ); + if (CLIPPIXEL( x[i], fy )) + READ_STENCIL( stencil[i], x[i], fy ); + } + } + HW_ENDCLIPLOOP(); + } + HW_UNLOCK(); +} + + + + +#undef WRITE_STENCIL +#undef READ_STENCIL +#undef TAG diff --git a/xc/lib/GL/mesa/src/drv/ffb/Imakefile b/xc/lib/GL/mesa/src/drv/ffb/Imakefile index 5ad3d5a18..d66bc2bfb 100644 --- a/xc/lib/GL/mesa/src/drv/ffb/Imakefile +++ b/xc/lib/GL/mesa/src/drv/ffb/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/drv/ffb/Imakefile,v 1.5 2000/08/24 22:20:06 tsi Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/drv/ffb/Imakefile,v 1.6 2000/10/20 12:57:22 alanh Exp $ #include <Threads.tmpl> @@ -204,7 +204,7 @@ MESA_INCLUDES = -I. -I.. -I../../include \ SRCS = $(FFBSRCS) $(DRISRCS) $(DRMSRCS) $(MESASRCS) OBJS = $(FFBOBJS) $(DRIOBJS) $(DRMOBJS) $(MESAOBJS) -REQUIREDLIBS += -lm +REQUIREDLIBS += MathLibrary #if !GlxBuiltInFfb REQUIREDLIBS += -L../../../.. -lGL #endif diff --git a/xc/lib/GL/mesa/src/drv/ffb/ffb_vb.c b/xc/lib/GL/mesa/src/drv/ffb/ffb_vb.c index c48b06082..6fa6a4ae2 100644 --- a/xc/lib/GL/mesa/src/drv/ffb/ffb_vb.c +++ b/xc/lib/GL/mesa/src/drv/ffb/ffb_vb.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_vb.c,v 1.1 2000/06/20 05:08:40 dawes Exp $ +/* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_vb.c,v 1.2 2000/09/24 13:51:03 alanh Exp $ * * GLX Hardware Device Driver for Sun Creator/Creator3D * Copyright (C) 2000 David S. Miller @@ -28,7 +28,7 @@ #include "ffb_xmesa.h" #include "ffb_context.h" #include "ffb_vb.h" - +#include "mem.h" #include "stages.h" #define COL { \ @@ -242,8 +242,8 @@ void ffbDDResizeVB(struct vertex_buffer *VB, GLuint size) exit(1); } - free(VB->ClipMask); - VB->ClipMask = (GLubyte *)malloc(sizeof(GLubyte) * mvb->size); + ALIGN_FREE(VB->ClipMask); + VB->ClipMask = (GLubyte *) ALIGN_MALLOC(sizeof(GLubyte) * mvb->size, 4); if (!VB->ClipMask) { fprintf(stderr, "ffb-glx: out of memory !\n"); exit(1); @@ -283,8 +283,8 @@ void ffbDDRegisterVB(struct vertex_buffer *VB) exit(1); } - free(VB->ClipMask); - VB->ClipMask = (GLubyte *)malloc(sizeof(GLubyte) * mvb->size); + ALIGN_FREE(VB->ClipMask); + VB->ClipMask = (GLubyte *) ALIGN_MALLOC(sizeof(GLubyte) * mvb->size, 4); if (!VB->ClipMask) { fprintf(stderr, "ffb-glx: out of memory !\n"); exit(1); diff --git a/xc/lib/GL/mesa/src/drv/gamma/Imakefile b/xc/lib/GL/mesa/src/drv/gamma/Imakefile index 33d3759ba..ff31fdf2b 100644 --- a/xc/lib/GL/mesa/src/drv/gamma/Imakefile +++ b/xc/lib/GL/mesa/src/drv/gamma/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/drv/gamma/Imakefile,v 1.13 2000/08/24 22:20:06 tsi Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/drv/gamma/Imakefile,v 1.14 2000/10/20 12:57:22 alanh Exp $ #include <Threads.tmpl> @@ -259,7 +259,7 @@ XCOMM Disabling 3Dnow code for the time being. SRCS = $(LOWSRC) $(DRISRCS) $(DRMSRCS) $(MESASRCS) $(ASMSRCS) $(GAMMASRCS) $(HISRC) OBJS = $(LOWOBJ) $(DRIOBJS) $(DRMOBJS) $(MESAOBJS) $(ASMOBJS) $(GAMMAOBJS) $(HIOBJ) -REQUIREDLIBS += -lm +REQUIREDLIBS += MathLibrary #if !GlxBuiltInGamma REQUIREDLIBS += -L../../../.. -lGL #endif diff --git a/xc/lib/GL/mesa/src/drv/i810/Imakefile b/xc/lib/GL/mesa/src/drv/i810/Imakefile index 0b0bad1b3..b66d715c1 100644 --- a/xc/lib/GL/mesa/src/drv/i810/Imakefile +++ b/xc/lib/GL/mesa/src/drv/i810/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/drv/i810/Imakefile,v 1.9 2000/08/25 13:42:19 dawes Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/drv/i810/Imakefile,v 1.11 2000/10/20 12:57:22 alanh Exp $ #include <Threads.tmpl> @@ -25,7 +25,6 @@ ALLOC_DEFINES = -DMALLOC_0_RETURNS_NULL MESA_INCLUDES = -I. -I.. -I../../include \ -I../../../../dri/drm - DEFINES = $(ALLOC_DEFINES) $(DRI_DEFINES) INCLUDES = -I$(XLIBSRC) -I$(EXTINCSRC) $(MESA_INCLUDES) $(DRI_INCLUDES) @@ -229,7 +228,7 @@ MESA_INCLUDES = -I. -I.. -I../../include \ MMX_OBJS = ../../X86/mmx_blend.o XCOMM Disabling 3Dnow code for the time being. -#if 0 +#ifdef MesaUse3DNow 3DNOW_SRCS = ../../X86/3dnow.c \ ../../X86/3dnow_norm_raw.S \ ../../X86/3dnow_xform_masked1.S \ @@ -268,7 +267,7 @@ XCOMM Disabling 3Dnow code for the time being. OBJS = $(LOOBJS) $(DRIOBJS) $(DRMOBJS) $(MESAOBJS) $(ASMOBJS) \ $(COMMONOBJS) $(I810OBJS) $(HIOBJS) -REQUIREDLIBS += -lm +REQUIREDLIBS += MathLibrary #if !GlxBuiltInI810 REQUIREDLIBS += -L../../../.. -lGL #endif diff --git a/xc/lib/GL/mesa/src/drv/i810/i810_xmesa.c b/xc/lib/GL/mesa/src/drv/i810/i810_xmesa.c index 5934b9ebc..7b445e683 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810_xmesa.c +++ b/xc/lib/GL/mesa/src/drv/i810/i810_xmesa.c @@ -24,7 +24,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ -/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810_xmesa.c,v 1.6 2000/08/25 13:42:20 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810_xmesa.c,v 1.7 2000/09/24 13:51:04 alanh Exp $ */ /* * Authors: @@ -395,9 +395,6 @@ GLboolean XMesaCreateContext( Display *dpy, GLvisual *mesaVis, */ ctx->TriangleCaps |= DD_CLIP_FOG_COORD; - ctx->Shared->DefaultD[2][0].DriverData = 0; - ctx->Shared->DefaultD[2][1].DriverData = 0; - if (ctx->VB) i810DDRegisterVB( ctx->VB ); diff --git a/xc/lib/GL/mesa/src/drv/i810/i810dd.c b/xc/lib/GL/mesa/src/drv/i810/i810dd.c index 73e518fb8..eb78a91c6 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810dd.c +++ b/xc/lib/GL/mesa/src/drv/i810/i810dd.c @@ -21,7 +21,7 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ -/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810dd.c,v 1.3 2000/06/22 16:59:24 tsi Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810dd.c,v 1.4 2000/09/24 13:51:04 alanh Exp $ */ #include "types.h" #include "vbrender.h" @@ -77,8 +77,15 @@ static GLint i810GetParameteri(const GLcontext *ctx, GLint param) static void i810BufferSize(GLcontext *ctx, GLuint *width, GLuint *height) { i810ContextPtr imesa = I810_CONTEXT(ctx); + + /* Need to lock to make sure the driDrawable is uptodate. This + * information is used to resize Mesa's software buffers, so it has + * to be correct. + */ + LOCK_HARDWARE(imesa); *width = imesa->driDrawable->w; *height = imesa->driDrawable->h; + UNLOCK_HARDWARE(imesa); } @@ -97,17 +104,19 @@ void i810DDExtensionsInit( GLcontext *ctx ) /* The imaging subset of 1.2 isn't supported by any mesa driver. */ gl_extensions_disable( ctx, "ARB_imaging" ); + gl_extensions_disable( ctx, "GL_ARB_texture_compression" ); + gl_extensions_disable( ctx, "GL_ARB_texture_cube_map" ); gl_extensions_disable( ctx, "GL_EXT_blend_color" ); - gl_extensions_disable( ctx, "GL_EXT_blend_minmax" ); gl_extensions_disable( ctx, "GL_EXT_blend_logic_op" ); + gl_extensions_disable( ctx, "GL_EXT_blend_minmax" ); gl_extensions_disable( ctx, "GL_EXT_blend_subtract" ); - gl_extensions_disable( ctx, "GL_INGR_blend_func_separate" ); + gl_extensions_disable( ctx, "GL_EXT_convolution" ); gl_extensions_disable( ctx, "GL_EXT_texture_lod_bias" ); + gl_extensions_disable( ctx, "GL_INGR_blend_func_separate" ); gl_extensions_disable( ctx, "GL_MESA_resize_buffers" ); - - - if (0) gl_extensions_disable( ctx, "GL_ARB_multitexture" ); - + gl_extensions_disable( ctx, "GL_SGIX_pixel_texture" ); + gl_extensions_disable( ctx, "GL_SGI_color_matrix" ); + gl_extensions_disable( ctx, "GL_SGI_color_table" ); /* We do support tex_env_add, however */ diff --git a/xc/lib/GL/mesa/src/drv/i810/i810ioctl.h b/xc/lib/GL/mesa/src/drv/i810/i810ioctl.h index 57f72be67..6f74526ae 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810ioctl.h +++ b/xc/lib/GL/mesa/src/drv/i810/i810ioctl.h @@ -1,7 +1,7 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810ioctl.h,v 1.4 2000/08/28 02:43:11 tsi Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810ioctl.h,v 1.5 2000/10/24 22:45:01 dawes Exp $ */ -#ifndef MGA_IOCTL_H -#define MGA_IOCTL_H +#ifndef I810_IOCTL_H +#define I810_IOCTL_H #include "i810context.h" diff --git a/xc/lib/GL/mesa/src/drv/i810/i810tris.c b/xc/lib/GL/mesa/src/drv/i810/i810tris.c index 2b55a8d7b..e97e7e644 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810tris.c +++ b/xc/lib/GL/mesa/src/drv/i810/i810tris.c @@ -22,7 +22,7 @@ * * */ -/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810tris.c,v 1.4 2000/08/28 02:43:11 tsi Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810tris.c,v 1.5 2000/09/24 13:51:04 alanh Exp $ */ #include <stdio.h> #include <math.h> @@ -98,7 +98,7 @@ void i810DDTrifuncInit() -#define ALL_FALLBACK (DD_MULTIDRAW | DD_SELECT | DD_FEEDBACK) +#define ALL_FALLBACK (DD_MULTIDRAW | DD_SELECT | DD_FEEDBACK | DD_STENCIL) #define POINT_FALLBACK (ALL_FALLBACK) #define LINE_FALLBACK (ALL_FALLBACK | DD_LINE_STIPPLE) #define TRI_FALLBACK (ALL_FALLBACK | DD_TRI_UNFILLED) diff --git a/xc/lib/GL/mesa/src/drv/i810/i810tris.h b/xc/lib/GL/mesa/src/drv/i810/i810tris.h index c1e8cf7bc..20e7cbd80 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810tris.h +++ b/xc/lib/GL/mesa/src/drv/i810/i810tris.h @@ -22,7 +22,7 @@ * * */ -/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810tris.h,v 1.4 2000/08/28 02:43:11 tsi Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810tris.h,v 1.6 2000/09/29 08:59:42 eich Exp $ */ #ifndef I810TRIS_INC #define I810TRIS_INC @@ -53,7 +53,7 @@ static void __inline__ i810_draw_triangle( i810ContextPtr imesa, GLuint *vb = i810AllocDwordsInline( imesa, 3 * vertsize ); int j; -#if 1 +#if defined(USE_X86_ASM) __asm__ __volatile__( "rep ; movsl" : "=%c" (j) : "0" (vertsize), "D" ((long)vb), "S" ((long)v0) diff --git a/xc/lib/GL/mesa/src/drv/i810/i810vb.c b/xc/lib/GL/mesa/src/drv/i810/i810vb.c index 5c6e1455e..98bb09567 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810vb.c +++ b/xc/lib/GL/mesa/src/drv/i810/i810vb.c @@ -22,16 +22,16 @@ * * */ -/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810vb.c,v 1.5 2000/08/28 02:43:12 tsi Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810vb.c,v 1.6 2000/09/24 13:51:04 alanh Exp $ */ +#include <stdio.h> +#include <stdlib.h> #include "i810context.h" #include "i810vb.h" #include "i810log.h" - +#include "mem.h" #include "stages.h" -#include <stdio.h> -#include <stdlib.h> #define TEX0 { \ @@ -387,8 +387,8 @@ void i810DDResizeVB( struct vertex_buffer *VB, GLuint size ) exit(1); } - free( VB->ClipMask ); - VB->ClipMask = (GLubyte *)malloc(sizeof(GLubyte) * mvb->size); + ALIGN_FREE( VB->ClipMask ); + VB->ClipMask = (GLubyte *) ALIGN_MALLOC(sizeof(GLubyte) * mvb->size, 4); if (!VB->ClipMask) { fprintf(stderr, "i810-glx: out of memory !\n"); exit(1); @@ -429,8 +429,8 @@ void i810DDRegisterVB( struct vertex_buffer *VB ) exit(1); } - free( VB->ClipMask ); - VB->ClipMask = (GLubyte *)malloc(sizeof(GLubyte) * mvb->size); + ALIGN_FREE( VB->ClipMask ); + VB->ClipMask = (GLubyte *) ALIGN_MALLOC(sizeof(GLubyte) * mvb->size, 4); if (!VB->ClipMask) { fprintf(stderr, "i810-glx: out of memory !\n"); exit(1); diff --git a/xc/lib/GL/mesa/src/drv/mga/Imakefile b/xc/lib/GL/mesa/src/drv/mga/Imakefile index 90ccceecf..ba384a1ee 100644 --- a/xc/lib/GL/mesa/src/drv/mga/Imakefile +++ b/xc/lib/GL/mesa/src/drv/mga/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/drv/mga/Imakefile,v 1.9 2000/08/25 13:42:22 dawes Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/drv/mga/Imakefile,v 1.11 2000/10/20 12:57:22 alanh Exp $ #include <Threads.tmpl> @@ -34,7 +34,6 @@ ALLOC_DEFINES = -DMALLOC_0_RETURNS_NULL MESA_INCLUDES = -I. -I.. -I../../include \ -I../../../../dri/drm - DEFINES = $(ALLOC_DEFINES) $(DRI_DEFINES) $(ASM_DEFS) INCLUDES = -I$(XLIBSRC) -I$(EXTINCSRC) $(MESA_INCLUDES) $(DRI_INCLUDES) @@ -56,17 +55,15 @@ MESA_INCLUDES = -I. -I.. -I../../include \ ../../../../dri/drm/xf86drmSL.o - MGASRCS = mgaclear.c mgacnvtex.c mgadd.c \ - mgafastpath.c mgaeltpath.c \ - mgapipeline.c \ - mgaspan.c mgastate.c mgatex.c \ - mgatris.c mgavb.c mgaioctl.c mga_xmesa.c mgabuffers.c + MGASRCS = mgatexcnv.c mgadd.c mgafastpath.c \ + mgaeltpath.c mgapipeline.c mgaspan.c mgastate.c \ + mgatex.c mgatexmem.c mgatris.c mgavb.c mgaioctl.c \ + mga_xmesa.c mgabuffers.c - MGAOBJS = mgaclear.o mgacnvtex.o mgadd.o \ - mgafastpath.o mgaeltpath.o \ - mgapipeline.o \ - mgaspan.o mgastate.o mgatex.o \ - mgatris.o mgavb.o mgaioctl.o mga_xmesa.o mgabuffers.o + MGAOBJS = mgatexcnv.o mgadd.o mgafastpath.o \ + mgaeltpath.o mgapipeline.o mgaspan.o mgastate.o \ + mgatex.o mgatexmem.o mgatris.o mgavb.o mgaioctl.o \ + mga_xmesa.o mgabuffers.o MESASRCS = ../../aatriangle.c \ ../../accum.c \ @@ -279,7 +276,7 @@ MESA_INCLUDES = -I. -I.. -I../../include \ OBJS = $(LOOBJS) $(DRIOBJS) $(DRMOBJS) $(MESAOBJS) $(ASMOBJS) \ $(COMMONOBJS) $(MGAOBJS) $(HIOBJS) -REQUIREDLIBS += -lm +REQUIREDLIBS += MathLibrary #if !GlxBuiltInMga REQUIREDLIBS += -L../../../.. -lGL -L../../../../../X11 -lX11 #endif 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 edcad5800..1152b06d2 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c +++ b/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c,v 1.5 2000/08/25 13:42:22 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c,v 1.6 2000/09/24 13:51:05 alanh Exp $ */ /************************************************************************** Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. @@ -44,6 +44,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "matrix.h" #include "mmath.h" #include "simple_list.h" +#include "mem.h" #include "mgadd.h" #include "mgastate.h" @@ -76,7 +77,6 @@ int MGA_DEBUG = (0 static mgaContextPtr mgaCtx = 0; -mgaGlx_t mgaglx; /* These functions are accessed externally to the driver: * @@ -99,6 +99,9 @@ GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv) mgaScreenPrivate *mgaScreen; MGADRIPtr serverInfo = (MGADRIPtr)sPriv->pDevPriv; + if (MGA_DEBUG&DEBUG_VERBOSE_DRI) + fprintf(stderr, "XMesaInitDriver\n"); + /* Check the DRI version */ { int major, minor, patch; @@ -123,27 +126,23 @@ GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv) } /* Check that the DRM driver version is compatible */ - if (sPriv->drmMajor != 1 || + if (sPriv->drmMajor != 2 || sPriv->drmMinor != 0 || sPriv->drmPatch < 0) { char msg[1000]; - sprintf(msg, "MGA DRI driver expected DRM driver version 1.0.x but got version %d.%d.%d", sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch); + sprintf(msg, "MGA DRI driver expected DRM driver version 2.0.x but got version %d.%d.%d", sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch); __driMesaMessage(msg); return GL_FALSE; } /* Allocate the private area */ - mgaScreen = (mgaScreenPrivate *)Xmalloc(sizeof(mgaScreenPrivate)); + mgaScreen = (mgaScreenPrivate *)MALLOC(sizeof(mgaScreenPrivate)); if (!mgaScreen) return GL_FALSE; mgaScreen->sPriv = sPriv; sPriv->private = (void *)mgaScreen; - /* - fprintf(stderr, "serverInfo->chipset: %d\n", serverInfo->chipset); - */ - if (serverInfo->chipset != MGA_CARD_TYPE_G200 && serverInfo->chipset != MGA_CARD_TYPE_G400) { XFree(mgaScreen); @@ -182,12 +181,6 @@ GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv) mgaScreen->textureOffset[MGA_AGP_HEAP] = (serverInfo->agpTextureOffset | PDEA_pagpxfer_enable | 1); - /* - fprintf(stderr, "CARD texture size %x, granul %d --> %x\n", - serverInfo->textureSize, serverInfo->logTextureGranularity, - 1<<serverInfo->logTextureGranularity); - */ - mgaScreen->textureSize[MGA_CARD_HEAP] = serverInfo->textureSize; mgaScreen->textureSize[MGA_AGP_HEAP] = serverInfo->agpTextureSize; @@ -208,12 +201,6 @@ GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv) */ mgaScreen->dmaOffset = serverInfo->agpBufferOffset; - /* - fprintf(stderr, "\n\n\nbackOffset: %x pitch %x\n", - mgaScreen->backOffset, - mgaScreen->backPitch); - */ - mgaScreen->bufs = drmMapBufs(sPriv->fd); if (!mgaScreen->bufs) { /*drmUnmap(mgaScreen->agp_tex.map, mgaScreen->agp_tex.size);*/ @@ -222,10 +209,6 @@ GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv) return GL_FALSE; } - /* Other mgaglx stuff, too?? - */ - memset(&mgaglx, 0, sizeof(mgaglx)); - mgaDDFastPathInit(); mgaDDEltPathInit(); mgaDDTrifuncInit(); @@ -240,6 +223,10 @@ GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv) void XMesaResetDriver(__DRIscreenPrivate *sPriv) { mgaScreenPrivate *mgaScreen = (mgaScreenPrivate *) sPriv->private; + + if (MGA_DEBUG&DEBUG_VERBOSE_DRI) + fprintf(stderr, "XMesaResetDriver\n"); + /*drmUnmap(mgaScreen->agp_tex.map, mgaScreen->agp_tex.size);*/ Xfree(mgaScreen); sPriv->private = NULL; @@ -251,6 +238,9 @@ GLvisual *XMesaCreateVisual(Display *dpy, const XVisualInfo *visinfo, const __GLXvisualConfig *config) { + if (MGA_DEBUG&DEBUG_VERBOSE_DRI) + fprintf(stderr, "XMesaCreateVisual\n"); + /* Drivers may change the args to _mesa_create_visual() in order to * setup special visuals. */ @@ -282,9 +272,11 @@ GLboolean XMesaCreateContext( Display *dpy, GLvisual *mesaVis, mgaScreenPrivate *mgaScreen = (mgaScreenPrivate *)sPriv->private; drm_mga_sarea_t *saPriv=(drm_mga_sarea_t*)(((char*)sPriv->pSAREA)+ sizeof(XF86DRISAREARec)); - /*fprintf(stderr, "XMesaCreateContext\n");*/ - mmesa = (mgaContextPtr)Xcalloc(sizeof(mgaContext), 1); + if (MGA_DEBUG&DEBUG_VERBOSE_DRI) + fprintf(stderr, "XMesaCreateContext\n"); + + mmesa = (mgaContextPtr)CALLOC(sizeof(mgaContext)); if (!mmesa) { return GL_FALSE; } @@ -310,7 +302,6 @@ GLboolean XMesaCreateContext( Display *dpy, GLvisual *mesaVis, make_empty_list(&mmesa->TexObjList[i]); } - /* Set the maximum texture size small enough that we can guarentee * that both texture units can bind a maximal texture and have them * on the card at once. @@ -333,11 +324,37 @@ GLboolean XMesaCreateContext( Display *dpy, GLvisual *mesaVis, } } - if (mgaScreen->cpp == 2) - mmesa->depth_scale = 1.0/(GLdouble)0xffff; - else - mmesa->depth_scale = 1.0/(GLdouble)0xffffffff; - + mmesa->hw_stencil = mesaVis->StencilBits && mesaVis->DepthBits == 24; + +/* fprintf(stderr, */ +/* "mesaVis->DepthBits: %d " */ +/* "mmesa->glCtx->Visual->DepthBits: %d " */ +/* "mmesa->glCtx->Visual->DepthMax: %x\n", */ +/* mesaVis->DepthBits, */ +/* ctx->Visual->DepthBits, */ +/* ctx->Visual->DepthMax); */ + + switch (mesaVis->DepthBits) { + case 16: + mmesa->depth_scale = 1.0/(GLdouble)0xffff; + mmesa->depth_clear_mask = ~0; + mmesa->ClearDepth = 0xffff; + break; + case 24: + mmesa->depth_scale = 1.0/(GLdouble)0xffffff; + if (mmesa->hw_stencil) { + mmesa->depth_clear_mask = 0xffffff00; + mmesa->stencil_clear_mask = 0x000000ff; + } else + mmesa->depth_clear_mask = ~0; + mmesa->ClearDepth = 0xffffff00; + break; + case 32: + mmesa->depth_scale = 1.0/(GLdouble)0xffffffff; + mmesa->depth_clear_mask = ~0; + mmesa->ClearDepth = 0xffffffff; + break; + }; mmesa->renderindex = -1; /* impossible value */ @@ -372,9 +389,6 @@ GLboolean XMesaCreateContext( Display *dpy, GLvisual *mesaVis, */ ctx->TriangleCaps |= DD_CLIP_FOG_COORD; - ctx->Shared->DefaultD[2][0].DriverData = 0; - ctx->Shared->DefaultD[2][1].DriverData = 0; - if (ctx->VB) mgaDDRegisterVB( ctx->VB ); @@ -395,17 +409,11 @@ void XMesaDestroyContext(__DRIcontextPrivate *driContextPriv) { mgaContextPtr mmesa = (mgaContextPtr) driContextPriv->driverPrivate; - if (mmesa) { -/* mgaTextureObjectPtr next_t, t; */ - -/* foreach_s (t, next_t, &(mmesa->TexObjList)) */ -/* mgaDestroyTexObj(mmesa, t); */ - -/* foreach_s (t, next_t, &(mmesa->SwappedOut)) */ -/* mgaDestroyTexObj(mmesa, t); */ + if (MGA_DEBUG&DEBUG_VERBOSE_DRI) + fprintf(stderr, "XMesaDestroyContext\n"); + if (mmesa) { Xfree(mmesa); - driContextPriv->driverPrivate = NULL; } } @@ -416,6 +424,9 @@ GLframebuffer *XMesaCreateWindowBuffer( Display *dpy, __DRIdrawablePrivate *driDrawPriv, GLvisual *mesaVis) { + if (MGA_DEBUG&DEBUG_VERBOSE_DRI) + fprintf(stderr, "XMesaCreateWindowBuffer\n"); + return gl_create_framebuffer(mesaVis, GL_FALSE, /* software depth buffer? */ mesaVis->StencilBits > 0, @@ -480,9 +491,11 @@ GLboolean XMesaMakeCurrent(__DRIcontextPrivate *driContextPriv, gl_make_current2(mgaCtx->glCtx, driDrawPriv->mesaBuffer, driReadPriv->mesaBuffer); - mgaCtx->driDrawable = driDrawPriv; - mgaCtx->dirty = ~0; - mgaCtx->dirty_cliprects = (MGA_FRONT|MGA_BACK); + if (mgaCtx->driDrawable != driDrawPriv) { + mgaCtx->driDrawable = driDrawPriv; + mgaCtx->dirty = ~0; + mgaCtx->dirty_cliprects = (MGA_FRONT|MGA_BACK); + } if (!mgaCtx->glCtx->Viewport.Width) gl_Viewport(mgaCtx->glCtx, 0, 0, driDrawPriv->w, driDrawPriv->h); @@ -531,4 +544,5 @@ void mgaGetLock( mgaContextPtr mmesa, GLuint flags ) + #endif diff --git a/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.h b/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.h index 013c004f5..f562ad094 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.h +++ b/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.h @@ -24,7 +24,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mga_xmesa.h,v 1.5 2000/08/28 02:43:12 tsi Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mga_xmesa.h,v 1.6 2000/09/24 13:51:05 alanh Exp $ */ /* * Authors: @@ -50,7 +50,7 @@ typedef struct { char *map; } mgaRegion, *mgaRegionPtr; -typedef struct { +typedef struct mga_screen_private_s { int chipset; int width; @@ -88,7 +88,7 @@ typedef struct { } mgaScreenPrivate; -#include "mgalib.h" +#include "mgacontext.h" extern void mgaGetLock( mgaContextPtr mmesa, GLuint flags ); extern void mgaEmitHwStateLocked( mgaContextPtr mmesa ); diff --git a/xc/lib/GL/mesa/src/drv/mga/mgabuffers.c b/xc/lib/GL/mesa/src/drv/mga/mgabuffers.c index da288e3c9..75d322c47 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgabuffers.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgabuffers.c @@ -24,7 +24,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgabuffers.c,v 1.3 2000/08/25 13:42:22 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgabuffers.c,v 1.4 2000/09/24 13:51:05 alanh Exp $ */ /* * Authors: @@ -34,7 +34,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include <stdio.h> -#include "mgalib.h" +#include "mgacontext.h" #include "mgabuffers.h" #include "mgastate.h" #include "mgaioctl.h" @@ -88,37 +88,29 @@ static void mgaUpdateRectsFromSarea( mgaContextPtr mmesa ) if (sarea->exported_buffers & MGA_BACK) { - XF86DRIClipRectPtr boxes = - (XF86DRIClipRectPtr)malloc( sarea->exported_nback * sizeof(*boxes) ); - - if (driDrawable->pBackClipRects) - free(driDrawable->pBackClipRects); driDrawable->numBackClipRects = sarea->exported_nback; - driDrawable->pBackClipRects = boxes; + driDrawable->pBackClipRects = mmesa->tmp_boxes[0]; top = sarea->exported_nback; for (i = 0 ; i < top ; i++) - boxes[i] = *(XF86DRIClipRectPtr)&(sarea->exported_boxes[i]); + driDrawable->pBackClipRects[i] = + *(XF86DRIClipRectPtr)&(sarea->exported_boxes[i]); } if (sarea->exported_buffers & MGA_FRONT) { int start = top; - XF86DRIClipRectPtr boxes = - (XF86DRIClipRectPtr)malloc( sarea->exported_nfront * sizeof(*boxes) ); - - if (driDrawable->pClipRects) - free(driDrawable->pClipRects); driDrawable->numClipRects = sarea->exported_nfront; - driDrawable->pClipRects = boxes; + driDrawable->pClipRects = mmesa->tmp_boxes[1]; top += sarea->exported_nfront; for ( ; i < top ; i++) - boxes[i-start] = *(XF86DRIClipRectPtr)&(sarea->exported_boxes[i]); - + driDrawable->pClipRects[i-start] = + *(XF86DRIClipRectPtr)&(sarea->exported_boxes[i]); + } @@ -223,7 +215,8 @@ void mgaUpdateRects( mgaContextPtr mmesa, GLuint buffers ) */ if (0) printSareaRects(mmesa); - if (sarea->exported_drawable == driDrawable->draw && + if (0 && + sarea->exported_drawable == driDrawable->draw && (sarea->exported_buffers & buffers) == buffers) { mgaUpdateRectsFromSarea( mmesa ); diff --git a/xc/lib/GL/mesa/src/drv/mga/mgacontext.h b/xc/lib/GL/mesa/src/drv/mga/mgacontext.h new file mode 100644 index 000000000..1f6ffc6c6 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/mga/mgacontext.h @@ -0,0 +1,316 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgacontext.h,v 1.1 2000/09/24 13:51:06 alanh Exp $*/ +/* + * GLX Hardware Device Driver for Matrox Millenium G200 + * Copyright (C) 1999 Wittawat Yamwong + * + * 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 + * WITTAWAT YAMWONG, OR ANY OTHER CONTRIBUTORS 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. + * + * + * Wittawat Yamwong <Wittawat.Yamwong@stud.uni-hannover.de> + */ + + +#ifndef MGALIB_INC +#define MGALIB_INC + +#include <X11/Xlibint.h> +#include "dri_tmm.h" +#include "dri_mesaint.h" +#include "dri_mesa.h" + +#include "types.h" + +#include "drm.h" +#include "mm.h" +#include "mgavb.h" +#include "mem.h" + + +#define MGA_SET_FIELD(reg,mask,val) reg = ((reg) & (mask)) | ((val) & ~(mask)) +#define MGA_FIELD(field,val) (((val) << (field ## _SHIFT)) & ~(field ## _MASK)) +#define MGA_GET_FIELD(field, val) ((val & ~(field ## _MASK)) >> (field ## _SHIFT)) + +#define MGA_IS_G200(mmesa) (mmesa->mgaScreen->chipset == MGA_CARD_TYPE_G200) +#define MGA_IS_G400(mmesa) (mmesa->mgaScreen->chipset == MGA_CARD_TYPE_G400) + + +/* SoftwareFallback + * - texture env GL_BLEND -- can be fixed + * - 1D and 3D textures + * - incomplete textures + */ +#define MGA_FALLBACK_TEXTURE 0x1 +#define MGA_FALLBACK_BUFFER 0x2 +#define MGA_FALLBACK_LOGICOP 0x4 +#define MGA_FALLBACK_STENCIL 0x8 + + +/* For mgaCtx->new_state. + */ +#define MGA_NEW_DEPTH 0x1 +#define MGA_NEW_ALPHA 0x2 +#define MGA_NEW_FOG 0x4 +#define MGA_NEW_CLIP 0x8 +#define MGA_NEW_MASK 0x10 +#define MGA_NEW_TEXTURE 0x20 +#define MGA_NEW_CULL 0x40 +#define MGA_NEW_WARP 0x80 +#define MGA_NEW_STENCIL 0x100 +#define MGA_NEW_CONTEXT 0x200 + + +typedef void (*mga_interp_func)( GLfloat t, + GLfloat *result, + const GLfloat *in, + const GLfloat *out ); + + + + + + +/* Reasons why the GL_BLEND fallback mightn't work: + */ +#define MGA_BLEND_ENV_COLOR 0x1 +#define MGA_BLEND_MULTITEX 0x2 + +struct mga_elt_tab; +struct mga_texture_object_s; +struct mga_screen_private_s; + +#define MGA_TEX_MAXLEVELS 5 + +typedef struct mga_texture_object_s +{ + struct mga_texture_object_s *next; + struct mga_texture_object_s *prev; + struct gl_texture_object *tObj; + struct mga_context_t *ctx; + PMemBlock MemBlock; + GLuint offsets[MGA_TEX_MAXLEVELS]; + int lastLevel; + GLuint dirty_images; + GLuint totalSize; + int texelBytes; + GLuint age; + int bound; + int heap; /* agp or card */ + int Setup[MGA_TEX_SETUP_SIZE]; +} mgaTextureObject_t; + +struct mga_context_t { + + GLcontext *glCtx; + + + /* Bookkeeping for texturing + */ + int lastTexHeap; + struct mga_texture_object_s TexObjList[MGA_NR_TEX_HEAPS]; + struct mga_texture_object_s SwappedOut; + struct mga_texture_object_s *CurrentTexObj[2]; + memHeap_t *texHeap[MGA_NR_TEX_HEAPS]; + int c_texupload; + int c_texusage; + int tex_thrash; + + + /* Map GL texture units onto hardware. + */ + GLuint multitex; + GLuint tmu_source[2]; + GLuint tex_dest[2]; + + GLboolean default32BitTextures; + + /* Manage fallbacks + */ + GLuint IndirectTriangles; + int Fallback; + + + /* Support for CVA and the fastpath + */ + unsigned int setupdone; + unsigned int setupindex; + unsigned int renderindex; + unsigned int using_fast_path; + mga_interp_func interp; + + + /* Support for limited GL_BLEND fallback + */ + unsigned int blend_flags; + unsigned int envcolor; + + + /* Shortcircuit some state changes + */ + points_func PointsFunc; + line_func LineFunc; + triangle_func TriangleFunc; + quad_func QuadFunc; + + + /* Manage driver and hardware state + */ + GLuint new_state; + GLuint dirty; + GLuint Setup[MGA_CTX_SETUP_SIZE]; + GLuint warp_pipe; + GLuint vertsize; + GLushort MonoColor; + GLushort ClearColor; + GLuint ClearDepth; + GLuint poly_stipple; + GLfloat depth_scale; + + GLuint depth_clear_mask; + GLuint stencil_clear_mask; + GLuint hw_stencil; + + /* Dma buffers + */ + drmBufPtr vertex_dma_buffer; + drmBufPtr iload_buffer; + + + /* Drawable, cliprect and scissor information + */ + int dirty_cliprects; /* which sets of cliprects are uptodate? */ + int draw_buffer; /* which buffer are we rendering to */ + unsigned int drawOffset; /* draw buffer address in space */ + int read_buffer; + int readOffset; + int drawX, drawY; /* origin of drawable in draw buffer */ + int lastX, lastY; /* detect DSTORG bug */ + GLuint numClipRects; /* cliprects for the draw buffer */ + XF86DRIClipRectPtr pClipRects; + XF86DRIClipRectRec draw_rect; + drm_clip_rect_t scissor_rect; + int scissor; + + XF86DRIClipRectRec tmp_boxes[2][MGA_NR_SAREA_CLIPRECTS]; + + + /* Texture aging and DMA based aging. + */ + unsigned int texAge[MGA_NR_TEX_HEAPS];/* texture LRU age */ + unsigned int dirtyAge; /* buffer age for synchronization */ + unsigned int lastSwap; /* throttling runaway apps */ + + + + /* Mirrors of some DRI state. + */ + GLframebuffer *glBuffer; + drmContext hHWContext; + drmLock *driHwLock; + int driFd; + Display *display; + __DRIdrawablePrivate *driDrawable; + __DRIscreenPrivate *driScreen; + struct mga_screen_private_s *mgaScreen; + drm_mga_sarea_t *sarea; + + + /* New setupdma path + */ + drmBufPtr elt_buf, retained_buf; + GLuint *first_elt, *next_elt; + GLfloat *next_vert; + GLuint next_vert_phys; + GLuint first_vert_phys; + struct mga_elt_tab *elt_tab; + GLfloat device_matrix[16]; +}; + + + +#define MGAPACKCOLOR555(r,g,b,a) \ + ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \ + ((a) ? 0x8000 : 0)) + +#define MGAPACKCOLOR565(r,g,b) \ + ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3)) + +#define MGAPACKCOLOR888(r,g,b) \ + (((r) << 16) | ((g) << 8) | (b)) + +#define MGAPACKCOLOR8888(r,g,b,a) \ + (((a) << 24) | ((r) << 16) | ((g) << 8) | (b)) + +#define MGAPACKCOLOR4444(r,g,b,a) \ + ((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4)) + + +#define MGA_DEBUG 0 +#ifndef MGA_DEBUG +extern int MGA_DEBUG; +#endif + +#define DEBUG_ALWAYS_SYNC 0x1 +#define DEBUG_VERBOSE_MSG 0x2 +#define DEBUG_VERBOSE_LRU 0x4 +#define DEBUG_VERBOSE_DRI 0x8 +#define DEBUG_VERBOSE_IOCTL 0x10 +#define DEBUG_VERBOSE_2D 0x20 + +static __inline__ GLuint mgaPackColor(GLuint cpp, + GLubyte r, GLubyte g, + GLubyte b, GLubyte a) +{ + switch (cpp) { + case 2: + return MGAPACKCOLOR565(r,g,b); + case 4: + return MGAPACKCOLOR8888(r,g,b,a); + default: + return 0; + } +} + + +/* + * Subpixel offsets for window coordinates: + */ +#define SUBPIXEL_X (-0.5F) +#define SUBPIXEL_Y (-0.5F + 0.125) + + +typedef struct mga_context_t mgaContext; +typedef struct mga_context_t *mgaContextPtr; + +struct mga_elt_tab { + void (*emit_unclipped_verts)( struct vertex_buffer *VB ); + + void (*build_tri_verts)( mgaContextPtr mmesa, + struct vertex_buffer *VB, + GLfloat *O, GLuint *elt ); + + void (*interp)( GLfloat t, GLfloat *O, + const GLfloat *I, const GLfloat *J ); + + void (*project_and_emit_verts)( mgaContextPtr mmesa, + const GLfloat *verts, + GLuint *elts, + int nr ); +}; + +#endif diff --git a/xc/lib/GL/mesa/src/drv/mga/mgadd.c b/xc/lib/GL/mesa/src/drv/mga/mgadd.c index 70e53efa8..86304e243 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgadd.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgadd.c @@ -23,7 +23,7 @@ * * Wittawat Yamwong <Wittawat.Yamwong@stud.uni-hannover.de> */ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgadd.c,v 1.4 2000/08/25 13:42:23 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgadd.c,v 1.5 2000/09/24 13:51:06 alanh Exp $ */ @@ -35,10 +35,8 @@ #include <stdlib.h> #include "mm.h" -#include "mgalib.h" -#include "mgaclear.h" +#include "mgacontext.h" #include "mgadd.h" -#include "mgalog.h" #include "mgastate.h" #include "mgaspan.h" #include "mgatex.h" @@ -74,24 +72,28 @@ static const GLubyte *mgaDDGetString( GLcontext *ctx, GLenum name ) static GLint mgaGetParameteri(const GLcontext *ctx, GLint param) { - switch (param) { - case DD_HAVE_HARDWARE_FOG: - return 1; - default: - mgaError("mgaGetParameteri(): unknown parameter!\n"); - return 0; - } + switch (param) { + case DD_HAVE_HARDWARE_FOG: + return 1; + default: + fprintf(stderr, "mgaGetParameteri(): unknown parameter!\n"); + return 0; + } } static void mgaBufferSize(GLcontext *ctx, GLuint *width, GLuint *height) { mgaContextPtr mmesa = MGA_CONTEXT(ctx); - -/* LOCK_HARDWARE( mmesa ); */ + + /* Need to lock to make sure the driDrawable is uptodate. This + * information is used to resize Mesa's software buffers, so it has + * to be correct. + */ + LOCK_HARDWARE( mmesa ); *width = mmesa->driDrawable->w; *height = mmesa->driDrawable->h; -/* UNLOCK_HARDWARE( mmesa ); */ + UNLOCK_HARDWARE( mmesa ); } void mgaDDExtensionsInit( GLcontext *ctx ) @@ -141,10 +143,6 @@ void mgaDDExtensionsInit( GLcontext *ctx ) - - - - void mgaDDInitDriverFuncs( GLcontext *ctx ) { ctx->Driver.GetBufferSize = mgaBufferSize; diff --git a/xc/lib/GL/mesa/src/drv/mga/mgaeltpath.c b/xc/lib/GL/mesa/src/drv/mga/mgaeltpath.c index b0db7dba3..8d09236d6 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgaeltpath.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgaeltpath.c @@ -21,7 +21,7 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgaeltpath.c,v 1.3 2000/08/28 02:43:12 tsi Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgaeltpath.c,v 1.5 2000/09/26 15:56:47 tsi Exp $ */ #include <stdio.h> @@ -32,7 +32,7 @@ #include "mmath.h" #include "xform.h" -#include "mgalib.h" +#include "mgacontext.h" #include "mgapipeline.h" #include "mgatris.h" #include "mgastate.h" @@ -58,10 +58,10 @@ static void fire_elts( mgaContextPtr mmesa ) if (mmesa->first_elt != mmesa->next_elt) { mgaFireEltsLocked( mmesa, - ((GLuint)mmesa->first_elt - - (GLuint)mmesa->elt_buf->address), - ((GLuint)mmesa->next_elt - - (GLuint)mmesa->elt_buf->address), + ((char *)mmesa->first_elt - + (char *)mmesa->elt_buf->address), + ((char *)mmesa->next_elt - + (char *)mmesa->elt_buf->address), !retain ); } else if (!retain) mgaReleaseBufLocked( mmesa, mmesa->elt_buf ); @@ -77,7 +77,7 @@ static void fire_elts( mgaContextPtr mmesa ) UNLOCK_HARDWARE( mmesa ); - mmesa->next_vert = (GLfloat *)((GLuint)mmesa->elt_buf->address + + mmesa->next_vert = (GLfloat *)((char *)mmesa->elt_buf->address + mmesa->elt_buf->total - BUFFER_STRIDE * sizeof(GLfloat)); @@ -99,10 +99,10 @@ static void release_bufs( mgaContextPtr mmesa ) LOCK_HARDWARE( mmesa ); if (mmesa->first_elt != mmesa->next_elt) { mgaFireEltsLocked( mmesa, - ((GLuint)mmesa->first_elt - - (GLuint)mmesa->elt_buf->address), - ((GLuint)mmesa->next_elt - - (GLuint)mmesa->elt_buf->address), + ((char *)mmesa->first_elt - + (char *)mmesa->elt_buf->address), + ((char *)mmesa->next_elt - + (char *)mmesa->elt_buf->address), 0 ); mmesa->first_elt = mmesa->next_elt; @@ -205,7 +205,7 @@ static void mga_tri_clip( mgaContextPtr mmesa, { GLuint *out = inlist[in]; - GLuint space = (GLuint)mmesa->next_vert - (GLuint)mmesa->next_elt; + GLuint space = (char *)mmesa->next_vert - (char *)mmesa->next_elt; if (space < n * (BUFFER_STRIDE + 3) * sizeof(GLuint)) fire_elts(mmesa); @@ -242,15 +242,15 @@ static void mga_tri_clip( mgaContextPtr mmesa, #define UNCLIPPED_VERT(x) (mmesa->first_vert_phys - x * BUFFER_STRIDE * 4) -#define TRIANGLE( e2, e1, e0 ) \ -do { \ - if ((GLuint)mmesa->next_vert - \ - (GLuint)mmesa->next_elt < TRI_THRESHOLD) \ - fire_elts(mmesa); \ - mmesa->next_elt[0] = UNCLIPPED_VERT(e2); \ - mmesa->next_elt[1] = UNCLIPPED_VERT(e1); \ - mmesa->next_elt[2] = UNCLIPPED_VERT(e0); \ - mmesa->next_elt+=3; \ +#define TRIANGLE( e2, e1, e0 ) \ +do { \ + if (((char *)mmesa->next_vert - \ + (char *)mmesa->next_elt) < TRI_THRESHOLD) \ + fire_elts(mmesa); \ + mmesa->next_elt[0] = UNCLIPPED_VERT(e2); \ + mmesa->next_elt[1] = UNCLIPPED_VERT(e1); \ + mmesa->next_elt[2] = UNCLIPPED_VERT(e0); \ + mmesa->next_elt+=3; \ } while (0) #define CLIP_TRIANGLE( e2, e1, e0 ) \ @@ -428,7 +428,7 @@ void mgaDDEltPath( struct vertex_buffer *VB ) /* Allocate a single buffer to hold unclipped vertices. All * unclipped vertices must be contiguous. */ - if ((GLuint)mmesa->next_vert - (GLuint)mmesa->next_elt < + if ((char *)mmesa->next_vert - (char *)mmesa->next_elt < VB->Count * BUFFER_STRIDE * sizeof(GLuint)) fire_elts( mmesa ); diff --git a/xc/lib/GL/mesa/src/drv/mga/mgafastpath.c b/xc/lib/GL/mesa/src/drv/mga/mgafastpath.c index ea12c20b4..c2e672a46 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgafastpath.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgafastpath.c @@ -21,7 +21,7 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgafastpath.c,v 1.4 2000/08/28 02:43:12 tsi Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgafastpath.c,v 1.5 2000/09/24 13:51:06 alanh Exp $ */ #include <stdio.h> @@ -31,7 +31,7 @@ #include "vertices.h" #include "mmath.h" -#include "mgalib.h" +#include "mgacontext.h" #include "mgapipeline.h" #include "mgatris.h" #include "mgastate.h" @@ -487,8 +487,10 @@ void mgaDDFastPath( struct vertex_buffer *VB ) struct mga_fast_tab *tab = &mgaFastTab[mmesa->setupindex & VALID_SETUP]; GLuint do_cliptest = 1; + gl_prepare_arrays_cva( VB ); /* still need this */ +#if 1 if (gl_reduce_prim[prim] == GL_TRIANGLES && VB->Count < (MGA_DMA_BUF_SZ / 48) && (ctx->ModelProjectMatrix.flags & (MAT_FLAG_GENERAL| @@ -498,6 +500,7 @@ void mgaDDFastPath( struct vertex_buffer *VB ) mgaDDEltPath( VB ); return; } +#endif /* Reserve enough space for the pathological case. */ diff --git a/xc/lib/GL/mesa/src/drv/mga/mgaioctl.c b/xc/lib/GL/mesa/src/drv/mga/mgaioctl.c index 059284405..cc49b1b2b 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgaioctl.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgaioctl.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgaioctl.c,v 1.5 2000/08/28 02:43:12 tsi Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgaioctl.c,v 1.7 2000/09/26 15:56:47 tsi Exp $ */ #include <stdio.h> @@ -7,11 +7,10 @@ #include "dd.h" #include "mm.h" -#include "mgalib.h" +#include "mgacontext.h" #include "mgadd.h" #include "mgastate.h" #include "mgatex.h" -#include "mgalog.h" #include "mgavb.h" #include "mgatris.h" #include "mgabuffers.h" @@ -136,10 +135,10 @@ drmBufPtr mga_get_buffer_ioctl( mgaContextPtr mmesa ) if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL) fprintf(stderr, "drmDMA (get) returns size[0] 0x%x idx[0] %d\n" - "dma_buffer now: buf idx: %d size: %d used: %d\n", + "dma_buffer now: buf idx: %d size: %d used: %d addr %p\n", dma.request_sizes[0], dma.request_list[0], buf->idx, buf->total, - buf->used); + buf->used, buf->address); if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL) fprintf(stderr, "finished getbuffer\n"); @@ -155,7 +154,6 @@ GLbitfield mgaClear( GLcontext *ctx, GLbitfield mask, GLboolean all, { mgaContextPtr mmesa = MGA_CONTEXT( ctx ); __DRIdrawablePrivate *dPriv = mmesa->driDrawable; - const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask); drm_mga_clear_t clear; int retcode; int i; @@ -165,30 +163,39 @@ GLbitfield mgaClear( GLcontext *ctx, GLbitfield mask, GLboolean all, clear.flags = 0; clear.clear_color = mmesa->ClearColor; - - if (mmesa->mgaScreen->cpp == 2) - clear.clear_depth = ctx->Depth.Clear * (GLdouble)0xffff; - else { - clear.clear_depth = ctx->Depth.Clear * (GLdouble)0xffffffff; - } + clear.clear_depth = 0; + clear.clear_depth_mask = 0; FLUSH_BATCH( mmesa ); - if ((mask & DD_FRONT_LEFT_BIT) && colorMask == ~0) { + if (mask & DD_FRONT_LEFT_BIT) { clear.flags |= MGA_FRONT; + clear.clear_color_mask = mmesa->Setup[MGA_CTXREG_PLNWT]; mask &= ~DD_FRONT_LEFT_BIT; } - if ((mask & DD_BACK_LEFT_BIT) && colorMask == ~0) { + if (mask & DD_BACK_LEFT_BIT) { clear.flags |= MGA_BACK; + clear.clear_color_mask = mmesa->Setup[MGA_CTXREG_PLNWT]; mask &= ~DD_BACK_LEFT_BIT; } if ((mask & DD_DEPTH_BIT) && ctx->Depth.Mask) { clear.flags |= MGA_DEPTH; + clear.clear_depth_mask |= mmesa->depth_clear_mask; + clear.clear_depth = (mmesa->ClearDepth & + mmesa->depth_clear_mask); mask &= ~DD_DEPTH_BIT; } + if ((mask & DD_STENCIL_BIT) && mmesa->hw_stencil) { + clear.flags |= MGA_DEPTH; + clear.clear_depth_mask |= mmesa->stencil_clear_mask; + clear.clear_depth |= (ctx->Stencil.Clear & + mmesa->stencil_clear_mask); + mask &= ~DD_STENCIL_BIT; + } + if (!clear.flags) return mask; @@ -267,6 +274,8 @@ GLbitfield mgaClear( GLcontext *ctx, GLbitfield mask, GLboolean all, } +int nrswaps; + /* @@ -278,7 +287,6 @@ void mgaSwapBuffers( mgaContextPtr mmesa ) XF86DRIClipRectPtr pbox; int nbox; drm_mga_swap_t swap; - static int nrswaps; int retcode; int i; int tmp; @@ -312,12 +320,16 @@ void mgaSwapBuffers( mgaContextPtr mmesa ) if (0) fprintf(stderr, "DRM_IOCTL_MGA_SWAP\n"); +#if 1 if((retcode = ioctl(mmesa->driFd, DRM_IOCTL_MGA_SWAP, &swap))) { printf("send swap retcode = %d\n", retcode); exit(1); } +#else + mgaUpdateLock( mmesa, DRM_LOCK_FLUSH ); +#endif - if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL) + if (0) fprintf(stderr, "finished swap %d\n", ++nrswaps); } @@ -508,10 +520,10 @@ void mgaFlushEltsLocked( mgaContextPtr mmesa ) { if (mmesa->first_elt != mmesa->next_elt) { mgaFireEltsLocked( mmesa, - ((GLuint)mmesa->first_elt - - (GLuint)mmesa->elt_buf->address), - ((GLuint)mmesa->next_elt - - (GLuint)mmesa->elt_buf->address), + ((char *)mmesa->first_elt - + (char *)mmesa->elt_buf->address), + ((char *)mmesa->next_elt - + (char *)mmesa->elt_buf->address), 0 ); mmesa->first_elt = mmesa->next_elt; } @@ -525,10 +537,10 @@ void mgaFlushElts( mgaContextPtr mmesa ) } -mgaUI32 *mgaAllocVertexDwords( mgaContextPtr mmesa, int dwords ) +GLuint *mgaAllocVertexDwords( mgaContextPtr mmesa, int dwords ) { int bytes = dwords * 4; - mgaUI32 *head; + GLuint *head; if (!mmesa->vertex_dma_buffer) { LOCK_HARDWARE( mmesa ); @@ -546,7 +558,7 @@ mgaUI32 *mgaAllocVertexDwords( mgaContextPtr mmesa, int dwords ) UNLOCK_HARDWARE( mmesa ); } - head = (mgaUI32 *)((char *)mmesa->vertex_dma_buffer->address + + head = (GLuint *)((char *)mmesa->vertex_dma_buffer->address + mmesa->vertex_dma_buffer->used); mmesa->vertex_dma_buffer->used += bytes; @@ -565,7 +577,10 @@ void mgaFireILoadLocked( mgaContextPtr mmesa, if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL) fprintf(stderr, "mgaFireILoad idx %d ofs 0x%x length %d\n", mmesa->iload_buffer->idx, (int)offset, (int)length ); - + + /* HACK + */ + mgaUpdateLock( mmesa, DRM_LOCK_QUIESCENT | DRM_LOCK_FLUSH); mga_iload_dma_ioctl( mmesa, offset, length ); } diff --git a/xc/lib/GL/mesa/src/drv/mga/mgaioctl.h b/xc/lib/GL/mesa/src/drv/mga/mgaioctl.h index 0aafb1e37..869d50160 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgaioctl.h +++ b/xc/lib/GL/mesa/src/drv/mga/mgaioctl.h @@ -1,9 +1,9 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgaioctl.h,v 1.4 2000/08/28 02:43:12 tsi Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgaioctl.h,v 1.5 2000/09/24 13:51:07 alanh Exp $ */ #ifndef MGA_IOCTL_H #define MGA_IOCTL_H -#include "mgalib.h" +#include "mgacontext.h" #include "mga_xmesa.h" GLbitfield mgaClear( GLcontext *ctx, GLbitfield mask, GLboolean all, @@ -14,7 +14,7 @@ void mgaSwapBuffers( mgaContextPtr mmesa ); -mgaUI32 *mgaAllocVertexDwords( mgaContextPtr mmesa, int dwords ); +GLuint *mgaAllocVertexDwords( mgaContextPtr mmesa, int dwords ); void mgaGetILoadBufferLocked( mgaContextPtr mmesa ); @@ -46,6 +46,7 @@ void mgaFlushElts( mgaContextPtr mmesa ) ; /* upload texture */ +void mgaDDFlush( GLcontext *ctx ); void mgaDDFinish( GLcontext *ctx ); void mgaDDInitIoctlFuncs( GLcontext *ctx ); @@ -60,10 +61,10 @@ void mgaDDInitIoctlFuncs( GLcontext *ctx ); extern drmBufPtr mga_get_buffer_ioctl( mgaContextPtr mmesa ); static __inline -mgaUI32 *mgaAllocVertexDwordsInline( mgaContextPtr mmesa, int dwords ) +GLuint *mgaAllocVertexDwordsInline( mgaContextPtr mmesa, int dwords ) { int bytes = dwords * 4; - mgaUI32 *head; + GLuint *head; if (!mmesa->vertex_dma_buffer) { LOCK_HARDWARE( mmesa ); @@ -81,12 +82,11 @@ mgaUI32 *mgaAllocVertexDwordsInline( mgaContextPtr mmesa, int dwords ) UNLOCK_HARDWARE( mmesa ); } - head = (mgaUI32 *)((char *)mmesa->vertex_dma_buffer->address + + head = (GLuint *)((char *)mmesa->vertex_dma_buffer->address + mmesa->vertex_dma_buffer->used); mmesa->vertex_dma_buffer->used += bytes; return head; } - #endif diff --git a/xc/lib/GL/mesa/src/drv/mga/mgapipeline.c b/xc/lib/GL/mesa/src/drv/mga/mgapipeline.c index 8f8fea669..1f5288de5 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgapipeline.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgapipeline.c @@ -1,9 +1,9 @@ -/* #include "mgapipeline.h" */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgapipeline.c,v 1.3 2000/09/26 15:56:47 tsi Exp $ */ #include <stdio.h> #include "mgavb.h" #include "mgadd.h" -#include "mgalib.h" +#include "mgacontext.h" #include "mgatris.h" #include "mgapipeline.h" #include "fog.h" diff --git a/xc/lib/GL/mesa/src/drv/mga/mgaspan.c b/xc/lib/GL/mesa/src/drv/mga/mgaspan.c index 5400510fb..3df15ddce 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgaspan.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgaspan.c @@ -1,9 +1,8 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgaspan.c,v 1.4 2000/08/28 02:43:12 tsi Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgaspan.c,v 1.5 2000/09/24 13:51:07 alanh Exp $ */ #include "types.h" #include "mgadd.h" -#include "mgalib.h" -#include "mgalog.h" +#include "mgacontext.h" #include "mgaspan.h" #include "mgaioctl.h" @@ -18,13 +17,13 @@ GLuint height = dPriv->h; \ char *read_buf = (char *)(sPriv->pFB + \ mmesa->readOffset + \ - dPriv->x * mgaScreen->cpp + \ - dPriv->y * pitch); \ + dPriv->x * mgaScreen->cpp + \ + dPriv->y * pitch); \ char *buf = (char *)(sPriv->pFB + \ mmesa->drawOffset + \ - dPriv->x * mgaScreen->cpp + \ - dPriv->y * pitch); \ - GLushort p = MGA_CONTEXT( ctx )->MonoColor; \ + dPriv->x * mgaScreen->cpp + \ + dPriv->y * pitch); \ + GLushort p = MGA_CONTEXT( ctx )->MonoColor; \ (void) read_buf; (void) buf; (void) p @@ -40,6 +39,8 @@ dPriv->x * 2 + \ dPriv->y * pitch) +#define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS + #define INIT_MONO_PIXEL(p) #define CLIPPIXEL(_x,_y) (_x >= minx && _x < maxx && \ @@ -150,21 +151,48 @@ do { \ +/* 32 bit depthbuffer functions. + */ +#define WRITE_DEPTH( _x, _y, d ) \ + *(GLuint *)(buf + _x*4 + _y*pitch) = d; +#define READ_DEPTH( d, _x, _y ) \ + d = *(GLuint *)(buf + _x*4 + _y*pitch); +#define TAG(x) mga##x##_32 +#include "depthtmp.h" -/* 32 bit depthbuffer functions. + +/* 24/8 bit interleaved depth/stencil functions */ -#define WRITE_DEPTH( _x, _y, d ) \ - *(GLushort *)(buf + _x*4 + _y*pitch) = d; +#define WRITE_DEPTH( _x, _y, d ) { \ + GLuint tmp = *(GLuint *)(buf + _x*4 + _y*pitch); \ + tmp &= 0xff; \ + tmp |= (d) & 0xffffff00; \ + *(GLuint *)(buf + _x*4 + _y*pitch) = tmp; \ +} #define READ_DEPTH( d, _x, _y ) \ - d = *(GLushort *)(buf + _x*4 + _y*pitch); + d = *(GLuint *)(buf + _x*4 + _y*pitch) >> 8; -#define TAG(x) mga##x##_32 + +#define TAG(x) mga##x##_24_8 #include "depthtmp.h" +#define WRITE_STENCIL( _x, _y, d ) { \ + GLuint tmp = *(GLuint *)(buf + _x*4 + _y*pitch); \ + tmp &= 0xffffff00; \ + tmp |= d & 0xff; \ + *(GLuint *)(buf + _x*4 + _y*pitch) = tmp; \ +} + +#define READ_STENCIL( d, _x, _y ) \ + d = *(GLuint *)(buf + _x*4 + _y*pitch) & 0xff; + +#define TAG(x) mga##x##_24_8 +#include "stenciltmp.h" + @@ -196,20 +224,32 @@ void mgaDDInitSpanFuncs( GLcontext *ctx ) ctx->Driver.WriteMonoRGBAPixels = mgaWriteMonoRGBAPixels_8888; ctx->Driver.ReadRGBASpan = mgaReadRGBASpan_8888; ctx->Driver.ReadRGBAPixels = mgaReadRGBAPixels_8888; - - ctx->Driver.ReadDepthSpan = mgaReadDepthSpan_32; - ctx->Driver.WriteDepthSpan = mgaWriteDepthSpan_32; - ctx->Driver.ReadDepthPixels = mgaReadDepthPixels_32; - ctx->Driver.WriteDepthPixels = mgaWriteDepthPixels_32; + + if (mmesa->hw_stencil) { + ctx->Driver.ReadDepthSpan = mgaReadDepthSpan_32; + ctx->Driver.WriteDepthSpan = mgaWriteDepthSpan_32; + ctx->Driver.ReadDepthPixels = mgaReadDepthPixels_32; + ctx->Driver.WriteDepthPixels = mgaWriteDepthPixels_32; + } else { + ctx->Driver.ReadDepthSpan = mgaReadDepthSpan_24_8; + ctx->Driver.WriteDepthSpan = mgaWriteDepthSpan_24_8; + ctx->Driver.ReadDepthPixels = mgaReadDepthPixels_24_8; + ctx->Driver.WriteDepthPixels = mgaWriteDepthPixels_24_8; + + ctx->Driver.ReadStencilSpan = mgaReadStencilSpan_24_8; + ctx->Driver.WriteStencilSpan = mgaWriteStencilSpan_24_8; + ctx->Driver.ReadStencilPixels = mgaReadStencilPixels_24_8; + ctx->Driver.WriteStencilPixels = mgaWriteStencilPixels_24_8; + } break; } - ctx->Driver.WriteCI8Span =NULL; - ctx->Driver.WriteCI32Span =NULL; - ctx->Driver.WriteMonoCISpan =NULL; - ctx->Driver.WriteCI32Pixels =NULL; - ctx->Driver.WriteMonoCIPixels =NULL; - ctx->Driver.ReadCI32Span =NULL; - ctx->Driver.ReadCI32Pixels =NULL; + ctx->Driver.WriteCI8Span = 0; + ctx->Driver.WriteCI32Span = 0; + ctx->Driver.WriteMonoCISpan = 0; + ctx->Driver.WriteCI32Pixels = 0; + ctx->Driver.WriteMonoCIPixels = 0; + ctx->Driver.ReadCI32Span = 0; + ctx->Driver.ReadCI32Pixels = 0; } diff --git a/xc/lib/GL/mesa/src/drv/mga/mgastate.c b/xc/lib/GL/mesa/src/drv/mga/mgastate.c index 4b344b8c3..b1e8d872d 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgastate.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgastate.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgastate.c,v 1.4 2000/08/25 13:42:25 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgastate.c,v 1.5 2000/09/24 13:51:07 alanh Exp $ */ #include <stdio.h> @@ -7,11 +7,10 @@ #include "dd.h" #include "mm.h" -#include "mgalib.h" +#include "mgacontext.h" #include "mgadd.h" #include "mgastate.h" #include "mgatex.h" -#include "mgalog.h" #include "mgavb.h" #include "mgatris.h" #include "mgaregs.h" @@ -33,6 +32,156 @@ static GLuint mgarop_NoBLK[16] = { #endif +static void mgaUpdateStencil(const GLcontext *ctx) +{ + mgaContextPtr mmesa = MGA_CONTEXT(ctx); + GLuint stencil = 0, stencilctl = 0; + + if (ctx->Stencil.Enabled) + { + stencil = ctx->Stencil.Ref | + ( ctx->Stencil.ValueMask << 8 ) | + ( ctx->Stencil.WriteMask << 16 ); + + switch (ctx->Stencil.Function) + { + case GL_NEVER: + MGA_SET_FIELD(stencilctl, SC_smode_MASK, SC_smode_snever); + break; + case GL_LESS: + MGA_SET_FIELD(stencilctl, SC_smode_MASK, SC_smode_slt); + break; + case GL_LEQUAL: + MGA_SET_FIELD(stencilctl, SC_smode_MASK, SC_smode_slte); + break; + case GL_GREATER: + MGA_SET_FIELD(stencilctl, SC_smode_MASK, SC_smode_sgt); + break; + case GL_GEQUAL: + MGA_SET_FIELD(stencilctl, SC_smode_MASK, SC_smode_sgte); + break; + case GL_NOTEQUAL: + MGA_SET_FIELD(stencilctl, SC_smode_MASK, SC_smode_sne); + break; + case GL_EQUAL: + MGA_SET_FIELD(stencilctl, SC_smode_MASK, SC_smode_se); + break; + case GL_ALWAYS: + MGA_SET_FIELD(stencilctl, SC_smode_MASK, SC_smode_salways); + default: + break; + } + + switch (ctx->Stencil.FailFunc) + { + case GL_KEEP: + MGA_SET_FIELD(stencilctl, SC_sfailop_MASK, SC_sfailop_keep); + break; + case GL_ZERO: + MGA_SET_FIELD(stencilctl, SC_sfailop_MASK, SC_sfailop_zero); + break; + case GL_REPLACE: + MGA_SET_FIELD(stencilctl, SC_sfailop_MASK, SC_sfailop_replace); + break; + case GL_INCR: + MGA_SET_FIELD(stencilctl, SC_sfailop_MASK, SC_sfailop_incrsat); + break; + case GL_DECR: + MGA_SET_FIELD(stencilctl, SC_sfailop_MASK, SC_sfailop_decrsat); + break; + case GL_INVERT: + MGA_SET_FIELD(stencilctl, SC_sfailop_MASK, SC_sfailop_invert); + break; + default: + break; + } + + switch (ctx->Stencil.ZFailFunc) + { + case GL_KEEP: + MGA_SET_FIELD(stencilctl, SC_szfailop_MASK, SC_szfailop_keep); + break; + case GL_ZERO: + MGA_SET_FIELD(stencilctl, SC_szfailop_MASK, SC_szfailop_zero); + break; + case GL_REPLACE: + MGA_SET_FIELD(stencilctl, SC_szfailop_MASK, SC_szfailop_replace); + break; + case GL_INCR: + MGA_SET_FIELD(stencilctl, SC_szfailop_MASK, SC_szfailop_incrsat); + break; + case GL_DECR: + MGA_SET_FIELD(stencilctl, SC_szfailop_MASK, SC_szfailop_decrsat); + break; + case GL_INVERT: + MGA_SET_FIELD(stencilctl, SC_szfailop_MASK, SC_szfailop_invert); + break; + default: + break; + } + + switch (ctx->Stencil.ZPassFunc) + { + case GL_KEEP: + MGA_SET_FIELD(stencilctl, SC_szpassop_MASK, SC_szpassop_keep); + break; + case GL_ZERO: + MGA_SET_FIELD(stencilctl, SC_szpassop_MASK, SC_szpassop_zero); + break; + case GL_REPLACE: + MGA_SET_FIELD(stencilctl, SC_szpassop_MASK, SC_szpassop_replace); + break; + case GL_INCR: + MGA_SET_FIELD(stencilctl, SC_szpassop_MASK, SC_szpassop_incrsat); + break; + case GL_DECR: + MGA_SET_FIELD(stencilctl, SC_szpassop_MASK, SC_szpassop_decrsat); + break; + case GL_INVERT: + MGA_SET_FIELD(stencilctl, SC_szpassop_MASK, SC_szpassop_invert); + break; + default: + break; + } + } + + mmesa->Setup[MGA_CTXREG_STENCIL] = stencil; + mmesa->Setup[MGA_CTXREG_STENCILCTL] = stencilctl; + mmesa->dirty |= MGA_UPLOAD_CTX; +} + +static void mgaDDStencilFunc(GLcontext *ctx, GLenum func, GLint ref, + GLuint mask) +{ + FLUSH_BATCH( MGA_CONTEXT(ctx) ); + MGA_CONTEXT(ctx)->new_state |= MGA_NEW_STENCIL; +} + +static void mgaDDStencilMask(GLcontext *ctx, GLuint mask) +{ + FLUSH_BATCH( MGA_CONTEXT(ctx) ); + MGA_CONTEXT(ctx)->new_state |= MGA_NEW_STENCIL; +} + +static void mgaDDStencilOp(GLcontext *ctx, GLenum fail, GLenum zfail, + GLenum zpass) +{ + FLUSH_BATCH( MGA_CONTEXT(ctx) ); + MGA_CONTEXT(ctx)->new_state |= MGA_NEW_STENCIL; +} + +static void mgaDDClearDepth(GLcontext *ctx, GLclampd d) +{ + mgaContextPtr mmesa = MGA_CONTEXT(ctx); + + switch (mmesa->Setup[MGA_CTXREG_MACCESS] & MA_zwidth_MASK) { + case MA_zwidth_16: mmesa->ClearDepth = d * 0x0000ffff; break; + case MA_zwidth_24: mmesa->ClearDepth = d * 0xffffff00; break; + case MA_zwidth_32: mmesa->ClearDepth = d * 0xffffffff; break; + default: return; + } +} + static void mgaUpdateZMode(const GLcontext *ctx) { mgaContextPtr mmesa = MGA_CONTEXT( ctx ); @@ -122,11 +271,8 @@ static void mgaDDLightModelfv(GLcontext *ctx, GLenum pname, static void mgaDDShadeModel(GLcontext *ctx, GLenum mode) { - if (1) { - FLUSH_BATCH( MGA_CONTEXT(ctx) ); - MGA_CONTEXT(ctx)->new_state |= MGA_NEW_TEXTURE; - mgaMsg(8, "mgaDDShadeModel: %x\n", mode); - } + FLUSH_BATCH( MGA_CONTEXT(ctx) ); + MGA_CONTEXT(ctx)->new_state |= MGA_NEW_TEXTURE; } @@ -167,9 +313,9 @@ static void mgaUpdateFogAttrib( GLcontext *ctx ) { mgaContextPtr mmesa = MGA_CONTEXT(ctx); - mgaUI32 color = MGAPACKCOLOR888((mgaUI8)(ctx->Fog.Color[0]*255.0F), - (mgaUI8)(ctx->Fog.Color[1]*255.0F), - (mgaUI8)(ctx->Fog.Color[2]*255.0F)); + GLuint color = MGAPACKCOLOR888((GLubyte)(ctx->Fog.Color[0]*255.0F), + (GLubyte)(ctx->Fog.Color[1]*255.0F), + (GLubyte)(ctx->Fog.Color[2]*255.0F)); if (color != mmesa->Setup[MGA_CTXREG_FOGCOLOR]) mmesa->Setup[MGA_CTXREG_FOGCOLOR] = color; @@ -433,7 +579,7 @@ static void mgaUpdateCull( GLcontext *ctx ) mode ^= (_CULL_POSITIVE ^ _CULL_NEGATIVE); if (ctx->Polygon.FrontFace != GL_CCW) mode ^= (_CULL_POSITIVE ^ _CULL_NEGATIVE); - if (mmesa->multitex) + if (mmesa->warp_pipe & MGA_TEX1_BIT) mode ^= (_CULL_POSITIVE ^ _CULL_NEGATIVE); /* why??? */ } @@ -564,9 +710,6 @@ static void mgaDDPolygonStipple( GLcontext *ctx, const GLubyte *mask ) /* ============================================================= */ - - - static void mgaDDPrintDirty( const char *msg, GLuint state ) { fprintf(stderr, "%s (0x%x): %s%s%s%s%s%s%s\n", @@ -582,11 +725,80 @@ static void mgaDDPrintDirty( const char *msg, GLuint state ) ); } +/* static int tex0[11] = { */ +/* 0x2050003, */ +/* 0x90, */ +/* 0x82100000, */ +/* 0x0, */ +/* 0xc6d000, */ +/* 0xc7d000, */ +/* 0xc81000, */ +/* 0xc82000, */ +/* 0xc82400, */ +/* 0x3fc7413, */ +/* 0x1fc7612 */ +/* }; */ + +/* static int tex1[11] = { */ +/* 0x2040003, */ +/* 0x90, */ +/* 0x82100000, */ +/* 0x0, */ +/* 0xc82500, */ +/* 0xc8a500, */ +/* 0xc8c500, */ +/* 0xc8cd00, */ +/* 0xc8cf00, */ +/* 0x1fc7612, */ +/* 0x1fc7612 */ +/* }; */ + +/* static int tex0_single[11] = { */ +/* 0x2040003, */ +/* 0x10, */ +/* 0x82100000, */ +/* 0x0, */ +/* 0x196d000, */ +/* 0x1975000, */ +/* 0x1977000, */ +/* 0x1977800, */ +/* 0x1977a00, */ +/* 0x1fc7612, */ +/* 0x1fc7612, */ +/* }; */ + +/* static int ctx_single[] = { */ +/* 0x727000, */ +/* 0x1, */ +/* 0xffffffff, */ +/* 0xc4436, */ +/* 0x101, */ +/* 0x7fff7f, */ +/* 0x0, */ +/* 0x0, */ +/* 0x0, */ +/* 0x0 */ +/* }; */ + +/* static int ctx_multi[] = { */ +/* 0x727000, */ +/* 0x1, */ +/* 0xffffffff, */ +/* 0xc4076, */ +/* 0x2000101, */ +/* 0x0, */ +/* 0x0, */ +/* 0xc0600000, */ +/* 0xc3600013, */ +/* 0x0 */ +/* }; */ /* Push the state into the sarea and/or texture memory. */ void mgaEmitHwStateLocked( mgaContextPtr mmesa ) { + drm_mga_sarea_t *sarea = mmesa->sarea; + if (MGA_DEBUG & DEBUG_VERBOSE_MSG) mgaDDPrintDirty( "mgaEmitHwStateLocked", mmesa->dirty ); @@ -596,28 +808,40 @@ void mgaEmitHwStateLocked( mgaContextPtr mmesa ) if ((mmesa->dirty & MGA_UPLOAD_TEX1IMAGE) && mmesa->CurrentTexObj[1]) mgaUploadTexImages(mmesa, mmesa->CurrentTexObj[1]); - if (mmesa->dirty & MGA_UPLOAD_CTX) - memcpy( mmesa->sarea->ContextState, - mmesa->Setup, - sizeof(mmesa->Setup)); + if (mmesa->dirty & MGA_UPLOAD_CTX) { + memcpy( sarea->ContextState, mmesa->Setup, sizeof(mmesa->Setup)); + } - if ((mmesa->dirty & MGA_UPLOAD_TEX0) && mmesa->CurrentTexObj[0]) - memcpy(mmesa->sarea->TexState[0], - mmesa->CurrentTexObj[0]->Setup, - sizeof(mmesa->sarea->TexState[0])); + if ((mmesa->dirty & MGA_UPLOAD_TEX0) && mmesa->CurrentTexObj[0]) { + memcpy(sarea->TexState[0], + mmesa->CurrentTexObj[0]->Setup, + sizeof(sarea->TexState[0])); + } - if ((mmesa->dirty & MGA_UPLOAD_TEX1) && mmesa->CurrentTexObj[1]) - memcpy(mmesa->sarea->TexState[1], - mmesa->CurrentTexObj[1]->Setup, - sizeof(mmesa->sarea->TexState[1])); + if ((mmesa->dirty & MGA_UPLOAD_TEX1) && mmesa->CurrentTexObj[1]) { + memcpy(sarea->TexState[1], + mmesa->CurrentTexObj[1]->Setup, + sizeof(sarea->TexState[1])); + } + + if (sarea->TexState[0][MGA_TEXREG_CTL2] != + sarea->TexState[1][MGA_TEXREG_CTL2]) { + memcpy(sarea->TexState[1], + sarea->TexState[0], + sizeof(sarea->TexState[0])); + mmesa->dirty |= MGA_UPLOAD_TEX1|MGA_UPLOAD_TEX0; + } mmesa->sarea->WarpPipe = mmesa->warp_pipe; + mmesa->sarea->vertexsize = mmesa->vertsize; +/* mmesa->sarea->vertexsize = 10; */ mmesa->sarea->dirty |= mmesa->dirty; #if 0 - mgaPrintSetupFlags("warp pipe", mmesa->sarea->WarpPipe); - fprintf(stderr, "in mgaEmitHwStateLocked: dirty now %x\n", - mmesa->sarea->dirty); + if (mmesa->dirty & MGA_UPLOAD_PIPE) + mgaPrintSetupFlags("warp pipe", mmesa->sarea->WarpPipe); +/* fprintf(stderr, "in mgaEmitHwStateLocked: dirty now %x\n", */ +/* mmesa->sarea->dirty); */ #endif mmesa->dirty &= (MGA_UPLOAD_CLIPRECTS|MGA_WAIT_AGE); @@ -686,6 +910,14 @@ static void mgaDDEnable(GLcontext *ctx, GLenum cap, GLboolean state) mmesa->new_state |= MGA_NEW_DEPTH; #endif break; + case GL_STENCIL_TEST: + FLUSH_BATCH( mmesa ); + if (mmesa->hw_stencil) + mmesa->new_state |= MGA_NEW_STENCIL; + else if (state) + mmesa->Fallback |= MGA_FALLBACK_STENCIL; + else + mmesa->Fallback &= ~MGA_FALLBACK_STENCIL; default: break; } @@ -704,7 +936,11 @@ static void mgaWarpUpdateState( GLcontext *ctx ) int index = mmesa->setupindex; index &= ~(MGA_WIN_BIT|MGA_TEX0_BIT|MGA_RGBA_BIT); - index |= MGA_ALPHA_BIT | MGA_SPEC_BIT | MGA_FOG_BIT; + index |= (MGA_ALPHA_BIT | + MGA_SPEC_BIT | + MGA_FOG_BIT | +/* MGA_TEX1_BIT | */ + 0); if (index != mmesa->warp_pipe) { @@ -722,7 +958,7 @@ static void mgaWarpUpdateState( GLcontext *ctx ) static void mgaDDPrintState( const char *msg, GLuint state ) { - mgaMsg(1, "%s (0x%x): %s%s%s%s%s%s%s%s\n", + fprintf(stderr, "%s (0x%x): %s%s%s%s%s%s%s%s\n", msg, state, (state & MGA_NEW_DEPTH) ? "depth, " : "", @@ -761,6 +997,9 @@ void mgaDDUpdateHwState( GLcontext *ctx ) if (new_state & MGA_NEW_CLIP) mgaUpdateClipping(ctx); + if (new_state & MGA_NEW_STENCIL) + mgaUpdateStencil(ctx); + if (new_state & (MGA_NEW_WARP|MGA_NEW_CULL)) mgaUpdateCull(ctx); @@ -800,7 +1039,6 @@ void mgaDDReducedPrimitiveChange( GLcontext *ctx, GLenum prim ) void mgaDDUpdateState( GLcontext *ctx ) { mgaContextPtr mmesa = MGA_CONTEXT( ctx ); - mgaglx.c_setupPointers++; if (ctx->NewState & INTERESTED) { mgaDDChooseRenderState(ctx); @@ -848,22 +1086,35 @@ void mgaInitState( mgaContextPtr mmesa ) mmesa->Setup[MGA_CTXREG_DSTORG] = mgaScreen->frontOffset; } - if (mgaScreen->cpp == 2) + switch (mmesa->glCtx->Visual->DepthBits) { + case 16: mmesa->Setup[MGA_CTXREG_MACCESS] = (MA_pwidth_16 | - MA_zwidth_16 | + MA_zwidth_16 | /* 1bit stencil? */ MA_memreset_disable | MA_fogen_disable | MA_tlutload_disable | MA_nodither_disable | MA_dit555_disable); - else + break; + case 24: + mmesa->Setup[MGA_CTXREG_MACCESS] = (MA_pwidth_32 | + MA_zwidth_24 | + MA_memreset_disable | + MA_fogen_disable | + MA_tlutload_disable | + MA_nodither_enable | + MA_dit555_disable); + break; + case 32: mmesa->Setup[MGA_CTXREG_MACCESS] = (MA_pwidth_32 | - MA_zwidth_32 | /* stencil? */ + MA_zwidth_32 | MA_memreset_disable | MA_fogen_disable | MA_tlutload_disable | MA_nodither_enable | MA_dit555_disable); + break; + } mmesa->Setup[MGA_CTXREG_DWGCTL] = (DC_opcod_trap | DC_atype_i | @@ -928,14 +1179,18 @@ void mgaDDInitStateFuncs( GLcontext *ctx ) ctx->Driver.SetReadBuffer = mgaDDSetReadBuffer; ctx->Driver.Color = mgaDDSetColor; ctx->Driver.ClearColor = mgaDDClearColor; + ctx->Driver.ClearDepth = mgaDDClearDepth; ctx->Driver.Dither = mgaDDDither; ctx->Driver.LogicOpcode = mgaDDLogicOp; ctx->Driver.PolygonStipple = mgaDDPolygonStipple; + ctx->Driver.StencilFunc = mgaDDStencilFunc; + ctx->Driver.StencilMask = mgaDDStencilMask; + ctx->Driver.StencilOp = mgaDDStencilOp; + ctx->Driver.Index = 0; ctx->Driver.ClearIndex = 0; ctx->Driver.IndexMask = 0; - } diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatex.c b/xc/lib/GL/mesa/src/drv/mga/mgatex.c index 3286744da..6f3592af6 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgatex.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgatex.c @@ -1,4 +1,3 @@ -/* -*- mode: C; c-basic-offset:8 -*- */ /* * GLX Hardware Device Driver for Matrox Millenium G200 * Copyright (C) 1999 Wittawat Yamwong @@ -26,376 +25,122 @@ * 9/20/99 rewrite by John Carmack <johnc@idsoftware.com> * 13/1/00 port to DRI by Keith Whitwell <keithw@precisioninsight.com> */ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatex.c,v 1.5 2000/08/25 13:42:25 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatex.c,v 1.6 2000/09/24 13:51:07 alanh Exp $ */ #include <stdlib.h> #include <stdio.h> #include <GL/gl.h> #include "mm.h" -#include "mgalib.h" +#include "mgacontext.h" #include "mgatex.h" -#include "mgalog.h" #include "mgaregs.h" #include "mgaioctl.h" +#include "enums.h" #include "simple_list.h" +#include "mem.h" +#define TEX_0 1 +#define TEX_1 2 /* * mgaDestroyTexObj * Free all memory associated with a texture and NULL any pointers * to it. */ -static void mgaDestroyTexObj( mgaContextPtr mmesa, mgaTextureObjectPtr t ) { - - if ( !t ) return; +void +mgaDestroyTexObj( mgaContextPtr mmesa, mgaTextureObjectPtr t ) +{ + if ( !t ) return; - /* free the texture memory */ - if (t->MemBlock) { - mmFreeMem( t->MemBlock ); - t->MemBlock = 0; - - if (t->age > mmesa->dirtyAge) - mmesa->dirtyAge = t->age; - } + /* free the texture memory */ + if (t->MemBlock) { + mmFreeMem( t->MemBlock ); + t->MemBlock = 0; + + if (t->age > mmesa->dirtyAge) + mmesa->dirtyAge = t->age; + } - /* free mesa's link */ - if (t->tObj) - t->tObj->DriverData = NULL; + /* free mesa's link */ + if (t->tObj) + t->tObj->DriverData = NULL; - /* see if it was the driver's current object */ - if (t->bound) - mmesa->CurrentTexObj[t->bound - 1] = 0; + /* see if it was the driver's current object */ + if (t->bound & TEX_0) mmesa->CurrentTexObj[0] = 0; + if (t->bound & TEX_1) mmesa->CurrentTexObj[1] = 0; - remove_from_list(t); - free( t ); -} - -static void mgaSwapOutTexObj(mgaContextPtr mmesa, mgaTextureObjectPtr t) -{ - if (t->MemBlock) { - mmFreeMem(t->MemBlock); - t->MemBlock = 0; - - if (t->age > mmesa->dirtyAge) - mmesa->dirtyAge = t->age; - } - - t->dirty_images = ~0; - move_to_tail(&(mmesa->SwappedOut), t); + remove_from_list(t); + FREE( t ); } -static void mgaPrintLocalLRU( mgaContextPtr mmesa, int heap ) -{ - mgaTextureObjectPtr t; - int sz = 1 << (mmesa->mgaScreen->logTextureGranularity[heap]); - - fprintf(stderr, "\nLocal LRU, heap %d:\n", heap); - - foreach( t, &(mmesa->TexObjList[heap]) ) { - if (!t->tObj) - fprintf(stderr, "Placeholder %d at %x sz %x\n", - t->MemBlock->ofs / sz, - t->MemBlock->ofs, - t->MemBlock->size); - else - fprintf(stderr, "Texture (bound %d) at %x sz %x\n", - t->bound, - t->MemBlock->ofs, - t->MemBlock->size); - - } - - fprintf(stderr, "\n\n"); -} - -static void mgaPrintGlobalLRU( mgaContextPtr mmesa, int heap ) +/* + * mgaSetTexWrappings + */ +static void mgaSetTexWrapping( mgaTextureObjectPtr t, + GLenum sWrap, + GLenum tWrap ) { - int i, j; - drm_mga_tex_region_t *list = mmesa->sarea->texList[heap]; + GLuint val = 0; - fprintf(stderr, "\nGlobal LRU, heap %d list %p:\n", heap, list); - - for (i = 0, j = MGA_NR_TEX_REGIONS ; i < MGA_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 == MGA_NR_TEX_REGIONS) break; - } - - if (j != MGA_NR_TEX_REGIONS) { - fprintf(stderr, "Loop detected in global LRU\n\n\n"); - for (i = 0 ; i < MGA_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); - } - } + if (sWrap != GL_REPEAT) + val |= TMC_clampu_enable; - fprintf(stderr, "\n\n"); -} - - -static void mgaResetGlobalLRU( mgaContextPtr mmesa, GLuint heap ) -{ - drm_mga_tex_region_t *list = mmesa->sarea->texList[heap]; - int sz = 1 << mmesa->mgaScreen->logTextureGranularity[heap]; - int i; - - mmesa->texAge[heap] = ++mmesa->sarea->texAge[heap]; - - if (0) fprintf(stderr, "mgaResetGlobalLRU %d\n", (int)heap); - - /* (Re)initialize the global circular LRU list. The last element - * in the array (MGA_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 <= mmesa->mgaScreen->textureSize[heap] ; i++) { - list[i].prev = i-1; - list[i].next = i+1; - list[i].age = mmesa->sarea->texAge[heap]; - } - - i--; - list[0].prev = MGA_NR_TEX_REGIONS; - list[i].prev = i-1; - list[i].next = MGA_NR_TEX_REGIONS; - list[MGA_NR_TEX_REGIONS].prev = i; - list[MGA_NR_TEX_REGIONS].next = 0; + if (tWrap != GL_REPEAT) + val |= TMC_clampv_enable; + t->Setup[MGA_TEXREG_CTL] &= ~(TMC_clampu_enable|TMC_clampv_enable); + t->Setup[MGA_TEXREG_CTL] |= val; } -static void mgaUpdateTexLRU( mgaContextPtr mmesa, mgaTextureObjectPtr t ) -{ - int i; - int heap = t->heap; - int logsz = mmesa->mgaScreen->logTextureGranularity[heap]; - int start = t->MemBlock->ofs >> logsz; - int end = (t->MemBlock->ofs + t->MemBlock->size - 1) >> logsz; - drm_mga_tex_region_t *list = mmesa->sarea->texList[heap]; - - mmesa->texAge[heap] = ++mmesa->sarea->texAge[heap]; - - if (!t->MemBlock) { - fprintf(stderr, "no memblock\n\n"); - return; - } - - /* Update our local LRU - */ - move_to_head( &(mmesa->TexObjList[heap]), t ); - - - if (0) - fprintf(stderr, "mgaUpdateTexLRU heap %d list %p\n", heap, list); - - - /* Update the global LRU - */ - for (i = start ; i <= end ; i++) { - - list[i].in_use = 1; - list[i].age = mmesa->texAge[heap]; - - /* remove_from_list(i) - */ - list[(unsigned)list[i].next].prev = list[i].prev; - list[(unsigned)list[i].prev].next = list[i].next; - - /* insert_at_head(list, i) - */ - list[i].prev = MGA_NR_TEX_REGIONS; - list[i].next = list[MGA_NR_TEX_REGIONS].next; - list[(unsigned)list[MGA_NR_TEX_REGIONS].next].prev = i; - list[MGA_NR_TEX_REGIONS].next = i; - } - - if (0) { - mgaPrintGlobalLRU(mmesa, t->heap); - mgaPrintLocalLRU(mmesa, t->heap); - } -} - -/* Called for every shared texture region which has increased in age - * since we last held the lock. - * - * Figures out which of our textures have been ejected by other clients, - * and pushes a placeholder texture onto the LRU list to represent - * the other client's textures. +/* + * mgaSetTexFilter */ -static void mgaTexturesGone( mgaContextPtr mmesa, - GLuint heap, - GLuint offset, - GLuint size, - GLuint in_use ) +static void mgaSetTexFilter(mgaTextureObjectPtr t, GLenum minf, GLenum magf) { - mgaTextureObjectPtr t, tmp; - - - - foreach_s ( t, tmp, &(mmesa->TexObjList[heap]) ) { - - if (t->MemBlock->ofs >= offset + size || - t->MemBlock->ofs + t->MemBlock->size <= offset) - continue; - - - - - /* It overlaps - kick it off. Need to hold onto the currently bound - * objects, however. - */ - if (t->bound) - mgaSwapOutTexObj( mmesa, t ); - else - mgaDestroyTexObj( mmesa, t ); + GLuint val = 0; + + switch (minf) { + case GL_NEAREST: val = TF_minfilter_nrst; break; + case GL_LINEAR: val = TF_minfilter_bilin; break; + case GL_NEAREST_MIPMAP_NEAREST: val = TF_minfilter_mm1s; break; + case GL_LINEAR_MIPMAP_NEAREST: val = TF_minfilter_mm4s; break; + case GL_NEAREST_MIPMAP_LINEAR: val = TF_minfilter_mm2s; break; + case GL_LINEAR_MIPMAP_LINEAR: val = TF_minfilter_mm8s; break; + default: val = TF_minfilter_nrst; break; } - - if (in_use) { - t = (mgaTextureObjectPtr) calloc(1,sizeof(*t)); - if (!t) return; - - t->heap = heap; - t->MemBlock = mmAllocMem( mmesa->texHeap[heap], size, 0, offset); - if (!t->MemBlock) { - fprintf(stderr, "Couldn't alloc placeholder sz %x ofs %x\n", - (int)size, (int)offset); - mmDumpMemInfo( mmesa->texHeap[heap]); - return; - } - insert_at_head( &(mmesa->TexObjList[heap]), t ); + switch (magf) { + case GL_NEAREST: val |= TF_magfilter_nrst; break; + case GL_LINEAR: val |= TF_magfilter_bilin; break; + default: val |= TF_magfilter_nrst; break; } -} - - -void mgaAgeTextures( mgaContextPtr mmesa, int heap ) -{ - drm_mga_sarea_t *sarea = mmesa->sarea; - int sz = 1 << (mmesa->mgaScreen->logTextureGranularity[heap]); - int idx, nr = 0; - - /* Have to go right round from the back to ensure stuff ends up - * LRU in our local list... Fix with a cursor pointer. - */ - for (idx = sarea->texList[heap][MGA_NR_TEX_REGIONS].prev ; - idx != MGA_NR_TEX_REGIONS && nr < MGA_NR_TEX_REGIONS ; - idx = sarea->texList[heap][idx].prev, nr++) - { - if (sarea->texList[heap][idx].age > mmesa->texAge[heap]) { - mgaTexturesGone(mmesa, heap, idx * sz, sz, 1); - } - } - - if (nr == MGA_NR_TEX_REGIONS) { - mgaTexturesGone(mmesa, heap, 0, - mmesa->mgaScreen->textureSize[heap], 0); - mgaResetGlobalLRU( mmesa, heap ); - } - - - if (0) { - mgaPrintGlobalLRU( mmesa, heap ); - mgaPrintLocalLRU( mmesa, heap ); - } - - mmesa->texAge[heap] = sarea->texAge[heap]; - mmesa->dirty |= MGA_UPLOAD_TEX0IMAGE | MGA_UPLOAD_TEX1IMAGE; -} - - -/* - * mgaSetTexWrappings - */ -static void mgaSetTexWrapping( mgaTextureObjectPtr t, - GLenum sWrap, GLenum tWrap ) { - if (sWrap == GL_REPEAT) { - t->Setup[MGA_TEXREG_CTL] &= ~TMC_clampu_enable; - } else { - t->Setup[MGA_TEXREG_CTL] |= TMC_clampu_enable; - } - if (tWrap == GL_REPEAT) { - t->Setup[MGA_TEXREG_CTL] &= ~TMC_clampv_enable; - } else { - t->Setup[MGA_TEXREG_CTL] |= TMC_clampv_enable; - } -} - -/* - * mgaSetTexFilter - */ -static void mgaSetTexFilter(mgaTextureObjectPtr t, GLenum minf, GLenum magf) { - switch (minf) { - case GL_NEAREST: - MGA_SET_FIELD(t->Setup[MGA_TEXREG_FILTER], - TF_minfilter_MASK, TF_minfilter_nrst); - break; - case GL_LINEAR: - MGA_SET_FIELD(t->Setup[MGA_TEXREG_FILTER], - TF_minfilter_MASK, TF_minfilter_bilin); - break; - case GL_NEAREST_MIPMAP_NEAREST: - MGA_SET_FIELD(t->Setup[MGA_TEXREG_FILTER], - TF_minfilter_MASK, TF_minfilter_mm1s); - break; - case GL_LINEAR_MIPMAP_NEAREST: - MGA_SET_FIELD(t->Setup[MGA_TEXREG_FILTER], - TF_minfilter_MASK, TF_minfilter_mm4s); - break; - case GL_NEAREST_MIPMAP_LINEAR: - MGA_SET_FIELD(t->Setup[MGA_TEXREG_FILTER], - TF_minfilter_MASK, TF_minfilter_mm2s); - break; - case GL_LINEAR_MIPMAP_LINEAR: - MGA_SET_FIELD(t->Setup[MGA_TEXREG_FILTER], - TF_minfilter_MASK, TF_minfilter_mm8s); - break; - default: - mgaError("mgaSetTexFilter(): not supported min. filter %d\n", - (int)minf); - break; - } - - switch (magf) { - case GL_NEAREST: - MGA_SET_FIELD(t->Setup[MGA_TEXREG_FILTER], - TF_magfilter_MASK,TF_magfilter_nrst); - break; - case GL_LINEAR: - MGA_SET_FIELD(t->Setup[MGA_TEXREG_FILTER], - TF_magfilter_MASK,TF_magfilter_bilin); - break; - default: - mgaError("mgaSetTexFilter(): not supported mag. filter %d\n", - (int)magf); - break; - } - /* See OpenGL 1.2 specification */ - if (magf == GL_LINEAR && (minf == GL_NEAREST_MIPMAP_NEAREST || - minf == GL_NEAREST_MIPMAP_LINEAR)) { - /* c = 0.5 */ - MGA_SET_FIELD(t->Setup[MGA_TEXREG_FILTER],TF_fthres_MASK, - 0x20 << TF_fthres_SHIFT); - } else { - /* c = 0 */ - MGA_SET_FIELD(t->Setup[MGA_TEXREG_FILTER],TF_fthres_MASK, - 0x10 << TF_fthres_SHIFT); - } + /* See OpenGL 1.2 specification */ + if (magf == GL_LINEAR && (minf == GL_NEAREST_MIPMAP_NEAREST || + minf == GL_NEAREST_MIPMAP_LINEAR)) { + val |= (0x20 << TF_fthres_SHIFT); /* c = 0.5 */ + } else { + val |= (0x10 << TF_fthres_SHIFT); /* c = 0 */ + } + + t->Setup[MGA_TEXREG_FILTER] &= (TF_minfilter_MASK | + TF_magfilter_MASK | + TF_fthres_MASK); + t->Setup[MGA_TEXREG_FILTER] |= val; } /* * mgaSetTexBorderColor */ -static void mgaSetTexBorderColor(mgaTextureObjectPtr t, GLubyte color[4]) { - t->Setup[MGA_TEXREG_BORDERCOL] = - MGAPACKCOLOR8888(color[0],color[1],color[2],color[3]); - +static void mgaSetTexBorderColor(mgaTextureObjectPtr t, GLubyte color[4]) +{ + t->Setup[MGA_TEXREG_BORDERCOL] = MGAPACKCOLOR8888(color[0],color[1], + color[2],color[3]); } @@ -404,152 +149,6 @@ static void mgaSetTexBorderColor(mgaTextureObjectPtr t, GLubyte color[4]) { -/* - * mgaUploadSubImageLocked - * - * Perform an iload based update of a resident buffer. This is used for - * both initial loading of the entire image, and texSubImage updates. - * - * Performed with the hardware lock held. - */ -static void mgaUploadSubImageLocked( mgaContextPtr mmesa, - mgaTextureObjectPtr t, - int level, - int x, int y, int width, int height ) { - int x2; - int dwords; - int offset; - struct gl_texture_image *image; - int texelBytes, texelsPerDword, texelMaccess, length; - - if ( level < 0 || level >= MGA_TEX_MAXLEVELS ) { - mgaMsg( 1, "mgaUploadSubImage: bad level: %i\n", level ); - return; - } - - image = t->tObj->Image[level]; - if ( !image ) { - mgaError( "mgaUploadSubImage: NULL image\n" ); - return; - } - - /* find the proper destination offset for this level */ - offset = (t->MemBlock->ofs + - t->offsets[level]); - - texelBytes = t->texelBytes; - switch( texelBytes ) { - case 1: - texelsPerDword = 4; - texelMaccess = 0; - break; - case 2: - texelsPerDword = 2; - texelMaccess = 1; - break; - case 4: - texelsPerDword = 1; - texelMaccess = 2; - break; - default: - return; - } - - - /* We can't do a subimage update if pitch is < 32 texels due - * to hardware XY addressing limits, so we will need to - * linearly upload all modified rows. - */ - if ( image->Width < 32 ) { - x = 0; - width = image->Width * height; - height = 1; - - /* Assume that 1x1 textures aren't going to cause a - * bus error if we read up to four texels from that - * location: - */ - if ( width < texelsPerDword ) { - width = texelsPerDword; - } - } else { - /* pad the size out to dwords. The image is a pointer - to the entire image, so we can safely reference - outside the x,y,width,height bounds if we need to */ - x2 = x + width; - x2 = (x2 + (texelsPerDword-1)) & ~(texelsPerDword-1); - x = (x + (texelsPerDword-1)) & ~(texelsPerDword-1); - width = x2 - x; - } - - /* we may not be able to upload the entire texture in one - batch due to register limits or dma buffer limits. - Recursively split it up. */ - while ( 1 ) { - dwords = height * width / texelsPerDword; - if ( dwords * 4 <= MGA_DMA_BUF_SZ ) { - break; - } - mgaMsg(10, "mgaUploadSubImage: recursively subdividing\n" ); - - mgaUploadSubImageLocked( mmesa, t, level, x, y, - width, height >> 1 ); - y += ( height >> 1 ); - height -= ( height >> 1 ); - } - - mgaMsg(10, "mgaUploadSubImage: %i,%i of %i,%i at %i,%i\n", - width, height, image->Width, image->Height, x, y ); - - /* bump the performance counter */ - mgaglx.c_textureSwaps += ( dwords << 2 ); - - length = dwords * 4; - - /* Fill in the secondary buffer with properly converted texels - * from the mesa buffer. */ - if(t->heap == MGA_CARD_HEAP) { - mgaGetILoadBufferLocked( mmesa ); - mgaConvertTexture( (mgaUI32 *)mmesa->iload_buffer->address, - texelBytes, image, x, y, width, height ); - if(length < 64) length = 64; - mgaMsg(10, "TexelBytes : %d, offset: %d, length : %d\n", - texelBytes, - mmesa->mgaScreen->textureOffset[t->heap] + - offset + - y * width * 4/texelsPerDword, - length); - - mgaFireILoadLocked( mmesa, - mmesa->mgaScreen->textureOffset[t->heap] + - offset + - y * width * 4/texelsPerDword, - length); - } else { - /* This works, is slower for uploads to card space and needs - * additional synchronization with the dma stream. - */ - mgaConvertTexture( (mgaUI32 *) - (mmesa->mgaScreen->texVirtual[t->heap] + - offset + - y * width * 4/texelsPerDword), - texelBytes, image, x, y, width, height ); - } -} - - -static void mgaUploadTexLevel( mgaContextPtr mmesa, - mgaTextureObjectPtr t, - int l ) -{ - mgaUploadSubImageLocked( mmesa, - t, - l, - 0, 0, - t->tObj->Image[l]->Width, - t->tObj->Image[l]->Height); -} - /* @@ -558,502 +157,334 @@ static void mgaUploadTexLevel( mgaContextPtr mmesa, * This will happen before drawing with a new texture, or drawing with a * texture after it was swapped out or teximaged again. */ -static void mgaCreateTexObj(mgaContextPtr mmesa, struct gl_texture_object *tObj) +static void mgaCreateTexObj(mgaContextPtr mmesa, + struct gl_texture_object *tObj) { - mgaTextureObjectPtr t; - int i, ofs, size; - struct gl_texture_image *image; - int LastLevel; - int s, s2; - int textureFormat; - - mgaMsg( 10,"mgaCreateTexObj( %p )\n", tObj ); - - t = malloc( sizeof( *t ) ); - if ( !t ) { - mgaError( "mgaCreateTexObj: Failed to malloc mgaTextureObject\n" ); - return; - } - memset( t, 0, sizeof( *t ) ); - - image = tObj->Image[ 0 ]; - if ( !image ) { - return; - } - - if ( 0 ) { - /* G400 texture format options */ - - } else { - /* G200 texture format options */ - - switch( image->Format ) { - case GL_RGB: - case GL_LUMINANCE: - if ( image->IntFormat != GL_RGB5 && - ( image->IntFormat == GL_RGB8 || - mgaglx.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 || - mgaglx.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: - mgaError( "mgaCreateTexObj: bad image->Format\n" ); - free( t ); - return; - } - } - - /* we are going to upload all levels that are present, even if - later levels wouldn't be used by the current filtering mode. This - allows the filtering mode to change without forcing another upload - of the images */ - LastLevel = MGA_TEX_MAXLEVELS-1; - - ofs = 0; - for ( i = 0 ; i <= LastLevel ; i++ ) { - int levelWidth, levelHeight; - - t->offsets[i] = ofs; - image = tObj->Image[ i ]; - if ( !image ) { - LastLevel = i - 1; - mgaMsg( 10, " missing images after LastLevel: %i\n", - LastLevel ); - break; - } - /* the G400 doesn't work with textures less than 8 - units in size */ - levelWidth = image->Width; - levelHeight = image->Height; - if ( levelWidth < 8 ) { - levelWidth = 8; - } - if ( levelHeight < 8 ) { - levelHeight = 8; - } - size = levelWidth * levelHeight * t->texelBytes; - size = ( size + 31 ) & ~31; /* 32 byte aligned */ - ofs += size; - t->dirty_images |= (1<<i); - } - t->totalSize = ofs; - t->lastLevel = LastLevel; + const struct gl_texture_image *image = tObj->Image[ 0 ]; + mgaTextureObjectPtr t; + int i, ofs; + int LastLevel; + int s, s2; + int textureFormat; - /* fill in our mga texture object */ - t->tObj = tObj; - t->ctx = mmesa; - t->age = 0; - t->bound = 0; + if (!image) return; - - insert_at_tail(&(mmesa->SwappedOut), t); - - t->MemBlock = 0; - /* base image */ - image = tObj->Image[ 0 ]; + tObj->DriverData = t = CALLOC( sizeof( *t ) ); + if (!t) { + fprintf(stderr, "mgaCreateTexObj: Failed to malloc mgaTextureObject\n" ); + return; + } - /* setup hardware register values */ - t->Setup[MGA_TEXREG_CTL] = (TMC_takey_1 | - TMC_tamask_0 | - textureFormat ); + 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; + } + + /* We are going to upload all levels that are present, even if + * later levels wouldn't be used by the current filtering mode. This + * allows the filtering mode to change without forcing another upload + * of the images. + */ + LastLevel = MGA_TEX_MAXLEVELS-1; - if (image->WidthLog2 >= 3) { - t->Setup[MGA_TEXREG_CTL] |= ((image->WidthLog2 - 3) << - TMC_tpitch_SHIFT); - } else { - t->Setup[MGA_TEXREG_CTL] |= (TMC_tpitchlin_enable | - (image->Width << - TMC_tpitchext_SHIFT)); - } + ofs = 0; + for ( i = 0 ; i <= LastLevel ; i++ ) { + if ( !tObj->Image[i] ) { + LastLevel = i - 1; + break; + } + t->offsets[i] = ofs; + t->dirty_images |= (1<<i); - t->Setup[MGA_TEXREG_CTL2] = TMC_ckstransdis_enable; + ofs += ((MAX2( tObj->Image[i]->Width, 8 ) * + MAX2( tObj->Image[i]->Height, 8 ) * + t->texelBytes) + 31) & ~31; + } - if ( mmesa->glCtx->Light.Model.ColorControl == - GL_SEPARATE_SPECULAR_COLOR ) - { - t->Setup[MGA_TEXREG_CTL2] |= TMC_specen_enable; - } - - t->Setup[MGA_TEXREG_FILTER] = (TF_minfilter_nrst | - TF_magfilter_nrst | - TF_filteralpha_enable | - (0x10 << TF_fthres_SHIFT) | - (LastLevel << TF_mapnb_SHIFT)); - - /* warp texture registers */ - if (MGA_IS_G200(mmesa)) { - ofs = 28; - } else { - ofs = 11; - } - - s = image->Width; - s2 = image->WidthLog2; - t->Setup[MGA_TEXREG_WIDTH] = - MGA_FIELD(TW_twmask, s - 1) | - MGA_FIELD(TW_rfw, (10 - s2 - 8) & 63 ) | - MGA_FIELD(TW_tw, (s2 + ofs ) | 0x40 ); + t->totalSize = ofs; + t->lastLevel = LastLevel; + t->tObj = tObj; + t->ctx = mmesa; + t->age = 0; + t->bound = 0; + t->MemBlock = 0; + insert_at_tail(&(mmesa->SwappedOut), t); - s = image->Height; - s2 = image->HeightLog2; - t->Setup[MGA_TEXREG_HEIGHT] = - MGA_FIELD(TH_thmask, s - 1) | - MGA_FIELD(TH_rfh, (10 - s2 - 8) & 63 ) | - MGA_FIELD(TH_th, (s2 + ofs ) | 0x40 ); - - - /* set all the register values for filtering, border, etc */ - mgaSetTexWrapping( t, tObj->WrapS, tObj->WrapT ); - mgaSetTexFilter( t, tObj->MinFilter, tObj->MagFilter ); - mgaSetTexBorderColor( t, tObj->BorderColor ); - - tObj->DriverData = t; -} - -static void mgaMigrateTexture( mgaContextPtr mmesa, mgaTextureObjectPtr t ) -{ - /* NOT DONE */ -} - -static int mgaChooseTexHeap( mgaContextPtr mmesa, mgaTextureObjectPtr t ) -{ - return 0; -} + /* setup hardware register values */ + t->Setup[MGA_TEXREG_CTL] = (TMC_takey_1 | + TMC_tamask_0 | + textureFormat ); + if (image->WidthLog2 >= 3) + t->Setup[MGA_TEXREG_CTL] |= ((image->WidthLog2 - 3) << TMC_tpitch_SHIFT); + else + t->Setup[MGA_TEXREG_CTL] |= (TMC_tpitchlin_enable | + (image->Width << TMC_tpitchext_SHIFT)); -int mgaUploadTexImages( mgaContextPtr mmesa, mgaTextureObjectPtr t ) -{ - int heap; - int i; - int ofs; - mgaglx.c_textureSwaps++; - - heap = t->heap = mgaChooseTexHeap( mmesa, t ); - - /* Do we need to eject LRU texture objects? - */ - if (!t->MemBlock) { - while (1) - { - mgaTextureObjectPtr tmp = mmesa->TexObjList[heap].prev; - - t->MemBlock = mmAllocMem( mmesa->texHeap[heap], - t->totalSize, - 6, 0 ); - if (t->MemBlock) - break; - - if (mmesa->TexObjList[heap].prev->bound) { - fprintf(stderr, - "Hit bound texture in upload\n"); - return -1; - } - - if (mmesa->TexObjList[heap].prev == - &(mmesa->TexObjList[heap])) - { - fprintf(stderr, "Failed to upload texture, " - "sz %d\n", t->totalSize); - mmDumpMemInfo( mmesa->texHeap[heap] ); - return -1; - } - - mgaDestroyTexObj( mmesa, tmp ); - } - - ofs = t->MemBlock->ofs - + mmesa->mgaScreen->textureOffset[heap] - ; - t->Setup[MGA_TEXREG_ORG] = ofs; - t->Setup[MGA_TEXREG_ORG1] = ofs + t->offsets[1]; - t->Setup[MGA_TEXREG_ORG2] = ofs + t->offsets[2]; - t->Setup[MGA_TEXREG_ORG3] = ofs + t->offsets[3]; - t->Setup[MGA_TEXREG_ORG4] = ofs + t->offsets[4]; + t->Setup[MGA_TEXREG_CTL2] = TMC_ckstransdis_enable; - mmesa->dirty |= MGA_UPLOAD_CTX; - } - - /* Let the world know we've used this memory recently. - */ - mgaUpdateTexLRU( mmesa, t ); + if ( mmesa->glCtx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR ) + t->Setup[MGA_TEXREG_CTL2] |= TMC_specen_enable; - if (MGA_DEBUG&DEBUG_VERBOSE_LRU) - fprintf(stderr, "dispatch age: %d age freed memory: %d\n", - GET_DISPATCH_AGE(mmesa), mmesa->dirtyAge); - - if (mmesa->dirtyAge >= GET_DISPATCH_AGE(mmesa)) - mgaWaitAgeLocked( mmesa, mmesa->dirtyAge ); - - if (t->dirty_images) { - if (MGA_DEBUG&DEBUG_VERBOSE_LRU) - fprintf(stderr, "*"); + t->Setup[MGA_TEXREG_FILTER] = (TF_minfilter_nrst | + TF_magfilter_nrst | + TF_filteralpha_enable | + (0x10 << TF_fthres_SHIFT) | + (LastLevel << TF_mapnb_SHIFT)); + + /* warp texture registers */ + ofs = MGA_IS_G200(mmesa) ? 28 : 11; + s = image->Width; + s2 = image->WidthLog2; + t->Setup[MGA_TEXREG_WIDTH] = (MGA_FIELD(TW_twmask, s - 1) | + MGA_FIELD(TW_rfw, (10 - s2 - 8) & 63 ) | + MGA_FIELD(TW_tw, (s2 + ofs ) | 0x40 )); - for (i = 0 ; i <= t->lastLevel ; i++) - if (t->dirty_images & (1<<i)) - mgaUploadTexLevel( mmesa, t, i ); - } + + s = image->Height; + s2 = image->HeightLog2; + t->Setup[MGA_TEXREG_HEIGHT] = (MGA_FIELD(TH_thmask, s - 1) | + MGA_FIELD(TH_rfh, (10 - s2 - 8) & 63 ) | + MGA_FIELD(TH_th, (s2 + ofs ) | 0x40 )); - t->dirty_images = 0; - return 0; + /* set all the register values for filtering, border, etc */ + mgaSetTexWrapping( t, tObj->WrapS, tObj->WrapT ); + mgaSetTexFilter( t, tObj->MinFilter, tObj->MagFilter ); + mgaSetTexBorderColor( t, tObj->BorderColor ); } -/* -============================================================================ - -PUBLIC MGA FUNCTIONS - -============================================================================ -*/ static void mgaUpdateTextureEnvG200( GLcontext *ctx ) { - struct gl_texture_object *tObj = ctx->Texture.Unit[0].Current; - mgaTextureObjectPtr t; - - if (!tObj || !tObj->DriverData) - return; - - t = (mgaTextureObjectPtr)tObj->DriverData; - - switch (ctx->Texture.Unit[0].EnvMode) { - case GL_REPLACE: - t->Setup[MGA_TEXREG_CTL] &= ~TMC_tmodulate_enable; - t->Setup[MGA_TEXREG_CTL2] &= ~TMC_decaldis_enable; - break; - case GL_MODULATE: - t->Setup[MGA_TEXREG_CTL] |= TMC_tmodulate_enable; - t->Setup[MGA_TEXREG_CTL2] &= ~TMC_decaldis_enable; - break; - case GL_DECAL: - t->Setup[MGA_TEXREG_CTL] &= ~TMC_tmodulate_enable; - t->Setup[MGA_TEXREG_CTL2] &= ~TMC_decaldis_enable; - break; - case GL_BLEND: - t->ctx->Fallback |= MGA_FALLBACK_TEXTURE; - break; - default: - break; - } + struct gl_texture_object *tObj = ctx->Texture.Unit[0].Current; + mgaTextureObjectPtr t; + + if (!tObj || !tObj->DriverData) + return; + + t = (mgaTextureObjectPtr)tObj->DriverData; + + switch (ctx->Texture.Unit[0].EnvMode) { + case GL_REPLACE: + t->Setup[MGA_TEXREG_CTL] &= ~TMC_tmodulate_enable; + break; + case GL_MODULATE: + t->Setup[MGA_TEXREG_CTL] |= TMC_tmodulate_enable; + break; + case GL_DECAL: + t->Setup[MGA_TEXREG_CTL] &= ~TMC_tmodulate_enable; + break; + case GL_BLEND: + t->ctx->Fallback |= MGA_FALLBACK_TEXTURE; + break; + default: + break; + } } -static void mgaUpdateTextureStage( GLcontext *ctx, int unit ) +static void mgaUpdateTextureEnvG400( GLcontext *ctx, int unit ) { - mgaContextPtr mmesa = MGA_CONTEXT( ctx ); - GLuint *reg = &mmesa->Setup[MGA_CTXREG_TDUAL0 + unit]; - GLuint source = mmesa->tmu_source[unit]; - struct gl_texture_object *tObj = ctx->Texture.Unit[source].Current; - - *reg = 0; - if (unit == 1) - *reg = mmesa->Setup[MGA_CTXREG_TDUAL0]; - - if ( tObj != ctx->Texture.Unit[source].CurrentD[2] ) - return; + mgaContextPtr mmesa = MGA_CONTEXT( ctx ); + GLuint *reg = &mmesa->Setup[MGA_CTXREG_TDUAL0 + unit]; + GLuint source = mmesa->tmu_source[unit]; + struct gl_texture_object *tObj = ctx->Texture.Unit[source].Current; + + if ( tObj != ctx->Texture.Unit[source].CurrentD[2] || + !tObj || + !tObj->Complete || + ((ctx->Enabled>>(source*4))&TEXTURE0_ANY) != TEXTURE0_2D ) + return; - if ( ((ctx->Enabled>>(source*4))&TEXTURE0_ANY) != TEXTURE0_2D ) - return; - - if (!tObj || !tObj->Complete) - return; - - switch (ctx->Texture.Unit[source].EnvMode) { - case GL_REPLACE: - *reg = (TD0_color_sel_arg1 | - TD0_alpha_sel_arg1 ); - break; - - case GL_MODULATE: - if (unit == 0) - *reg = ( TD0_color_arg2_diffuse | - TD0_color_sel_mul | - TD0_alpha_arg2_diffuse | - TD0_alpha_sel_mul); - 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 (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 ); - - 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); - break; - - case GL_BLEND: - if (0) - fprintf(stderr, "GL_BLEND unit %d flags %x\n", unit, - mmesa->blend_flags); - - if (mmesa->blend_flags) - mmesa->Fallback |= MGA_FALLBACK_TEXTURE; - return; - - /* 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: - break; - } -} + switch (ctx->Texture.Unit[source].EnvMode) { + case GL_REPLACE: + *reg = (TD0_color_sel_arg1 | + TD0_alpha_sel_arg1 ); + break; + + case GL_MODULATE: + if (unit == 0) + *reg = ( TD0_color_arg2_diffuse | + TD0_color_sel_mul | + TD0_alpha_arg2_diffuse | + TD0_alpha_sel_mul); + 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 (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 ); + + 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); + 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 + */ + *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: + break; + } +} -static void mgaUpdateTextureObject( GLcontext *ctx, int unit ) { - mgaTextureObjectPtr t; - struct gl_texture_object *tObj; - GLuint enabled; - mgaContextPtr mmesa = MGA_CONTEXT( ctx ); - GLuint source = mmesa->tmu_source[unit]; - - mgaMsg(15,"mgaUpdateTextureState %d\n", unit); - - /* disable texturing until it is known to be good */ - mmesa->Setup[MGA_CTXREG_DWGCTL] &= DC_opcod_MASK; - mmesa->Setup[MGA_CTXREG_DWGCTL] |= DC_opcod_trap; - - enabled = (ctx->Texture.Enabled>>(source*4))&TEXTURE0_ANY; - if (enabled != TEXTURE0_2D) { - if (enabled) - mmesa->Fallback |= MGA_FALLBACK_TEXTURE; - return; - } - tObj = ctx->Texture.Unit[source].Current; +static void mgaUpdateTextureObject( GLcontext *ctx, int unit ) +{ + mgaTextureObjectPtr t; + struct gl_texture_object *tObj; + GLuint enabled; + mgaContextPtr mmesa = MGA_CONTEXT( ctx ); + GLuint source = mmesa->tmu_source[unit]; - if ( !tObj || tObj != ctx->Texture.Unit[source].CurrentD[2] ) - return; -/* fprintf(stderr, "unit %d: %d\n", unit, tObj->Name); */ - - /* if the texture object doesn't exist at all (never used or - swapped out), create it now, uploading all texture images */ + enabled = (ctx->Texture.Enabled>>(source*4))&TEXTURE0_ANY; + tObj = ctx->Texture.Unit[source].Current; - if ( !tObj->DriverData ) { - /* clear the current pointer so that texture object can be - swapped out if necessary to make room */ - mgaCreateTexObj( mmesa, tObj ); + if (enabled != TEXTURE0_2D) { + if (enabled) + mmesa->Fallback |= MGA_FALLBACK_TEXTURE; + return; + } - if ( !tObj->DriverData ) { - mgaMsg( 5, "mgaUpdateTextureState: create failed\n" ); - mmesa->Fallback |= MGA_FALLBACK_TEXTURE; - return; /* can't create a texture object */ - } - } + if ( !tObj || tObj != ctx->Texture.Unit[source].CurrentD[2] ) { + mmesa->Fallback |= MGA_FALLBACK_TEXTURE; + return; + } - /* we definately have a valid texture now */ - mmesa->Setup[MGA_CTXREG_DWGCTL] &= DC_opcod_MASK; - mmesa->Setup[MGA_CTXREG_DWGCTL] |= DC_opcod_texture_trap; +/* if (!tObj) tObj = ctx->Texture.Unit[0].Current; */ +/* if (!tObj) return; */ - t = (mgaTextureObjectPtr)tObj->DriverData; + if ( !tObj->DriverData ) { + mgaCreateTexObj( mmesa, tObj ); + if ( !tObj->DriverData ) { + mmesa->Fallback |= MGA_FALLBACK_TEXTURE; + return; + } + } - if (t->dirty_images) - mmesa->dirty |= (MGA_UPLOAD_TEX0IMAGE << unit); + t = (mgaTextureObjectPtr)tObj->DriverData; - mmesa->CurrentTexObj[unit] = t; - t->bound = unit+1; + if (t->dirty_images) + mmesa->dirty |= (MGA_UPLOAD_TEX0IMAGE << unit); - if (t->MemBlock) - mgaUpdateTexLRU( mmesa, t ); + mmesa->CurrentTexObj[unit] = t; + t->bound |= unit+1; +/* if (t->MemBlock) */ +/* mgaUpdateTexLRU( mmesa, t ); */ - t->Setup[MGA_TEXREG_CTL2] &= ~TMC_dualtex_enable; - if (ctx->Texture.Enabled == (TEXTURE0_2D|TEXTURE1_2D)) - t->Setup[MGA_TEXREG_CTL2] |= TMC_dualtex_enable; + t->Setup[MGA_TEXREG_CTL2] &= ~TMC_dualtex_enable; + if (mmesa->multitex) + t->Setup[MGA_TEXREG_CTL2] |= TMC_dualtex_enable; - t->Setup[MGA_TEXREG_CTL2] &= ~TMC_specen_enable; - if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) - t->Setup[MGA_TEXREG_CTL2] |= TMC_specen_enable; - + t->Setup[MGA_TEXREG_CTL2] &= ~TMC_specen_enable; + if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) + t->Setup[MGA_TEXREG_CTL2] |= TMC_specen_enable; } @@ -1065,278 +496,259 @@ static void mgaUpdateTextureObject( GLcontext *ctx, int unit ) { */ void mgaUpdateTextureState( GLcontext *ctx ) { - mgaContextPtr mmesa = MGA_CONTEXT( ctx ); - mmesa->Fallback &= ~MGA_FALLBACK_TEXTURE; - - if (mmesa->CurrentTexObj[0]) mmesa->CurrentTexObj[0]->bound = 0; - if (mmesa->CurrentTexObj[1]) mmesa->CurrentTexObj[1]->bound = 0; - mmesa->CurrentTexObj[0] = 0; - mmesa->CurrentTexObj[1] = 0; + mgaContextPtr mmesa = MGA_CONTEXT( ctx ); + mmesa->Fallback &= ~MGA_FALLBACK_TEXTURE; - if (MGA_IS_G400(mmesa)) { - mgaUpdateTextureObject( ctx, 0 ); - mgaUpdateTextureStage( ctx, 0 ); + if (mmesa->CurrentTexObj[0]) { + mmesa->CurrentTexObj[0]->bound = 0; + mmesa->CurrentTexObj[0] = 0; + } - mmesa->Setup[MGA_CTXREG_TDUAL1] = - mmesa->Setup[MGA_CTXREG_TDUAL0]; + if (mmesa->CurrentTexObj[1]) { + mmesa->CurrentTexObj[1]->bound = 0; + mmesa->CurrentTexObj[1] = 0; + } - if (mmesa->multitex) { - mgaUpdateTextureObject( ctx, 1 ); - mgaUpdateTextureStage( ctx, 1 ); - } - - mmesa->dirty |= MGA_UPLOAD_TEX0 | MGA_UPLOAD_TEX1; - } else { - mgaUpdateTextureObject( ctx, 0 ); - mgaUpdateTextureEnvG200( ctx ); - } - - /* schedule the register writes */ - mmesa->dirty |= MGA_UPLOAD_CTX | MGA_UPLOAD_TEX0; -} + if (MGA_IS_G400(mmesa)) { + mgaUpdateTextureObject( ctx, 0 ); + mgaUpdateTextureEnvG400( ctx, 0 ); + + mmesa->Setup[MGA_CTXREG_TDUAL1] = mmesa->Setup[MGA_CTXREG_TDUAL0]; + + if (mmesa->multitex || 1) { + mgaUpdateTextureObject( ctx, 1 ); + mgaUpdateTextureEnvG400( ctx, 1 ); + } +/* else */ +/* mmesa->Setup[MGA_CTXREG_TDUAL1] = ( TD0_color_arg2_prevstage | */ +/* TD0_color_sel_arg2 | */ +/* TD0_alpha_arg2_prevstage | */ +/* TD0_alpha_sel_arg2); */ + + + mmesa->dirty |= MGA_UPLOAD_TEX1; + } else { + mgaUpdateTextureObject( ctx, 0 ); + mgaUpdateTextureEnvG200( ctx ); + } + mmesa->dirty |= MGA_UPLOAD_CTX | MGA_UPLOAD_TEX0; + mmesa->Setup[MGA_CTXREG_DWGCTL] &= DC_opcod_MASK; + mmesa->Setup[MGA_CTXREG_DWGCTL] |= (ctx->Texture.Enabled + ? DC_opcod_texture_trap + : DC_opcod_trap); +} -/* -============================================================================ -Driver functions called directly from mesa -============================================================================ -*/ -/* - * mgaTexEnv - */ -void mgaTexEnv( GLcontext *ctx, GLenum target, - GLenum pname, const GLfloat *param ) +static void mgaDDTexEnv( GLcontext *ctx, GLenum target, + GLenum pname, const GLfloat *param ) { - mgaContextPtr mmesa = MGA_CONTEXT(ctx); - mgaMsg( 10, "mgaTexEnv( %i )\n", pname ); - - - if (pname == GL_TEXTURE_ENV_MODE) { - /* force the texture state to be updated */ - FLUSH_BATCH( MGA_CONTEXT(ctx) ); - MGA_CONTEXT(ctx)->new_state |= (MGA_NEW_TEXTURE | - MGA_NEW_ALPHA); - } - else if (pname == GL_TEXTURE_ENV_COLOR) - { - struct gl_texture_unit *texUnit = - &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; - GLfloat *fc = texUnit->EnvColor; - GLubyte c[4]; - GLuint col; - - - c[0] = fc[0]; - c[1] = fc[1]; - c[2] = fc[2]; - c[3] = fc[3]; + mgaContextPtr mmesa = MGA_CONTEXT(ctx); - col = mgaPackColor( mmesa->mgaScreen->cpp, - c[0], c[1], c[2], c[3] ); - mmesa->envcolor = (c[3]<<24) | (c[0]<<16) | (c[1]<<8) | (c[2]); + if (pname == GL_TEXTURE_ENV_MODE) { + /* force the texture state to be updated */ + FLUSH_BATCH( MGA_CONTEXT(ctx) ); + MGA_CONTEXT(ctx)->new_state |= (MGA_NEW_TEXTURE | + MGA_NEW_ALPHA); + } + else if (pname == GL_TEXTURE_ENV_COLOR) + { + struct gl_texture_unit *texUnit = + &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + GLfloat *fc = texUnit->EnvColor; + GLubyte c[4]; + GLuint col; + + COPY_4V(c, fc); + col = mgaPackColor( mmesa->mgaScreen->cpp, c[0], c[1], c[2], c[3] ); + mmesa->envcolor = (c[3]<<24) | (c[0]<<16) | (c[1]<<8) | (c[2]); - if (mmesa->Setup[MGA_CTXREG_FCOL] != col) { - FLUSH_BATCH(mmesa); - mmesa->Setup[MGA_CTXREG_FCOL] = col; - mmesa->dirty |= MGA_UPLOAD_CTX; - - mmesa->blend_flags &= ~MGA_BLEND_ENV_COLOR; - - /* Actually just require all four components to be - * equal. This permits a single-pass GL_BLEND. - * - * More complex multitexture/multipass fallbacks - * for blend can be done later. - */ - if (mmesa->envcolor != 0x0 && - mmesa->envcolor != 0xffffffff) - mmesa->blend_flags |= MGA_BLEND_ENV_COLOR; - } - } - + if (mmesa->Setup[MGA_CTXREG_FCOL] != col) { + FLUSH_BATCH(mmesa); + mmesa->Setup[MGA_CTXREG_FCOL] = col; + mmesa->dirty |= MGA_UPLOAD_CTX; + + mmesa->blend_flags &= ~MGA_BLEND_ENV_COLOR; + + /* Actually just require all four components to be + * equal. This permits a single-pass GL_BLEND. + * + * More complex multitexture/multipass fallbacks + * for blend can be done later. + */ + if (mmesa->envcolor != 0x0 && mmesa->envcolor != 0xffffffff) + mmesa->blend_flags |= MGA_BLEND_ENV_COLOR; + } + } } -/* - * mgaTexImage - */ -void mgaTexImage( GLcontext *ctx, GLenum target, - struct gl_texture_object *tObj, GLint level, - GLint internalFormat, - const struct gl_texture_image *image ) + +static void mgaDDTexImage( GLcontext *ctx, GLenum target, + struct gl_texture_object *tObj, GLint level, + GLint internalFormat, + const struct gl_texture_image *image ) { - mgaContextPtr mmesa = MGA_CONTEXT( ctx ); - mgaTextureObjectPtr t; + mgaContextPtr mmesa = MGA_CONTEXT( ctx ); + mgaTextureObjectPtr t; - mgaMsg( 10,"mgaTexImage( %p, level %i )\n", tObj, level ); - - /* just free the mga texture if it exists, it will be recreated at - mgaUpdateTextureState time. */ - t = (mgaTextureObjectPtr) tObj->DriverData; - if ( t ) { - if (t->bound) FLUSH_BATCH(mmesa); - /* if this is the current object, it will force an update */ - mgaDestroyTexObj( mmesa, t ); - mmesa->new_state |= MGA_NEW_TEXTURE; - } + /* just free the mga texture if it exists, it will be recreated at + mgaUpdateTextureState time. */ + t = (mgaTextureObjectPtr) tObj->DriverData; + if ( t ) { + if (t->bound) FLUSH_BATCH(mmesa); + /* if this is the current object, it will force an update */ + mgaDestroyTexObj( mmesa, t ); + mmesa->new_state |= MGA_NEW_TEXTURE; + } + + if (0) + fprintf(stderr, "mgaDDTexImage tObj %p, level %d, image %p\n", + tObj, level, image); + } -/* - * mgaTexSubImage - */ -void mgaTexSubImage( 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 ) +static void mgaDDTexSubImage( 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 ) { - mgaContextPtr mmesa = MGA_CONTEXT( ctx ); - mgaTextureObjectPtr t; - - mgaMsg(10,"mgaTexSubImage() Size: %d,%d of %d,%d; Level %d\n", - width, height, image->Width,image->Height, level); + mgaContextPtr mmesa = MGA_CONTEXT( ctx ); + mgaTextureObjectPtr t; - t = (mgaTextureObjectPtr) tObj->DriverData; + t = (mgaTextureObjectPtr) tObj->DriverData; - /* just free the mga texture if it exists, it will be recreated at - mgaUpdateTextureState time. */ - t = (mgaTextureObjectPtr) tObj->DriverData; - if ( t ) { - if (t->bound) FLUSH_BATCH(mmesa); - /* if this is the current object, it will force an update */ - mgaDestroyTexObj( mmesa, t ); - mmesa->new_state |= MGA_NEW_TEXTURE; - } + /* just free the mga texture if it exists, it will be recreated at + mgaUpdateTextureState time. */ + t = (mgaTextureObjectPtr) tObj->DriverData; + if ( t ) { + if (t->bound) FLUSH_BATCH(mmesa); + /* if this is the current object, it will force an update */ + mgaDestroyTexObj( mmesa, t ); + mmesa->new_state |= MGA_NEW_TEXTURE; + } #if 0 - /* the texture currently exists, so directly update it */ - mgaUploadSubImage( t, level, xoffset, yoffset, width, height ); + /* the texture currently exists, so directly update it */ + mgaUploadSubImage( t, level, xoffset, yoffset, width, height ); #endif } + + /* * mgaTexParameter * This just changes variables and flags for a state update, which * will happen at the next mgaUpdateTextureState */ -void mgaTexParameter( GLcontext *ctx, GLenum target, - struct gl_texture_object *tObj, - GLenum pname, const GLfloat *params ) +static void +mgaDDTexParameter( GLcontext *ctx, GLenum target, + struct gl_texture_object *tObj, + GLenum pname, const GLfloat *params ) { - mgaContextPtr mmesa = MGA_CONTEXT( ctx ); - mgaTextureObjectPtr t; - - mgaMsg( 10, "mgaTexParameter( %p, %i )\n", tObj, pname ); - - t = (mgaTextureObjectPtr) tObj->DriverData; - - /* if we don't have a hardware texture, it will be automatically - created with current state before it is used, so we don't have - to do anything now */ - if ( !t || target != GL_TEXTURE_2D ) { - return; - } - - switch (pname) { - case GL_TEXTURE_MIN_FILTER: - case GL_TEXTURE_MAG_FILTER: - if (t->bound) FLUSH_BATCH(mmesa); - mgaSetTexFilter( t, tObj->MinFilter, tObj->MagFilter ); - break; - - case GL_TEXTURE_WRAP_S: - case GL_TEXTURE_WRAP_T: - if (t->bound) FLUSH_BATCH(mmesa); - mgaSetTexWrapping(t,tObj->WrapS,tObj->WrapT); - break; + mgaContextPtr mmesa = MGA_CONTEXT( ctx ); + mgaTextureObjectPtr t; + + t = (mgaTextureObjectPtr) tObj->DriverData; + + /* if we don't have a hardware texture, it will be automatically + created with current state before it is used, so we don't have + to do anything now */ + if ( !t || !t->bound || target != GL_TEXTURE_2D ) { + return; + } + + switch (pname) { + case GL_TEXTURE_MIN_FILTER: + case GL_TEXTURE_MAG_FILTER: + FLUSH_BATCH(mmesa); + mgaSetTexFilter( t, tObj->MinFilter, tObj->MagFilter ); + break; + + case GL_TEXTURE_WRAP_S: + case GL_TEXTURE_WRAP_T: + FLUSH_BATCH(mmesa); + mgaSetTexWrapping(t,tObj->WrapS,tObj->WrapT); + break; - case GL_TEXTURE_BORDER_COLOR: - if (t->bound) FLUSH_BATCH(mmesa); - mgaSetTexBorderColor(t,tObj->BorderColor); - break; + case GL_TEXTURE_BORDER_COLOR: + FLUSH_BATCH(mmesa); + mgaSetTexBorderColor(t,tObj->BorderColor); + break; - default: - return; - } + default: + return; + } - mmesa->new_state |= MGA_NEW_TEXTURE; + mmesa->new_state |= MGA_NEW_TEXTURE; } -/* - * mgaBindTexture - */ -void mgaBindTexture( GLcontext *ctx, GLenum target, - struct gl_texture_object *tObj ) -{ - mgaContextPtr mmesa = MGA_CONTEXT( ctx ); - mgaMsg( 10, "mgaBindTexture( %p )\n", tObj ); +static void +mgaDDBindTexture( GLcontext *ctx, GLenum target, + struct gl_texture_object *tObj ) +{ + mgaContextPtr mmesa = MGA_CONTEXT( ctx ); + int unit = ctx->Texture.CurrentUnit; - FLUSH_BATCH(mmesa); + FLUSH_BATCH(mmesa); - if (mmesa->CurrentTexObj[ctx->Texture.CurrentUnit]) { - mmesa->CurrentTexObj[ctx->Texture.CurrentUnit]->bound = 0; - mmesa->CurrentTexObj[ctx->Texture.CurrentUnit] = 0; - } + if (mmesa->CurrentTexObj[unit]) { + mmesa->CurrentTexObj[unit]->bound &= ~(unit+1); + mmesa->CurrentTexObj[unit] = 0; + } - /* force the texture state to be updated - */ - MGA_CONTEXT(ctx)->new_state |= MGA_NEW_TEXTURE; + /* force the texture state to be updated + */ + MGA_CONTEXT(ctx)->new_state |= MGA_NEW_TEXTURE; } -/* - * mgaDeleteTexture - */ -void mgaDeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj ) + +static void +mgaDDDeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj ) { - mgaContextPtr mmesa = MGA_CONTEXT( ctx ); - mgaTextureObjectPtr t = (mgaTextureObjectPtr)tObj->DriverData; + mgaContextPtr mmesa = MGA_CONTEXT( ctx ); + mgaTextureObjectPtr t = (mgaTextureObjectPtr)tObj->DriverData; + + if ( t ) { + if (t->bound) { + FLUSH_BATCH(mmesa); + if (t->bound & TEX_0) mmesa->CurrentTexObj[0] = 0; + if (t->bound & TEX_1) mmesa->CurrentTexObj[1] = 0; + mmesa->new_state |= MGA_NEW_TEXTURE; + } - mgaMsg( 10, "mgaDeleteTexture( %p )\n", tObj ); - - if ( t ) { - if (t->bound) { - FLUSH_BATCH(mmesa); - mmesa->CurrentTexObj[t->bound-1] = 0; - mmesa->new_state |= MGA_NEW_TEXTURE; - } - - mgaDestroyTexObj( mmesa, t ); - mmesa->new_state |= MGA_NEW_TEXTURE; - } + mgaDestroyTexObj( mmesa, t ); + mmesa->new_state |= MGA_NEW_TEXTURE; + } } -/* Have to grab the lock to find out if anyone has kicked out our - * textures. - */ -GLboolean mgaIsTextureResident( GLcontext *ctx, struct gl_texture_object *t ) +static GLboolean +mgaDDIsTextureResident( GLcontext *ctx, struct gl_texture_object *t ) { - mgaTextureObjectPtr mt; - -/* LOCK_HARDWARE; */ - mt = (mgaTextureObjectPtr)t->DriverData; -/* UNLOCK_HARDWARE; */ - - return mt && mt->MemBlock; + mgaTextureObjectPtr mt = (mgaTextureObjectPtr)t->DriverData; + return mt && mt->MemBlock; } -void mgaDDInitTextureFuncs( GLcontext *ctx ) + +void +mgaDDInitTextureFuncs( GLcontext *ctx ) { - ctx->Driver.TexEnv = mgaTexEnv; - ctx->Driver.TexImage = mgaTexImage; - ctx->Driver.TexSubImage = mgaTexSubImage; - ctx->Driver.BindTexture = mgaBindTexture; - ctx->Driver.DeleteTexture = mgaDeleteTexture; - ctx->Driver.TexParameter = mgaTexParameter; + ctx->Driver.TexEnv = mgaDDTexEnv; + ctx->Driver.TexImage = mgaDDTexImage; + ctx->Driver.TexSubImage = mgaDDTexSubImage; + ctx->Driver.BindTexture = mgaDDBindTexture; + ctx->Driver.DeleteTexture = mgaDDDeleteTexture; + ctx->Driver.TexParameter = mgaDDTexParameter; ctx->Driver.UpdateTexturePalette = 0; - ctx->Driver.IsTextureResident = mgaIsTextureResident; + ctx->Driver.IsTextureResident = mgaDDIsTextureResident; } diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatex.h b/xc/lib/GL/mesa/src/drv/mga/mgatex.h index 748c9c42b..02e95f59f 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgatex.h +++ b/xc/lib/GL/mesa/src/drv/mga/mgatex.h @@ -24,43 +24,15 @@ * John Carmack <johnc@idsoftware.com> * Keith Whitwell <keithw@precisioninsight.com> */ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatex.h,v 1.3 2000/06/22 16:59:24 tsi Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatex.h,v 1.4 2000/09/24 13:51:07 alanh Exp $ */ #ifndef MGATEX_INC #define MGATEX_INC -#include "types.h" -#include "mgacommon.h" -#include "mm.h" +#include "mgacontext.h" +typedef struct mga_texture_object_s *mgaTextureObjectPtr; -#define MGA_TEX_MAXLEVELS 5 - - -typedef struct mga_texture_object_s { - struct mga_texture_object_s *next; - struct mga_texture_object_s *prev; - struct gl_texture_object *tObj; - mgaContextPtr ctx; - PMemBlock MemBlock; - mgaUI32 offsets[MGA_TEX_MAXLEVELS]; - int lastLevel; - mgaUI32 dirty_images; - mgaUI32 totalSize; - int texelBytes; - mgaUI32 age; - int bound; - int heap; /* agp or card */ - mgaUI32 Setup[MGA_TEX_SETUP_SIZE]; -} mgaTextureObject_t; - -typedef mgaTextureObject_t *mgaTextureObjectPtr; - -/* called to check for environment variable options */ -void mgaInitTextureSystem( void ); - -/* called when a context is being destroyed */ -void mgaDestroyContextTextures( mgaContextPtr ctx ); /* Called before a primitive is rendered to make sure the texture * state is properly setup. Texture residence is checked later @@ -71,35 +43,7 @@ void mgaUpdateTextureState( GLcontext *ctx ); /* Driver functions which are called directly from mesa */ -void mgaTexEnv( GLcontext *ctx, GLenum target, GLenum pname, - const GLfloat *param ); - -void mgaTexImage( GLcontext *ctx, GLenum target, - struct gl_texture_object *tObj, GLint level, - GLint internalFormat, - const struct gl_texture_image *image ); - -void mgaTexSubImage( 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 ); - -void mgaTexParameter( GLcontext *ctx, GLenum target, - struct gl_texture_object *tObj, - GLenum pname, const GLfloat *params ); - -void mgaBindTexture( GLcontext *ctx, GLenum target, - struct gl_texture_object *tObj ); - -void mgaDeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj ); - -void mgaUpdateTexturePalette( GLcontext *ctx, struct gl_texture_object *tObj ); - -GLboolean mgaIsTextureResident( GLcontext *ctx, struct gl_texture_object *t ); - -void mgaConvertTexture( mgaUI32 *dest, int texelBytes, +void mgaConvertTexture( GLuint *dest, int texelBytes, struct gl_texture_image *image, int x, int y, int width, int height ); @@ -107,14 +51,11 @@ void mgaConvertTexture( mgaUI32 *dest, int texelBytes, int mgaUploadTexImages( mgaContextPtr mmesa, mgaTextureObjectPtr t ); - - +void mgaDestroyTexObj( mgaContextPtr mmesa, mgaTextureObjectPtr t ); void mgaAgeTextures( mgaContextPtr mmesa, int heap ); void mgaDDInitTextureFuncs( GLcontext *ctx ); - - #endif diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatexcnv.c b/xc/lib/GL/mesa/src/drv/mga/mgatexcnv.c new file mode 100644 index 000000000..4e5bf8607 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/mga/mgatexcnv.c @@ -0,0 +1,257 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatexcnv.c,v 1.1 2000/09/24 13:51:08 alanh Exp $ */ +/* + * GLX Hardware Device Driver for Matrox Millenium G200 + * Copyright (C) 1999 Wittawat Yamwong + * + * 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 + * WITTAWAT YAMWONG, OR ANY OTHER CONTRIBUTORS 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. + * + * + * original by Wittawat Yamwong <Wittawat.Yamwong@stud.uni-hannover.de> + * 9/20/99 rewrite by John Carmack <johnc@idsoftware.com> + */ + + +#include <stdlib.h> +#include <stdio.h> + +#include <GL/gl.h> + +#include "mm.h" +#include "mgacontext.h" +#include "mgatex.h" + + +/* + * mgaConvertTexture + * Converts a mesa format texture to the apropriate hardware format + * Note that sometimes width may be larger than the texture, like 64x1 + * for an 8x8 texture. This happens when we have to crutch the pitch + * limits of the mga by uploading a block of texels as a single line. + */ +void mgaConvertTexture( GLuint *destPtr, int texelBytes, + struct gl_texture_image *image, + int x, int y, int width, int height ) +{ + register int i, j; + GLubyte *src; + int stride; + + if (0) + fprintf(stderr, "texture image %p\n", image->Data); + + if (image->Data == 0) + return; + + /* FIXME: g400 luminance_alpha internal format */ + switch (texelBytes) { + case 1: + switch (image->Format) { + case GL_COLOR_INDEX: + case GL_INTENSITY: + case GL_LUMINANCE: + case GL_ALPHA: + src = (GLubyte *)image->Data + ( y * image->Width + x ); + stride = (image->Width - width); + for ( i = height ; i ; i-- ) { + for ( j = width >> 2 ; j ; j-- ) { + + *destPtr++ = src[0] | ( src[1] << 8 ) | ( src[2] << 16 ) | ( src[3] << 24 ); + src += 4; + } + src += stride; + } + break; + default: + goto format_error; + } + break; + case 2: + switch (image->Format) { + case GL_RGB: + src = (GLubyte *)image->Data + ( y * image->Width + x ) * 3; + stride = (image->Width - width) * 3; + for ( i = height ; i ; i-- ) { + for ( j = width >> 1 ; j ; j-- ) { + + *destPtr++ = MGAPACKCOLOR565(src[0],src[1],src[2]) | + ( MGAPACKCOLOR565(src[3],src[4],src[5]) << 16 ); + src += 6; + } + src += stride; + } + break; + case GL_RGBA: + src = (GLubyte *)image->Data + ( y * image->Width + x ) * 4; + stride = (image->Width - width) * 4; + for ( i = height ; i ; i-- ) { + for ( j = width >> 1 ; j ; j-- ) { + + *destPtr++ = MGAPACKCOLOR4444(src[0],src[1],src[2],src[3]) | + ( MGAPACKCOLOR4444(src[4],src[5],src[6],src[7]) << 16 ); + src += 8; + } + src += stride; + } + break; + case GL_LUMINANCE: + src = (GLubyte *)image->Data + ( y * image->Width + x ); + stride = (image->Width - width); + for ( i = height ; i ; i-- ) { + for ( j = width >> 1 ; j ; j-- ) { + /* FIXME: should probably use 555 texture to get true grey */ + *destPtr++ = MGAPACKCOLOR565(src[0],src[0],src[0]) | + ( MGAPACKCOLOR565(src[1],src[1],src[1]) << 16 ); + src += 2; + } + src += stride; + } + break; + case GL_INTENSITY: + src = (GLubyte *)image->Data + ( y * image->Width + x ); + stride = (image->Width - width); + for ( i = height ; i ; i-- ) { + for ( j = width >> 1 ; j ; j-- ) { + + *destPtr++ = MGAPACKCOLOR4444(src[0],src[0],src[0],src[0]) | + ( MGAPACKCOLOR4444(src[1],src[1],src[1],src[1]) << 16 ); + src += 2; + } + src += stride; + } + break; + case GL_ALPHA: + src = (GLubyte *)image->Data + ( y * image->Width + x ); + stride = (image->Width - width); + for ( i = height ; i ; i-- ) { + for ( j = width >> 1 ; j ; j-- ) { + + *destPtr++ = MGAPACKCOLOR4444(255,255,255,src[0]) | + ( MGAPACKCOLOR4444(255,255,255,src[1]) << 16 ); + src += 2; + } + src += stride; + } + break; + case GL_LUMINANCE_ALPHA: + src = (GLubyte *)image->Data + ( y * image->Width + x ) * 2; + stride = (image->Width - width) * 2; + for ( i = height ; i ; i-- ) { + for ( j = width >> 1 ; j ; j-- ) { + + *destPtr++ = MGAPACKCOLOR4444(src[0],src[0],src[0],src[1]) | + ( MGAPACKCOLOR4444(src[2],src[2],src[2],src[3]) << 16 ); + src += 4; + } + src += stride; + } + break; + default: + goto format_error; + } + break; + case 4: + switch (image->Format) { + case GL_RGB: + src = (GLubyte *)image->Data + ( y * image->Width + x ) * 3; + stride = (image->Width - width) * 3; + for ( i = height ; i ; i-- ) { + for ( j = width ; j ; j-- ) { + + *destPtr++ = MGAPACKCOLOR8888(src[0],src[1],src[2], 255); + src += 3; + } + src += stride; + } + break; + case GL_RGBA: + src = (GLubyte *)image->Data + ( y * image->Width + x ) * 4; + stride = (image->Width - width) * 4; + for ( i = height ; i ; i-- ) { + for ( j = width ; j ; j-- ) { + + *destPtr++ = MGAPACKCOLOR8888(src[0],src[1],src[2],src[3]); + src += 4; + } + src += stride; + } + break; + case GL_LUMINANCE: + src = (GLubyte *)image->Data + ( y * image->Width + x ); + stride = (image->Width - width); + for ( i = height ; i ; i-- ) { + for ( j = width ; j ; j-- ) { + + *destPtr++ = MGAPACKCOLOR8888(src[0],src[0],src[0], 255); + src += 1; + } + src += stride; + } + break; + case GL_INTENSITY: + src = (GLubyte *)image->Data + ( y * image->Width + x ); + stride = (image->Width - width); + for ( i = height ; i ; i-- ) { + for ( j = width ; j ; j-- ) { + + *destPtr++ = MGAPACKCOLOR8888(src[0],src[0],src[0],src[0]); + src += 1; + } + src += stride; + } + break; + case GL_ALPHA: + src = (GLubyte *)image->Data + ( y * image->Width + x ); + stride = (image->Width - width); + for ( i = height ; i ; i-- ) { + for ( j = width ; j ; j-- ) { + + *destPtr++ = MGAPACKCOLOR8888(255,255,255,src[0]); + src += 1; + } + src += stride; + } + break; + case GL_LUMINANCE_ALPHA: + src = (GLubyte *)image->Data + ( y * image->Width + x ) * 2; + stride = (image->Width - width) * 2; + for ( i = height ; i ; i-- ) { + for ( j = width ; j ; j-- ) { + + *destPtr++ = MGAPACKCOLOR8888(src[0],src[0], + src[0],src[1]); + src += 2; + } + src += stride; + } + break; + default: + goto format_error; + } + break; + default: + goto format_error; + } + + return; + + format_error: + + fprintf(stderr, "Unsupported texelBytes %i, image->Format %i\n", + (int)texelBytes, (int)image->Format ); +} diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatexmem.c b/xc/lib/GL/mesa/src/drv/mga/mgatexmem.c new file mode 100644 index 000000000..9d328f064 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/mga/mgatexmem.c @@ -0,0 +1,492 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatexmem.c,v 1.1 2000/09/24 13:51:08 alanh Exp $ */ + +#include <stdlib.h> +#include <stdio.h> +#include <GL/gl.h> + +#include "mm.h" +#include "mgacontext.h" +#include "mgatex.h" +#include "mgaregs.h" +#include "mgaioctl.h" + +#include "mem.h" +#include "simple_list.h" + +static void +mgaSwapOutTexObj(mgaContextPtr mmesa, mgaTextureObjectPtr t) +{ + if (t->MemBlock) { + mmFreeMem(t->MemBlock); + t->MemBlock = 0; + + if (t->age > mmesa->dirtyAge) + mmesa->dirtyAge = t->age; + } + + t->dirty_images = ~0; + move_to_tail(&(mmesa->SwappedOut), t); +} + +static void +mgaPrintLocalLRU( mgaContextPtr mmesa, int heap ) +{ + mgaTextureObjectPtr t; + int sz = 1 << (mmesa->mgaScreen->logTextureGranularity[heap]); + + fprintf(stderr, "\nLocal LRU, heap %d:\n", heap); + + foreach( t, &(mmesa->TexObjList[heap]) ) { + if (!t->tObj) + fprintf(stderr, "Placeholder %d at %x sz %x\n", + t->MemBlock->ofs / sz, + t->MemBlock->ofs, + t->MemBlock->size); + else + fprintf(stderr, "Texture (bound %d) at %x sz %x\n", + t->bound, + t->MemBlock->ofs, + t->MemBlock->size); + } + + fprintf(stderr, "\n\n"); +} + +static void +mgaPrintGlobalLRU( mgaContextPtr mmesa, int heap ) +{ + int i, j; + drm_mga_tex_region_t *list = mmesa->sarea->texList[heap]; + + fprintf(stderr, "\nGlobal LRU, heap %d list %p:\n", heap, list); + + for (i = 0, j = MGA_NR_TEX_REGIONS ; i < MGA_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 == MGA_NR_TEX_REGIONS) break; + } + + if (j != MGA_NR_TEX_REGIONS) { + fprintf(stderr, "Loop detected in global LRU\n\n\n"); + for (i = 0 ; i < MGA_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\n"); +} + + +static void mgaResetGlobalLRU( mgaContextPtr mmesa, GLuint heap ) +{ + drm_mga_tex_region_t *list = mmesa->sarea->texList[heap]; + int sz = 1 << mmesa->mgaScreen->logTextureGranularity[heap]; + int i; + + mmesa->texAge[heap] = ++mmesa->sarea->texAge[heap]; + + if (0) fprintf(stderr, "mgaResetGlobalLRU %d\n", (int)heap); + + /* (Re)initialize the global circular LRU list. The last element + * in the array (MGA_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 <= mmesa->mgaScreen->textureSize[heap] ; i++) { + list[i].prev = i-1; + list[i].next = i+1; + list[i].age = mmesa->sarea->texAge[heap]; + } + + i--; + list[0].prev = MGA_NR_TEX_REGIONS; + list[i].prev = i-1; + list[i].next = MGA_NR_TEX_REGIONS; + list[MGA_NR_TEX_REGIONS].prev = i; + list[MGA_NR_TEX_REGIONS].next = 0; + +} + + +static void mgaUpdateTexLRU( mgaContextPtr mmesa, mgaTextureObjectPtr t ) +{ + int i; + int heap = t->heap; + int logsz = mmesa->mgaScreen->logTextureGranularity[heap]; + int start = t->MemBlock->ofs >> logsz; + int end = (t->MemBlock->ofs + t->MemBlock->size - 1) >> logsz; + drm_mga_tex_region_t *list = mmesa->sarea->texList[heap]; + + mmesa->texAge[heap] = ++mmesa->sarea->texAge[heap]; + + if (!t->MemBlock) { + fprintf(stderr, "no memblock\n\n"); + return; + } + + /* Update our local LRU + */ + move_to_head( &(mmesa->TexObjList[heap]), t ); + + + if (0) + fprintf(stderr, "mgaUpdateTexLRU heap %d list %p\n", heap, list); + + + /* Update the global LRU + */ + for (i = start ; i <= end ; i++) { + + list[i].in_use = 1; + list[i].age = mmesa->texAge[heap]; + + /* remove_from_list(i) + */ + list[(unsigned)list[i].next].prev = list[i].prev; + list[(unsigned)list[i].prev].next = list[i].next; + + /* insert_at_head(list, i) + */ + list[i].prev = MGA_NR_TEX_REGIONS; + list[i].next = list[MGA_NR_TEX_REGIONS].next; + list[(unsigned)list[MGA_NR_TEX_REGIONS].next].prev = i; + list[MGA_NR_TEX_REGIONS].next = i; + } + + if (0) { + mgaPrintGlobalLRU(mmesa, t->heap); + mgaPrintLocalLRU(mmesa, t->heap); + } +} + +/* Called for every shared texture region which has increased in age + * since we last held the lock. + * + * Figures out which of our textures have been ejected by other clients, + * and pushes a placeholder texture onto the LRU list to represent + * the other client's textures. + */ +static void mgaTexturesGone( mgaContextPtr mmesa, + GLuint heap, + GLuint offset, + GLuint size, + GLuint in_use ) +{ + mgaTextureObjectPtr t, tmp; + + + + foreach_s ( t, tmp, &(mmesa->TexObjList[heap]) ) { + + if (t->MemBlock->ofs >= offset + size || + t->MemBlock->ofs + t->MemBlock->size <= offset) + continue; + + + + + /* It overlaps - kick it off. Need to hold onto the currently bound + * objects, however. + */ + if (t->bound) + mgaSwapOutTexObj( mmesa, t ); + else + mgaDestroyTexObj( mmesa, t ); + } + + + if (in_use) { + t = (mgaTextureObjectPtr) CALLOC(sizeof(*t)); + if (!t) return; + + t->heap = heap; + t->MemBlock = mmAllocMem( mmesa->texHeap[heap], size, 0, offset); + if (!t->MemBlock) { + fprintf(stderr, "Couldn't alloc placeholder sz %x ofs %x\n", + (int)size, (int)offset); + mmDumpMemInfo( mmesa->texHeap[heap]); + return; + } + insert_at_head( &(mmesa->TexObjList[heap]), t ); + } +} + + +void mgaAgeTextures( mgaContextPtr mmesa, int heap ) +{ + drm_mga_sarea_t *sarea = mmesa->sarea; + int sz = 1 << (mmesa->mgaScreen->logTextureGranularity[heap]); + int idx, nr = 0; + + /* Have to go right round from the back to ensure stuff ends up + * LRU in our local list... Fix with a cursor pointer. + */ + for (idx = sarea->texList[heap][MGA_NR_TEX_REGIONS].prev ; + idx != MGA_NR_TEX_REGIONS && nr < MGA_NR_TEX_REGIONS ; + idx = sarea->texList[heap][idx].prev, nr++) + { + if (sarea->texList[heap][idx].age > mmesa->texAge[heap]) { + mgaTexturesGone(mmesa, heap, idx * sz, sz, 1); + } + } + + if (nr == MGA_NR_TEX_REGIONS) { + mgaTexturesGone(mmesa, heap, 0, + mmesa->mgaScreen->textureSize[heap], 0); + mgaResetGlobalLRU( mmesa, heap ); + } + + + if (0) { + mgaPrintGlobalLRU( mmesa, heap ); + mgaPrintLocalLRU( mmesa, heap ); + } + + mmesa->texAge[heap] = sarea->texAge[heap]; + mmesa->dirty |= MGA_UPLOAD_TEX0IMAGE | MGA_UPLOAD_TEX1IMAGE; +} + +/* + * mgaUploadSubImageLocked + * + * Perform an iload based update of a resident buffer. This is used for + * both initial loading of the entire image, and texSubImage updates. + * + * Performed with the hardware lock held. + */ +static void mgaUploadSubImageLocked( mgaContextPtr mmesa, + mgaTextureObjectPtr t, + int level, + int x, int y, int width, int height ) +{ + int x2; + int dwords; + int offset; + struct gl_texture_image *image; + int texelBytes, texelsPerDword, texelMaccess, length; + + if ( level < 0 || level >= MGA_TEX_MAXLEVELS ) + return; + + image = t->tObj->Image[level]; + if ( !image ) return; + + + if (image->Data == 0) { + fprintf(stderr, "null texture image data tObj %p level %d\n", + t->tObj, level); + return; + } + + + /* find the proper destination offset for this level */ + offset = (t->MemBlock->ofs + + t->offsets[level]); + + + texelBytes = t->texelBytes; + switch( texelBytes ) { + case 1: + texelsPerDword = 4; + texelMaccess = 0; + break; + case 2: + texelsPerDword = 2; + texelMaccess = 1; + break; + case 4: + texelsPerDword = 1; + texelMaccess = 2; + break; + default: + return; + } + + + /* We can't do a subimage update if pitch is < 32 texels due + * to hardware XY addressing limits, so we will need to + * linearly upload all modified rows. + */ + if ( image->Width < 32 ) { + x = 0; + width = image->Width * height; + height = 1; + + /* Assume that 1x1 textures aren't going to cause a + * bus error if we read up to four texels from that + * location: + */ +/* if ( width < texelsPerDword ) { */ +/* width = texelsPerDword; */ +/* } */ + } else { + /* pad the size out to dwords. The image is a pointer + to the entire image, so we can safely reference + outside the x,y,width,height bounds if we need to */ + x2 = x + width; + x2 = (x2 + (texelsPerDword-1)) & ~(texelsPerDword-1); + x = (x + (texelsPerDword-1)) & ~(texelsPerDword-1); + width = x2 - x; + } + + /* we may not be able to upload the entire texture in one + batch due to register limits or dma buffer limits. + Recursively split it up. */ + while ( 1 ) { + dwords = height * width / texelsPerDword; + if ( dwords * 4 <= MGA_DMA_BUF_SZ ) { + break; + } + + mgaUploadSubImageLocked( mmesa, t, level, x, y, + width, height >> 1 ); + y += ( height >> 1 ); + height -= ( height >> 1 ); + } + + length = dwords * 4; + + /* Fill in the secondary buffer with properly converted texels + * from the mesa buffer. */ + if(t->heap == MGA_CARD_HEAP) { + mgaGetILoadBufferLocked( mmesa ); + mgaConvertTexture( (GLuint *)mmesa->iload_buffer->address, + texelBytes, image, x, y, width, height ); + if(length < 64) length = 64; + + if (0) + fprintf(stderr, "TexelBytes : %d, offset: %d, length : %d\n", + texelBytes, + mmesa->mgaScreen->textureOffset[t->heap] + + offset + + y * width * 4/texelsPerDword, + length); + + mgaFireILoadLocked( mmesa, + mmesa->mgaScreen->textureOffset[t->heap] + + offset + + y * width * 4/texelsPerDword, + length); + } else { + /* This works, is slower for uploads to card space and needs + * additional synchronization with the dma stream. + */ + mgaConvertTexture( (GLuint *) + (mmesa->mgaScreen->texVirtual[t->heap] + + offset + + y * width * 4/texelsPerDword), + texelBytes, image, x, y, width, height ); + } +} + + +static void mgaUploadTexLevel( mgaContextPtr mmesa, + mgaTextureObjectPtr t, + int l ) +{ +/* return; */ + mgaUploadSubImageLocked( mmesa, + t, + l, + 0, 0, + t->tObj->Image[l]->Width, + t->tObj->Image[l]->Height); +} + + + + +#if 0 +static void mgaMigrateTexture( mgaContextPtr mmesa, mgaTextureObjectPtr t ) +{ + /* NOT DONE */ +} +#endif + + +static int mgaChooseTexHeap( mgaContextPtr mmesa, mgaTextureObjectPtr t ) +{ + return 0; +} + + +int mgaUploadTexImages( mgaContextPtr mmesa, mgaTextureObjectPtr t ) +{ + int heap; + int i; + int ofs; + + heap = t->heap = mgaChooseTexHeap( mmesa, t ); + + /* Do we need to eject LRU texture objects? + */ + if (!t->MemBlock) { + while (1) + { + mgaTextureObjectPtr tmp = mmesa->TexObjList[heap].prev; + + t->MemBlock = mmAllocMem( mmesa->texHeap[heap], + t->totalSize, + 6, 0 ); + if (t->MemBlock) + break; + + if (mmesa->TexObjList[heap].prev->bound) { + fprintf(stderr, + "Hit bound texture in upload\n"); + return -1; + } + + if (mmesa->TexObjList[heap].prev == + &(mmesa->TexObjList[heap])) + { + fprintf(stderr, "Failed to upload texture, " + "sz %d\n", t->totalSize); + mmDumpMemInfo( mmesa->texHeap[heap] ); + return -1; + } + + mgaDestroyTexObj( mmesa, tmp ); + } + + ofs = t->MemBlock->ofs + + mmesa->mgaScreen->textureOffset[heap] + ; + + t->Setup[MGA_TEXREG_ORG] = ofs; + t->Setup[MGA_TEXREG_ORG1] = ofs + t->offsets[1]; + t->Setup[MGA_TEXREG_ORG2] = ofs + t->offsets[2]; + t->Setup[MGA_TEXREG_ORG3] = ofs + t->offsets[3]; + t->Setup[MGA_TEXREG_ORG4] = ofs + t->offsets[4]; + + mmesa->dirty |= MGA_UPLOAD_CTX; + } + + /* Let the world know we've used this memory recently. + */ + mgaUpdateTexLRU( mmesa, t ); + + + if (MGA_DEBUG&DEBUG_VERBOSE_LRU) + fprintf(stderr, "dispatch age: %d age freed memory: %d\n", + GET_DISPATCH_AGE(mmesa), mmesa->dirtyAge); + + if (mmesa->dirtyAge >= GET_DISPATCH_AGE(mmesa)) + mgaWaitAgeLocked( mmesa, mmesa->dirtyAge ); + + if (t->dirty_images) { + if (MGA_DEBUG&DEBUG_VERBOSE_LRU) + fprintf(stderr, "*"); + + for (i = 0 ; i <= t->lastLevel ; i++) + if (t->dirty_images & (1<<i)) + mgaUploadTexLevel( mmesa, t, i ); + } + + + t->dirty_images = 0; + return 0; +} diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatris.c b/xc/lib/GL/mesa/src/drv/mga/mgatris.c index bf38066ee..d842e5252 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgatris.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgatris.c @@ -23,7 +23,7 @@ * * Wittawat Yamwong <Wittawat.Yamwong@stud.uni-hannover.de> */ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatris.c,v 1.4 2000/08/28 02:43:12 tsi Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatris.c,v 1.5 2000/09/24 13:51:08 alanh Exp $ */ #include <stdio.h> #include <math.h> @@ -33,22 +33,27 @@ #include "pipeline.h" #include "mm.h" -#include "mgalib.h" +#include "mgacontext.h" #include "mgatris.h" #include "mgavb.h" -#include "mgalog.h" static void mga_null_quad( GLcontext *ctx, GLuint v0, - GLuint v1, GLuint v2, GLuint v3, GLuint pv ) { + GLuint v1, GLuint v2, GLuint v3, GLuint pv ) +{ } + static void mga_null_triangle( GLcontext *ctx, GLuint v0, - GLuint v1, GLuint v2, GLuint pv ) { + GLuint v1, GLuint v2, GLuint pv ) +{ } -static void mga_null_line( GLcontext *ctx, 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 ) { +static void mga_null_points( GLcontext *ctx, GLuint first, GLuint last ) +{ } @@ -66,17 +71,6 @@ static quad_func quad_tab[0x10]; static line_func line_tab[0x10]; static points_func points_tab[0x10]; -static void mgaPrintRenderState( const char *msg, GLuint state ) -{ - fprintf(stderr, "%s: (%x) %s%s%s%s%s\n", - msg, state, - (state & MGA_FLAT_BIT) ? "flat, " : "", - (state & MGA_OFFSET_BIT) ? "offset, " : "", - (state & MGA_TWOSIDE_BIT) ? "twoside, " : "", - (state & MGA_NODRAW_BIT) ? "no-draw, " : "", - (state & MGA_FALLBACK_BIT) ? "fallback" : ""); -} - #define IND (0) #define TAG(x) x #include "mgatritmp.h" @@ -148,8 +142,8 @@ void mgaDDTrifuncInit() void mgaDDChooseRenderState(GLcontext *ctx) { mgaContextPtr mmesa = MGA_CONTEXT(ctx); - GLuint flags = ctx->TriangleCaps; - CARD32 index = 0; + GLuint flags = ctx->TriangleCaps; + GLuint index = 0; if (mmesa->Fallback) { mmesa->renderindex = MGA_FALLBACK_BIT; @@ -203,8 +197,3 @@ void mgaDDChooseRenderState(GLcontext *ctx) } } } - - - - - diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatris.h b/xc/lib/GL/mesa/src/drv/mga/mgatris.h index 038d11689..0c27ab43d 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgatris.h +++ b/xc/lib/GL/mesa/src/drv/mga/mgatris.h @@ -23,7 +23,7 @@ * * Wittawat Yamwong <Wittawat.Yamwong@stud.uni-hannover.de> */ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatris.h,v 1.4 2000/08/28 02:43:12 tsi Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatris.h,v 1.5 2000/09/24 13:51:08 alanh Exp $ */ #ifndef MGATIS_INC #define MGATIS_INC @@ -41,47 +41,123 @@ extern void mgaDDTrifuncInit( void ); #define MGA_NODRAW_BIT 0x8 #define MGA_FALLBACK_BIT 0x10 - - +extern int nrswaps; + + +#define VERTSIZE vertsize + +/* static float _v0[] = { */ +/* 242.202515, */ +/* 250.469604, */ +/* 0.961081, */ +/* 0.013503, */ +/* 0, */ +/* 0.000000, */ +/* 2.600000, */ +/* 0.000000, */ +/* 1.000000, */ +/* 0.600000 */ +/* }; */ + +/* static float _v1[] = { */ +/* 246.448914, */ +/* 54.697876, */ +/* 0.953817, */ +/* 0.014156, */ +/* 0, */ +/* 0.000000, */ +/* 2.600000, */ +/* 2.000000, */ +/* 1.000000, */ +/* 1.600000 */ +/* }; */ + +/* static float _v2[] = { */ +/* 55.999474, */ +/* 85.196106, */ +/* 0.942609, */ +/* 0.015165, */ +/* 0, */ +/* 0.000000, */ +/* 0.600000, */ +/* 2.000000, */ +/* 0.000000, */ +/* 1.600000, */ +/* }; */ static __inline void mga_draw_triangle( mgaContextPtr mmesa, mgaVertex *v0, mgaVertex *v1, mgaVertex *v2 ) { - mgaUI32 vertsize = mmesa->vertsize; - mgaUI32 *wv = mgaAllocVertexDwordsInline( mmesa, 3 * vertsize ); + GLuint vertsize = mmesa->vertsize; + GLuint *wv = mgaAllocVertexDwordsInline( mmesa, 3 * VERTSIZE ); int j; + (void) vertsize; + +/* for (j = 0 ; j < vertsize ; j++) */ +/* fprintf(stderr, "v0 %d: %f 0x%x\n", j, v0->f[j], v0->ui[j]); */ + +/* for (j = 0 ; j < vertsize ; j++) */ +/* fprintf(stderr, "v1 %d: %f 0x%x\n", j, v1->f[j], v1->ui[j]); */ + +/* for (j = 0 ; j < vertsize ; j++) */ +/* fprintf(stderr, "v2 %d: %f 0x%x\n", j, v2->f[j], v2->ui[j]); */ + +/* v0 = (mgaVertex *)_v0; */ +/* v1 = (mgaVertex *)_v1; */ +/* v2 = (mgaVertex *)_v2; */ + + +/* if (v0->v.x < 0 || v0->v.x > 1920 || */ +/* v0->v.y < 0 || v0->v.y > 1440 || */ +/* v0->v.z < 0 || v0->v.z > 1) */ +/* fprintf(stderr, "v0 %f %f %f %f\n", v0->v.x, v0->v.y, v0->v.z, v0->v.rhw); */ + + +/* if (v1->v.x < 0 || v1->v.x > 1920 || */ +/* v1->v.y < 0 || v1->v.y > 1440 || */ +/* v1->v.z < 0 || v1->v.z > 1) */ +/* fprintf(stderr, "v1 %f %f %f %f\n", v1->v.x, v1->v.y, v1->v.z, v1->v.rhw); */ + +/* if (v2->v.x < 0 || v2->v.x > 1920 || */ +/* v2->v.y < 0 || v2->v.y > 1440 || */ +/* v2->v.z < 0 || v2->v.z > 1) */ +/* fprintf(stderr, "v2 %f %f %f %f\n", v2->v.x, v2->v.y, v2->v.z, v2->v.rhw); */ + + #if defined (USE_X86_ASM) - /* GTH: We can safely assume the vertex stride is some number of - * dwords, and thus a "rep movsd" is okay. The vb pointer is - * automagically updated with this instruction, so we don't have - * to manually take care of incrementing it. - */ - __asm__ __volatile__( "rep ; movsl" - : "=%c" (j) - : "0" (vertsize), "D" ((long)wv), "S" ((long)v0) - : "memory" ); - __asm__ __volatile__( "rep ; movsl" - : "=%c" (j) - : "0" (vertsize), "S" ((long)v1) - : "memory" ); - __asm__ __volatile__( "rep ; movsl" - : "=%c" (j) - : "0" (vertsize), "S" ((long)v2) - : "memory" ); + /* GTH: We can safely assume the vertex stride is some number of + * dwords, and thus a "rep movsd" is okay. The vb pointer is + * automagically updated with this instruction, so we don't have + * to manually take care of incrementing it. + */ + __asm__ __volatile__( "rep ; movsl" + : "=%c" (j) + : "0" (VERTSIZE), "D" ((long)wv), "S" ((long)v0) + : "memory" ); + __asm__ __volatile__( "rep ; movsl" + : "=%c" (j) + : "0" (VERTSIZE), "S" ((long)v1) + : "memory" ); + __asm__ __volatile__( "rep ; movsl" + : "=%c" (j) + : "0" (VERTSIZE), "S" ((long)v2) + : "memory" ); #else - for (j = 0 ; j < vertsize ; j++) - wv[j] = v0->ui[j]; + { + for (j = 0 ; j < vertsize ; j++) + wv[j] = v0->ui[j]; - wv += vertsize; - for (j = 0 ; j < vertsize ; j++) - wv[j] = v1->ui[j]; + wv += VERTSIZE; + for (j = 0 ; j < vertsize ; j++) + wv[j] = v1->ui[j]; - wv += vertsize; - for (j = 0 ; j < vertsize ; j++) - wv[j] = v2->ui[j]; + wv += VERTSIZE; + for (j = 0 ; j < vertsize ; j++) + wv[j] = v2->ui[j]; + } #endif } @@ -89,39 +165,39 @@ static __inline void mga_draw_triangle( mgaContextPtr mmesa, static __inline void mga_draw_point( mgaContextPtr mmesa, mgaVertex *tmp, float sz ) { - mgaUI32 vertsize = mmesa->vertsize; - mgaUI32 *wv = mgaAllocVertexDwords( mmesa, 6*vertsize); + GLuint vertsize = mmesa->vertsize; + GLuint *wv = mgaAllocVertexDwords( mmesa, 6*VERTSIZE); int j; *(float *)&wv[0] = tmp->v.x - sz; *(float *)&wv[1] = tmp->v.y - sz; for (j = 2 ; j < vertsize ; j++) wv[j] = tmp->ui[j]; - wv += vertsize; + wv += VERTSIZE; *(float *)&wv[0] = tmp->v.x + sz; *(float *)&wv[1] = tmp->v.y - sz; for (j = 2 ; j < vertsize ; j++) wv[j] = tmp->ui[j]; - wv += vertsize; + wv += VERTSIZE; *(float *)&wv[0] = tmp->v.x + sz; *(float *)&wv[1] = tmp->v.y + sz; for (j = 2 ; j < vertsize ; j++) wv[j] = tmp->ui[j]; - wv += vertsize; + wv += VERTSIZE; *(float *)&wv[0] = tmp->v.x + sz; *(float *)&wv[1] = tmp->v.y + sz; for (j = 2 ; j < vertsize ; j++) wv[j] = tmp->ui[j]; - wv += vertsize; + wv += VERTSIZE; *(float *)&wv[0] = tmp->v.x - sz; *(float *)&wv[1] = tmp->v.y + sz; for (j = 2 ; j < vertsize ; j++) wv[j] = tmp->ui[j]; - wv += vertsize; + wv += VERTSIZE; *(float *)&wv[0] = tmp->v.x - sz; *(float *)&wv[1] = tmp->v.y - sz; @@ -135,8 +211,8 @@ static __inline void mga_draw_line( mgaContextPtr mmesa, const mgaVertex *tmp1, float width ) { - mgaUI32 vertsize = mmesa->vertsize; - mgaUI32 *wv = mgaAllocVertexDwords( mmesa, 6 * vertsize ); + GLuint vertsize = mmesa->vertsize; + GLuint *wv = mgaAllocVertexDwords( mmesa, 6 * VERTSIZE ); float dx, dy, ix, iy; int j; @@ -156,37 +232,37 @@ static __inline void mga_draw_line( mgaContextPtr mmesa, *(float *)&wv[1] = tmp0->v.y - iy; for (j = 2 ; j < vertsize ; j++) wv[j] = tmp0->ui[j]; - wv += vertsize; + wv += VERTSIZE; *(float *)&wv[0] = tmp1->v.x + ix; *(float *)&wv[1] = tmp1->v.y + iy; for (j = 2 ; j < vertsize ; j++) wv[j] = tmp1->ui[j]; - wv += vertsize; + wv += VERTSIZE; *(float *)&wv[0] = tmp0->v.x + ix; *(float *)&wv[1] = tmp0->v.y + iy; for (j = 2 ; j < vertsize ; j++) wv[j] = tmp0->ui[j]; - wv += vertsize; + wv += VERTSIZE; *(float *)&wv[0] = tmp0->v.x - ix; *(float *)&wv[1] = tmp0->v.y - iy; for (j = 2 ; j < vertsize ; j++) wv[j] = tmp0->ui[j]; - wv += vertsize; + wv += VERTSIZE; *(float *)&wv[0] = tmp1->v.x - ix; *(float *)&wv[1] = tmp1->v.y - iy; for (j = 2 ; j < vertsize ; j++) wv[j] = tmp1->ui[j]; - wv += vertsize; + wv += VERTSIZE; *(float *)&wv[0] = tmp1->v.x + ix; *(float *)&wv[1] = tmp1->v.y + iy; for (j = 2 ; j < vertsize ; j++) wv[j] = tmp1->ui[j]; - wv += vertsize; + wv += VERTSIZE; } diff --git a/xc/lib/GL/mesa/src/drv/mga/mgavb.c b/xc/lib/GL/mesa/src/drv/mga/mgavb.c index cc9066fda..47f9278e3 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgavb.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgavb.c @@ -23,11 +23,12 @@ * * Wittawat Yamwong <Wittawat.Yamwong@stud.uni-hannover.de> */ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgavb.c,v 1.5 2000/08/28 02:43:13 tsi Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgavb.c,v 1.6 2000/09/24 13:51:09 alanh Exp $ */ -#include "mgalib.h" +#include "mgacontext.h" #include "mgavb.h" -#include "mgalog.h" +#include "mga_xmesa.h" + #include "stages.h" #include "mem.h" @@ -83,12 +84,13 @@ } -#define COORD \ - GLfloat *win = VB->Win.data[i]; \ +#define COORD \ + GLfloat *win = VB->Win.data[i]; \ v->v.rhw = win[3]; \ v->v.z = depth_scale * win[2]; \ - v->v.x = win[0] + xoffset; \ - v->v.y = - win[1] + yoffset; + v->v.x = win[0] + xoffset; \ + v->v.y = - win[1] + yoffset; + #define NOP @@ -181,7 +183,7 @@ SETUPFUNC(rs_gfst0t1, NOP,COL,TEX0,TEX1,TEX0_4,SPC,FOG) static void rs_invalid(struct vertex_buffer *VB, GLuint start, GLuint end) { - mgaError("mgaRasterSetup(): invalid combination\n"); + fprintf(stderr, "mgaRasterSetup(): invalid combination\n"); } typedef void (*setupFunc)(struct vertex_buffer *,GLuint,GLuint); @@ -256,6 +258,7 @@ void mgaChooseRasterSetupFunc(GLcontext *ctx) { mgaContextPtr mmesa = MGA_CONTEXT( ctx ); int funcindex = (MGA_WIN_BIT | MGA_RGBA_BIT); + int multi = mmesa->multitex; mmesa->vertsize = 8; mmesa->tmu_source[0] = 0; @@ -312,6 +315,19 @@ void mgaChooseRasterSetupFunc(GLcontext *ctx) } } +/* if (mmesa->multitex == 0) { */ +/* mmesa->tmu_source[1] = mmesa->tmu_source[0]; */ +/* mmesa->tex_dest[1] = mmesa->tex_dest[0]; */ +/* mmesa->vertsize = 10; */ +/* mmesa->multitex = 1; */ +/* funcindex |= MGA_TEX0_BIT|MGA_TEX1_BIT; */ +/* } */ + +/* mmesa->vertsize = 10; */ + if (multi != mmesa->multitex) + mmesa->new_state |= MGA_NEW_WARP; + + /* Not really a good place to do this - need to make the mga state * management code more event-driven so this can be calculated for * free. @@ -423,11 +439,6 @@ static void FatalError( char *s ) } -#ifndef ALIGN_MALLOC -#define ALIGN_MALLOC(x,y) malloc(y) -#define ALIGN_FREE free -#endif - void mgaDDResizeVB( struct vertex_buffer *VB, GLuint size ) { mgaVertexBufferPtr mvb = MGA_DRIVER_DATA(VB); @@ -435,8 +446,8 @@ void mgaDDResizeVB( struct vertex_buffer *VB, GLuint size ) while (mvb->size < size) mvb->size *= 2; - free( mvb->vert_store ); - mvb->vert_store = malloc( sizeof(mgaVertex) * mvb->size + 31); + FREE( mvb->vert_store ); + mvb->vert_store = MALLOC( sizeof(mgaVertex) * mvb->size + 31); if (!mvb->vert_store) FatalError("mga-glx: out of memory !\n"); @@ -448,15 +459,15 @@ void mgaDDResizeVB( struct vertex_buffer *VB, GLuint size ) FatalError("mga-glx: out of memory !\n"); ALIGN_FREE( VB->ClipMask ); - VB->ClipMask = (GLubyte *)ALIGN_MALLOC(4, sizeof(GLubyte) * mvb->size); + VB->ClipMask = (GLubyte *)ALIGN_MALLOC(sizeof(GLubyte) * mvb->size, 32); if (!VB->ClipMask) FatalError("mga-glx: out of memory !\n"); if (VB->Type == VB_IMMEDIATE) { - free( mvb->primitive ); - free( mvb->next_primitive ); - mvb->primitive = (GLuint *)malloc( sizeof(GLuint) * mvb->size ); - mvb->next_primitive = (GLuint *)malloc( sizeof(GLuint) * mvb->size ); + FREE( mvb->primitive ); + FREE( mvb->next_primitive ); + mvb->primitive = (GLuint *)MALLOC( sizeof(GLuint) * mvb->size ); + mvb->next_primitive = (GLuint *)MALLOC( sizeof(GLuint) * mvb->size ); if (!mvb->primitive || !mvb->next_primitive) FatalError("mga-glx: out of memory!"); } @@ -467,14 +478,14 @@ void mgaDDRegisterVB( struct vertex_buffer *VB ) { mgaVertexBufferPtr mvb; - mvb = (mgaVertexBufferPtr)calloc( 1, sizeof(*mvb) ); + mvb = (mgaVertexBufferPtr)MALLOC( sizeof(*mvb) ); /* This looks like it allocates a lot of memory, but it basically * just sets an upper limit on how much can be used - nothing like * this amount will ever be turned into 'real' memory. */ mvb->size = VB->Size * 5; - mvb->vert_store = malloc( sizeof(mgaVertex) * mvb->size + 31); + mvb->vert_store = MALLOC( sizeof(mgaVertex) * mvb->size + 31); if (!mvb->vert_store) FatalError("mga-glx: out of memory !\n"); @@ -485,12 +496,12 @@ void mgaDDRegisterVB( struct vertex_buffer *VB ) FatalError("mga-glx: out of memory !\n"); ALIGN_FREE( VB->ClipMask ); - VB->ClipMask = (GLubyte *)ALIGN_MALLOC(4, sizeof(GLubyte) * mvb->size); + VB->ClipMask = (GLubyte *)ALIGN_MALLOC(sizeof(GLubyte) * mvb->size, 32); if (!VB->ClipMask) FatalError("mga-glx: out of memory !\n"); - mvb->primitive = (GLuint *)malloc( sizeof(GLuint) * mvb->size ); - mvb->next_primitive = (GLuint *)malloc( sizeof(GLuint) * mvb->size ); + mvb->primitive = (GLuint *)MALLOC( sizeof(GLuint) * mvb->size ); + mvb->next_primitive = (GLuint *)MALLOC( sizeof(GLuint) * mvb->size ); if (!mvb->primitive || !mvb->next_primitive) FatalError("mga-glx: out of memory!"); @@ -503,11 +514,11 @@ void mgaDDUnregisterVB( struct vertex_buffer *VB ) mgaVertexBufferPtr mvb = MGA_DRIVER_DATA(VB); if (mvb) { - if (mvb->vert_store) free(mvb->vert_store); - if (mvb->primitive) free(mvb->primitive); - if (mvb->next_primitive) free(mvb->next_primitive); + if (mvb->vert_store) FREE(mvb->vert_store); + if (mvb->primitive) FREE(mvb->primitive); + if (mvb->next_primitive) FREE(mvb->next_primitive); gl_vector1ui_free( &mvb->clipped_elements ); - free(mvb); + FREE(mvb); VB->driver_data = 0; } } diff --git a/xc/lib/GL/mesa/src/drv/mga/mgavb.h b/xc/lib/GL/mesa/src/drv/mga/mgavb.h index cc902ae0f..c51fd0744 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgavb.h +++ b/xc/lib/GL/mesa/src/drv/mga/mgavb.h @@ -23,14 +23,13 @@ * * Wittawat Yamwong <Wittawat.Yamwong@stud.uni-hannover.de> */ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgavb.h,v 1.4 2000/08/28 02:43:13 tsi Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgavb.h,v 1.5 2000/09/24 13:51:09 alanh Exp $ */ #ifndef MGAVB_INC #define MGAVB_INC #include "types.h" #include "vb.h" -#include "mgacommon.h" /* common datatypes for the mga warp engines */ @@ -67,7 +66,7 @@ typedef struct mga_warp_vertex_t { union mga_vertex_t { mga_warp_vertex v; float f[16]; - mgaUI32 ui[16]; + GLuint ui[16]; }; typedef union mga_vertex_t mgaVertex; @@ -82,9 +81,9 @@ struct mga_vertex_buffer_t { void *vert_store; GLuint size; - mgaUI32 *vert_buf; - mgaUI32 *elt_buf; - mgaUI32 vert_phys_start; + GLuint *vert_buf; + GLuint *elt_buf; + GLuint vert_phys_start; }; typedef struct mga_vertex_buffer_t *mgaVertexBufferPtr; diff --git a/xc/lib/GL/mesa/src/drv/r128/Imakefile b/xc/lib/GL/mesa/src/drv/r128/Imakefile index 049428b46..cf9c82b86 100644 --- a/xc/lib/GL/mesa/src/drv/r128/Imakefile +++ b/xc/lib/GL/mesa/src/drv/r128/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/drv/r128/Imakefile,v 1.5 2000/08/24 22:20:07 tsi Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/drv/r128/Imakefile,v 1.7 2000/10/20 12:57:23 alanh Exp $ #include <Threads.tmpl> @@ -262,8 +262,7 @@ MESA_INCLUDES = -I. -I.. -I../../include \ MMX_OBJS = ../../X86/mmx_blend.o -XCOMM Disabling 3Dnow code for the time being. -#if 0 +#ifdef MesaUse3DNow 3DNOW_SRCS = ../../X86/3dnow.c \ ../../X86/3dnow_norm_raw.S \ ../../X86/3dnow_xform_masked1.S \ @@ -303,7 +302,7 @@ XCOMM Disabling 3Dnow code for the time being. OBJS = $(DRIOBJS) $(DRMOBJS) $(MESAOBJS) $(ASMOBJS) \ $(COMMONOBJS) $(R128OBJS) -REQUIREDLIBS += -lm +REQUIREDLIBS += MathLibrary #if !GlxBuiltInMga REQUIREDLIBS += -L../../../.. -lGL #endif diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_tex.c b/xc/lib/GL/mesa/src/drv/r128/r128_tex.c index 5d140adb8..72f190b1b 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_tex.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_tex.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_tex.c,v 1.3 2000/08/25 13:42:30 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_tex.c,v 1.4 2000/09/27 03:39:03 tsi Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -149,7 +149,7 @@ static r128TexObjPtr r128CreateTexObj(r128ContextPtr r128ctx, t->tObj = tObj; t->memBlock = NULL; - t->bufAddr = NULL; + t->bufAddr = 0; t->regs.tex_cntl = t->textureFormat; t->regs.size_pitch = ((log2Pitch << R128_TEX_PITCH_SHIFT) | @@ -702,7 +702,7 @@ static void r128UploadSubImage(r128ContextPtr r128ctx, } dwords = width * height / texelsPerDword; - offset = (CARD32)(t->bufAddr + t->image[level].offset); + offset = t->bufAddr + t->image[level].offset; #if ENABLE_PERF_BOXES /* Bump the performace counter */ @@ -868,8 +868,7 @@ int r128UploadTexImages(r128ContextPtr r128ctx, r128TexObjPtr t) } /* Set the base offset of the texture image */ - t->bufAddr = (unsigned char *)r128ctx->r128Screen->texOffset[heap]; - t->bufAddr += t->memBlock->ofs; + t->bufAddr = r128ctx->r128Screen->texOffset[heap] + t->memBlock->ofs; maxLevel = ((t->regs.size_pitch & R128_TEX_SIZE_MASK) >> R128_TEX_SIZE_SHIFT); @@ -882,11 +881,11 @@ int r128UploadTexImages(r128ContextPtr r128ctx, r128TexObjPtr t) /* Set texture offsets */ if (t->regs.tex_cntl & R128_MIP_MAP_DISABLE) { for (i = 0; i < R128_TEX_MAXLEVELS; i++) - r128ctx->regs.prim_tex_offset[i] = (CARD32)t->bufAddr; + r128ctx->regs.prim_tex_offset[i] = t->bufAddr; } else { for (i = maxLevel; i >= minLevel; i--) r128ctx->regs.prim_tex_offset[i] = - t->image[maxLevel-i].offset + (CARD32)t->bufAddr; + t->image[maxLevel-i].offset + t->bufAddr; } /* Fix AGP texture offsets */ if (heap == R128_AGP_TEX_HEAP) @@ -903,11 +902,11 @@ int r128UploadTexImages(r128ContextPtr r128ctx, r128TexObjPtr t) /* Set texture offsets */ if (t->regs.tex_cntl & R128_MIP_MAP_DISABLE) { for (i = 0; i < R128_TEX_MAXLEVELS; i++) - r128ctx->regs.sec_tex_offset[i] = (CARD32)t->bufAddr; + r128ctx->regs.sec_tex_offset[i] = t->bufAddr; } else { for (i = maxLevel; i >= minLevel; i--) r128ctx->regs.sec_tex_offset[i] = - t->image[maxLevel-i].offset + (CARD32)t->bufAddr; + t->image[maxLevel-i].offset + t->bufAddr; } /* Fix AGP texture offsets */ if (heap == R128_AGP_TEX_HEAP) @@ -1258,7 +1257,7 @@ static void r128UpdateTex0State(r128ContextPtr r128ctx) /* Set texture offsets */ if (t->regs.tex_cntl & R128_MIP_MAP_DISABLE) { for (i = 0; i < R128_TEX_MAXLEVELS; i++) - r128ctx->regs.prim_tex_offset[i] = (CARD32)t->bufAddr; + r128ctx->regs.prim_tex_offset[i] = t->bufAddr; } else { int maxLevel = ((t->regs.size_pitch & R128_TEX_SIZE_MASK) >> R128_TEX_SIZE_SHIFT); @@ -1266,7 +1265,7 @@ static void r128UpdateTex0State(r128ContextPtr r128ctx) R128_TEX_MIN_SIZE_SHIFT); for (i = maxLevel; i >= minLevel; i--) r128ctx->regs.prim_tex_offset[i] = - t->image[maxLevel-i].offset + (CARD32)t->bufAddr; + t->image[maxLevel-i].offset + t->bufAddr; } /* Fix AGP texture offsets */ if (t->heap == R128_AGP_TEX_HEAP) @@ -1575,7 +1574,7 @@ static void r128UpdateTex1State(r128ContextPtr r128ctx) /* Set texture offsets */ if (t->regs.tex_cntl & R128_MIP_MAP_DISABLE) { for (i = 0; i < R128_TEX_MAXLEVELS; i++) - r128ctx->regs.sec_tex_offset[i] = (CARD32)t->bufAddr; + r128ctx->regs.sec_tex_offset[i] = t->bufAddr; } else { int maxLevel = ((t->regs.size_pitch & R128_TEX_SIZE_MASK) >> R128_TEX_SIZE_SHIFT); @@ -1583,7 +1582,7 @@ static void r128UpdateTex1State(r128ContextPtr r128ctx) R128_TEX_MIN_SIZE_SHIFT); for (i = maxLevel; i >= minLevel; i--) r128ctx->regs.sec_tex_offset[i] = - t->image[maxLevel-i].offset + (CARD32)t->bufAddr; + t->image[maxLevel-i].offset + t->bufAddr; } /* Fix AGP texture offsets */ if (t->heap == R128_AGP_TEX_HEAP) diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_texobj.h b/xc/lib/GL/mesa/src/drv/r128/r128_texobj.h index 8ccaaf9fe..504d35087 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_texobj.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_texobj.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_texobj.h,v 1.1 2000/06/17 00:03:08 martin Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_texobj.h,v 1.2 2000/09/27 03:39:03 tsi Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -64,7 +64,7 @@ struct r128_tex_obj { struct gl_texture_object *tObj; /* Mesa texture object */ PMemBlock memBlock; /* Memory block containing texture */ - unsigned char *bufAddr; /* Offset to start of locally + CARD32 bufAddr; /* Offset to start of locally shared texture block */ CARD32 dirty_images; /* Flags for whether or not diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_vb.c b/xc/lib/GL/mesa/src/drv/r128/r128_vb.c index bb846701c..b3d79dd97 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_vb.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_vb.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_vb.c,v 1.4 2000/08/25 13:42:31 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_vb.c,v 1.6 2000/09/26 15:56:47 tsi Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -40,7 +40,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r128_cce.h" #include "r128_state.h" #include "r128_vb.h" - +#include "mem.h" #include "stages.h" #define TEX0 \ @@ -413,7 +413,8 @@ void r128DDResizeVB(struct vertex_buffer *VB, GLuint size) exit(1); } - r128vb->verts = (r128VertexPtr)(((CARD32)r128vb->vert_store + 31) & ~31); + r128vb->verts = + (r128VertexPtr)(((unsigned long)r128vb->vert_store + 31) & ~31); gl_vector1ui_free(&r128vb->clipped_elements); gl_vector1ui_alloc(&r128vb->clipped_elements, @@ -423,8 +424,8 @@ void r128DDResizeVB(struct vertex_buffer *VB, GLuint size) exit(1); } - free(VB->ClipMask); - VB->ClipMask = (GLubyte *)malloc(sizeof(GLubyte) * r128vb->size); + ALIGN_FREE(VB->ClipMask); + VB->ClipMask = (GLubyte *) ALIGN_MALLOC(sizeof(GLubyte) * r128vb->size, 4); if (!VB->ClipMask) { fprintf(stderr, "Cannot allocate clipmask! Exiting...\n"); exit(1); @@ -445,7 +446,8 @@ void r128DDRegisterVB(struct vertex_buffer *VB) exit(1); } - r128vb->verts = (r128VertexPtr)(((CARD32)r128vb->vert_store + 31) & ~31); + r128vb->verts = + (r128VertexPtr)(((unsigned long)r128vb->vert_store + 31) & ~31); gl_vector1ui_alloc(&r128vb->clipped_elements, VEC_WRITABLE, r128vb->size, 32); @@ -454,8 +456,8 @@ void r128DDRegisterVB(struct vertex_buffer *VB) exit(1); } - free(VB->ClipMask); - VB->ClipMask = (GLubyte *)malloc(sizeof(GLubyte) * r128vb->size); + ALIGN_FREE(VB->ClipMask); + VB->ClipMask = (GLubyte *) ALIGN_MALLOC(sizeof(GLubyte) * r128vb->size, 4); if (!VB->ClipMask) { fprintf(stderr, "Cannot allocate clipmask! Exiting...\n"); exit(1); diff --git a/xc/lib/GL/mesa/src/drv/sis/Imakefile b/xc/lib/GL/mesa/src/drv/sis/Imakefile index cdcfcaf78..59f2429ac 100644 --- a/xc/lib/GL/mesa/src/drv/sis/Imakefile +++ b/xc/lib/GL/mesa/src/drv/sis/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/drv/sis/Imakefile,v 1.7 2000/08/24 22:20:08 tsi Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/drv/sis/Imakefile,v 1.10 2000/10/20 12:57:23 alanh Exp $ #include <Threads.tmpl> @@ -164,8 +164,7 @@ LinkSourceFile(xdriP.h, ../../X) ../../vertices.c \ ../../winpos.c \ ../../xform.c \ - ../../zoom.c \ - ../../X86/common_x86.c + ../../zoom.c MESAOBJS = ../../aatriangle.o \ ../../accum.o \ @@ -257,7 +256,7 @@ LinkSourceFile(xdriP.h, ../../X) MMX_OBJS = ../../X86/mmx_blend.o -#if MesaUse3DNow +#ifdef MesaUse3DNow 3DNOW_SRCS = ../../X86/3dnow.c \ ../../X86/3dnow_norm_raw.S \ ../../X86/3dnow_xform_masked1.S \ @@ -291,7 +290,7 @@ LinkSourceFile(xdriP.h, ../../X) SRCS = $(DRISRCS) $(DRMSRCS) $(SISSRCS) $(MESASRCS) $(ASMSRCS) OBJS = $(DRIOBJS) $(DRMOBJS) $(SISOBJS) $(MESAOBJS) $(ASMOBJS) -REQUIREDLIBS += -lm +REQUIREDLIBS += MathLibrary #if !GlxBuiltInSIS REQUIREDLIBS += -L../../../.. -lGL -L../../../../../X11 -lX11 #endif diff --git a/xc/lib/GL/mesa/src/drv/sis/sis_alloc.c b/xc/lib/GL/mesa/src/drv/sis/sis_alloc.c index 935a220e6..1caa57200 100644 --- a/xc/lib/GL/mesa/src/drv/sis/sis_alloc.c +++ b/xc/lib/GL/mesa/src/drv/sis/sis_alloc.c @@ -24,6 +24,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ +/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_alloc.c,v 1.6 2000/09/26 15:56:48 tsi Exp $ */ /* * Authors: @@ -40,7 +41,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # include "xf86fbman.h" #else # include "drm.h" -# include "sis_drm_public.h" +# include "sis_drm.h" # include <sys/ioctl.h> #endif @@ -147,7 +148,7 @@ sis_free_fb (int hHWContext, void *free) } fb.context = hHWContext; - fb.free = (unsigned int)free; + fb.free = (unsigned long)free; ioctl(gDRMSubFD, SIS_IOCTL_FB_FREE, &fb); } @@ -217,7 +218,7 @@ sis_free_agp (int hHWContext, void *free) } agp.context = hHWContext; - agp.free = (unsigned int)free; + agp.free = (unsigned long)free; ioctl(gDRMSubFD, SIS_IOCTL_AGP_FREE, &agp); } @@ -263,7 +264,7 @@ sis_alloc_z_stencil_buffer (GLcontext * ctx) fprintf(stderr, "sis_alloc_z_stencil_buffer: addr=%lu\n", (DWORD)addr); } - addr = (GLubyte *) ALIGNMENT ((GLuint) addr, Z_BUFFER_HW_ALIGNMENT); + addr = (GLubyte *) ALIGNMENT ((unsigned long) addr, Z_BUFFER_HW_ALIGNMENT); xm_buffer->depthbuffer = (void *) addr; @@ -342,9 +343,9 @@ sis_alloc_back_image (GLcontext * ctx, XMesaImage *image, void **free, sis_fatal_error (); } - addr = (GLbyte *) ALIGNMENT ((GLuint) addr, DRAW_BUFFER_HW_ALIGNMENT); + addr = (GLbyte *) ALIGNMENT ((unsigned long) addr, DRAW_BUFFER_HW_ALIGNMENT); - image->data = addr; + image->data = (char *)addr; image->bytes_per_line = width2 * depth; image->bits_per_pixel = depth * 8; @@ -499,7 +500,8 @@ sis_alloc_texture_image (GLcontext * ctx, GLtextureImage * image) return; } - area->Data = (GLbyte *) ALIGNMENT ((GLuint) addr, TEXTURE_HW_ALIGNMENT); + area->Data = + (GLbyte *) ALIGNMENT ((unsigned long) addr, TEXTURE_HW_ALIGNMENT); area->Pitch = image->Width * texel_size; area->Format = driver_format; area->Size = image->Width * image->Height * texel_size; diff --git a/xc/lib/GL/mesa/src/drv/sis/sis_clear.c b/xc/lib/GL/mesa/src/drv/sis/sis_clear.c index 03da12499..b29f7904c 100644 --- a/xc/lib/GL/mesa/src/drv/sis/sis_clear.c +++ b/xc/lib/GL/mesa/src/drv/sis/sis_clear.c @@ -24,6 +24,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ +/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_clear.c,v 1.5 2000/09/26 15:56:48 tsi Exp $ */ /* * Authors: diff --git a/xc/lib/GL/mesa/src/drv/sis/sis_common.h b/xc/lib/GL/mesa/src/drv/sis/sis_common.h index 8b62fadcf..b2ace4d45 100644 --- a/xc/lib/GL/mesa/src/drv/sis/sis_common.h +++ b/xc/lib/GL/mesa/src/drv/sis/sis_common.h @@ -24,6 +24,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ +/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_common.h,v 1.5 2000/09/26 15:56:48 tsi Exp $ */ /* * Authors: diff --git a/xc/lib/GL/mesa/src/drv/sis/sis_ctx.c b/xc/lib/GL/mesa/src/drv/sis/sis_ctx.c index a45934fac..e7b865942 100644 --- a/xc/lib/GL/mesa/src/drv/sis/sis_ctx.c +++ b/xc/lib/GL/mesa/src/drv/sis/sis_ctx.c @@ -24,6 +24,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ +/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_ctx.c,v 1.3 2000/09/26 15:56:48 tsi Exp $ */ /* * Authors: diff --git a/xc/lib/GL/mesa/src/drv/sis/sis_ctx.h b/xc/lib/GL/mesa/src/drv/sis/sis_ctx.h index 5bbaa29b4..61a9fcb70 100644 --- a/xc/lib/GL/mesa/src/drv/sis/sis_ctx.h +++ b/xc/lib/GL/mesa/src/drv/sis/sis_ctx.h @@ -24,6 +24,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ +/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_ctx.h,v 1.5 2000/09/26 15:56:48 tsi Exp $ */ /* * Authors: diff --git a/xc/lib/GL/mesa/src/drv/sis/sis_debug.c b/xc/lib/GL/mesa/src/drv/sis/sis_debug.c index d95579ac0..33041c4b9 100644 --- a/xc/lib/GL/mesa/src/drv/sis/sis_debug.c +++ b/xc/lib/GL/mesa/src/drv/sis/sis_debug.c @@ -24,6 +24,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ +/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_debug.c,v 1.5 2000/09/26 15:56:48 tsi Exp $ */ /* * Authors: diff --git a/xc/lib/GL/mesa/src/drv/sis/sis_debug.h b/xc/lib/GL/mesa/src/drv/sis/sis_debug.h index 546aa361a..6b7c79698 100644 --- a/xc/lib/GL/mesa/src/drv/sis/sis_debug.h +++ b/xc/lib/GL/mesa/src/drv/sis/sis_debug.h @@ -24,6 +24,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ +/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_debug.h,v 1.3 2000/09/26 15:56:48 tsi Exp $ */ /* * Authors: diff --git a/xc/lib/GL/mesa/src/drv/sis/sis_fastpath.c b/xc/lib/GL/mesa/src/drv/sis/sis_fastpath.c index ba1092d30..1e94e1e9a 100644 --- a/xc/lib/GL/mesa/src/drv/sis/sis_fastpath.c +++ b/xc/lib/GL/mesa/src/drv/sis/sis_fastpath.c @@ -24,6 +24,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ +/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_fastpath.c,v 1.3 2000/09/26 15:56:48 tsi Exp $ */ /* * Authors: diff --git a/xc/lib/GL/mesa/src/drv/sis/sis_fog.c b/xc/lib/GL/mesa/src/drv/sis/sis_fog.c index 7a2f5302c..dcffcca5b 100644 --- a/xc/lib/GL/mesa/src/drv/sis/sis_fog.c +++ b/xc/lib/GL/mesa/src/drv/sis/sis_fog.c @@ -24,6 +24,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ +/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_fog.c,v 1.3 2000/09/26 15:56:48 tsi Exp $ */ /* * Authors: diff --git a/xc/lib/GL/mesa/src/drv/sis/sis_init.h b/xc/lib/GL/mesa/src/drv/sis/sis_init.h index 8b8f3b4ab..6e9a6c241 100644 --- a/xc/lib/GL/mesa/src/drv/sis/sis_init.h +++ b/xc/lib/GL/mesa/src/drv/sis/sis_init.h @@ -24,6 +24,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ +/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_init.h,v 1.3 2000/09/26 15:56:48 tsi Exp $ */ /* * Authors: diff --git a/xc/lib/GL/mesa/src/drv/sis/sis_linefunc.h b/xc/lib/GL/mesa/src/drv/sis/sis_linefunc.h index 33f4542bf..09781a629 100644 --- a/xc/lib/GL/mesa/src/drv/sis/sis_linefunc.h +++ b/xc/lib/GL/mesa/src/drv/sis/sis_linefunc.h @@ -24,6 +24,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ +/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_linefunc.h,v 1.5 2000/09/26 15:56:48 tsi Exp $ */ /* * Authors: diff --git a/xc/lib/GL/mesa/src/drv/sis/sis_lock.h b/xc/lib/GL/mesa/src/drv/sis/sis_lock.h index 99bee12ca..647a05357 100644 --- a/xc/lib/GL/mesa/src/drv/sis/sis_lock.h +++ b/xc/lib/GL/mesa/src/drv/sis/sis_lock.h @@ -24,6 +24,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ +/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_lock.h,v 1.3 2000/09/26 15:56:48 tsi Exp $ */ /* * Authors: diff --git a/xc/lib/GL/mesa/src/drv/sis/sis_mesa.c b/xc/lib/GL/mesa/src/drv/sis/sis_mesa.c index d733a4cf8..e83a6a0e9 100644 --- a/xc/lib/GL/mesa/src/drv/sis/sis_mesa.c +++ b/xc/lib/GL/mesa/src/drv/sis/sis_mesa.c @@ -24,6 +24,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ +/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_mesa.c,v 1.5 2000/09/26 15:56:48 tsi Exp $ */ /* * Authors: @@ -1044,8 +1045,8 @@ void sis_set_render_pos(GLcontext * ctx, GLubyte *base, GLuint pitch) assert (base != NULL); if (SIS_VERBOSE&VERBOSE_SIS_BUFFER){ - fprintf(stderr, "set drawing position: base=%x, pitch=%u\n", - (unsigned int)base, pitch); + fprintf(stderr, "set drawing position: base=%x, pitch=%lu\n", + (unsigned long)base, pitch); } /* software render */ diff --git a/xc/lib/GL/mesa/src/drv/sis/sis_mesa.h b/xc/lib/GL/mesa/src/drv/sis/sis_mesa.h index 033ee56ad..309a1ba8f 100644 --- a/xc/lib/GL/mesa/src/drv/sis/sis_mesa.h +++ b/xc/lib/GL/mesa/src/drv/sis/sis_mesa.h @@ -24,6 +24,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ +/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_mesa.h,v 1.3 2000/09/26 15:56:48 tsi Exp $ */ /* * Authors: diff --git a/xc/lib/GL/mesa/src/drv/sis/sis_reg.h b/xc/lib/GL/mesa/src/drv/sis/sis_reg.h index 1d023e634..53708ca9b 100644 --- a/xc/lib/GL/mesa/src/drv/sis/sis_reg.h +++ b/xc/lib/GL/mesa/src/drv/sis/sis_reg.h @@ -24,6 +24,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ +/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_reg.h,v 1.3 2000/09/26 15:56:48 tsi Exp $ */ /* * Authors: diff --git a/xc/lib/GL/mesa/src/drv/sis/sis_render.c b/xc/lib/GL/mesa/src/drv/sis/sis_render.c index f990d43b5..b019ec724 100644 --- a/xc/lib/GL/mesa/src/drv/sis/sis_render.c +++ b/xc/lib/GL/mesa/src/drv/sis/sis_render.c @@ -24,6 +24,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ +/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_render.c,v 1.5 2000/09/26 15:56:49 tsi Exp $ */ /* * Authors: diff --git a/xc/lib/GL/mesa/src/drv/sis/sis_span.c b/xc/lib/GL/mesa/src/drv/sis/sis_span.c index 1128e39b3..70fbd7f64 100644 --- a/xc/lib/GL/mesa/src/drv/sis/sis_span.c +++ b/xc/lib/GL/mesa/src/drv/sis/sis_span.c @@ -24,6 +24,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ +/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_span.c,v 1.4 2000/09/26 15:56:49 tsi Exp $ */ /* * Authors: @@ -45,7 +46,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. XMesaContext xmesa = (XMesaContext) ctx->DriverCtx; \ __GLSiScontext *hwcx = (__GLSiScontext *) xmesa->private; \ GLuint pitch = hwcx->swRenderPitch; \ - char *buf = hwcx->swRenderBase + char *buf = (char *)hwcx->swRenderBase #define CLIPPIXEL(_x,_y) (_x >= minx && _x < maxx && \ _y >= miny && _y < maxy) diff --git a/xc/lib/GL/mesa/src/drv/sis/sis_stencil.c b/xc/lib/GL/mesa/src/drv/sis/sis_stencil.c index 3f2abb5bb..19d68288f 100644 --- a/xc/lib/GL/mesa/src/drv/sis/sis_stencil.c +++ b/xc/lib/GL/mesa/src/drv/sis/sis_stencil.c @@ -24,6 +24,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ +/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_stencil.c,v 1.3 2000/09/26 15:56:49 tsi Exp $ */ /* * Authors: diff --git a/xc/lib/GL/mesa/src/drv/sis/sis_swzfunc.h b/xc/lib/GL/mesa/src/drv/sis/sis_swzfunc.h index f2969bec2..b4b8ea61f 100644 --- a/xc/lib/GL/mesa/src/drv/sis/sis_swzfunc.h +++ b/xc/lib/GL/mesa/src/drv/sis/sis_swzfunc.h @@ -24,6 +24,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ +/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_swzfunc.h,v 1.3 2000/09/26 15:56:49 tsi Exp $ */ /* * Authors: diff --git a/xc/lib/GL/mesa/src/drv/sis/sis_texture.c b/xc/lib/GL/mesa/src/drv/sis/sis_texture.c index bbbe73dd7..3c817a8c9 100644 --- a/xc/lib/GL/mesa/src/drv/sis/sis_texture.c +++ b/xc/lib/GL/mesa/src/drv/sis/sis_texture.c @@ -24,6 +24,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ +/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_texture.c,v 1.5 2000/09/26 15:56:49 tsi Exp $ */ /* * Authors: @@ -181,7 +182,7 @@ sis_TexImage (GLcontext * ctx, GLenum target, if (area->Format == GL_RGB8) { int i; - GLbyte *src = image->Data; + GLbyte *src = (GLbyte *)image->Data; GLbyte *dst = area->Data; for (i = 0; i < area->Size / 4; i++) @@ -231,7 +232,7 @@ sis_TexSubImage (GLcontext * ctx, GLenum target, if (area->Format == GL_RGB8) { - src = image->Data + (xoffset + yoffset * image->Width) * 3; + src = (GLbyte *)image->Data + (xoffset + yoffset * image->Width) * 3; dst = area->Data + (xoffset + yoffset * image->Width) * 4; soffset = (image->Width - width) * 3; doffset = (image->Width - width) * 4; @@ -252,7 +253,8 @@ sis_TexSubImage (GLcontext * ctx, GLenum target, GLuint texelSize = area->texelSize; GLuint copySize = texelSize * width; - src = image->Data + (xoffset + yoffset * image->Width) * texelSize; + src = (GLbyte *)image->Data + + (xoffset + yoffset * image->Width) * texelSize; dst = area->Data + (xoffset + yoffset * image->Width) * texelSize; soffset = image->Width * texelSize; @@ -773,11 +775,11 @@ sis_set_texobj_parm (GLcontext * ctx, GLtextureObject * object, int hw_unit) switch(area->memType){ case VIDEO_TYPE: - texOffset = ((GLuint) area->Data - (GLuint) GET_FbBase (hwcx)); + texOffset = ((char *) area->Data - (char *) GET_FbBase (hwcx)); break; case AGP_TYPE: - texOffset = ((GLuint) area->Data - (GLuint) GET_AGPBase (hwcx) + - (GLuint) hwcx->AGPAddr); + texOffset = ((char *) area->Data - (char *) GET_AGPBase (hwcx)) + + (unsigned long) hwcx->AGPAddr; current->texture[hw_unit].hwTextureMip |= (0x40000 << i); break; default: diff --git a/xc/lib/GL/mesa/src/drv/sis/sis_trifunc.h b/xc/lib/GL/mesa/src/drv/sis/sis_trifunc.h index 7c57a615f..ca9fdc656 100644 --- a/xc/lib/GL/mesa/src/drv/sis/sis_trifunc.h +++ b/xc/lib/GL/mesa/src/drv/sis/sis_trifunc.h @@ -24,6 +24,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ +/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_trifunc.h,v 1.3 2000/09/26 15:56:49 tsi Exp $ */ /* * Authors: diff --git a/xc/lib/GL/mesa/src/drv/sis/sis_xmesa.c b/xc/lib/GL/mesa/src/drv/sis/sis_xmesa.c index 0f9bb0619..318684ae8 100644 --- a/xc/lib/GL/mesa/src/drv/sis/sis_xmesa.c +++ b/xc/lib/GL/mesa/src/drv/sis/sis_xmesa.c @@ -24,6 +24,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ +/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_xmesa.c,v 1.5 2000/09/26 15:56:49 tsi Exp $ */ /* * Authors: diff --git a/xc/lib/GL/mesa/src/drv/sis/sis_xmesaP.h b/xc/lib/GL/mesa/src/drv/sis/sis_xmesaP.h index dc19c1be4..7cf4b0b00 100644 --- a/xc/lib/GL/mesa/src/drv/sis/sis_xmesaP.h +++ b/xc/lib/GL/mesa/src/drv/sis/sis_xmesaP.h @@ -21,7 +21,7 @@ * 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: xc/lib/GL/mesa/src/drv/sis/sis_xmesaP.h,v 1.5 2000/09/26 15:56:49 tsi Exp $ */ #ifndef XMESAP_H #define XMESAP_H diff --git a/xc/lib/GL/mesa/src/drv/sis/sis_xwin.c b/xc/lib/GL/mesa/src/drv/sis/sis_xwin.c index c651b444b..f04b677b2 100644 --- a/xc/lib/GL/mesa/src/drv/sis/sis_xwin.c +++ b/xc/lib/GL/mesa/src/drv/sis/sis_xwin.c @@ -24,6 +24,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ +/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_xwin.c,v 1.3 2000/09/26 15:56:49 tsi Exp $ */ /* * Authors: diff --git a/xc/lib/GL/mesa/src/drv/tdfx/Imakefile b/xc/lib/GL/mesa/src/drv/tdfx/Imakefile index 05ad70e5b..ae70f81d9 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/Imakefile +++ b/xc/lib/GL/mesa/src/drv/tdfx/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/drv/tdfx/Imakefile,v 1.12 2000/08/25 13:42:32 dawes Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/drv/tdfx/Imakefile,v 1.15 2000/10/28 01:05:22 dawes Exp $ #include <Threads.tmpl> @@ -13,7 +13,7 @@ ALLOC_DEFINES = -DMALLOC_0_RETURNS_NULL #endif #if BuildXF86DRI - DRI_DEFINES = GlxDefines -DFX -DFX_GLIDE3 -DGLIDE3 -DDRIVERTS + DRI_DEFINES = GlxDefines -DFX_GLIDE3 -DDRIVERTS DRI_INCLUDES = -I../../../../dri -I../../../../glx \ -I../../../dri \ -I$(TOP)/include -I$(TOP)/include/GL \ @@ -25,32 +25,6 @@ ALLOC_DEFINES = -DMALLOC_0_RETURNS_NULL MESA_INCLUDES = -I. -I.. -I../../include \ -I../../../../dri/drm -LinkSourceFile(fxclip.c, $(MESASRCDIR)/src/FX) -LinkSourceFile(fxcliptmp.h, $(MESASRCDIR)/src/FX) -LinkSourceFile(fxcva.c, $(MESASRCDIR)/src/FX) -LinkSourceFile(fxcva.h, $(MESASRCDIR)/src/FX) -LinkSourceFile(fxcvatmp.h, $(MESASRCDIR)/src/FX) -LinkSourceFile(fxdd.c, $(MESASRCDIR)/src/FX) -LinkSourceFile(fxddspan.c, $(MESASRCDIR)/src/FX) -LinkSourceFile(fxddtex.c, $(MESASRCDIR)/src/FX) -LinkSourceFile(fxdrv.h, $(MESASRCDIR)/src/FX) -LinkSourceFile(fxfastpath.c, $(MESASRCDIR)/src/FX) -LinkSourceFile(fxfasttmp.h, $(MESASRCDIR)/src/FX) -LinkSourceFile(fxglidew.c, $(MESASRCDIR)/src/FX) -LinkSourceFile(fxglidew.h, $(MESASRCDIR)/src/FX) -LinkSourceFile(fxpipeline.c, $(MESASRCDIR)/src/FX) -LinkSourceFile(fxrender.c, $(MESASRCDIR)/src/FX) -LinkSourceFile(fxsanity.c, $(MESASRCDIR)/src/FX) -LinkSourceFile(fxsdettmp.h, $(MESASRCDIR)/src/FX) -LinkSourceFile(fxsetup.c, $(MESASRCDIR)/src/FX) -LinkSourceFile(fxstripdet.c, $(MESASRCDIR)/src/FX) -LinkSourceFile(fxtexman.c, $(MESASRCDIR)/src/FX) -LinkSourceFile(fxtrifuncs.c, $(MESASRCDIR)/src/FX) -LinkSourceFile(fxtritmp.h, $(MESASRCDIR)/src/FX) -LinkSourceFile(fxvsetup.c, $(MESASRCDIR)/src/FX) -LinkSourceFile(fxvsetup.h, $(MESASRCDIR)/src/FX) -LinkSourceFile(fxvs_tmp.h, $(MESASRCDIR)/src/FX) - DEFINES = $(ALLOC_DEFINES) $(DRI_DEFINES) INCLUDES = -I$(XLIBSRC) -I$(EXTINCSRC) $(MESA_INCLUDES) $(DRI_INCLUDES) \ -I$(GLIDE3INCDIR) @@ -71,6 +45,14 @@ LinkSourceFile(fxvs_tmp.h, $(MESASRCDIR)/src/FX) ../../../../dri/drm/xf86drmRandom.o \ ../../../../dri/drm/xf86drmSL.o +#ifdef GlxSoProf + HIOBJS = ../../../../highpc.o + LOOBJS = ../../../../lowpc.o +#else + HIOBJS = + LOOBJS = +#endif + TDFXSRCS = tdfx_xmesa.c tdfx_init.c tdfx_inithw.c \ fxclip.c fxcva.c fxdd.c fxddspan.c fxddtex.c fxfastpath.c \ fxglidew.c fxpipeline.c fxrender.c fxsanity.c fxsetup.c \ @@ -246,7 +228,7 @@ LinkSourceFile(fxvs_tmp.h, $(MESASRCDIR)/src/FX) MMX_OBJS = ../../X86/mmx_blend.o -#if MesaUse3DNow +#ifdef MesaUse3DNow 3DNOW_SRCS = ../../X86/3dnow.c \ ../../X86/3dnow_norm_raw.S \ ../../X86/3dnow_xform_masked1.S \ @@ -272,13 +254,39 @@ LinkSourceFile(fxvs_tmp.h, $(MESASRCDIR)/src/FX) ../../X86/vertex_3dnow.o #endif +#ifdef MesaUseKatmai + KATMAI_SRCS = ../../X86/katmai.c \ + ../../X86/katmai_norm_raw.S \ + ../../X86/katmai_xform_masked1.S \ + ../../X86/katmai_xform_masked2.S \ + ../../X86/katmai_xform_masked3.S \ + ../../X86/katmai_xform_masked4.S \ + ../../X86/katmai_xform_raw1.S \ + ../../X86/katmai_xform_raw2.S \ + ../../X86/katmai_xform_raw3.S \ + ../../X86/katmai_xform_raw4.S \ + ../../X86/vertex_katmai.S + + KATMAI_OBJS = ../../X86/katmai.o \ + ../../X86/katmai_norm_raw.o \ + ../../X86/katmai_xform_masked1.o \ + ../../X86/katmai_xform_masked2.o \ + ../../X86/katmai_xform_masked3.o \ + ../../X86/katmai_xform_masked4.o \ + ../../X86/katmai_xform_raw1.o \ + ../../X86/katmai_xform_raw2.o \ + ../../X86/katmai_xform_raw3.o \ + ../../X86/katmai_xform_raw4.o \ + ../../X86/vertex_katmai.o #endif - ASMSRCS = $(X86_SRCS) $(MMX_SRCS) $(3DNOW_SRCS) - ASMOBJS = $(X86_OBJS) $(MMX_OBJS) $(3DNOW_OBJS) +#endif - SRCS = $(DRISRCS) $(DRMSRCS) $(TDFXSRCS) $(MESASRCS) $(ASMSRCS) - OBJS = $(DRIOBJS) $(DRMOBJS) $(TDFXOBJS) $(MESAOBJS) $(ASMOBJS) + ASMSRCS = $(X86_SRCS) $(MMX_SRCS) $(3DNOW_SRCS) $(KATMAI_SRCS) + ASMOBJS = $(X86_OBJS) $(MMX_OBJS) $(3DNOW_OBJS) $(KATMAI_OBJS) + + SRCS = $(LOSRCS) $(DRISRCS) $(DRMSRCS) $(TDFXSRCS) $(MESASRCS) $(ASMSRCS) $(HISRCS) + OBJS = $(LOOBJS) $(DRIOBJS) $(DRMOBJS) $(TDFXOBJS) $(MESAOBJS) $(ASMOBJS) $(HIOBJS) REQUIREDLIBS = -l$(GLIDE3LIBNAME) MathLibrary #if !GlxBuiltInTdfx @@ -306,6 +314,12 @@ ALL_OBJS = $(OBJS) ALL_DEPS = DONE SharedDepModuleTarget($(LIBNAME),$(ALL_DEPS),$(ALL_OBJS)) InstallDynamicModule($(LIBNAME),$(MODULEDIR),dri) + +#ifdef GlxSoProf +SOPROF_LIBNAME = _tdfx_dri_p +NormalDepLibraryTarget($(SOPROF_LIBNAME),$(ALL_DEPS),$(ALL_OBJS)) +InstallLibrary($(SOPROF_LIBNAME),$(MODULEDIR)/dri) +#endif #endif DependTarget() diff --git a/xc/lib/GL/mesa/src/drv/tdfx/X86/fx_3dnow_fastpath.S b/xc/lib/GL/mesa/src/drv/tdfx/X86/fx_3dnow_fastpath.S new file mode 100644 index 000000000..0f4cc4508 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/tdfx/X86/fx_3dnow_fastpath.S @@ -0,0 +1,84 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/X86/fx_3dnow_fastpath.S,v 1.2 2000/09/26 15:56:51 tsi Exp $ */ + +#include "../../X86/assyntax.h" + +#define SETUP_RGBA 0x1 +#define SETUP_TMU0 0x2 +#define SETUP_TMU1 0x4 + + +/* Pack either rgba or texture into the remaining half of a 32 byte vertex. + */ +#define CLIP_R 24 +#define CLIP_G 16 +#define CLIP_B 20 +#define CLIP_A 28 /* defined inf fxdrv.h */ + +#define CLIP_S0 16 +#define CLIP_T0 20 +#define CLIP_S1 24 +#define CLIP_T1 28 + +#define SIZE 4 +#define TYPE (0) +#define TAG(x) x +#include "fx_3dnow_fasttmp.h" + +#define SIZE 8 +#define TYPE (SETUP_RGBA) +#define TAG(x) x##_RGBA +#include "fx_3dnow_fasttmp.h" + +#define SIZE 6 +#define TYPE (SETUP_TMU0) +#define TAG(x) x##_TMU0 +#include "fx_3dnow_fasttmp.h" + +#define SIZE 8 +#define TYPE (SETUP_TMU0|SETUP_TMU1) +#define TAG(x) x##_TMU0_TMU1 +#include "fx_3dnow_fasttmp.h" + +#undef CLIP_S1 +#undef CLIP_T1 +#define CLIP_S1 16 +#define CLIP_T1 20 + +#define SIZE 6 +#define TYPE (SETUP_TMU1) +#define TAG(x) x##_TMU1 +#include "fx_3dnow_fasttmp.h" + +/* These three need to use a full 64 byte clip-space vertex. + */ +#undef CLIP_S0 +#undef CLIP_T0 +#undef CLIP_S1 +#undef CLIP_T1 + +#define CLIP_S0 32 +#define CLIP_T0 36 +#define CLIP_S1 40 +#define CLIP_T1 44 + +#define SIZE 10 +#define TYPE (SETUP_RGBA|SETUP_TMU0) +#define TAG(x) x##_RGBA_TMU0 +#include "fx_3dnow_fasttmp.h" + +#define SIZE 12 +#define TYPE (SETUP_RGBA|SETUP_TMU0|SETUP_TMU1) +#define TAG(x) x##_RGBA_TMU0_TMU1 +#include "fx_3dnow_fasttmp.h" + +#undef CLIP_S1 +#undef CLIP_T1 +#define CLIP_S1 32 +#define CLIP_T1 36 + +#define SIZE 10 +#define TYPE (SETUP_RGBA|SETUP_TMU1) +#define TAG(x) x##_RGBA_TMU1 +#include "fx_3dnow_fasttmp.h" + + diff --git a/xc/lib/GL/mesa/src/drv/tdfx/X86/fx_3dnow_fasttmp.h b/xc/lib/GL/mesa/src/drv/tdfx/X86/fx_3dnow_fasttmp.h new file mode 100644 index 000000000..9ec4935d7 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/tdfx/X86/fx_3dnow_fasttmp.h @@ -0,0 +1,314 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/X86/fx_3dnow_fasttmp.h,v 1.2 2000/09/26 15:56:51 tsi Exp $ */ + +#if !defined(NASM_ASSEMBLER) && !defined(MASM_ASSEMBLER) +#define TAGLLBL(a) TAG(.L##a) +#else +#define TAGLLBL(a) TAG(a) +#endif + +#if !GLIDE3 + +#define GR_VERTEX_X_OFFSET 0 +#define GR_VERTEX_Y_OFFSET 4 +#define GR_VERTEX_Z_OFFSET 8 +#define GR_VERTEX_R_OFFSET 12 +#define GR_VERTEX_G_OFFSET 16 +#define GR_VERTEX_B_OFFSET 20 +#define GR_VERTEX_OOZ_OFFSET 24 +#define GR_VERTEX_A_OFFSET 28 +#define GR_VERTEX_OOW_OFFSET 32 + +#else /* GLIDE3 */ + +#define GR_VERTEX_X_OFFSET 0 +#define GR_VERTEX_Y_OFFSET 4 +#define GR_VERTEX_OOZ_OFFSET 8 +#define GR_VERTEX_OOW_OFFSET 12 +#define GR_VERTEX_R_OFFSET 16 +#define GR_VERTEX_G_OFFSET 20 +#define GR_VERTEX_B_OFFSET 24 +#define GR_VERTEX_A_OFFSET 28 +#define GR_VERTEX_Z_OFFSET 32 + +#endif /* GLIDE3 */ + +#define GR_VERTEX_SOW_TMU0_OFFSET 36 +#define GR_VERTEX_TOW_TMU0_OFFSET 40 +#define GR_VERTEX_OOW_TMU0_OFFSET 44 +#define GR_VERTEX_SOW_TMU1_OFFSET 48 +#define GR_VERTEX_TOW_TMU1_OFFSET 52 +#define GR_VERTEX_OOW_TMU1_OFFSET 56 + + + + +/*#define MAT_SX 0 /* accessed by REGIND !! */ +#define MAT_SY 20 +#define MAT_SZ 40 +#define MAT_TX 48 +#define MAT_TY 52 +#define MAT_TZ 56 + + + + +/* Do viewport map, device scale and perspective projection. + * + * void project_verts( GLfloat *first, + * GLfloat *last, + * const GLfloat *m, + * GLuint stride ) + * + * + * Rearrange fxVertices to look like grVertices. + */ + +GLOBL GLNAME( TAG(fx_3dnow_project_vertices) ) +GLNAME( TAG(fx_3dnow_project_vertices) ): + + PUSH_L ( EBP ) + + MOV_L ( REGOFF(8, ESP), ECX ) /* first_vert */ + MOV_L ( REGOFF(12, ESP), EDX ) /* last_vert */ + + CMP_L ( ECX, EDX ) + JE ( TAGLLBL(FXPV_end) ) + + FEMMS + + PREFETCH ( REGIND(ECX) ) /* fetch the first vertex */ + + MOV_L ( REGOFF(16, ESP), EBP ) /* matrix */ + MOV_L ( REGOFF(20, ESP), EAX ) /* stride */ + + MOVD ( REGOFF(MAT_TX, EBP), MM6 ) /* | tx */ + PUNPCKLDQ ( REGOFF(MAT_TY, EBP), MM6 ) /* ty | tx */ + +#if !defined(FX_V2) + MOV_L ( CONST(0x49400000), REGOFF(-8, ESP) ) /* snapper */ + MOV_L ( CONST(0x49400000), REGOFF(-4, ESP) ) /* snapper */ +#endif + + MOVQ ( REGOFF(-8, ESP), MM4 ) /* snapper | snapper */ + PFADD ( MM4, MM6 ) /* ty+snapper | tx+snapper */ + + MOVD ( REGIND(EBP), MM5 ) + PUNPCKLDQ ( REGOFF(MAT_SY, EBP), MM5 ) /* vsy | vsx */ + + MOVD ( REGOFF(MAT_SZ, EBP), MM1 ) /* | vsz */ + + +ALIGNTEXT32 +TAGLLBL(FXPV_loop_start): + + PREFETCH ( REGOFF(64, ECX) ) /* fetch the next-ish vertex */ + + + MOVD ( REGOFF(12, ECX), MM0 ) /* | f[3] */ + PFRCP ( MM0, MM0 ) /* oow = 1/f[3] */ + + MOVD ( REGOFF(12, ECX), MM7 ) /* | f[3] */ + PFRCPIT1 ( MM0, MM7 ) + PFRCPIT2 ( MM0, MM7 ) /* oow | oow */ + + PUNPCKLDQ ( MM7, MM7 ) + + +#if (TYPE & SETUP_RGBA) + MOVD ( REGOFF(CLIP_R, ECX ), MM0 ) /* f[RCOORD] = f[CLIP_R]; */ + MOVD ( MM0, REGOFF(GR_VERTEX_R_OFFSET, ECX) ) +#endif + +#if (TYPE & SETUP_TMU1) + MOVQ ( REGOFF(CLIP_S1, ECX), MM0 ) /* f[S1COORD] = f[CLIP_S1] * oow */ + PFMUL ( MM7, MM0 ) /* f[T1COORD] = f[CLIP_T1] * oow */ + MOVQ ( MM0, REGOFF(GR_VERTEX_SOW_TMU1_OFFSET, ECX) ) +#endif + + +#if (TYPE & SETUP_TMU0) + MOVQ ( REGOFF(CLIP_S0, ECX), MM0 ) /* f[S0COORD] = f[CLIP_S0] * oow */ + PFMUL ( MM7, MM0 ) /* f[T0COORD] = f[CLIP_T0] * oow */ + MOVQ ( MM0, REGOFF(GR_VERTEX_SOW_TMU0_OFFSET, ECX) ) +#endif + + + + + +/* DO_SETUP_XYZ */ + + MOVQ ( REGIND(ECX), MM2 ) /* f[1] | f[0] */ + PFMUL ( MM7, MM2 ) /* f[1] * oow | f[0] * oow */ + + MOVD ( REGOFF(8, ECX), MM3 ) /* | f[2] */ + PFMUL ( MM7, MM3 ) /* | f[2] * oow */ + + MOVD ( REGOFF(MAT_TZ, EBP), MM0 ) /* | vtz */ + PFMUL ( MM1, MM3 ) /* | f[2] *= vsz */ + + PFADD ( MM0, MM3 ) /* | f[2] += vtz */ + PFMUL ( MM5, MM2 ) /* f[1] *= vsy | f[0] *= vsx */ + + PFADD ( MM6, MM2 ) /* f[1] += vty | f[0] += vtx */ + +#if !defined(FX_V2) + PFSUB ( MM4, MM2 ) /* f[0,1] -= snapper */ +#endif + + MOVQ ( MM2, REGOFF(GR_VERTEX_X_OFFSET, ECX) ) + MOVD ( MM3, REGOFF(GR_VERTEX_OOZ_OFFSET, ECX) ) + + +/* end of DO_SETUP_XYZ */ + + MOVD ( MM7, REGOFF(GR_VERTEX_OOW_OFFSET, ECX) ) /* f[OOWCOORD] = oow */ + ADD_L ( EAX, ECX ) /* f += stride */ + + CMP_L ( ECX, EDX ) /* stall??? */ + JA ( TAGLLBL(FXPV_loop_start) ) + +TAGLLBL(FXPV_end): + FEMMS + POP_L ( EBP ) + RET + + + + + + + +/* void project_verts( GLfloat *first, + * GLfloat *last, + * const GLfloat *m, + * GLuint stride, + * const GLubyte *mask ) + * + */ + +GLOBL GLNAME( TAG(fx_3dnow_project_clipped_vertices) ) +GLNAME( TAG(fx_3dnow_project_clipped_vertices) ): + + PUSH_L ( EBP ) + + MOV_L ( REGOFF(8, ESP), ECX ) /* first FXDRIVER(VB)->verts*/ + MOV_L ( REGOFF(12, ESP), EDX ) /* last FXDRIVER(VB)->last_vert */ + + FEMMS + + PUSH_L ( EDI ) + PUSH_L ( ESI ) + + PREFETCH ( REGIND(ECX) ) /* fetch the first vertex */ + + MOV_L ( REGOFF(24, ESP), EBP ) /* mat ctx->Viewport.WindowMap.M */ + MOV_L ( REGOFF(28, ESP), EAX ) /* stride */ + MOV_L ( REGOFF(32, ESP), ESI ) /* VB->ClipMask */ + + MOVD ( REGOFF(MAT_TX, EBP), MM6 ) /* | tx */ + PUNPCKLDQ ( REGOFF(MAT_TY, EBP), MM6 ) /* ty | tx */ + +#if !defined(FX_V2) + MOV_L ( CONST(0x49400000), REGOFF(-8, ESP) ) /* snapper */ + MOV_L ( CONST(0x49400000), REGOFF(-4, ESP) ) /* snapper */ +#endif + + MOVQ ( REGOFF(-8, ESP), MM4 ) /* snapper | snapper */ + PFADD ( MM4, MM6 ) /* ty+snapper | tx+snapper */ + + MOVD ( REGIND(EBP), MM5 ) + PUNPCKLDQ ( REGOFF(MAT_SY, EBP), MM5 ) /* vsy | vsx */ + + MOVD ( REGOFF(MAT_SZ, EBP), MM1 ) /* | vsz */ + + + +ALIGNTEXT32 +TAGLLBL(FXPCV_loop_start): + + PREFETCH ( REGOFF(64, ECX) ) /* fetch the next-ish vertex */ + + CMP_B ( CONST(0), REGIND(ESI) ) + JNE ( TAGLLBL(FXPCV_skip) ) + + MOVD ( REGOFF(12, ECX), MM0) /* | f[3] */ + PFRCP ( MM0, MM0 ) /* oow = 1/f[3] */ + + MOVD ( REGOFF(12, ECX), MM7) /* | f[3] */ + PFRCPIT1 ( MM0, MM7 ) + PFRCPIT2 ( MM0, MM7 ) /* oow | oow */ + + PUNPCKLDQ ( MM7, MM7 ) + + +#if (TYPE & SETUP_RGBA) + MOVD ( REGOFF(CLIP_R, ECX ), MM0 ) /* f[RCOORD] = f[CLIP_R]; */ + MOVD ( MM0, REGOFF(GR_VERTEX_R_OFFSET, ECX) ) +#endif + +#if (TYPE & SETUP_TMU1) + MOVQ ( REGOFF(CLIP_S1, ECX), MM0 ) /* f[S1COORD] = f[CLIP_S1] * oow */ + PFMUL ( MM7, MM0 ) /* f[T1COORD] = f[CLIP_T1] * oow */ + MOVQ ( MM0, REGOFF(GR_VERTEX_SOW_TMU1_OFFSET, ECX) ) +#endif + + +#if (TYPE & SETUP_TMU0) + MOVQ ( REGOFF(CLIP_S0, ECX), MM0 ) /* f[S0COORD] = f[CLIP_S0] * oow */ + PFMUL ( MM7, MM0 ) /* f[T0COORD] = f[CLIP_T0] * oow */ + MOVQ ( MM0, REGOFF(GR_VERTEX_SOW_TMU0_OFFSET, ECX) ) +#endif + + + + +/* DO_SETUP_XYZ */ + + MOVQ ( REGIND(ECX), MM2 ) /* f[1] | f[0] */ + PFMUL ( MM7, MM2 ) /* f[1] * oow | f[0] * oow */ + + MOVD ( REGOFF(8, ECX), MM3 ) /* | f[2] */ + PFMUL ( MM7, MM3 ) /* | f[2] * oow */ + + MOVD ( REGOFF(MAT_TZ, EBP), MM0 ) /* | vtz */ + PFMUL ( MM1, MM3 ) /* | f[2] *= vsz */ + + PFADD ( MM0, MM3 ) /* | f[2] += vtz */ + PFMUL ( MM5, MM2 ) /* f[1] *= vsy | f[0] *= vsx */ + + PFADD ( MM6, MM2 ) /* f[1] += vty | f[0] += vtx */ + +#if !defined(FX_V2) + PFSUB ( MM4, MM2 ) /* f[0,1] -= snapper */ +#endif + + MOVQ ( MM2, REGOFF(GR_VERTEX_X_OFFSET, ECX) ) + MOVD ( MM3, REGOFF(GR_VERTEX_OOZ_OFFSET, ECX) ) + + +/* end of DO_SETUP_XYZ */ + + MOVD ( MM7, REGOFF(GR_VERTEX_OOW_OFFSET, ECX) ) /* f[OOWCOORD] = oow */ + +TAGLLBL(FXPCV_skip): + ADD_L ( EAX, ECX ) /* f += stride */ + + INC_L ( ESI ) /* next ClipMask */ + CMP_L ( ECX, EDX ) + JA ( TAGLLBL(FXPCV_loop_start) ) + + POP_L ( ESI ) + POP_L ( EDI ) + +TAGLLBL(FXPCV_end): + FEMMS + POP_L ( EBP ) + RET + + + +#undef TYPE +#undef TAG +#undef SIZE + diff --git a/xc/lib/GL/mesa/src/drv/tdfx/fxclip.c b/xc/lib/GL/mesa/src/drv/tdfx/fxclip.c new file mode 100644 index 000000000..0cac71a06 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/tdfx/fxclip.c @@ -0,0 +1,537 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/fxclip.c,v 1.1 2000/09/24 13:51:12 alanh Exp $ */ +/* + * Mesa 3-D graphics library + * Version: 3.3 + * + * 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. + * + * + * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the + * terms stated above. + * + * Thank you for your contribution, David! + * + * Please make note of the above copyright/license statement. If you + * contributed code or bug fixes to this code under the previous (GNU + * Library) license and object to the new license, your code will be + * removed at your request. Please see the Mesa docs/COPYRIGHT file + * for more information. + * + * Additional Mesa/3Dfx driver developers: + * Daryll Strauss <daryll@precisioninsight.com> + * Keith Whitwell <keith@precisioninsight.com> + * + * See fxapi.h for more revision/author details. + */ + + +#include "fxdrv.h" +#include "fxtexman.h" +#include "mmath.h" +#include "macros.h" +#include "vector.h" +#include "types.h" + + +#if 0 && defined(__i386__) +#define NEGATIVE(f) ((*(int *)&f) < 0) +#define DIFFERENT_SIGNS(a,b) (((*(int *)&a)^(*(int *)&b)) < 0) +#else +#define NEGATIVE(f) (f < 0) +#define DIFFERENT_SIGNS(a,b) ((a*b) < 0) +#endif + +#define LINTERP( T, A, B ) ( (A) + (T) * ( (B) - (A) ) ) + + +#define CLIP(sgn,v) \ +do { \ + GLuint out = in ^ 1; \ + GLfloat **indata = inlist[in]; \ + GrVertex **inverts = vertlist[in]; \ + GrVertex **outverts = vertlist[out]; \ + GLfloat **outdata = inlist[in = out]; \ + GLfloat *J = indata[n-1]; \ + GLfloat dpJ = (sgn J[v]) + J[3]; \ + GLuint nr = n; \ + \ + for (i = n = 0 ; i < nr ; i++) { \ + GLfloat *I = indata[i]; \ + GLfloat dpI = (sgn I[v]) + I[3]; \ + \ + if (DIFFERENT_SIGNS(dpI, dpJ)) { \ + GLuint j; \ + GLfloat t = dpI / (dpI - dpJ); \ + outverts[n] = 0; \ + outdata[n++] = store; \ + store[3] = LINTERP(t, I[3], J[3]); \ + store[v] = - sgn store[3]; \ + if (v != 0) store[0] = LINTERP(t, I[0], J[0]); \ + if (v != 1) store[1] = LINTERP(t, I[1], J[1]); \ + if (v != 2) store[2] = LINTERP(t, I[2], J[2]); \ + store += 4; \ + for (j = 4 ; j < sz ; j+=4,store+=4) { \ + store[0] = LINTERP(t, I[j], J[j] ); \ + store[1] = LINTERP(t, I[j+1], J[j+1] ); \ + store[2] = LINTERP(t, I[j+2], J[j+2] ); \ + store[3] = LINTERP(t, I[j+3], J[j+3] ); \ + } \ + } \ + \ + if (!NEGATIVE(dpI)) { \ + outverts[n] = inverts[i]; \ + outdata[n++] = I; \ + } \ + \ + \ + J = I; \ + dpJ = dpI; \ + } \ + \ + if (n < 3) return 0; \ +} while (0) + + +/* Originally used this for the viewclip planes as well, as in + * CLIP(-1,0,0,1), which was just as fast, but tended to lead to + * cracks. I haven't figured out exactly why this is, but the above + * code only really differs in the way it sets store[v] to +- w. + */ +#define UCLIP(a,b,c,d) \ +do { \ + GLuint out = in ^ 1; \ + GLfloat **indata = inlist[in]; \ + GrVertex **inverts = vertlist[in]; \ + GrVertex **outverts = vertlist[out]; \ + GLfloat **outdata = inlist[in = out]; \ + GLfloat *J = indata[n-1]; \ + GLfloat dpJ = DOT4V(J,a,b,c,d); \ + GLuint nr = n; \ + \ + for (i = n = 0 ; i < nr ; i++) { \ + GLfloat *I = indata[i]; \ + GLfloat dpI = DOT4V(I,a,b,c,d); \ + \ + if (DIFFERENT_SIGNS(dpI, dpJ)) { \ + GLuint j; \ + GLfloat t = dpI / (dpI - dpJ); \ + outverts[n] = 0; \ + outdata[n++] = store; \ + for (j = 0 ; j < sz ; j+=4,store+=4) { \ + store[0] = LINTERP(t, I[j], J[j] ); \ + store[1] = LINTERP(t, I[j+1], J[j+1] ); \ + store[2] = LINTERP(t, I[j+2], J[j+2] ); \ + store[3] = LINTERP(t, I[j+3], J[j+3] ); \ + } \ + } \ + \ + if (!NEGATIVE(dpI)) { \ + outverts[n] = inverts[i]; \ + outdata[n++] = I; \ + } \ + \ + \ + J = I; \ + dpJ = dpI; \ + } \ + \ + if (n < 3) return 0; \ +} while (0) + + + +/* Data parameter is organized as 4 clip coordinates followed by an + * arbitary number (sz-4) of additional data. The three original + * vertices are packed together at the start, and there is room for at + * least VB_MAX_CLIPPED_VERTS vertices of the same size in this + * storage. + * + */ +static INLINE GLuint +fx_clip_triangle(GLcontext * ctx, + GLfloat * inoutlist[], + GrVertex ** verts, GLuint sz, GLuint mask) +{ + GLuint n = 3; + GLfloat *store = inoutlist[n - 1] + sz; + GLfloat *vlist[VB_MAX_CLIPPED_VERTS]; + GrVertex *verts2[VB_MAX_CLIPPED_VERTS]; + GLfloat **inlist[2]; + GrVertex **vertlist[2]; + GLuint in = 0; + GLuint i; + + inlist[0] = inoutlist; + inlist[1] = vlist; + + vertlist[0] = verts; + vertlist[1] = verts2; + + if (mask & CLIP_ALL_BITS) { + if (mask & CLIP_RIGHT_BIT) + CLIP(-, 0); + + if (mask & CLIP_LEFT_BIT) + CLIP(+, 0); + + if (mask & CLIP_TOP_BIT) + CLIP(-, 1); + + if (mask & CLIP_BOTTOM_BIT) + CLIP(+, 1); + + if (mask & CLIP_FAR_BIT) + CLIP(-, 2); + + if (mask & CLIP_NEAR_BIT) + CLIP(+, 2); + } + + if (mask & CLIP_USER_BIT) { + GLuint bit; + GLfloat(*plane)[4] = &ctx->Transform.ClipUserPlane[0]; + for (bit = 0x100; bit < mask; plane++, bit *= 2) { + if (mask & bit) { + GLfloat a = plane[0][0]; + GLfloat b = plane[0][1]; + GLfloat c = plane[0][2]; + GLfloat d = plane[0][3]; + UCLIP(a, b, c, d); + } + } + } + + if (inlist[in] != inoutlist) + for (i = 0; i < n; i++) { + inoutlist[i] = inlist[in][i]; + verts[i] = verts2[i]; + } + + return n; +} + + + +static INLINE GLuint +fx_view_clip_triangle(GLcontext * ctx, + GLfloat * inoutlist[], + GrVertex ** verts, GLuint sz, GLubyte mask) +{ + GLuint n = 3; + GLfloat *store = inoutlist[n - 1] + sz; + GLfloat *vlist[VB_MAX_CLIPPED_VERTS]; + GrVertex *verts2[VB_MAX_CLIPPED_VERTS]; + GLfloat **inlist[2]; + GrVertex **vertlist[2]; + GLuint in = 0; + GLuint i; + + inlist[0] = inoutlist; + inlist[1] = vlist; + + vertlist[0] = verts; + vertlist[1] = verts2; + + if (mask & CLIP_RIGHT_BIT) + CLIP(-, 0); + + if (mask & CLIP_LEFT_BIT) + CLIP(+, 0); + + if (mask & CLIP_TOP_BIT) + CLIP(-, 1); + + if (mask & CLIP_BOTTOM_BIT) + CLIP(+, 1); + + if (mask & CLIP_FAR_BIT) + CLIP(-, 2); + + if (mask & CLIP_NEAR_BIT) + CLIP(+, 2); + + if (inlist[in] != inoutlist) + for (i = 0; i < n; i++) { + inoutlist[i] = inlist[in][i]; + verts[i] = verts2[i]; + } + + return n; +} + + + +#undef CLIP + +#define CLIP(x,y,z,w) \ +do { \ + GLfloat dpI = DOT4V(I,x,y,z,w); \ + GLfloat dpJ = DOT4V(J,x,y,z,w); \ + \ + if (DIFFERENT_SIGNS(dpI, dpJ)) { \ + GLuint j; \ + GLfloat t = dpI / (dpI - dpJ); \ + GLfloat *tmp = store; \ + \ + for (j = 0 ; j < sz ; j+=2) { \ + *store++ = LINTERP(t, I[j], J[j] ); \ + *store++ = LINTERP(t, I[j+1], J[j+1] ); \ + } \ + \ + if (NEGATIVE(dpI)) \ + I = tmp; \ + else \ + J = tmp; \ + \ + } \ + else if (NEGATIVE(dpI)) \ + return 0; \ + \ +} while (0) + + +static GLuint +fx_clip_line(GLcontext * ctx, + GLfloat * inoutlist[], GLuint sz, GLubyte clipor) +{ + GLfloat *I = inoutlist[0]; + GLfloat *J = inoutlist[1]; + GLfloat *store = J + sz; + + if (clipor & CLIP_ALL_BITS) { + if (clipor & CLIP_LEFT_BIT) + CLIP(1, 0, 0, 1); + + if (clipor & CLIP_RIGHT_BIT) + CLIP(-1, 0, 0, 1); + + if (clipor & CLIP_TOP_BIT) + CLIP(0, -1, 0, 1); + + if (clipor & CLIP_BOTTOM_BIT) + CLIP(0, 1, 0, 1); + + if (clipor & CLIP_FAR_BIT) + CLIP(0, 0, -1, 1); + + if (clipor & CLIP_NEAR_BIT) + CLIP(0, 0, 1, 1); + } + + if (clipor & CLIP_USER_BIT) { + GLuint i; + for (i = 0; i < MAX_CLIP_PLANES; i++) { + if (ctx->Transform.ClipEnabled[i]) { + GLfloat a = ctx->Transform.ClipUserPlane[i][0]; + GLfloat b = ctx->Transform.ClipUserPlane[i][1]; + GLfloat c = ctx->Transform.ClipUserPlane[i][2]; + GLfloat d = ctx->Transform.ClipUserPlane[i][3]; + CLIP(a, b, c, d); + } + } + } + + inoutlist[0] = I; + inoutlist[1] = J; + + return 2; +} + + + + + + +#if defined(FX_V2) + +#define VARS_XYZW \ + GLfloat vsx = mat[MAT_SX]; \ + GLfloat vsy = mat[MAT_SY]; \ + GLfloat vsz = mat[MAT_SZ]; \ + GLfloat vtx = mat[MAT_TX]; \ + GLfloat vty = mat[MAT_TY]; \ + GLfloat vtz = mat[MAT_TZ]; + +#define DO_SETUP_XYZW \ +{ \ + GLfloat oow = 1.0 / data[3]; \ + v->x = data[0]*oow*vsx + vtx; \ + v->y = data[1]*oow*vsy + vty; \ + v->ooz = data[2]*oow*vsz + vtz; \ + v->oow = oow; \ +} +#else + +#if defined(DRIVERTS) + +#define VARS_XYZW \ + GLfloat vsx = mat[MAT_SX]; \ + GLfloat vsy = mat[MAT_SY]; \ + GLfloat vsz = mat[MAT_SZ]; \ + GLfloat vtx = mat[MAT_TX]+fxMesa->x_offset; \ + GLfloat vty = mat[MAT_TY]+fxMesa->y_delta; \ + GLfloat vtz = mat[MAT_TZ]; + +#define DO_SETUP_XYZW \ +{ \ + GLfloat oow = 1.0 / data[3]; \ + v->x = data[0]*oow*vsx + vtx; \ + v->y = data[1]*oow*vsy + vty; \ + v->ooz = data[2]*oow*vsz + vtz; \ + v->oow = oow; \ +} + +#else +#define VARS_XYZW \ + GLfloat vsx = mat[MAT_SX]; \ + GLfloat vsy = mat[MAT_SY]; \ + GLfloat vsz = mat[MAT_SZ]; \ + const GLfloat snapper = (3L << 18); \ + GLfloat snap_tx = mat[MAT_TX] + snapper; \ + GLfloat snap_ty = mat[MAT_TY] + snapper; \ + GLfloat vtz = mat[MAT_TZ]; + +#define DO_SETUP_XYZW \ +{ \ + GLfloat oow = 1.0 / data[3]; \ + v->x = data[0]*oow*vsx + snap_tx; \ + v->y = data[1]*oow*vsy + snap_ty; \ + v->ooz = data[2]*oow*vsz + vtz; \ + v->oow = oow; \ + v->x -= snapper; \ + v->y -= snapper; \ +} + +#endif +#endif + +#define COPY_XYZW_STRIDE \ + { GLfloat *clip = VEC_ELT(VB->ClipPtr, GLfloat, e); \ + COPY_4FV(out, clip); } + +#define VARS_RGBA + +#define COPY_RGBA_STRIDE \ + { GLubyte *color = VEC_ELT(VB->ColorPtr, GLubyte, e); \ + UBYTE_RGBA_TO_FLOAT_255_RGBA((out+4), color); } + +#if FX_USE_PARGB +#define DO_SETUP_RGBA \ + GET_PARGB(v) = (((int)data[4+3]) << 24) | \ + (((int)data[4+0]) << 16) | \ + (((int)data[4+1]) << 8) | \ + (((int)data[4+2]) << 0); +#else +#define DO_SETUP_RGBA \ + v->r = data[4+0]; \ + v->g = data[4+1]; \ + v->b = data[4+2]; \ + v->a = data[4+3]; +#endif /* FX_USE_PARGB */ + +#define VARS_TMU0 \ + struct gl_texture_unit *t0 = &ctx->Texture.Unit[tmu0_source]; \ + GLfloat sScale0 = fxTMGetTexInfo(t0->Current)->sScale; \ + GLfloat tScale0 = fxTMGetTexInfo(t0->Current)->tScale; \ + + +#define COPY_TMU0_STRIDE(offset) \ + { GLfloat *tc0 = VEC_ELT(tc0_vec, GLfloat, e); \ + COPY_2V((out+offset), tc0); } + + +#define DO_SETUP_TMU0(offset) \ + v->tmuvtx[0].sow = data[offset+0]*sScale0*v->oow; \ + v->tmuvtx[0].tow = data[offset+1]*tScale0*v->oow; + +#define VARS_TMU1 \ + struct gl_texture_unit *t1 = &ctx->Texture.Unit[tmu1_source]; \ + GLfloat sScale1 = fxTMGetTexInfo(t1->Current)->sScale; \ + GLfloat tScale1 = fxTMGetTexInfo(t1->Current)->tScale; + +#define COPY_TMU1_STRIDE(offset) \ + { GLfloat *tc1 = VEC_ELT(tc1_vec, GLfloat, e); \ + COPY_2V((out+offset), tc1); } + + +#define DO_SETUP_TMU1(offset) \ + v->tmuvtx[1].sow = data[offset+0]*sScale1*v->oow; \ + v->tmuvtx[1].tow = data[offset+1]*tScale1*v->oow; + +#define COPY_NIL(offset) ASSIGN_2V((out+offset), 0, 0); + +#define IND 0 +#define TAG(x) x##_nil +#include "fxcliptmp.h" + +#define IND SETUP_RGBA +#define TAG(x) x##_RGBA +#include "fxcliptmp.h" + +#define IND SETUP_TMU0 +#define TAG(x) x##_TMU0 +#include "fxcliptmp.h" + +#define IND (SETUP_TMU0|SETUP_TMU1) +#define TAG(x) x##_TMU0_TMU1 +#include "fxcliptmp.h" + +#define IND (SETUP_RGBA|SETUP_TMU0) +#define TAG(x) x##_RGBA_TMU0 +#include "fxcliptmp.h" + +#define IND (SETUP_RGBA|SETUP_TMU0|SETUP_TMU1) +#define TAG(x) x##_RGBA_TMU0_TMU1 +#include "fxcliptmp.h" + +tfxTriViewClipFunc fxTriViewClipTab[0x8]; +tfxTriClipFunc fxTriClipStrideTab[0x8]; +tfxLineClipFunc fxLineClipTab[0x8]; + + +void +fxDDClipInit() +{ + fxTriViewClipTab[0] = fx_tri_view_clip_nil; + fxTriViewClipTab[SETUP_RGBA] = fx_tri_view_clip_RGBA; + fxTriViewClipTab[SETUP_TMU0] = fx_tri_view_clip_TMU0; + fxTriViewClipTab[SETUP_TMU0 | SETUP_TMU1] = fx_tri_view_clip_TMU0_TMU1; + fxTriViewClipTab[SETUP_RGBA | SETUP_TMU0] = fx_tri_view_clip_RGBA_TMU0; + fxTriViewClipTab[SETUP_RGBA | SETUP_TMU0 | SETUP_TMU1] = + fx_tri_view_clip_RGBA_TMU0_TMU1; + + fxTriClipStrideTab[0] = fx_tri_clip_stride_nil; + fxTriClipStrideTab[SETUP_RGBA] = fx_tri_clip_stride_RGBA; + fxTriClipStrideTab[SETUP_TMU0] = fx_tri_clip_stride_TMU0; + fxTriClipStrideTab[SETUP_TMU0 | SETUP_TMU1] = + fx_tri_clip_stride_TMU0_TMU1; + fxTriClipStrideTab[SETUP_RGBA | SETUP_TMU0] = + fx_tri_clip_stride_RGBA_TMU0; + fxTriClipStrideTab[SETUP_RGBA | SETUP_TMU0 | SETUP_TMU1] = + fx_tri_clip_stride_RGBA_TMU0_TMU1; + + fxLineClipTab[0] = fx_line_clip_nil; + fxLineClipTab[SETUP_RGBA] = fx_line_clip_RGBA; + fxLineClipTab[SETUP_TMU0] = fx_line_clip_TMU0; + fxLineClipTab[SETUP_TMU0 | SETUP_TMU1] = fx_line_clip_TMU0_TMU1; + fxLineClipTab[SETUP_RGBA | SETUP_TMU0] = fx_line_clip_RGBA_TMU0; + fxLineClipTab[SETUP_RGBA | SETUP_TMU0 | SETUP_TMU1] = + fx_line_clip_RGBA_TMU0_TMU1; +} diff --git a/xc/lib/GL/mesa/src/drv/tdfx/fxcliptmp.h b/xc/lib/GL/mesa/src/drv/tdfx/fxcliptmp.h new file mode 100644 index 000000000..b84e3c3f2 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/tdfx/fxcliptmp.h @@ -0,0 +1,353 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/fxcliptmp.h,v 1.1 2000/09/24 13:51:13 alanh Exp $ */ +/* + * Mesa 3-D graphics library + * Version: 3.3 + * + * 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. + * + * + * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the + * terms stated above. + * + * Thank you for your contribution, David! + * + * Please make note of the above copyright/license statement. If you + * contributed code or bug fixes to this code under the previous (GNU + * Library) license and object to the new license, your code will be + * removed at your request. Please see the Mesa docs/COPYRIGHT file + * for more information. + * + * Additional Mesa/3Dfx driver developers: + * Daryll Strauss <daryll@precisioninsight.com> + * Keith Whitwell <keith@precisioninsight.com> + * + * See fxapi.h for more revision/author details. + */ + + +#define V1 VARS_XYZW +#define S1 DO_SETUP_XYZW +#define T1 COPY_XYZW_STRIDE +#define Z1 4 + +#if (IND & SETUP_RGBA) +#define V2 V1 VARS_RGBA +#define S2 S1 DO_SETUP_RGBA +#define T2 T1 COPY_RGBA_STRIDE +#define Z2 (Z1 + 4) +#else +#define V2 V1 +#define S2 S1 +#define T2 T1 +#define Z2 Z1 +#endif + +#if (IND & SETUP_TMU0) +#define V3 V2 VARS_TMU0 +#define S3 S2 DO_SETUP_TMU0(Z2) +#define T3 T2 COPY_TMU0_STRIDE(Z2) +#define Z3 (Z2 + 2) +#else +#define V3 V2 +#define S3 S2 +#define T3 T2 +#define Z3 Z2 +#endif + +#if (IND & SETUP_TMU1) +#define V4 V3 VARS_TMU1 +#define S4 S3 DO_SETUP_TMU1(Z3) +#define T4 T3 COPY_TMU1_STRIDE(Z3) +#define Z4 (Z3 + 2) +#else +#define V4 V3 +#define S4 S3 +#define T4 T3 +#define Z4 Z3 +#endif + +#if (Z4 & 2) +#define SIZE (Z4+2) +#define COPY_STRIDE T4 COPY_NIL(Z4) +#else +#define SIZE Z4 +#define COPY_STRIDE T4 +#endif + +#define VARS V4 +#define SETUP S4 + +#define DRAW_LINE(fxMesa, tmp0, tmp1, width) \ + if (width <= 1.0) { \ + FX_grDrawLine(fxMesa, tmp0, tmp1); \ + } \ + else { \ + GrVertex verts[4]; \ + float dx, dy, ix, iy; \ + \ + dx = tmp0->x - tmp1->x; \ + dy = tmp0->y - tmp1->y; \ + \ + if (dx * dx > dy * dy) { \ + iy = width * .5; \ + ix = 0; \ + } \ + else { \ + iy = 0; \ + ix = width * .5; \ + } \ + \ + verts[0] = *tmp0; \ + verts[1] = *tmp0; \ + verts[2] = *tmp1; \ + verts[3] = *tmp1; \ + \ + verts[0].x = tmp0->x - ix; \ + verts[0].y = tmp0->y - iy; \ + \ + verts[1].x = tmp0->x + ix; \ + verts[1].y = tmp0->y + iy; \ + \ + verts[2].x = tmp1->x + ix; \ + verts[2].y = tmp1->y + iy; \ + \ + verts[3].x = tmp1->x - ix; \ + verts[3].y = tmp1->y - iy; \ + \ + FX_grDrawPolygonVertexList(fxMesa, 4, verts); \ + } + + + +static void TAG(fx_tri_view_clip) (struct vertex_buffer * VB, + GLuint v[], GLubyte mask) +{ + GLcontext *ctx = VB->ctx; + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + GLfloat data[VB_MAX_CLIPPED_VERTS * 12]; + GLfloat *vlist[VB_MAX_CLIPPED_VERTS]; + GrVertex *verts[VB_MAX_CLIPPED_VERTS]; + fxVertex *gWin = FX_DRIVER_DATA(VB)->verts; + GLfloat *out = data; + GLfloat *mat = ctx->Viewport.WindowMap.m; + GLuint i, n; + GLubyte *clipmask = VB->ClipMask; + + GLuint tmu0_source = fxMesa->tmu_source[0]; + GLuint tmu1_source = fxMesa->tmu_source[1]; + GLvector4f *tc0_vec = VB->TexCoordPtr[tmu0_source]; + GLvector4f *tc1_vec = VB->TexCoordPtr[tmu1_source]; + + (void) fxMesa; + (void) tmu0_source; + (void) tc0_vec; + (void) tmu1_source; + (void) tc1_vec; + + for (i = 0; i < 3; i++) { + GLuint e = v[i]; + verts[i] = 0; + if (!clipmask[e]) + verts[i] = (GrVertex *) gWin[e].f; + vlist[i] = out; + COPY_STRIDE; + out += SIZE; + } + + if ((n = fx_view_clip_triangle(ctx, vlist, verts, SIZE, mask)) >= 3) { + GrVertex tmp[VB_MAX_CLIPPED_VERTS]; + GrVertex *v = tmp, *v2, *v3; + VARS; + + for (i = 0; i < n; i++) + if (!verts[i]) { + GLfloat *data = vlist[i]; + SETUP; + verts[i] = v++; + } + + v = verts[0]; + v2 = verts[1]; + v3 = verts[2]; + + for (i = 2; i < n; v2 = v3, v3 = verts[++i]) + FX_grDrawTriangle(fxMesa, v, v2, v3); + } +} + + + + + +static void TAG(fx_tri_clip_stride) (struct vertex_buffer * VB, + GLuint v[], GLuint mask) +{ + GLcontext *ctx = VB->ctx; + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + GLfloat data[VB_MAX_CLIPPED_VERTS * 12]; + GLfloat *vlist[VB_MAX_CLIPPED_VERTS]; + GrVertex *verts[VB_MAX_CLIPPED_VERTS]; + fxVertex *gWin = FX_DRIVER_DATA(VB)->verts; + GLfloat *out = data; + GLfloat *mat = ctx->Viewport.WindowMap.m; + GLuint i, n; + GLubyte *clipmask = VB->ClipMask; + + GLuint tmu0_source = fxMesa->tmu_source[0]; + GLuint tmu1_source = fxMesa->tmu_source[1]; + GLvector4f *tc0_vec = VB->TexCoordPtr[tmu0_source]; + GLvector4f *tc1_vec = VB->TexCoordPtr[tmu1_source]; + + (void) fxMesa; + (void) tmu0_source; + (void) tc0_vec; + (void) tmu1_source; + (void) tc1_vec; + + for (i = 0; i < 3; i++) { + GLuint e = v[i]; + verts[i] = 0; + if (!clipmask[e]) + verts[i] = (GrVertex *) gWin[e].f; + vlist[i] = out; + COPY_STRIDE; + out += SIZE; + } + + if (VB->ClipPtr->size < 4) { + vlist[0][3] = vlist[1][3] = vlist[2][3] = 1.0; + if (VB->ClipPtr->size == 2) + vlist[0][2] = vlist[1][2] = vlist[2][2] = 0.0; + } + + if ((n = fx_clip_triangle(ctx, vlist, verts, SIZE, mask)) >= 3) { + GrVertex tmp[VB_MAX_CLIPPED_VERTS]; + GrVertex *v = tmp, *v2, *v3; + VARS; + + for (i = 0; i < n; i++) + if (!verts[i]) { + GLfloat *data = vlist[i]; + SETUP; + verts[i] = v++; + } + + v = verts[0]; + v2 = verts[1]; + v3 = verts[2]; + + for (i = 2; i < n; v2 = v3, v3 = verts[++i]) + FX_grDrawTriangle(fxMesa, v, v2, v3); + } +} + + + +static void TAG(fx_line_clip) (struct vertex_buffer * VB, + GLuint v1, GLuint v2, GLubyte mask) +{ + GLcontext *ctx = VB->ctx; + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + GLfloat data[VB_MAX_CLIPPED_VERTS * 12]; + GLfloat *vlist[VB_MAX_CLIPPED_VERTS]; + GLfloat *out = data; + GLfloat *mat = ctx->Viewport.WindowMap.m; + GLfloat w = ctx->Line.Width * .5; + GLuint e, n; + + GLuint tmu0_source = fxMesa->tmu_source[0]; + GLuint tmu1_source = fxMesa->tmu_source[1]; + GLvector4f *tc0_vec = VB->TexCoordPtr[tmu0_source]; + GLvector4f *tc1_vec = VB->TexCoordPtr[tmu1_source]; + + VARS; + + (void) fxMesa; + (void) tmu0_source; + (void) tc0_vec; + (void) tmu1_source; + (void) tc1_vec; + + vlist[0] = out; + e = v1; + COPY_STRIDE; + out += SIZE; + + vlist[1] = out; + e = v2; + COPY_STRIDE; + out += SIZE; + + if (VB->ClipPtr->size < 4) { + vlist[0][3] = vlist[1][3] = 1.0; + if (VB->ClipPtr->size == 2) + vlist[0][2] = vlist[1][2] = 0.0; + } + + if ((n = fx_clip_line(ctx, vlist, SIZE, mask)) != 0) { + GrVertex gWin[2]; + GrVertex *v; + GLfloat *data; + + v = gWin; + data = vlist[0]; + SETUP; + + v++; + data = vlist[1]; + SETUP; + + DRAW_LINE(fxMesa, gWin, v, w); + } +} + + + +#undef V1 +#undef S1 +#undef C1 +#undef Z1 +#undef T1 + +#undef V2 +#undef S2 +#undef C2 +#undef Z2 +#undef T2 + +#undef V3 +#undef S3 +#undef C3 +#undef Z3 +#undef T3 + +#undef V4 +#undef S4 +#undef C4 +#undef Z4 +#undef T4 + +#undef VARS +#undef SETUP +#undef COPY +#undef COPY_STRIDE +#undef SIZE +#undef IND +#undef TAG diff --git a/xc/lib/GL/mesa/src/drv/tdfx/fxcva.c b/xc/lib/GL/mesa/src/drv/tdfx/fxcva.c new file mode 100644 index 000000000..21a1c4dfb --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/tdfx/fxcva.c @@ -0,0 +1,492 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/fxcva.c,v 1.1 2000/09/24 13:51:14 alanh Exp $ */ +/* + * Mesa 3-D graphics library + * Version: 3.3 + * + * 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. + * + * + * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the + * terms stated above. + * + * Thank you for your contribution, David! + * + * Please make note of the above copyright/license statement. If you + * contributed code or bug fixes to this code under the previous (GNU + * Library) license and object to the new license, your code will be + * removed at your request. Please see the Mesa docs/COPYRIGHT file + * for more information. + * + * Additional Mesa/3Dfx driver developers: + * Daryll Strauss <daryll@precisioninsight.com> + * Keith Whitwell <keith@precisioninsight.com> + * + * See fxapi.h for more revision/author details. + */ + + +/* fxcva.c - the CVA related code */ + +#include "fxdrv.h" +#include "fxtexman.h" +#include "mmath.h" +#include "vbindirect.h" +#include "pb.h" +#include "fxsetup.h" +#include "fxvsetup.h" +#include "fxcva.h" +#include "pipeline.h" +#include "stages.h" + +#define PRIM_POINTS 0 +#define PRIM_LINES 1 +#define PRIM_TRIS 2 +#define PRIM_CULLED 3 + + +static GLuint reduce_prim[GL_POLYGON + 2] = { + PRIM_POINTS, + PRIM_LINES, + PRIM_LINES, + PRIM_LINES, + PRIM_TRIS, + PRIM_TRIS, + PRIM_TRIS, + PRIM_TRIS, + PRIM_TRIS, + PRIM_TRIS, + PRIM_CULLED +}; + +typedef void (*mergefunc) (struct vertex_buffer * cvaVB, + struct vertex_buffer * VB, + const struct gl_prim_state * state, + GLuint start, GLuint count); + +static void +fxCvaRenderNoop(struct vertex_buffer *cvaVB, + struct vertex_buffer *VB, + const struct gl_prim_state *state, GLuint start, GLuint count) +{ +} + +static INLINE void +fxRenderClippedTriangle2(struct vertex_buffer *VB, + GLuint v1, GLuint v2, GLuint v3) +{ + fxVertex *gWin = FX_DRIVER_DATA(VB)->verts; + GLubyte *clipmask = VB->ClipMask; + GLubyte mask = clipmask[v1] | clipmask[v2] | clipmask[v3]; + GLcontext *ctx = VB->ctx; + fxMesaContext fxMesa = FX_CONTEXT(ctx); + + if (!mask) { + FX_grDrawTriangle(fxMesa, (GrVertex *) gWin[v1].f, + (GrVertex *) gWin[v2].f, (GrVertex *) gWin[v3].f); + } + else if (!(clipmask[v1] & clipmask[v2] & clipmask[v3] & CLIP_ALL_BITS)) { + GLuint n; + GLuint vlist[VB_MAX_CLIPPED_VERTS]; + ASSIGN_3V(vlist, v1, v2, v3); + + n = (VB->ctx->poly_clip_tab[VB->ClipPtr->size]) (VB, 3, vlist, mask); + if (n >= 3) { + GLuint i, j0 = vlist[0]; + for (i = 2; i < n; i++) { + FX_grDrawTriangle(fxMesa, + (GrVertex *) gWin[j0].f, + (GrVertex *) gWin[vlist[i - 1]].f, + (GrVertex *) gWin[vlist[i]].f); + } + } + } +} + + +static mergefunc merge_and_render_tab[2][MAX_MERGABLE][PRIM_CULLED + 1]; + + +/* +#define CVA_VARS_RGBA \ + GLubyte (*color)[4] = VB->ColorPtr->data; \ + GLubyte (*cva_color)[4] = (cvaVB->ColorPtr = cvaVB->LitColor[0])->data; +*/ + +#define CVA_VARS_RGBA \ + GLubyte (*color)[4] = VB->ColorPtr->data; \ + GLubyte (*cva_color)[4] = cvaVB->ColorPtr->data; + + + +#undef DO_SETUP_RGBA +#if FX_USE_PARGB +#define DO_SETUP_RGBA \ +{ \ + GLubyte *col = color[i]; \ + GET_PARGB(v)= ((col[3] << 24) | \ + (col[0] << 16) | \ + (col[1] << 8) | \ + (col[2])); \ +} +#else +#define DO_SETUP_RGBA \ +{ \ + GLubyte *col = color[i]; \ + v[GR_VERTEX_R_OFFSET]=UBYTE_COLOR_TO_FLOAT_255_COLOR(col[0]); \ + v[GR_VERTEX_G_OFFSET]=UBYTE_COLOR_TO_FLOAT_255_COLOR(col[1]); \ + v[GR_VERTEX_B_OFFSET]=UBYTE_COLOR_TO_FLOAT_255_COLOR(col[2]); \ + v[GR_VERTEX_A_OFFSET]=UBYTE_COLOR_TO_FLOAT_255_COLOR(col[3]); \ +} +#endif /* FX_USE_PARGB */ + + +#define CVA_VARS_TMU0 \ + VARS_TMU0 \ + GLfloat (*cva_tex0)[4] = (cvaVB->TexCoordPtr[tmu0_source] = cvaVB->store.TexCoord[tmu0_source])->data; + +#define CVA_VARS_TMU1 \ + VARS_TMU1 \ + GLfloat (*cva_tex1)[4] = (cvaVB->TexCoordPtr[tmu1_source] = cvaVB->store.TexCoord[tmu1_source])->data; + + +#define INIT_RGBA (void) cva_color; +#define INIT_TMU0 (void) cva_tex0; (void) tmu0_stride; (void) tmu0_sz; +#define INIT_TMU1 (void) cva_tex1; (void) tmu1_stride; (void) tmu1_sz; + + +#define DRAW_POINT FX_grDrawPoint( fxMesa, (GrVertex *)v ) +#define DRAW_LINE FX_grDrawLine( fxMesa, (GrVertex *)v, (GrVertex *)prev_v ) +#define DRAW_TRI FX_grDrawTriangle( fxMesa, (GrVertex *)gWin[l[0]].f, (GrVertex *)gWin[l[1]].f, (GrVertex *)v ) +#define DRAW_TRI2 FX_grDrawTriangle( fxMesa, vl[0], vl[1], vl[2] ) +#define CLIP_LINE fxRenderClippedLine( cvaVB, e, prev ) +#define CLIP_OR_DRAW_TRI fxRenderClippedTriangle2( cvaVB, l[0], l[1], e ) +#define DIRECT 1 + +#define TAG(x) x +#define IDX 0 +#define VARS +#define INIT +#define INCR +#define MERGE_RAST +#define MERGE_VB +#include "fxcvatmp.h" + +#define TAG(x) x##RGBA +#define IDX SETUP_RGBA +#define VARS CVA_VARS_RGBA +#define INIT INIT_RGBA +#define INCR +#define MERGE_RAST DO_SETUP_RGBA +#define MERGE_VB COPY_4UBV(cva_color[e], color[i]) +#include "fxcvatmp.h" + +#define TAG(x) x##T0 +#define IDX SETUP_TMU0 +#define VARS CVA_VARS_TMU0 +#define INIT INIT_TMU0 +#define INCR , tmu0_data+=4 +#define MERGE_RAST DO_SETUP_TMU0 +#define MERGE_VB COPY_2FV(cva_tex0[e], tmu0_data) +#include "fxcvatmp.h" + +#define TAG(x) x##T1 +#define IDX SETUP_TMU1 +#define VARS CVA_VARS_TMU1 +#define INIT INIT_TMU1 +#define INCR , tmu1_data+=4 +#define MERGE_RAST DO_SETUP_TMU1 +#define MERGE_VB COPY_2FV(cva_tex1[e], tmu1_data) +#include "fxcvatmp.h" + +#define TAG(x) x##T0T1 +#define IDX SETUP_TMU0|SETUP_TMU1 +#define VARS CVA_VARS_TMU0 CVA_VARS_TMU1 +#define INIT INIT_TMU0 INIT_TMU1 +#define INCR , tmu0_data+=4 , tmu1_data+=4 +#define MERGE_RAST DO_SETUP_TMU0 DO_SETUP_TMU1 +#define MERGE_VB COPY_2FV(cva_tex0[e], tmu0_data); \ + COPY_2FV(cva_tex1[e], tmu1_data); +#include "fxcvatmp.h" + +#define TAG(x) x##RGBAT0 +#define IDX SETUP_RGBA|SETUP_TMU0 +#define VARS CVA_VARS_RGBA CVA_VARS_TMU0 +#define INIT INIT_RGBA INIT_TMU0 +#define INCR , tmu0_data+=4 +#define MERGE_RAST DO_SETUP_RGBA; DO_SETUP_TMU0 +#define MERGE_VB COPY_2FV(cva_tex0[e], tmu0_data); \ + COPY_4UBV(cva_color[e], color[i]); +#include "fxcvatmp.h" + +#define TAG(x) x##RGBAT1 +#define IDX SETUP_RGBA|SETUP_TMU1 +#define VARS CVA_VARS_RGBA CVA_VARS_TMU1 +#define INIT INIT_RGBA INIT_TMU1 +#define INCR , tmu1_data+=4 +#define MERGE_RAST DO_SETUP_RGBA; DO_SETUP_TMU1 +#define MERGE_VB COPY_2FV(cva_tex1[e], tmu1_data); \ + COPY_4UBV(cva_color[e], color[i]); +#include "fxcvatmp.h" + +#define TAG(x) x##RGBAT0T1 +#define IDX SETUP_RGBA|SETUP_TMU0|SETUP_TMU1 +#define VARS CVA_VARS_RGBA CVA_VARS_TMU0 CVA_VARS_TMU1 +#define INIT INIT_RGBA INIT_TMU0 INIT_TMU1 +#define INCR , tmu0_data+=4 , tmu1_data+=4 +#define MERGE_RAST DO_SETUP_RGBA; DO_SETUP_TMU0 DO_SETUP_TMU1 +#define MERGE_VB COPY_2FV(cva_tex0[e], tmu0_data); \ + COPY_2FV(cva_tex1[e], tmu1_data); \ + COPY_4UBV(cva_color[e], color[i]); +#include "fxcvatmp.h" + + + +#undef DRAW_POINT +#undef DRAW_LINE +#undef DRAW_TRI +#undef CLIP_LINE +#undef CLIP_OR_DRAW_TRI +#undef DIRECT + +#define DRAW_POINT ctx->Driver.PointsFunc( ctx, e, e ) +#define DRAW_LINE ctx->Driver.LineFunc( ctx, e, prev, e ) +#define DRAW_TRI ctx->TriangleFunc( ctx, l[0], l[1], e, e ) +#define CLIP_LINE gl_render_clipped_line( ctx, e, prev ) +#define CLIP_OR_DRAW_TRI \ +do { \ + if (clip[l[0]] | clip[l[1]] | clip[e]) { \ + if (!(clip[l[0]] & clip[l[1]] & clip[e] & CLIP_ALL_BITS)) { \ + COPY_3V(vlist, l); \ + gl_render_clipped_triangle( ctx, 3, vlist, e ); \ + } \ + } \ + else ctx->TriangleFunc( ctx, l[0], l[1], e, e ); \ +} while (0) + + +#define DIRECT 0 + +#define TAG(x) x##_indirect +#define IDX 0 +#define VARS +#define INIT +#define INCR +#define MERGE_RAST +#define MERGE_VB +#include "fxcvatmp.h" + +#define TAG(x) x##RGBA_indirect +#define IDX SETUP_RGBA +#define VARS CVA_VARS_RGBA +#define INIT INIT_RGBA +#define INCR +#define MERGE_RAST DO_SETUP_RGBA +#define MERGE_VB COPY_4UBV(cva_color[e], color[i]) +#include "fxcvatmp.h" + +#define TAG(x) x##T0_indirect +#define IDX SETUP_TMU0 +#define VARS CVA_VARS_TMU0 +#define INIT INIT_TMU0 +#define INCR , tmu0_data+=4 +#define MERGE_RAST DO_SETUP_TMU0 +#define MERGE_VB COPY_2FV(cva_tex0[e], tmu0_data) +#include "fxcvatmp.h" + +#define TAG(x) x##T1_indirect +#define IDX SETUP_TMU1 +#define VARS CVA_VARS_TMU1 +#define INIT INIT_TMU1 +#define INCR , tmu1_data+=4 +#define MERGE_RAST DO_SETUP_TMU1 +#define MERGE_VB COPY_2FV(cva_tex1[e], tmu1_data) +#include "fxcvatmp.h" + +#define TAG(x) x##T0T1_indirect +#define IDX SETUP_TMU0|SETUP_TMU1 +#define VARS CVA_VARS_TMU0 CVA_VARS_TMU1 +#define INIT INIT_TMU0 INIT_TMU1 +#define INCR , tmu0_data+=4 , tmu1_data+=4 +#define MERGE_RAST DO_SETUP_TMU0 DO_SETUP_TMU1 +#define MERGE_VB COPY_2FV(cva_tex0[e], tmu0_data); \ + COPY_2FV(cva_tex1[e], tmu1_data); +#include "fxcvatmp.h" + +#define TAG(x) x##RGBAT0_indirect +#define IDX SETUP_RGBA|SETUP_TMU0 +#define VARS CVA_VARS_RGBA CVA_VARS_TMU0 +#define INIT INIT_RGBA INIT_TMU0 +#define INCR , tmu0_data+=4 +#define MERGE_RAST DO_SETUP_RGBA; DO_SETUP_TMU0 +#define MERGE_VB COPY_2FV(cva_tex0[e], tmu0_data); \ + COPY_4UBV(cva_color[e], color[i]); +#include "fxcvatmp.h" + +#define TAG(x) x##RGBAT1_indirect +#define IDX SETUP_RGBA|SETUP_TMU1 +#define VARS CVA_VARS_RGBA CVA_VARS_TMU1 +#define INIT INIT_RGBA INIT_TMU1 +#define INCR , tmu1_data+=4 +#define MERGE_RAST DO_SETUP_RGBA; DO_SETUP_TMU1 +#define MERGE_VB COPY_2FV(cva_tex1[e], tmu1_data); \ + COPY_4UBV(cva_color[e], color[i]); +#include "fxcvatmp.h" + +#define TAG(x) x##RGBAT0T1_indirect +#define IDX SETUP_RGBA|SETUP_TMU0|SETUP_TMU1 +#define VARS CVA_VARS_RGBA CVA_VARS_TMU0 CVA_VARS_TMU1 +#define INIT INIT_RGBA INIT_TMU0 INIT_TMU1 +#define INCR , tmu0_data+=4 , tmu1_data+=4 +#define MERGE_RAST DO_SETUP_RGBA DO_SETUP_TMU0 DO_SETUP_TMU1 +#define MERGE_VB COPY_2FV(cva_tex0[e], tmu0_data); \ + COPY_2FV(cva_tex1[e], tmu1_data); \ + COPY_4UBV(cva_color[e], color[i]); +#include "fxcvatmp.h" + + + + +void +fxDDCvaInit() +{ + /* Call grDrawTriangle et al */ + init_cva(); + init_cvaT0(); + init_cvaT1(); + init_cvaT0T1(); + init_cvaRGBA(); + init_cvaRGBAT0(); + init_cvaRGBAT1(); + init_cvaRGBAT0T1(); + + /* Call ctx->TriangleFunc and friends */ + init_cva_indirect(); + init_cvaT0_indirect(); + init_cvaT1_indirect(); + init_cvaT0T1_indirect(); + init_cvaRGBA_indirect(); + init_cvaRGBAT0_indirect(); + init_cvaRGBAT1_indirect(); + init_cvaRGBAT0T1_indirect(); +} + + +void +fxDDCheckMergeAndRender(GLcontext * ctx, struct gl_pipeline_stage *d) +{ + GLuint inputs = ctx->RenderFlags & ~ctx->CVA.pre.outputs; + + if (!(ctx->TriangleCaps & DD_TRI_UNFILLED) && + (ctx->Array.Summary & VERT_OBJ_ANY)) { + d->inputs = (VERT_SETUP_PART | VERT_ELT | inputs); + d->outputs = 0; + d->type = PIPE_IMMEDIATE; + } + +/* gl_print_vert_flags("merge&render inputs", d->inputs); */ +} + + +extern void fxPointSmooth(GLcontext * ctx, GLuint first, GLuint last); +extern void fxLineSmooth(GLcontext * ctx, GLuint v1, GLuint v2, GLuint pv); +extern void fxTriangleSmooth(GLcontext * ctx, GLuint v1, GLuint v2, GLuint v3, + GLuint pv); +extern const char *gl_prim_name[]; + + +/* static GLboolean edge_flag[GL_POLYGON+2] = { 0,0,0,0,1,0,0,1,0,1,0 }; */ + +void +fxDDMergeAndRender(struct vertex_buffer *VB) +{ + GLcontext *ctx = VB->ctx; + struct vertex_buffer *cvaVB = ctx->CVA.VB; + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + GLuint i, next, prim; + GLuint parity = VB->Parity; + GLuint count = VB->Count; + const struct gl_prim_state *state; + mergefunc func; + struct vertex_buffer *saved_vb = ctx->VB; + GLuint inputs = ctx->RenderFlags & ~ctx->CVA.pre.outputs; + GLuint flags = 0; + GLuint direct = (fxMesa->render_index == 0); + mergefunc(*tab)[PRIM_CULLED + 1] = merge_and_render_tab[direct]; + GLuint p = 0; + + if (fxMesa->new_state) + fxSetupFXUnits(ctx); + + + /* May actually contain elements not present in fxMesa->setupindex, + * eg RGBA when flat shading. These need to be copied into the cva + * VB so that funcs like fxTriangleFlat will be able to reach them. + * + * This leads to some duplication of effort in the merge funcs. + */ + if (inputs & VERT_RGBA) { + cvaVB->ColorPtr = cvaVB->Color[0] = cvaVB->LitColor[0]; + cvaVB->Color[1] = cvaVB->LitColor[1]; + flags |= SETUP_RGBA; + } + + if (inputs & VERT_TEX0_ANY) { + cvaVB->TexCoordPtr[0] = cvaVB->store.TexCoord[0]; + flags |= fxMesa->tex_dest[0]; + } + + if (inputs & VERT_TEX1_ANY) { + cvaVB->TexCoordPtr[1] = cvaVB->store.TexCoord[1]; + flags |= fxMesa->tex_dest[1]; + } +#if 0 + fxPrintSetupFlags("FX cva merge & render", flags); +#endif + + if (cvaVB->ClipOrMask) + gl_import_client_data(cvaVB, ctx->RenderFlags, + VEC_WRITABLE | VEC_GOOD_STRIDE); + + ctx->VB = cvaVB; + + do { + for (i = VB->CopyStart; i < count; parity = 0, i = next) { + prim = VB->Primitive[i]; + next = VB->NextPrimitive[i]; + + state = gl_prim_state_machine[prim][parity]; + func = tab[flags][reduce_prim[prim]]; + func(cvaVB, VB, state, i, next); + + if (ctx->TriangleCaps & DD_TRI_LIGHT_TWOSIDE) { + cvaVB->Specular = cvaVB->Spec[0]; + cvaVB->ColorPtr = cvaVB->Color[0]; + cvaVB->IndexPtr = cvaVB->Index[0]; + } + } + } while (ctx->Driver.MultipassFunc && ctx->Driver.MultipassFunc(VB, ++p)); + + + + if (ctx->PB->count > 0) + gl_flush_pb(ctx); + + ctx->VB = saved_vb; +} diff --git a/xc/lib/GL/mesa/src/drv/tdfx/fxcva.h b/xc/lib/GL/mesa/src/drv/tdfx/fxcva.h new file mode 100644 index 000000000..98ae5f075 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/tdfx/fxcva.h @@ -0,0 +1,64 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/fxcva.h,v 1.1 2000/09/24 13:51:14 alanh Exp $ */ +/* + * Mesa 3-D graphics library + * Version: 3.3 + * + * 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. + * + * + * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the + * terms stated above. + * + * Thank you for your contribution, David! + * + * Please make note of the above copyright/license statement. If you + * contributed code or bug fixes to this code under the previous (GNU + * Library) license and object to the new license, your code will be + * removed at your request. Please see the Mesa docs/COPYRIGHT file + * for more information. + * + * Additional Mesa/3Dfx driver developers: + * Daryll Strauss <daryll@precisioninsight.com> + * Keith Whitwell <keith@precisioninsight.com> + * + * See fxapi.h for more revision/author details. + */ + + +#ifndef _FXCVA_H_ +#define _FXCVA_H_ + + + +extern GLboolean fxMergeAndRenderCVA(struct vertex_buffer *VB, + struct vertex_buffer *cvaVB); + +extern void fxRenderCVAElements(struct vertex_buffer *VB, + GLenum mode, GLuint * elts, GLuint n); + +extern GLboolean fxCheckCVA(GLcontext * ctx); + +extern void fxPrecalcCVA(struct vertex_buffer *VB); + +extern void fxDDCheckMergeAndRender(GLcontext * ctx, + struct gl_pipeline_stage *d); + + +#endif diff --git a/xc/lib/GL/mesa/src/drv/tdfx/fxcvatmp.h b/xc/lib/GL/mesa/src/drv/tdfx/fxcvatmp.h new file mode 100644 index 000000000..20523e33e --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/tdfx/fxcvatmp.h @@ -0,0 +1,278 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/fxcvatmp.h,v 1.1 2000/09/24 13:51:14 alanh Exp $ */ +/* + * Mesa 3-D graphics library + * Version: 3.3 + * + * 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. + * + * + * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the + * terms stated above. + * + * Thank you for your contribution, David! + * + * Please make note of the above copyright/license statement. If you + * contributed code or bug fixes to this code under the previous (GNU + * Library) license and object to the new license, your code will be + * removed at your request. Please see the Mesa docs/COPYRIGHT file + * for more information. + * + * Additional Mesa/3Dfx driver developers: + * Daryll Strauss <daryll@precisioninsight.com> + * Keith Whitwell <keith@precisioninsight.com> + * + * See fxapi.h for more revision/author details. + */ + + +static void TAG(cva_render_points) (struct vertex_buffer * cvaVB, + struct vertex_buffer * VB, + const struct gl_prim_state * state, + GLuint start, GLuint count) +{ + GLcontext *ctx = VB->ctx; + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + fxVertex *gWin = FX_DRIVER_DATA(cvaVB)->verts; + const GLuint *elt = VB->EltPtr->data; + GLuint i; + + VARS; + INIT; + (void) fxMesa; + + if (cvaVB->ClipOrMask) { + const GLubyte *clip = cvaVB->ClipMask; + for (i = start; i < count; i++ INCR) { + GLuint e = elt[i]; + if (!clip[e]) { + GLfloat *v = gWin[e].f; + (void) v; + if (!DIRECT) { + MERGE_VB; + } + MERGE_RAST; + DRAW_POINT; + } + } + } + else { + for (i = start; i < count; i++ INCR) { + GLuint e = elt[i]; + GLfloat *v = gWin[e].f; + (void) v; + if (!DIRECT) { + MERGE_VB; + } + MERGE_RAST; + DRAW_POINT; + } + } +} + +static void TAG(cva_render_lines) (struct vertex_buffer * cvaVB, + struct vertex_buffer * VB, + const struct gl_prim_state * state, + GLuint start, GLuint count) +{ + GLcontext *ctx = VB->ctx; + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + fxVertex *gWin = FX_DRIVER_DATA(cvaVB)->verts; + const GLuint *elt = VB->EltPtr->data; + GLuint i; + + VARS; + INIT; + (void) fxMesa; + + if (cvaVB->ClipOrMask) { + const GLubyte *clip = cvaVB->ClipMask; + GLuint prev = 0; + GLfloat *prev_v = 0; + + (void) ctx; + + for (i = start; i < count; i++ INCR) { + GLuint e = elt[i]; + GLfloat *v = gWin[e].f; + + MERGE_VB; + + if (!clip[e]) + MERGE_RAST; + + if (state->draw) { + if (clip[e] | clip[prev]) + CLIP_LINE; + else + DRAW_LINE; + } + + prev = e; + prev_v = v; + state = state->next; + } + if (state->finish_loop) { + GLuint e = elt[start]; + GLfloat *v = gWin[e].f; + (void) v; + + if (!DIRECT) { + MERGE_VB; + } + MERGE_RAST; + + if (clip[e] | clip[prev]) + CLIP_LINE; + else + DRAW_LINE; + } + } + else { + GLuint prev = 0; + GLfloat *prev_v = 0; + + for (i = start; i < count; i++ INCR) { + GLuint e = elt[i]; + GLfloat *v = gWin[e].f; + + if (!DIRECT) { + MERGE_VB; + } + MERGE_RAST; + if (state->draw) + DRAW_LINE; + prev = e; + prev_v = v; + state = state->next; + } + if (state->finish_loop) { + GLuint e = elt[start]; + GLfloat *v = gWin[e].f; + (void) v; + + if (!DIRECT) { + MERGE_VB; + } + MERGE_RAST; + DRAW_LINE; + } + } +} + + +static void TAG(cva_render_tris) (struct vertex_buffer * cvaVB, + struct vertex_buffer * VB, + const struct gl_prim_state * state, + GLuint start, GLuint count) +{ + GLcontext *ctx = VB->ctx; + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + fxVertex *gWin = FX_DRIVER_DATA(cvaVB)->verts; + const GLuint *elt = VB->EltPtr->data; + GLuint i; + VARS; + INIT; + (void) fxMesa; + + if (cvaVB->ClipOrMask) { + GLuint vlist[VB_MAX_CLIPPED_VERTS]; + GLuint l[3]; + const GLubyte *clip = cvaVB->ClipMask; + + (void) vlist; + + for (i = start; i < count; i++ INCR) { + GLuint e = l[2] = elt[i]; + GLfloat *v = gWin[e].f; + (void) v; + + MERGE_VB; /* needed for clip-interp */ + + if (!clip[e]) { + MERGE_RAST; + } + + if (state->draw) + CLIP_OR_DRAW_TRI; + + + l[0] = l[state->v0]; + l[1] = l[state->v1]; + state = state->next; + } + } + else if (DIRECT) { + GrVertex *vl[3]; + for (i = start; i < count; i++ INCR) { + GLuint e = elt[i]; + GLfloat *v = gWin[elt[i]].f; + + vl[2] = (GrVertex *) v; + + (void) v; + (void) e; + + MERGE_RAST; + + if (state->draw) + DRAW_TRI2; + + vl[0] = vl[state->v0]; + vl[1] = vl[state->v1]; + state = state->next; + } + } + else { + GLuint l[3]; + for (i = start; i < count; i++ INCR) { + GLuint e = l[2] = elt[i]; + GLfloat *v = gWin[e].f; + (void) v; + + MERGE_VB; /* needed for ctx->trianglefunc? */ + MERGE_RAST; + + if (state->draw) + DRAW_TRI; + + l[0] = l[state->v0]; + l[1] = l[state->v1]; + state = state->next; + } + } +} + + +static void TAG(init_cva) (void) +{ + merge_and_render_tab[DIRECT][IDX][PRIM_POINTS] = TAG(cva_render_points); + merge_and_render_tab[DIRECT][IDX][PRIM_LINES] = TAG(cva_render_lines); + merge_and_render_tab[DIRECT][IDX][PRIM_TRIS] = TAG(cva_render_tris); + merge_and_render_tab[DIRECT][IDX][PRIM_CULLED] = fxCvaRenderNoop; +} + + +#undef IDX +#undef MERGE_RAST +#undef MERGE_VB +#undef VARS +#undef INIT +#undef INCR +#undef TAG diff --git a/xc/lib/GL/mesa/src/drv/tdfx/fxdd.c b/xc/lib/GL/mesa/src/drv/tdfx/fxdd.c new file mode 100644 index 000000000..c24269ce3 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/tdfx/fxdd.c @@ -0,0 +1,1939 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/fxdd.c,v 1.1 2000/09/24 13:51:14 alanh Exp $ */ +/* + * Mesa 3-D graphics library + * Version: 3.3 + * + * 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. + * + * + * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the + * terms stated above. + * + * Thank you for your contribution, David! + * + * Please make note of the above copyright/license statement. If you + * contributed code or bug fixes to this code under the previous (GNU + * Library) license and object to the new license, your code will be + * removed at your request. Please see the Mesa docs/COPYRIGHT file + * for more information. + * + * Additional Mesa/3Dfx driver developers: + * Daryll Strauss <daryll@precisioninsight.com> + * Keith Whitwell <keith@precisioninsight.com> + * + * See fxapi.h for more revision/author details. + */ + + +#include <dlfcn.h> +#include "image.h" +#include "types.h" +#include "fxdrv.h" +#include "fxsetup.h" +#include "fxpipeline.h" +#include "fxddtex.h" +#include "fxtexman.h" +#include "enums.h" +#include "extensions.h" +#include "pb.h" + + +/* These are used in calls to FX_grColorMaskv() */ +static const GLboolean false4[4] = { GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE }; +static const GLboolean true4[4] = { GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE }; + +#if defined(FX_PXCONV_TABULAR) +/* These lookup table are used to extract RGB values in [0,255] from + * 16-bit pixel values. + */ +GLubyte FX_PixelToRArray[0x10000]; +GLubyte FX_PixelToGArray[0x10000]; +GLubyte FX_PixelToBArray[0x10000]; +#endif /* defined(FX_PXCONV_TABULAR) */ + +/* + * Initialize the FX_PixelTo{RGB} arrays. + * Input: bgrOrder - if TRUE, pixels are in BGR order, else RGB order. + */ +void +fxInitPixelTables(fxMesaContext fxMesa, GLboolean bgrOrder) +{ + fxMesa->bgrOrder = bgrOrder; +#ifdef FX_PXCONV_TABULAR + /* + * We add a level of braces so that we can define the + * variable pixel here. + */ + { + GLuint pixel = 0; + for (pixel = 0; pixel <= 0xffff; pixel++) { + GLuint r, g, b; + if (bgrOrder) { + r = (pixel & 0x001F) << 3; + g = (pixel & 0x07E0) >> 3; + b = (pixel & 0xF800) >> 8; + } + else { + r = (pixel & 0xF800) >> 8; + g = (pixel & 0x07E0) >> 3; + b = (pixel & 0x001F) << 3; + } + r = r * 255 / 0xF8; /* fill in low-order bits */ + g = g * 255 / 0xFC; + b = b * 255 / 0xF8; + FX_PixelToRArray[pixel] = r; + FX_PixelToGArray[pixel] = g; + FX_PixelToBArray[pixel] = b; + } + } +#endif /* FX_PXCONV_TABULAR */ +} + +/**********************************************************************/ +/***** Miscellaneous functions *****/ +/**********************************************************************/ + + +/* Return buffer size information */ +static void +fxDDBufferSize(GLcontext * ctx, GLuint * width, GLuint * height) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: fxDDBufferSize(...) Start\n"); + } + + *width = fxMesa->width; + *height = fxMesa->height; + + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: fxDDBufferSize(...) End\n"); + } +} + + +/* Set current drawing color */ +static void +fxDDSetColor(GLcontext * ctx, GLubyte red, GLubyte green, + GLubyte blue, GLubyte alpha) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GLubyte col[4]; + ASSIGN_4V(col, red, green, blue, alpha); + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: fxDDSetColor(%d,%d,%d,%d)\n", red, green, + blue, alpha); + } + fxMesa->color = FXCOLOR4(col); +} + + +/* Implements glClearColor() */ +static void +fxDDClearColor(GLcontext * ctx, GLubyte red, GLubyte green, + GLubyte blue, GLubyte alpha) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GLubyte col[4]; + ASSIGN_4V(col, red, green, blue, 255); + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: fxDDClearColor(%d,%d,%d,%d)\n", red, green, + blue, alpha); + } + fxMesa->clearC = FXCOLOR4(col); + fxMesa->clearA = alpha; +} + + +/* Clear the color and/or depth buffers */ +static GLbitfield +fxDDClear(GLcontext * ctx, GLbitfield mask, GLboolean all, + GLint x, GLint y, GLint width, GLint height) +{ + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + const GLuint colorMask = *((GLuint *) & ctx->Color.ColorMask); + const FxU32 clearD = (FxU32) (ctx->Depth.Clear * fxMesa->depthClear); + const FxU32 clearS = (FxU32) (ctx->Stencil.Clear); + GLbitfield softwareMask = mask & (DD_ACCUM_BIT); + GLuint stencil_size = + fxMesa->haveHwStencil ? fxMesa->glVis->StencilBits : 0; + + /* we can't clear accum buffers */ + mask &= ~(DD_ACCUM_BIT); + + if ((mask & DD_STENCIL_BIT) && !fxMesa->haveHwStencil) { + /* software stencil buffer */ + mask &= ~(DD_STENCIL_BIT); + softwareMask |= DD_STENCIL_BIT; + } + + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: fxDDClear(%d,%d,%d,%d)\n", (int) x, (int) y, + (int) width, (int) height); + } + + if (colorMask != 0xffffffff) { + /* do masked color buffer clears in software */ + softwareMask |= (mask & (DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT)); + mask &= ~(DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT); + } + + + if (fxMesa->haveHwStencil) { + /* + * If we want to clear stencil, it must be enabled + * in the HW, even if the stencil test is not enabled + * in the OGL state. + */ + if (mask & DD_STENCIL_BIT) { + FX_grStencilMask(fxMesa, ctx->Stencil.WriteMask); + /* set stencil ref value = desired clear value */ + FX_grStencilFunc(fxMesa, GR_CMP_ALWAYS, ctx->Stencil.Clear, 0xff); + FX_grStencilOp(fxMesa, GR_STENCILOP_REPLACE, + GR_STENCILOP_REPLACE, GR_STENCILOP_REPLACE); + FX_grEnable(fxMesa, GR_STENCIL_MODE_EXT); + } + else { + FX_grDisable(fxMesa, GR_STENCIL_MODE_EXT); + } + } + + /* + * This could probably be done fancier but doing each possible case + * explicitly is less error prone. + */ + switch (mask & ~DD_STENCIL_BIT) { + case DD_BACK_LEFT_BIT | DD_DEPTH_BIT: + /* back buffer & depth */ + FX_grDepthMask(fxMesa, FXTRUE); + FX_grRenderBuffer(fxMesa, GR_BUFFER_BACKBUFFER); + if (stencil_size > 0) + FX_grBufferClearExt(fxMesa, fxMesa->clearC, fxMesa->clearA, clearD, + clearS); + else + FX_grBufferClear(fxMesa, fxMesa->clearC, fxMesa->clearA, clearD); + if (!ctx->Depth.Mask || !ctx->Depth.Test) { + FX_grDepthMask(fxMesa, FXFALSE); + } + break; + case DD_FRONT_LEFT_BIT | DD_DEPTH_BIT: + /* XXX it appears that the depth buffer isn't cleared when + * glRenderBuffer(fxMesa, GR_BUFFER_FRONTBUFFER) is set. + * This is a work-around/ + */ + /* clear depth */ + FX_grDepthMask(fxMesa, FXTRUE); + FX_grRenderBuffer(fxMesa, GR_BUFFER_BACKBUFFER); + FX_grColorMaskv(ctx, false4); + if (stencil_size > 0) + FX_grBufferClearExt(fxMesa, fxMesa->clearC, fxMesa->clearA, clearD, + clearS); + else + FX_grBufferClear(fxMesa, fxMesa->clearC, fxMesa->clearA, clearD); + /* clear front */ + FX_grColorMaskv(ctx, true4); + FX_grRenderBuffer(fxMesa, GR_BUFFER_FRONTBUFFER); + if (stencil_size > 0) + FX_grBufferClearExt(fxMesa, fxMesa->clearC, fxMesa->clearA, clearD, + clearS); + else + FX_grBufferClear(fxMesa, fxMesa->clearC, fxMesa->clearA, clearD); + if (!ctx->Depth.Mask || !ctx->Depth.Test) { + FX_grDepthMask(fxMesa, FXFALSE); + } + break; + case DD_BACK_LEFT_BIT: + /* back buffer only */ + FX_grDepthMask(fxMesa, FXFALSE); + FX_grRenderBuffer(fxMesa, GR_BUFFER_BACKBUFFER); + if (stencil_size > 0) + FX_grBufferClearExt(fxMesa, fxMesa->clearC, fxMesa->clearA, clearD, + clearS); + else + FX_grBufferClear(fxMesa, fxMesa->clearC, fxMesa->clearA, clearD); + if (ctx->Depth.Mask && ctx->Depth.Test) { + FX_grDepthMask(fxMesa, FXTRUE); + } + break; + case DD_FRONT_LEFT_BIT: + /* front buffer only */ + FX_grDepthMask(fxMesa, FXFALSE); + FX_grRenderBuffer(fxMesa, GR_BUFFER_FRONTBUFFER); + if (stencil_size > 0) + FX_grBufferClearExt(fxMesa, fxMesa->clearC, fxMesa->clearA, clearD, + clearS); + else + FX_grBufferClear(fxMesa, fxMesa->clearC, fxMesa->clearA, clearD); + if (ctx->Depth.Mask && ctx->Depth.Test) { + FX_grDepthMask(fxMesa, FXTRUE); + } + break; + case DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT: + /* front and back */ + FX_grDepthMask(fxMesa, FXFALSE); + FX_grRenderBuffer(fxMesa, GR_BUFFER_BACKBUFFER); + if (stencil_size > 0) + FX_grBufferClearExt(fxMesa, fxMesa->clearC, fxMesa->clearA, clearD, + clearS); + else + FX_grBufferClear(fxMesa, fxMesa->clearC, fxMesa->clearA, clearD); + FX_grRenderBuffer(fxMesa, GR_BUFFER_FRONTBUFFER); + if (stencil_size > 0) + FX_grBufferClearExt(fxMesa, fxMesa->clearC, fxMesa->clearA, clearD, + clearS); + else + FX_grBufferClear(fxMesa, fxMesa->clearC, fxMesa->clearA, clearD); + if (ctx->Depth.Mask && ctx->Depth.Test) { + FX_grDepthMask(fxMesa, FXTRUE); + } + break; + case DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT | DD_DEPTH_BIT: + /* clear front */ + FX_grDepthMask(fxMesa, FXFALSE); + FX_grRenderBuffer(fxMesa, GR_BUFFER_FRONTBUFFER); + if (stencil_size > 0) + FX_grBufferClearExt(fxMesa, fxMesa->clearC, fxMesa->clearA, clearD, + clearS); + else + FX_grBufferClear(fxMesa, fxMesa->clearC, fxMesa->clearA, clearD); + /* clear back and depth */ + FX_grDepthMask(fxMesa, FXTRUE); + FX_grRenderBuffer(fxMesa, GR_BUFFER_BACKBUFFER); + if (stencil_size > 0) + FX_grBufferClearExt(fxMesa, fxMesa->clearC, fxMesa->clearA, clearD, + clearS); + else + FX_grBufferClear(fxMesa, fxMesa->clearC, fxMesa->clearA, clearD); + if (!ctx->Depth.Mask || !ctx->Depth.Mask) { + FX_grDepthMask(fxMesa, FXFALSE); + } + break; + case DD_DEPTH_BIT: + /* just the depth buffer */ + FX_grRenderBuffer(fxMesa, GR_BUFFER_BACKBUFFER); + FX_grColorMaskv(ctx, false4); + FX_grDepthMask(fxMesa, FXTRUE); + if (stencil_size > 0) + FX_grBufferClearExt(fxMesa, fxMesa->clearC, fxMesa->clearA, clearD, + clearS); + else + FX_grBufferClear(fxMesa, fxMesa->clearC, fxMesa->clearA, clearD); + FX_grColorMaskv(ctx, true4); + if (ctx->Color.DrawDestMask & FRONT_LEFT_BIT) + FX_grRenderBuffer(fxMesa, GR_BUFFER_FRONTBUFFER); + if (!ctx->Depth.Test || !ctx->Depth.Mask) + FX_grDepthMask(fxMesa, FXFALSE); + break; + default: + /* error */ + ; + } + + if (fxMesa->haveHwStencil) { + if (ctx->Stencil.Enabled) { + /* restore stencil state to as it was before the clear */ + GrStencil_t sfail = fxConvertGLStencilOp(ctx->Stencil.FailFunc); + GrStencil_t zfail = fxConvertGLStencilOp(ctx->Stencil.ZFailFunc); + GrStencil_t zpass = fxConvertGLStencilOp(ctx->Stencil.ZPassFunc); + FX_grStencilOp(fxMesa, sfail, zfail, zpass); + FX_grStencilMask(fxMesa, ctx->Stencil.WriteMask); + FX_grStencilFunc(fxMesa, ctx->Stencil.Function - GL_NEVER, + ctx->Stencil.Ref, ctx->Stencil.ValueMask); + FX_grEnable(fxMesa, GR_STENCIL_MODE_EXT); + } + else { + FX_grDisable(fxMesa, GR_STENCIL_MODE_EXT); + } + } + return softwareMask; +} + + +/* Set the buffer used for drawing */ +/* XXX support for separate read/draw buffers hasn't been tested */ +static GLboolean +fxDDSetDrawBuffer(GLcontext * ctx, GLenum mode) +{ + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: fxDDSetBuffer(%x)\n", (int) mode); + } + + if (mode == GL_FRONT_LEFT) { + fxMesa->currentFB = GR_BUFFER_FRONTBUFFER; + FX_grRenderBuffer(fxMesa, fxMesa->currentFB); + return GL_TRUE; + } + else if (mode == GL_BACK_LEFT) { + fxMesa->currentFB = GR_BUFFER_BACKBUFFER; + FX_grRenderBuffer(fxMesa, fxMesa->currentFB); + return GL_TRUE; + } + else if (mode == GL_NONE) { + FX_grColorMaskv(ctx, false4); + return GL_TRUE; + } + else { + return GL_FALSE; + } +} + + +/* Set the buffer used for reading */ +/* XXX support for separate read/draw buffers hasn't been tested */ +static void +fxDDSetReadBuffer(GLcontext * ctx, GLframebuffer * buffer, GLenum mode) +{ + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + (void) buffer; + + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: fxDDSetBuffer(%x)\n", (int) mode); + } + + if (mode == GL_FRONT_LEFT) { + fxMesa->currentFB = GR_BUFFER_FRONTBUFFER; + FX_grRenderBuffer(fxMesa, fxMesa->currentFB); + } + else if (mode == GL_BACK_LEFT) { + fxMesa->currentFB = GR_BUFFER_BACKBUFFER; + FX_grRenderBuffer(fxMesa, fxMesa->currentFB); + } +} + + +/* + * These functions just set new-state flags. The exact state + * values will be evaluated later. + */ +static void +fxDDStencilFunc(GLcontext * ctx, GLenum func, GLint ref, GLuint mask) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + (void) func; + (void) ref; + (void) mask; + fxMesa->new_state |= FX_NEW_STENCIL; + ctx->Driver.RenderStart = fxSetupFXUnits; +} + +static void +fxDDStencilMask(GLcontext * ctx, GLuint mask) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + (void) mask; + fxMesa->new_state |= FX_NEW_STENCIL; + ctx->Driver.RenderStart = fxSetupFXUnits; +} + +static void +fxDDStencilOp(GLcontext * ctx, GLenum sfail, GLenum zfail, GLenum zpass) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + (void) sfail; + (void) zfail; + (void) zpass; + fxMesa->new_state |= FX_NEW_STENCIL; + ctx->Driver.RenderStart = fxSetupFXUnits; +} + +static void +fxDDDepthFunc(GLcontext * ctx, GLenum func) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + (void) func; + fxMesa->new_state |= FX_NEW_DEPTH; + ctx->Driver.RenderStart = fxSetupFXUnits; +} + +static void +fxDDDepthMask(GLcontext * ctx, GLboolean mask) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + (void) mask; + fxMesa->new_state |= FX_NEW_DEPTH; + ctx->Driver.RenderStart = fxSetupFXUnits; +} + + + +/* + * Return the current value of the occlusion test flag and + * reset the flag (hardware counters) to false. + */ +static GLboolean +get_occlusion_result(GLcontext *ctx) +{ + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + GLboolean result; + + BEGIN_BOARD_LOCK(fxMesa); + + if (ctx->Depth.OcclusionTest) { + if (ctx->OcclusionResult) { + result = GL_TRUE; /* result of software rendering */ + } + else { + FxI32 zfail, in; + zfail = FX_grGetInteger_NoLock(GR_STATS_PIXELS_DEPTHFUNC_FAIL); + in = FX_grGetInteger_NoLock(GR_STATS_PIXELS_IN); + if (in == zfail) + result = GL_FALSE; /* geom was completely occluded */ + else + result = GL_TRUE; /* all or part of geom was visible */ + } + } + else { + result = ctx->OcclusionResultSaved; + } + + /* reset results now */ + grReset(GR_STATS_PIXELS); + ctx->OcclusionResult = GL_FALSE; + ctx->OcclusionResultSaved = GL_FALSE; + + END_BOARD_LOCK(fxMesa); + + return result; +} + + +/* + * We're only implementing this function to handle the + * GL_OCCLUSTION_TEST_RESULT_HP case. It's special because it + * has a side-effect: resetting the occlustion result flag. + */ +static GLboolean +fxDDGetBooleanv(GLcontext *ctx, GLenum pname, GLboolean *result) +{ + if (pname == GL_OCCLUSION_TEST_RESULT_HP) { + *result = get_occlusion_result(ctx); + return GL_TRUE; + } + return GL_FALSE; +} + + +static GLboolean +fxDDGetIntegerv(GLcontext *ctx, GLenum pname, GLint *result) +{ + if (pname == GL_OCCLUSION_TEST_RESULT_HP) { + *result = (GLint) get_occlusion_result(ctx); + return GL_TRUE; + } + return GL_FALSE; +} + + +static GLboolean +fxDDGetFloatv(GLcontext *ctx, GLenum pname, GLfloat *result) +{ + if (pname == GL_OCCLUSION_TEST_RESULT_HP) { + *result = (GLfloat) get_occlusion_result(ctx); + return GL_TRUE; + } + return GL_FALSE; +} + + +static GLboolean +fxDDGetDoublev(GLcontext *ctx, GLenum pname, GLdouble *result) +{ + if (pname == GL_OCCLUSION_TEST_RESULT_HP) { + *result = (GLdouble) get_occlusion_result(ctx); + return GL_TRUE; + } + return GL_FALSE; +} + + +#ifdef XF86DRI +/* test if window coord (px,py) is visible */ +static GLboolean +inClipRects(fxMesaContext fxMesa, int px, int py) +{ + int i; + for (i = 0; i < fxMesa->numClipRects; i++) { + if ((px >= fxMesa->pClipRects[i].x1) && + (px < fxMesa->pClipRects[i].x2) && + (py >= fxMesa->pClipRects[i].y1) && + (py < fxMesa->pClipRects[i].y2)) return GL_TRUE; + } + return GL_FALSE; +} +#endif + + + +static GLboolean +bitmap_R5G6B5(GLcontext * ctx, GLint px, GLint py, + GLsizei width, GLsizei height, + const struct gl_pixelstore_attrib *unpack, + const GLubyte * bitmap) +{ + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + GrLfbInfo_t info; + FxU16 color; + const struct gl_pixelstore_attrib *finalUnpack; + struct gl_pixelstore_attrib scissoredUnpack; + + /* check if there's any raster operations enabled which we can't handle */ + if (ctx->RasterMask & (ALPHATEST_BIT | + BLEND_BIT | + DEPTH_BIT | + FOG_BIT | + LOGIC_OP_BIT | + SCISSOR_BIT | + STENCIL_BIT | + MASKING_BIT | + ALPHABUF_BIT | MULTI_DRAW_BIT)) return GL_FALSE; + + if (ctx->Scissor.Enabled) { + /* This is a bit tricky, but by carefully adjusting the px, py, + * width, height, skipPixels and skipRows values we can do + * scissoring without special code in the rendering loop. + */ + + /* we'll construct a new pixelstore struct */ + finalUnpack = &scissoredUnpack; + scissoredUnpack = *unpack; + if (scissoredUnpack.RowLength == 0) + scissoredUnpack.RowLength = width; + + /* clip left */ + if (px < ctx->Scissor.X) { + scissoredUnpack.SkipPixels += (ctx->Scissor.X - px); + width -= (ctx->Scissor.X - px); + px = ctx->Scissor.X; + } + /* clip right */ + if (px + width >= ctx->Scissor.X + ctx->Scissor.Width) { + width -= (px + width - (ctx->Scissor.X + ctx->Scissor.Width)); + } + /* clip bottom */ + if (py < ctx->Scissor.Y) { + scissoredUnpack.SkipRows += (ctx->Scissor.Y - py); + height -= (ctx->Scissor.Y - py); + py = ctx->Scissor.Y; + } + /* clip top */ + if (py + height >= ctx->Scissor.Y + ctx->Scissor.Height) { + height -= (py + height - (ctx->Scissor.Y + ctx->Scissor.Height)); + } + + if (width <= 0 || height <= 0) + return GL_TRUE; /* totally scissored away */ + } + else { + finalUnpack = unpack; + } + + /* compute pixel value */ + { + GLint r = (GLint) (ctx->Current.RasterColor[0] * 255.0f); + GLint g = (GLint) (ctx->Current.RasterColor[1] * 255.0f); + GLint b = (GLint) (ctx->Current.RasterColor[2] * 255.0f); + /*GLint a = (GLint)(ctx->Current.RasterColor[3]*255.0f); */ + if (fxMesa->bgrOrder) { + color = (FxU16) + (((FxU16) 0xf8 & b) << (11 - 3)) | + (((FxU16) 0xfc & g) << (5 - 3 + 1)) | + (((FxU16) 0xf8 & r) >> 3); + } + else + color = (FxU16) + (((FxU16) 0xf8 & r) << (11 - 3)) | + (((FxU16) 0xfc & g) << (5 - 3 + 1)) | + (((FxU16) 0xf8 & b) >> 3); + } + + info.size = sizeof(info); + if (!FX_grLfbLock(fxMesa, + GR_LFB_WRITE_ONLY, + fxMesa->currentFB, + GR_LFBWRITEMODE_565, + GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) { +#ifndef FX_SILENT + fprintf(stderr, "fx Driver: error locking the linear frame buffer\n"); +#endif + return GL_TRUE; + } + +#ifdef XF86DRI +#define INSIDE(c, x, y) inClipRects((c), (x), (y)) +#else +#define INSIDE(c, x, y) (1) +#endif + + { + const GLint winX = fxMesa->x_offset; + const GLint winY = fxMesa->y_offset + fxMesa->height - 1; + /* The dest stride depends on the hardware and whether we're drawing + * to the front or back buffer. This compile-time test seems to do + * the job for now. + */ +#ifdef XF86DRI + const GLint dstStride = (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) + ? (fxMesa->screen_width) : (info.strideInBytes / 2); +#else + const GLint dstStride = info.strideInBytes / 2; /* stride in GLushorts */ +#endif + GLint row; + /* compute dest address of bottom-left pixel in bitmap */ + GLushort *dst = (GLushort *) info.lfbPtr + + (winY - py) * dstStride + (winX + px); + + for (row = 0; row < height; row++) { + const GLubyte *src = + (const GLubyte *) _mesa_image_address(finalUnpack, + bitmap, width, height, + GL_COLOR_INDEX, + GL_BITMAP, 0, row, 0); + if (finalUnpack->LsbFirst) { + /* least significan bit first */ + GLubyte mask = 1U << (finalUnpack->SkipPixels & 0x7); + GLint col; + for (col = 0; col < width; col++) { + if (*src & mask) { + if (INSIDE(fxMesa, winX + px + col, winY - py - row)) + dst[col] = color; + } + if (mask == 128U) { + src++; + mask = 1U; + } + else { + mask = mask << 1; + } + } + if (mask != 1) + src++; + } + else { + /* most significan bit first */ + GLubyte mask = 128U >> (finalUnpack->SkipPixels & 0x7); + GLint col; + for (col = 0; col < width; col++) { + if (*src & mask) { + if (INSIDE(fxMesa, winX + px + col, winY - py - row)) + dst[col] = color; + } + if (mask == 1U) { + src++; + mask = 128U; + } + else { + mask = mask >> 1; + } + } + if (mask != 128) + src++; + } + dst -= dstStride; + } + } + +#undef INSIDE + + FX_grLfbUnlock(fxMesa, GR_LFB_WRITE_ONLY, fxMesa->currentFB); + return GL_TRUE; +} + + +static GLboolean +bitmap_R8G8B8A8(GLcontext * ctx, GLint px, GLint py, + GLsizei width, GLsizei height, + const struct gl_pixelstore_attrib *unpack, + const GLubyte * bitmap) +{ + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + GrLfbInfo_t info; + GLuint color; + const struct gl_pixelstore_attrib *finalUnpack; + struct gl_pixelstore_attrib scissoredUnpack; + + /* check if there's any raster operations enabled which we can't handle */ + if (ctx->RasterMask & (ALPHATEST_BIT | + BLEND_BIT | + DEPTH_BIT | + FOG_BIT | + LOGIC_OP_BIT | + SCISSOR_BIT | + STENCIL_BIT | + MASKING_BIT | + ALPHABUF_BIT | MULTI_DRAW_BIT)) return GL_FALSE; + + if (ctx->Scissor.Enabled) { + /* This is a bit tricky, but by carefully adjusting the px, py, + * width, height, skipPixels and skipRows values we can do + * scissoring without special code in the rendering loop. + */ + + /* we'll construct a new pixelstore struct */ + finalUnpack = &scissoredUnpack; + scissoredUnpack = *unpack; + if (scissoredUnpack.RowLength == 0) + scissoredUnpack.RowLength = width; + + /* clip left */ + if (px < ctx->Scissor.X) { + scissoredUnpack.SkipPixels += (ctx->Scissor.X - px); + width -= (ctx->Scissor.X - px); + px = ctx->Scissor.X; + } + /* clip right */ + if (px + width >= ctx->Scissor.X + ctx->Scissor.Width) { + width -= (px + width - (ctx->Scissor.X + ctx->Scissor.Width)); + } + /* clip bottom */ + if (py < ctx->Scissor.Y) { + scissoredUnpack.SkipRows += (ctx->Scissor.Y - py); + height -= (ctx->Scissor.Y - py); + py = ctx->Scissor.Y; + } + /* clip top */ + if (py + height >= ctx->Scissor.Y + ctx->Scissor.Height) { + height -= (py + height - (ctx->Scissor.Y + ctx->Scissor.Height)); + } + + if (width <= 0 || height <= 0) + return GL_TRUE; /* totally scissored away */ + } + else { + finalUnpack = unpack; + } + + /* compute pixel value */ + { + GLint r = (GLint) (ctx->Current.RasterColor[0] * 255.0f); + GLint g = (GLint) (ctx->Current.RasterColor[1] * 255.0f); + GLint b = (GLint) (ctx->Current.RasterColor[2] * 255.0f); + GLint a = (GLint) (ctx->Current.RasterColor[3] * 255.0f); + color = PACK_BGRA32(r, g, b, a); + } + + info.size = sizeof(info); + if (!FX_grLfbLock(fxMesa, GR_LFB_WRITE_ONLY, + fxMesa->currentFB, GR_LFBWRITEMODE_8888, + GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) { +#ifndef FX_SILENT + fprintf(stderr, "fx Driver: error locking the linear frame buffer\n"); +#endif + return GL_TRUE; + } + +#ifdef XF86DRI +#define INSIDE(c, x, y) inClipRects((c), (x), (y)) +#else +#define INSIDE(c, x, y) (1) +#endif + + { + const GLint winX = fxMesa->x_offset; + const GLint winY = fxMesa->y_offset + fxMesa->height - 1; + GLint dstStride; + GLuint *dst; + GLint row; + + if (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) { + dstStride = fxMesa->screen_width; + dst = + (GLuint *) info.lfbPtr + (winY - py) * dstStride + (winX + + px); + } + else { + dstStride = info.strideInBytes / 4; + dst = + (GLuint *) info.lfbPtr + (winY - py) * dstStride + (winX + + px); + } + + /* compute dest address of bottom-left pixel in bitmap */ + for (row = 0; row < height; row++) { + const GLubyte *src = + (const GLubyte *) _mesa_image_address(finalUnpack, + bitmap, width, height, + GL_COLOR_INDEX, + GL_BITMAP, 0, row, 0); + if (finalUnpack->LsbFirst) { + /* least significan bit first */ + GLubyte mask = 1U << (finalUnpack->SkipPixels & 0x7); + GLint col; + for (col = 0; col < width; col++) { + if (*src & mask) { + if (INSIDE(fxMesa, winX + px + col, winY - py - row)) + dst[col] = color; + } + if (mask == 128U) { + src++; + mask = 1U; + } + else { + mask = mask << 1; + } + } + if (mask != 1) + src++; + } + else { + /* most significan bit first */ + GLubyte mask = 128U >> (finalUnpack->SkipPixels & 0x7); + GLint col; + for (col = 0; col < width; col++) { + if (*src & mask) { + if (INSIDE(fxMesa, winX + px + col, winY - py - row)) + dst[col] = color; + } + if (mask == 1U) { + src++; + mask = 128U; + } + else { + mask = mask >> 1; + } + } + if (mask != 128) + src++; + } + dst -= dstStride; + } + } + +#undef INSIDE + + FX_grLfbUnlock(fxMesa, GR_LFB_WRITE_ONLY, fxMesa->currentFB); + return GL_TRUE; +} + + +static GLboolean +readpixels_R5G6B5(GLcontext * ctx, GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *packing, + GLvoid * dstImage) +{ + if (ctx->Pixel.ScaleOrBiasRGBA || ctx->Pixel.MapColorFlag) { + return GL_FALSE; /* can't do this */ + } + else { + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + GrLfbInfo_t info; + GLboolean result = GL_FALSE; + + BEGIN_BOARD_LOCK(fxMesa); + info.size = sizeof(info); + if (grLfbLock(GR_LFB_READ_ONLY, + fxMesa->currentFB, + GR_LFBWRITEMODE_ANY, + GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) { + const GLint winX = fxMesa->x_offset; + const GLint winY = fxMesa->y_offset + fxMesa->height - 1; +#ifdef XF86DRI + const GLint srcStride = + (fxMesa->glCtx->Color.DrawBuffer == + GL_FRONT) ? (fxMesa->screen_width) : (info.strideInBytes / + 2); +#else + const GLint srcStride = info.strideInBytes / 2; /* stride in GLushorts */ +#endif + const GLushort *src = (const GLushort *) info.lfbPtr + + (winY - y) * srcStride + (winX + x); + GLubyte *dst = (GLubyte *) _mesa_image_address(packing, dstImage, + width, height, + format, type, 0, 0, + 0); + GLint dstStride = + _mesa_image_row_stride(packing, width, format, type); + + if (format == GL_RGB && type == GL_UNSIGNED_BYTE) { + /* convert 5R6G5B into 8R8G8B */ + GLint row, col; + const GLint halfWidth = width >> 1; + const GLint extraPixel = (width & 1); + for (row = 0; row < height; row++) { + GLubyte *d = dst; + for (col = 0; col < halfWidth; col++) { + const GLuint pixel = ((const GLuint *) src)[col]; + const GLint pixel0 = pixel & 0xffff; + const GLint pixel1 = pixel >> 16; + *d++ = FX_PixelToR(fxMesa, pixel0); + *d++ = FX_PixelToG(fxMesa, pixel0); + *d++ = FX_PixelToB(fxMesa, pixel0); + *d++ = FX_PixelToR(fxMesa, pixel1); + *d++ = FX_PixelToG(fxMesa, pixel1); + *d++ = FX_PixelToB(fxMesa, pixel1); + } + if (extraPixel) { + GLushort pixel = src[width - 1]; + *d++ = FX_PixelToR(fxMesa, pixel); + *d++ = FX_PixelToG(fxMesa, pixel); + *d++ = FX_PixelToB(fxMesa, pixel); + } + dst += dstStride; + src -= srcStride; + } + result = GL_TRUE; + } + else if (format == GL_RGBA && type == GL_UNSIGNED_BYTE) { + /* convert 5R6G5B into 8R8G8B8A */ + GLint row, col; + const GLint halfWidth = width >> 1; + const GLint extraPixel = (width & 1); + for (row = 0; row < height; row++) { + GLubyte *d = dst; + for (col = 0; col < halfWidth; col++) { + const GLuint pixel = ((const GLuint *) src)[col]; + const GLint pixel0 = pixel & 0xffff; + const GLint pixel1 = pixel >> 16; + *d++ = FX_PixelToR(fxMesa, pixel0); + *d++ = FX_PixelToG(fxMesa, pixel0); + *d++ = FX_PixelToB(fxMesa, pixel0); + *d++ = 255; + *d++ = FX_PixelToR(fxMesa, pixel1); + *d++ = FX_PixelToG(fxMesa, pixel1); + *d++ = FX_PixelToB(fxMesa, pixel1); + *d++ = 255; + } + if (extraPixel) { + const GLushort pixel = src[width - 1]; + *d++ = FX_PixelToR(fxMesa, pixel); + *d++ = FX_PixelToG(fxMesa, pixel); + *d++ = FX_PixelToB(fxMesa, pixel); + *d++ = 255; + } + dst += dstStride; + src -= srcStride; + } + result = GL_TRUE; + } + else if (format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5) { + /* directly memcpy 5R6G5B pixels into client's buffer */ + const GLint widthInBytes = width * 2; + GLint row; + for (row = 0; row < height; row++) { + MEMCPY(dst, src, widthInBytes); + dst += dstStride; + src -= srcStride; + } + result = GL_TRUE; + } + else { + result = GL_FALSE; + } + + grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB); + } + END_BOARD_LOCK(fxMesa); + return result; + } +} + + + +static GLboolean +readpixels_R8G8B8A8(GLcontext * ctx, GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *packing, + GLvoid * dstImage) +{ + if (!(format == GL_BGRA && type == GL_UNSIGNED_INT_8_8_8_8) + && !(format == GL_BGRA && type == GL_UNSIGNED_BYTE) + && !(format == GL_RGBA && type == GL_UNSIGNED_BYTE)) { + return GL_FALSE; /* format/type not optimised */ + } + + if (ctx->Pixel.ScaleOrBiasRGBA || ctx->Pixel.MapColorFlag) { + return GL_FALSE; /* can't do this */ + } + + { + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + GrLfbInfo_t info; + GLboolean result = GL_FALSE; + + const GLint winX = fxMesa->x_offset; + const GLint winY = fxMesa->y_offset + fxMesa->height - 1; + const GLint scrX = winX + x; + const GLint scrY = winY - y; + + BEGIN_BOARD_LOCK(fxMesa); + info.size = sizeof(info); + if (grLfbLock(GR_LFB_READ_ONLY, + fxMesa->currentFB, + GR_LFBWRITEMODE_ANY, + GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) { +#ifdef XF86DRI + const GLint srcStride = (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) + ? (fxMesa->screen_width) : (info.strideInBytes / 4); +#else + const GLint srcStride = info.strideInBytes / 4; /* stride in GLuints */ +#endif + const GLuint *src = (const GLuint *) info.lfbPtr + + scrY * srcStride + scrX; + const GLint dstStride = + _mesa_image_row_stride(packing, width, format, type); + const GLubyte *dst = (GLubyte *) _mesa_image_address(packing, + dstImage, width, height, format, type, 0, 0, 0); + + if ((format == GL_BGRA && type == GL_UNSIGNED_INT_8_8_8_8) + || (format == GL_BGRA && type == GL_UNSIGNED_BYTE)) { + const GLint widthInBytes = width * 4; + GLint row; + for (row = 0; row < height; row++) { + MEMCPY(dst, src, widthInBytes); + dst += dstStride; + src -= srcStride; + } + result = GL_TRUE; + } else + if (format == GL_RGBA && type == GL_UNSIGNED_BYTE) { + const GLint widthInBytes = width * 4; + GLuint *dstp = (GLuint *)dst; + GLint row; + GLint i; + for (row = 0; row < height; row++) { + MEMCPY(dst, src, widthInBytes); + dst += dstStride; + src -= srcStride; + /* Data is in memory in BGRA format - we need to convert now */ + for (i = 0; i < width; i++) { + const GLuint data = *dstp; + /* Swap R & B values */ + *dstp++ = ((data & 0xff) << 16) | + ((data & 0xff0000) >> 16) | + (data & 0xff00ff00); + } + } + result = GL_TRUE; + } + + grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB); + } + END_BOARD_LOCK(fxMesa); + return result; + } +} + + + +static GLboolean +drawpixels_R8G8B8A8(GLcontext * ctx, GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *unpack, + const GLvoid * pixels) +{ + if (!(format == GL_BGRA && type == GL_UNSIGNED_INT_8_8_8_8) + && !(format == GL_BGRA && type == GL_UNSIGNED_BYTE)) { + return GL_FALSE; /* format/type not optimised */ + } + + if (ctx->Pixel.ZoomX!=1.0F || ctx->Pixel.ZoomY!=1.0F) { + return GL_FALSE; /* can't scale pixels */ + } + + if (ctx->Pixel.ScaleOrBiasRGBA || ctx->Pixel.MapColorFlag) { + return GL_FALSE; /* can't do this */ + } + + if (ctx->RasterMask) { + return GL_FALSE; /* can't do any raster ops */ + } + + { + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + GrLfbInfo_t info; + GLboolean result = GL_FALSE; + + const GLint winX = fxMesa->x_offset; + const GLint winY = fxMesa->y_offset + fxMesa->height - 1; + const GLint scrX = winX + x; + const GLint scrY = winY - y; + + /* look for clipmasks, giveup if region obscured */ + if (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) { + int i; + for (i = 0; i < fxMesa->numClipRects; i++) { + const XF86DRIClipRectPtr rect = &fxMesa->pClipRects[i]; + + if (scrY < rect->y1 || scrY+height > rect->y2) { + if (scrX < rect->x1 || scrX+width > rect->x2) { + return GL_FALSE; /* dst is obscured */ + } + } + } + } + + BEGIN_BOARD_LOCK(fxMesa); + info.size = sizeof(info); + if (grLfbLock(GR_LFB_WRITE_ONLY, + fxMesa->currentFB, + GR_LFBWRITEMODE_8888, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) { +#ifdef XF86DRI + const GLint dstStride = (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) + ? (fxMesa->screen_width * 4) : (info.strideInBytes); +#else + const GLint dstStride = info.strideInBytes; +#endif + const GLubyte *dst = (const GLubyte *) info.lfbPtr + + scrY * dstStride + scrX * 4; + const GLint srcStride = + _mesa_image_row_stride(unpack, width, format, type); + const GLubyte *src = (GLubyte *) _mesa_image_address(unpack, + pixels, width, height, format, type, 0, 0, 0); + + if ((format == GL_BGRA && type == GL_UNSIGNED_INT_8_8_8_8) + || (format == GL_BGRA && type == GL_UNSIGNED_BYTE)) { + const GLint widthInBytes = width * 4; + GLint row; + for (row = 0; row < height; row++) { + MEMCPY(dst, src, widthInBytes); + dst -= dstStride; + src += srcStride; + } + result = GL_TRUE; + } + + grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->currentFB); + } + END_BOARD_LOCK(fxMesa); + return result; + } +} + + +static GLboolean +drawpixels_R8G8B8A8_v2(GLcontext * ctx, GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *unpack, + const GLvoid * pixels) +{ + if (!(format == GL_BGRA && type == GL_UNSIGNED_INT_8_8_8_8) + && !(format == GL_BGRA && type == GL_UNSIGNED_BYTE)) { + return GL_FALSE; /* format/type not optimised */ + } + + if (ctx->Pixel.ZoomX!=1.0F || ctx->Pixel.ZoomY!=1.0F) { + return GL_FALSE; /* can't scale pixels */ + } + + if (ctx->Pixel.ScaleOrBiasRGBA || ctx->Pixel.MapColorFlag) { + return GL_FALSE; /* can't do this */ + } + + if (ctx->RasterMask & (~BLEND_BIT)) { + return GL_FALSE; /* can't do any raster ops, except blend */ + } + + { + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + GrLfbInfo_t info; + GLboolean result = GL_FALSE; + + const GLint winX = fxMesa->x_offset; + const GLint winY = fxMesa->y_offset + fxMesa->height - 1; + const GLint scrX = winX + x; + const GLint scrY = winY - y; + + /* look for clipmasks, giveup if region obscured */ + if (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) { + int i; + for (i = 0; i < fxMesa->numClipRects; i++) { + const XF86DRIClipRectPtr rect = &fxMesa->pClipRects[i]; + + if (scrY < rect->y1 || scrY+height > rect->y2) { + if (scrX < rect->x1 || scrX+width > rect->x2) { + return GL_FALSE; /* dst is obscured */ + } + } + } + } + + BEGIN_BOARD_LOCK(fxMesa); + info.size = sizeof(info); + if (grLfbLock(GR_LFB_WRITE_ONLY, + fxMesa->currentFB, + GR_LFBWRITEMODE_8888, GR_ORIGIN_UPPER_LEFT, FXTRUE, &info)) { +#ifdef XF86DRI + const GLint dstStride = (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) + ? (fxMesa->screen_width * 4) : (info.strideInBytes); +#else + const GLint dstStride = info.strideInBytes; +#endif + const GLubyte *dst = (const GLubyte *) info.lfbPtr + + scrY * dstStride + scrX * 4; + const GLint srcStride = + _mesa_image_row_stride(unpack, width, format, type); + const GLubyte *src = (GLubyte *) _mesa_image_address(unpack, + pixels, width, height, format, type, 0, 0, 0); + + void *grState = NULL; + GLint grSize; + + if (grGet(GR_GLIDE_STATE_SIZE, sizeof(grSize), (void *) &grSize)) { + if ((grState = malloc(grSize)) != 0) { + grGlideGetState(grState); + } + } + + if (ctx->RasterMask & BLEND_BIT) { + grDisableAllEffects(); + grAlphaBlendFunction(GR_BLEND_SRC_ALPHA, + GR_BLEND_ONE_MINUS_SRC_ALPHA, + GR_BLEND_ONE, + GR_BLEND_ZERO); + grAlphaCombine(GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_OTHER_ALPHA, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_ITERATED, + FXFALSE); + grColorCombine(GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_OTHER_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_ITERATED, + FXFALSE); + } + + if ((format == GL_BGRA && type == GL_UNSIGNED_INT_8_8_8_8) + || (format == GL_BGRA && type == GL_UNSIGNED_BYTE)) { + const GLint widthInBytes = width * 4; + GLint row; + for (row = 0; row < height; row++) { + MEMCPY(dst, src, widthInBytes); + dst -= dstStride; + src += srcStride; + } + result = GL_TRUE; + } + + if (grState) { + grGlideSetState(grState); + free(grState); + } + + grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->currentFB); + } + END_BOARD_LOCK(fxMesa); + return result; + } +} + + +static void +fxDDFinish(GLcontext *ctx) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + FX_grFinish(fxMesa); +} + + +static void +fxDDFlush(GLcontext *ctx) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + FX_grFlush(fxMesa); +} + + +static GLint +fxDDGetParameteri(const GLcontext * ctx, GLint param) +{ + switch (param) { + case DD_HAVE_HARDWARE_FOG: + return 1; + default: + fprintf(stderr, + "fx Driver: internal error in fxDDGetParameteri(): %x\n", + (int) param); + return 0; + } +} + + +static void +fxDDSetNearFar(GLcontext * ctx, GLfloat n, GLfloat f) +{ + FX_CONTEXT(ctx)->new_state |= FX_NEW_FOG; + ctx->Driver.RenderStart = fxSetupFXUnits; +} + + +/* KW: Put the word Mesa in the render string because quakeworld + * checks for this rather than doing a glGet(GL_MAX_TEXTURE_SIZE). + * Why? + */ +static const GLubyte * +fxDDGetString(GLcontext * ctx, GLenum name) +{ + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + + switch (name) { + case GL_RENDERER: + { + static char buffer[100]; + char hardware[100]; + strcpy(hardware, FX_grGetString(fxMesa, GR_HARDWARE)); + if (strcmp(hardware, "Voodoo3 (tm)") == 0) + strcpy(hardware, "Voodoo3"); + else if (strcmp(hardware, "Voodoo Banshee (tm)") == 0) + strcpy(hardware, "VoodooBanshee"); + else { + /* 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 */ + sprintf(buffer, "Mesa DRI %s 20000821", hardware); + return buffer; + } + case GL_VENDOR: + return "VA Linux Systems, Inc."; + default: + return NULL; + } +} + + +#if 0 +/* Example extension function */ +static void +fxFooBarEXT(GLint i) +{ + printf("You called glFooBarEXT(%d)\n", i); +} +#endif + + + +/* + * Enable/Disable the extensions for this context. + */ +static void +fxDDInitExtensions(GLcontext * ctx) +{ + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + + gl_extensions_disable(ctx, "GL_EXT_blend_logic_op"); + gl_extensions_disable(ctx, "GL_EXT_blend_minmax"); + gl_extensions_disable(ctx, "GL_EXT_blend_subtract"); + gl_extensions_disable(ctx, "GL_EXT_blend_color"); + gl_extensions_disable(ctx, "GL_EXT_blend_func_separate"); + gl_extensions_disable(ctx, "GL_INGR_blend_func_separate"); + gl_extensions_enable(ctx, "GL_HP_occlusion_test"); + + if (!fxMesa->haveTwoTMUs) + gl_extensions_disable(ctx, "GL_EXT_texture_env_add"); + + if (!fxMesa->emulateTwoTMUs) + gl_extensions_disable(ctx, "GL_ARB_multitexture"); + + if (fxMesa->isNapalm) { + gl_extensions_enable(ctx, "GL_ARB_texture_compression"); + gl_extensions_enable(ctx, "GL_3DFX_texture_compression_FXT1"); + } + + /* Example of hooking in an extension function. + * For DRI-based drivers, also see __driRegisterExtensions in the + * tdfx_xmesa.c file. + */ +#if 0 + { + void **dispatchTable = (void **) ctx->Exec; + const int _gloffset_FooBarEXT = 555; /* just an example number! */ + const int tabSize = _glapi_get_dispatch_table_size(); + assert(_gloffset_FooBarEXT < tabSize); + dispatchTable[_gloffset_FooBarEXT] = (void *) fxFooBarEXT; + /* XXX You would also need to hook into the display list dispatch + * table. Really, the implementation of extensions might as well + * be in the core of Mesa since core Mesa and the device driver + * is one big shared lib. + */ + } +#endif +} + + + +/* + * Initialize the state in an fxMesaContext struct. + */ +int +fxDDInitFxMesaContext(fxMesaContext fxMesa) +{ + /* Get Glide3 extension function pointers */ + { + void *handle = dlopen(NULL, RTLD_NOW | RTLD_GLOBAL); + if (!handle) { + txImgQuantizePtr = 0; + txImgDequantizeFXT1Ptr = 0; + txErrorSetCallbackPtr = 0; + return 0; + } + else { + /* + * These are not exported by Glide. + */ + txImgQuantizePtr = dlsym(handle, "txImgQuantize"); + txImgDequantizeFXT1Ptr = dlsym(handle, "_txImgDequantizeFXT1"); + txErrorSetCallbackPtr = dlsym(handle, "txErrorSetCallback"); + grStencilFuncPtr = dlsym(handle, "grStencilFunc"); + grStencilMaskPtr = dlsym(handle, "grStencilMask"); + grStencilOpPtr = dlsym(handle, "grStencilOp"); + grBufferClearExtPtr = dlsym(handle, "grBufferClearExt"); + grColorMaskExtPtr = dlsym(handle, "grColorMaskExt"); + } + dlclose(handle); + } + + FX_setupGrVertexLayout(fxMesa); + + if (getenv("FX_EMULATE_SINGLE_TMU")) + fxMesa->haveTwoTMUs = GL_FALSE; + + fxMesa->emulateTwoTMUs = fxMesa->haveTwoTMUs; + + if (!getenv("FX_DONT_FAKE_MULTITEX")) + fxMesa->emulateTwoTMUs = GL_TRUE; + + if (getenv("FX_GLIDE_SWAPINTERVAL")) + fxMesa->swapInterval = atoi(getenv("FX_GLIDE_SWAPINTERVAL")); + else + fxMesa->swapInterval = 1; + + if (getenv("MESA_FX_SWAP_PENDING")) + fxMesa->maxPendingSwapBuffers = atoi(getenv("MESA_FX_SWAP_PENDING")); + else + fxMesa->maxPendingSwapBuffers = 2; + + if (getenv("MESA_FX_INFO")) + fxMesa->verbose = GL_TRUE; + else + fxMesa->verbose = GL_FALSE; + +#if 0 + printf("haveTwoTMUs=%d emulateTwoTMUs=%d\n", + fxMesa->haveTwoTMUs, fxMesa->emulateTwoTMUs); +#endif + + fxMesa->depthClear = FX_grGetInteger(fxMesa, FX_ZDEPTH_MAX); + + fxMesa->color = 0xffffffff; + fxMesa->clearC = 0; + fxMesa->clearA = 0; + + fxMesa->stats.swapBuffer = 0; + fxMesa->stats.reqTexUpload = 0; + fxMesa->stats.texUpload = 0; + fxMesa->stats.memTexUpload = 0; + + fxMesa->tmuSrc = FX_TMU_NONE; + fxTMInit(fxMesa); + + /* FX units setup */ + fxMesa->unitsState.alphaTestEnabled = GL_FALSE; + fxMesa->unitsState.alphaTestFunc = GR_CMP_ALWAYS; + fxMesa->unitsState.alphaTestRefValue = 0; + + fxMesa->unitsState.blendEnabled = GL_FALSE; + fxMesa->unitsState.blendSrcFuncRGB = GR_BLEND_ONE; + fxMesa->unitsState.blendDstFuncRGB = GR_BLEND_ZERO; + fxMesa->unitsState.blendSrcFuncAlpha = GR_BLEND_ONE; + fxMesa->unitsState.blendDstFuncAlpha = GR_BLEND_ZERO; + + /* + fxMesa->unitsState.depthTestEnabled = GL_FALSE; + fxMesa->unitsState.depthMask = GL_TRUE; + fxMesa->unitsState.depthTestFunc = GR_CMP_LESS; + */ + + FX_grColorMaskv(fxMesa->glCtx, true4); + if (fxMesa->glVis->DBflag) { + fxMesa->currentFB = GR_BUFFER_BACKBUFFER; + FX_grRenderBuffer(fxMesa, GR_BUFFER_BACKBUFFER); + } + else { + fxMesa->currentFB = GR_BUFFER_FRONTBUFFER; + FX_grRenderBuffer(fxMesa, GR_BUFFER_FRONTBUFFER); + } + + fxMesa->state = NULL; + fxMesa->fogTable = NULL; + + fxMesa->state = malloc(FX_grGetInteger(fxMesa, FX_GLIDE_STATE_SIZE)); + fxMesa->fogTable = + malloc(FX_grGetInteger(fxMesa, FX_FOG_TABLE_ENTRIES) * sizeof(GrFog_t)); + + if (!fxMesa->state || !fxMesa->fogTable) { + if (fxMesa->state) + free(fxMesa->state); + if (fxMesa->fogTable) + free(fxMesa->fogTable); + return 0; + } + + if (fxMesa->glVis->DepthBits > 0) + FX_grDepthBufferMode(fxMesa, GR_DEPTHBUFFER_ZBUFFER); + + FX_grLfbWriteColorFormat(fxMesa, GR_COLORFORMAT_ABGR); + + fxMesa->textureAlign = FX_grGetInteger(fxMesa, FX_TEXTURE_ALIGN); + if (fxMesa->isNapalm) { + fxMesa->glCtx->Const.MaxTextureLevels = 12; + fxMesa->glCtx->Const.MaxTextureSize = 2048; + fxMesa->glCtx->Const.NumCompressedTextureFormats = 1; + } + else { + fxMesa->glCtx->Const.MaxTextureLevels = 9; + fxMesa->glCtx->Const.MaxTextureSize = 256; + fxMesa->glCtx->Const.NumCompressedTextureFormats = 0; + } + fxMesa->glCtx->Const.MaxTextureUnits = fxMesa->emulateTwoTMUs ? 2 : 1; + fxMesa->glCtx->NewState |= NEW_DRVSTATE1; + fxMesa->new_state = NEW_ALL; + + fxDDSetupInit(); + fxDDCvaInit(); + fxDDClipInit(); + fxDDTrifuncInit(); + fxDDFastPathInit(); + + fxSetupDDPointers(fxMesa->glCtx); + fxDDRenderInit(fxMesa->glCtx); + fxDDInitExtensions(fxMesa->glCtx); + + fxDDSetNearFar(fxMesa->glCtx, 1.0, 100.0); + + FX_grGlideGetState(fxMesa, (GrState *) fxMesa->state); + + /* XXX Fix me: callback not registered when main VB is created. + */ + if (fxMesa->glCtx->VB) + fxDDRegisterVB(fxMesa->glCtx->VB); + + /* XXX Fix me too: need to have the 'struct dd' prepared prior to + * creating the context... The below is broken if you try to insert + * new stages. + */ + if (fxMesa->glCtx->NrPipelineStages) + fxMesa->glCtx->NrPipelineStages = + fxDDRegisterPipelineStages(fxMesa->glCtx->PipelineStage, + fxMesa->glCtx->PipelineStage, + fxMesa->glCtx->NrPipelineStages); + + /* this little bit ensures that all Glide state gets initialized */ + fxMesa->new_state = NEW_ALL; + fxMesa->glCtx->Driver.RenderStart = fxSetupFXUnits; + + fxInitPixelTables(fxMesa, GL_FALSE); /* Load tables of pixel colors */ + + /* Run the config file */ + gl_context_initialize(fxMesa->glCtx); + + return 1; +} + + +/************************************************************************/ +/************************************************************************/ +/************************************************************************/ + +/* Check if the hardware supports the current context + * + * Performs similar work to fxDDChooseRenderState() - should be merged. + */ +static GLboolean +fxIsInHardware(GLcontext * ctx) +{ + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + + if (!ctx->Hint.AllowDrawMem) + return GL_TRUE; /* you'll take it and like it */ + + if ( + ((ctx->Color.BlendEnabled) + && (ctx->Color.BlendEquation != GL_FUNC_ADD_EXT)) + || ((ctx->Color.ColorLogicOpEnabled) + && (ctx->Color.LogicOp != GL_COPY)) + || (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) + || + (!((ctx->Color.ColorMask[RCOMP] == ctx->Color.ColorMask[GCOMP]) + && (ctx->Color.ColorMask[GCOMP] == ctx->Color.ColorMask[BCOMP]) + && (ctx->Color.ColorMask[ACOMP] == ctx->Color.ColorMask[ACOMP]))) + ) { + return GL_FALSE; + } + /* Unsupported texture/multitexture cases */ + + if (fxMesa->emulateTwoTMUs) { + if ((ctx->Enabled & (TEXTURE0_3D | TEXTURE1_3D)) || + /* Not very well written ... */ + ((ctx->Enabled & (TEXTURE0_1D | TEXTURE1_1D)) && + ((ctx->Enabled & (TEXTURE0_2D | TEXTURE1_2D)) != + (TEXTURE0_2D | TEXTURE1_2D)))) { + return GL_FALSE; + } + + if (ctx->Texture.ReallyEnabled & TEXTURE0_2D) { +#if 0 + if (ctx->Texture.Unit[0].EnvMode == GL_BLEND) { + return GL_FALSE; + } +#endif + if (ctx->Texture.Unit[0].EnvMode == GL_BLEND && + (ctx->Texture.ReallyEnabled & TEXTURE1_2D || + ctx->Texture.Unit[0].EnvColor[0] != 0 || + ctx->Texture.Unit[0].EnvColor[1] != 0 || + ctx->Texture.Unit[0].EnvColor[2] != 0 || + ctx->Texture.Unit[0].EnvColor[3] != 1)) { + return GL_FALSE; + } + if (ctx->Texture.Unit[0].Current->Image[0]->Border > 0) + return GL_FALSE; + } + + if (ctx->Texture.ReallyEnabled & TEXTURE1_2D) { + if (ctx->Texture.Unit[1].EnvMode == GL_BLEND) + return GL_FALSE; + if (ctx->Texture.Unit[0].Current->Image[0]->Border > 0) + return GL_FALSE; + } + + if (MESA_VERBOSE & (VERBOSE_DRIVER | VERBOSE_TEXTURE)) + fprintf(stderr, "fxMesa: fxIsInHardware, envmode is %s/%s\n", + gl_lookup_enum_by_nr(ctx->Texture.Unit[0].EnvMode), + gl_lookup_enum_by_nr(ctx->Texture.Unit[1].EnvMode)); + + /* KW: This was wrong (I think) and I changed it... which doesn't mean + * it is now correct... + */ + if ((ctx->Enabled & (TEXTURE0_1D | TEXTURE0_2D | TEXTURE0_3D)) && + (ctx->Enabled & (TEXTURE1_1D | TEXTURE1_2D | TEXTURE1_3D))) { + /* Can't use multipass to blend a multitextured triangle - fall + * back to software. + */ + if (!fxMesa->haveTwoTMUs && ctx->Color.BlendEnabled) { + return GL_FALSE; + } + + if ((ctx->Texture.Unit[0].EnvMode != ctx->Texture.Unit[1].EnvMode) + && (ctx->Texture.Unit[0].EnvMode != GL_MODULATE) + && (ctx->Texture.Unit[0].EnvMode != GL_REPLACE)) { /* q2, seems ok... */ + if (MESA_VERBOSE & VERBOSE_DRIVER) + fprintf(stderr, + "fxMesa: unsupported multitex env mode\n"); + return GL_FALSE; + } + } + } + else { + if ((ctx->Enabled & (TEXTURE1_1D | TEXTURE1_2D | TEXTURE1_3D)) || + /* Not very well written ... */ + ((ctx->Enabled & TEXTURE0_1D) && (!(ctx->Enabled & TEXTURE0_2D))) + ) { + return GL_FALSE; + } + + + if ((ctx->Texture.ReallyEnabled & TEXTURE0_2D) && + (ctx->Texture.Unit[0].EnvMode == GL_BLEND)) { + return GL_FALSE; + } + } + + if (ctx->Stencil.Enabled && !fxMesa->haveHwStencil) + return GL_FALSE; + + return GL_TRUE; +} + + + +#define INTERESTED (~(NEW_MODELVIEW|NEW_PROJECTION|NEW_PROJECTION|NEW_TEXTURE_MATRIX|NEW_USER_CLIP|NEW_CLIENT_STATE|NEW_TEXTURE_ENABLE)) + +static void +fxDDUpdateDDPointers(GLcontext * ctx) +{ + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + GLuint new_state = ctx->NewState; + + if (MESA_VERBOSE & (VERBOSE_DRIVER | VERBOSE_STATE)) + fprintf(stderr, "fxmesa: fxDDUpdateDDPointers(...)\n"); + + if (new_state & (NEW_RASTER_OPS | NEW_TEXTURING)) + fxMesa->is_in_hardware = fxIsInHardware(ctx); + + if (fxMesa->is_in_hardware) { + if (fxMesa->new_state) + fxSetupFXUnits(ctx); + + if (new_state & INTERESTED) { + fxDDChooseRenderState(ctx); + fxMesa->RenderVBTables = fxDDChooseRenderVBTables(ctx); + fxMesa->RenderVBClippedTab = fxMesa->RenderVBTables[0]; + fxMesa->RenderVBCulledTab = fxMesa->RenderVBTables[1]; + fxMesa->RenderVBRawTab = fxMesa->RenderVBTables[2]; + + ctx->Driver.RasterSetup = fxDDChooseSetupFunction(ctx); + } + + ctx->Driver.PointsFunc = fxMesa->PointsFunc; + ctx->Driver.LineFunc = fxMesa->LineFunc; + ctx->Driver.TriangleFunc = fxMesa->TriangleFunc; + ctx->Driver.QuadFunc = fxMesa->QuadFunc; + } + else { + fxMesa->render_index = FX_FALLBACK; + } +} + +static void +fxDDReducedPrimitiveChange(GLcontext * ctx, GLenum prim) +{ + if (ctx->Polygon.CullFlag) { + if (ctx->PB->primitive != GL_POLYGON) { /* Lines or Points */ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + FX_grCullMode(fxMesa, GR_CULL_DISABLE); + fxMesa->cullMode = GR_CULL_DISABLE; + } + } +} + + +void +fxSetupDDPointers(GLcontext * ctx) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: fxSetupDDPointers()\n"); + } + ctx->Driver.UpdateState = fxDDUpdateDDPointers; + ctx->Driver.ClearIndex = NULL; + ctx->Driver.ClearColor = fxDDClearColor; + ctx->Driver.Clear = fxDDClear; + ctx->Driver.Index = NULL; + ctx->Driver.Color = fxDDSetColor; + ctx->Driver.SetDrawBuffer = fxDDSetDrawBuffer; + ctx->Driver.SetReadBuffer = fxDDSetReadBuffer; + ctx->Driver.GetBufferSize = fxDDBufferSize; + ctx->Driver.Finish = fxDDFinish; + ctx->Driver.Flush = fxDDFlush; + ctx->Driver.GetString = fxDDGetString; + ctx->Driver.NearFar = fxDDSetNearFar; + ctx->Driver.GetParameteri = fxDDGetParameteri; + ctx->Driver.GetBooleanv = fxDDGetBooleanv; + ctx->Driver.GetFloatv = fxDDGetFloatv; + ctx->Driver.GetDoublev = fxDDGetDoublev; + ctx->Driver.GetIntegerv = fxDDGetIntegerv; + + if (ctx->Visual->RedBits == 8 && + ctx->Visual->GreenBits == 8 && + ctx->Visual->BlueBits == 8 && + ctx->Visual->AlphaBits == 8) { + ctx->Driver.Bitmap = bitmap_R8G8B8A8; + ctx->Driver.DrawPixels = drawpixels_R8G8B8A8; + ctx->Driver.ReadPixels = readpixels_R8G8B8A8; + } + else if (ctx->Visual->RedBits == 5 && + ctx->Visual->GreenBits == 6 && + ctx->Visual->BlueBits == 5 && + ctx->Visual->AlphaBits == 0) { + ctx->Driver.Bitmap = bitmap_R5G6B5; + ctx->Driver.DrawPixels = NULL; + ctx->Driver.ReadPixels = readpixels_R5G6B5; + } + else { + ctx->Driver.Bitmap = NULL; + ctx->Driver.DrawPixels = NULL; + ctx->Driver.ReadPixels = NULL; + } + + ctx->Driver.RenderStart = NULL; + ctx->Driver.RenderFinish = NULL; + + ctx->Driver.TexImage2D = fxDDTexImage2D; + ctx->Driver.TexSubImage2D = fxDDTexSubImage2D; + ctx->Driver.GetTexImage = fxDDGetTexImage; + ctx->Driver.CompressedTexImage2D = fxDDCompressedTexImage2D; + ctx->Driver.CompressedTexSubImage2D = fxDDCompressedTexSubImage2D; + ctx->Driver.GetCompressedTexImage = fxDDGetCompressedTexImage; + ctx->Driver.SpecificCompressedTexFormat = fxDDSpecificCompressedTexFormat; + ctx->Driver.BaseCompressedTexFormat = fxDDBaseCompressedTexFormat; + ctx->Driver.IsCompressedFormat = fxDDIsCompressedFormat; + ctx->Driver.CompressedImageSize = fxDDCompressedImageSize; + ctx->Driver.TexEnv = fxDDTexEnv; + ctx->Driver.TexParameter = fxDDTexParam; + ctx->Driver.BindTexture = fxDDTexBind; + ctx->Driver.DeleteTexture = fxDDTexDel; + ctx->Driver.IsTextureResident = fxDDIsTextureResident; + ctx->Driver.UpdateTexturePalette = fxDDTexPalette; + + ctx->Driver.RectFunc = NULL; + + if (fxMesa->haveHwStencil) { + ctx->Driver.StencilFunc = fxDDStencilFunc; + ctx->Driver.StencilMask = fxDDStencilMask; + ctx->Driver.StencilOp = fxDDStencilOp; + } + + ctx->Driver.AlphaFunc = fxDDAlphaFunc; + ctx->Driver.BlendFunc = fxDDBlendFunc; + ctx->Driver.BlendFuncSeparate = fxDDBlendFuncSeparate; + ctx->Driver.DepthFunc = fxDDDepthFunc; + ctx->Driver.DepthMask = fxDDDepthMask; + ctx->Driver.ColorMask = fxDDColorMask; + ctx->Driver.Fogfv = fxDDFogfv; + ctx->Driver.Scissor = fxDDScissor; + ctx->Driver.FrontFace = fxDDFrontFace; + ctx->Driver.CullFace = fxDDCullFace; + ctx->Driver.ShadeModel = fxDDShadeModel; + ctx->Driver.Enable = fxDDEnable; + ctx->Driver.ReducedPrimitiveChange = fxDDReducedPrimitiveChange; + + ctx->Driver.RegisterVB = fxDDRegisterVB; + ctx->Driver.UnregisterVB = fxDDUnregisterVB; + + ctx->Driver.RegisterPipelineStages = fxDDRegisterPipelineStages; + + ctx->Driver.OptimizeImmediatePipeline = 0; /* nothing done yet */ + ctx->Driver.OptimizePrecalcPipeline = 0; + +/* if (getenv("MESA_USE_FAST") || getenv("FX_USE_FAST")) */ +/* ctx->Driver.OptimizePrecalcPipeline = fxDDOptimizePrecalcPipeline; */ + + if (!getenv("FX_NO_FAST")) + ctx->Driver.BuildPrecalcPipeline = fxDDBuildPrecalcPipeline; + + ctx->Driver.TriangleCaps = + DD_TRI_CULL | DD_TRI_OFFSET | DD_TRI_LIGHT_TWOSIDE; + + fxSetupDDSpanPointers(ctx); + + FX_CONTEXT(ctx)->render_index = 1; /* force an update */ + fxDDUpdateDDPointers(ctx); +} diff --git a/xc/lib/GL/mesa/src/drv/tdfx/fxddspan.c b/xc/lib/GL/mesa/src/drv/tdfx/fxddspan.c new file mode 100644 index 000000000..1170a3a68 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/tdfx/fxddspan.c @@ -0,0 +1,2054 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/fxddspan.c,v 1.1 2000/09/24 13:51:14 alanh Exp $ */ +/* + * Mesa 3-D graphics library + * Version: 3.3 + * + * 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. + * + * + * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the + * terms stated above. + * + * Thank you for your contribution, David! + * + * Please make note of the above copyright/license statement. If you + * contributed code or bug fixes to this code under the previous (GNU + * Library) license and object to the new license, your code will be + * removed at your request. Please see the Mesa docs/COPYRIGHT file + * for more information. + * + * Additional Mesa/3Dfx driver developers: + * Daryll Strauss <daryll@precisioninsight.com> + * Keith Whitwell <keith@precisioninsight.com> + * + * See fxapi.h for more revision/author details. + */ + + +/* fxdd.c - 3Dfx VooDoo Mesa span and pixel functions */ + + +#include "fxdrv.h" + +/* + * Examine the cliprects to generate an array of flags to indicate + * which pixels in a span are visible. Note: (x,y) is a screen + * coordinate. + */ +static void +generate_vismask(const fxMesaContext fxMesa, GLint x, GLint y, GLint n, + GLubyte vismask[]) +{ + GLboolean initialized = GL_FALSE; + GLint i, j; + + /* Ensure we clear the visual mask */ + MEMSET(vismask, 0, n); + + /* turn on flags for all visible pixels */ + for (i = 0; i < fxMesa->numClipRects; i++) { + const XF86DRIClipRectPtr rect = &fxMesa->pClipRects[i]; + + if (y >= rect->y1 && y < rect->y2) { + if (x >= rect->x1 && x + n <= rect->x2) { + /* common case, whole span inside cliprect */ + MEMSET(vismask, 1, n); + return; + } + if (x < rect->x2 && x + n >= rect->x1) { + /* some of the span is inside the rect */ + GLint start, end; + if (!initialized) { + MEMSET(vismask, 0, n); + initialized = GL_TRUE; + } + if (x < rect->x1) + start = rect->x1 - x; + else + start = 0; + if (x + n > rect->x2) + end = rect->x2 - x; + else + end = n; + assert(start >= 0); + assert(end <= n); + for (j = start; j < end; j++) + vismask[j] = 1; + } + } + } +} + +/* + * Examine cliprects and determine if the given screen pixel is visible. + */ +static GLboolean +visible_pixel(const fxMesaContext fxMesa, int scrX, int scrY) +{ + int i; + for (i = 0; i < fxMesa->numClipRects; i++) { + const XF86DRIClipRectPtr rect = &fxMesa->pClipRects[i]; + if (scrX >= rect->x1 && + scrX < rect->x2 && + scrY >= rect->y1 && scrY < rect->y2) return GL_TRUE; + } + return GL_FALSE; +} + +/* + * 16bpp span/pixel functions + */ +static void +write_R5G6B5_rgba_span(const GLcontext * ctx, GLuint n, GLint x, GLint y, + const GLubyte rgba[][4], const GLubyte mask[]) +{ + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + GrLfbInfo_t info; + + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: write_R5G6B5_rgba_span\n"); + } + BEGIN_BOARD_LOCK(fxMesa); + info.size = sizeof(info); + if (grLfbLock(GR_LFB_WRITE_ONLY, + fxMesa->currentFB, + GR_LFBWRITEMODE_565, + GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) { + const GLint winX = fxMesa->x_offset; + const GLint winY = fxMesa->y_offset + fxMesa->height - 1; + const GLint scrX = winX + x; + const GLint scrY = winY - y; + const GLint srcStride = (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) + ? (fxMesa->screen_width) : (info.strideInBytes / 2); + GLushort *data16 = (GLushort *) info.lfbPtr + scrY * srcStride + scrX; + GLuint i; + + if (mask) { + for (i = 0; i < n; i++) { + if (visible_pixel(fxMesa, scrX + i, scrY) && mask[i]) { + GLushort pixel; + if (fxMesa->bgrOrder) { + pixel = PACK_BGR16(rgba[i][0], + rgba[i][1], + rgba[i][2]); + } else { + pixel = PACK_RGB16(rgba[i][0], + rgba[i][1], + rgba[i][2]); + } + data16[i] = pixel; + } + } + } else { + for (i = 0; i < n; i++) { + if (visible_pixel(fxMesa, scrX + i, scrY)) { + GLushort pixel; + + if (fxMesa->bgrOrder) { + pixel = PACK_BGR16(rgba[i][0], + rgba[i][1], + rgba[i][2]); + } else { + pixel = PACK_RGB16(rgba[i][0], + rgba[i][1], + rgba[i][2]); + } + data16[i] = pixel; + } + } + } + grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->currentFB); + } + END_BOARD_LOCK(fxMesa); +} + + +static void +write_R5G6B5_rgb_span(const GLcontext * ctx, GLuint n, GLint x, GLint y, + const GLubyte rgb[][3], const GLubyte mask[]) +{ + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + GrLfbInfo_t info; + + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: write_R5G6B5_rgb_span\n"); + } + BEGIN_BOARD_LOCK(fxMesa); + info.size = sizeof(info); + if (grLfbLock(GR_LFB_WRITE_ONLY, + fxMesa->currentFB, + GR_LFBWRITEMODE_565, + GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) { + const GLint winX = fxMesa->x_offset; + const GLint winY = fxMesa->y_offset + fxMesa->height - 1; + const GLint scrX = winX + x; + const GLint scrY = winY - y; + const GLint srcStride = (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) + ? (fxMesa->screen_width) : (info.strideInBytes / 2); + GLushort *data16 = (GLushort *) info.lfbPtr + scrY * srcStride + scrX; + GLuint i; + + if (mask) { + for (i = 0; i < n; i++) { + if (visible_pixel(fxMesa, scrX + i, scrY) && mask[i]) { + GLushort pixel; + if (fxMesa->bgrOrder) { + pixel = PACK_BGR16(rgb[i][0], + rgb[i][1], + rgb[i][2]); + } else { + pixel = PACK_RGB16(rgb[i][0], + rgb[i][1], + rgb[i][2]); + } + data16[i] = pixel; + } + } + } else { + for (i = 0; i < n; i++) { + if (visible_pixel(fxMesa, scrX + i, scrY)) { + GLushort pixel; + if (fxMesa->bgrOrder) { + pixel = PACK_BGR16(rgb[i][0], + rgb[i][1], + rgb[i][2]); + } else { + pixel = PACK_RGB16(rgb[i][0], + rgb[i][1], + rgb[i][2]); + } + data16[i] = pixel; + } + } + } + grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->currentFB); + } + END_BOARD_LOCK(fxMesa); +} + +static void +write_R5G6B5_mono_span(const GLcontext * ctx, GLuint n, GLint x, GLint y, + const GLubyte mask[]) +{ + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + GrLfbInfo_t info; + GLubyte *constantColor = (GLubyte *)(&fxMesa->color); + GLushort pixel; + + if (fxMesa->bgrOrder) { + pixel = PACK_BGR16(constantColor[0], + constantColor[1], + constantColor[2]); + } else { + pixel = PACK_RGB16(constantColor[0], + constantColor[1], + constantColor[2]); + } + + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: write_r5g6b5_mono_span\n"); + } + BEGIN_BOARD_LOCK(fxMesa); + info.size = sizeof(info); + if (grLfbLock(GR_LFB_WRITE_ONLY, + fxMesa->currentFB, + GR_LFBWRITEMODE_565, + GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) { + const GLint winX = fxMesa->x_offset; + const GLint winY = fxMesa->y_offset + fxMesa->height - 1; + const GLint scrX = winX + x; + const GLint scrY = winY - y; + const GLint srcStride = (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) + ? (fxMesa->screen_width) : (info.strideInBytes / 2); + GLushort *data16 = (GLushort *) info.lfbPtr + + scrY * srcStride + scrX; + GLuint i; + + if (mask) { + for (i = 0; i < n; i++) { + if (visible_pixel(fxMesa, scrX + i, scrY) && mask[i]) { + data16[i] = pixel; + } + } + } else { + for (i = 0; i < n; i++) { + if (visible_pixel(fxMesa, scrX + i, scrY)) { + data16[i] = pixel; + } + } + } + grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->currentFB); + } + END_BOARD_LOCK(fxMesa); +} + +/* + * Read a span of 16-bit RGB pixels. Note, we don't worry about cliprects + * since OpenGL says obscured pixels have undefined values. + */ +static void +read_R5G6B5_span(const GLcontext * ctx, GLuint n, GLint x, GLint y, + GLubyte rgba[][4]) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GrLfbInfo_t info; + BEGIN_BOARD_LOCK(fxMesa); + info.size = sizeof(info); + if (grLfbLock(GR_LFB_READ_ONLY, + fxMesa->currentFB, + GR_LFBWRITEMODE_ANY, + GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) { + const GLint winX = fxMesa->x_offset; + const GLint winY = fxMesa->y_offset + fxMesa->height - 1; + const GLint srcStride = (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) + ? (fxMesa->screen_width) : (info.strideInBytes / 2); + const GLushort *data16 = (const GLushort *) info.lfbPtr + + (winY - y) * srcStride + (winX + x); + const GLuint *data32 = (const GLuint *) data16; + GLuint i, j; + GLuint extraPixel = (n & 1); + n -= extraPixel; + for (i = j = 0; i < n; i += 2, j++) { + GLuint pixel = data32[j]; + GLuint pixel0 = pixel & 0xffff; + GLuint pixel1 = pixel >> 16; + rgba[i][RCOMP] = FX_PixelToR(fxMesa, pixel0); + rgba[i][GCOMP] = FX_PixelToG(fxMesa, pixel0); + rgba[i][BCOMP] = FX_PixelToB(fxMesa, pixel0); + rgba[i][ACOMP] = 255; + rgba[i + 1][RCOMP] = FX_PixelToR(fxMesa, pixel1); + rgba[i + 1][GCOMP] = FX_PixelToG(fxMesa, pixel1); + rgba[i + 1][BCOMP] = FX_PixelToB(fxMesa, pixel1); + rgba[i + 1][ACOMP] = 255; + } + if (extraPixel) { + GLushort pixel = data16[n]; + rgba[n][RCOMP] = FX_PixelToR(fxMesa, pixel); + rgba[n][GCOMP] = FX_PixelToG(fxMesa, pixel); + rgba[n][BCOMP] = FX_PixelToB(fxMesa, pixel); + rgba[n][ACOMP] = 255; + } + grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB); + } + END_BOARD_LOCK(fxMesa); +} + + +static void +write_R5G6B5_pixels(const GLcontext * ctx, + GLuint n, const GLint x[], const GLint y[], + CONST GLubyte rgba[][4], const GLubyte mask[]) +{ + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + GrLfbInfo_t info; + + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: write_R5G6B5_pixels\n"); + } + BEGIN_BOARD_LOCK(fxMesa); + info.size = sizeof(info); + if (grLfbLock(GR_LFB_WRITE_ONLY, + fxMesa->currentFB, + GR_LFBWRITEMODE_565, + GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) { + const GLint winX = fxMesa->x_offset; + const GLint winY = fxMesa->y_offset + fxMesa->height - 1; + const GLint srcStride = (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) + ? (fxMesa->screen_width) : (info.strideInBytes / 2); + GLuint i; + + for (i = 0; i < n; i++) { + GLint scrX = winX + x[i]; + GLint scrY = winY - y[i]; + if (visible_pixel(fxMesa, scrX, scrY) && mask[i]) { + GLushort *data16 = (GLushort *) info.lfbPtr + + scrY * srcStride + scrX; + GLushort pixel; + if (fxMesa->bgrOrder) { + pixel = PACK_BGR16(rgba[i][0], + rgba[i][1], + rgba[i][2]); + } else { + pixel = PACK_RGB16(rgba[i][0], + rgba[i][1], + rgba[i][2]); + } + data16[0] = pixel; + } + } + grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->currentFB); + } + END_BOARD_LOCK(fxMesa); +} + +static void +write_R5G6B5_mono_pixels(const GLcontext * ctx, + GLuint n, const GLint x[], const GLint y[], + const GLubyte mask[]) +{ + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + GrLfbInfo_t info; + GLubyte *constantColor = (GLubyte *)(&fxMesa->color); + GLushort pixel; + + if (fxMesa->bgrOrder) { + pixel = PACK_BGR16(constantColor[0], + constantColor[1], + constantColor[2]); + } else { + pixel = PACK_RGB16(constantColor[0], + constantColor[1], + constantColor[2]); + } + + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: write_R5G6B5_mono_pixels\n"); + } + + BEGIN_BOARD_LOCK(fxMesa); + info.size = sizeof(info); + if (grLfbLock(GR_LFB_WRITE_ONLY, + fxMesa->currentFB, + GR_LFBWRITEMODE_565, + GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) { + const GLint winX = fxMesa->x_offset; + const GLint winY = fxMesa->y_offset + fxMesa->height - 1; + const GLint srcStride = (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) + ? (fxMesa->screen_width) : (info.strideInBytes / 2); + GLuint i; + + for (i = 0; i < n; i++) { + GLint scrX = winX + x[i]; + GLint scrY = winY - y[i]; + if (visible_pixel(fxMesa, scrX, scrY) && mask[i]) { + GLushort *data16 = (GLushort *) info.lfbPtr + + scrY * srcStride + scrX; + data16[0] = pixel; + } + } + grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->currentFB); + } + END_BOARD_LOCK(fxMesa); +} + +static void +read_R5G6B5_pixels(const GLcontext * ctx, + GLuint n, const GLint x[], const GLint y[], + GLubyte rgba[][4], const GLubyte mask[]) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GrLfbInfo_t info; + BEGIN_BOARD_LOCK(fxMesa); + info.size = sizeof(info); + if (grLfbLock(GR_LFB_READ_ONLY, + fxMesa->currentFB, + GR_LFBWRITEMODE_ANY, + GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) { + const GLint winX = fxMesa->x_offset; + const GLint winY = fxMesa->y_offset + fxMesa->height - 1; + const GLint srcStride = (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) + ? (fxMesa->screen_width) : (info.strideInBytes / 2); + GLuint i; + for (i = 0; i < n; i++) { + if (mask[i]) { + const GLushort *data16 = (const GLushort *) info.lfbPtr + + (winY - y[i]) * srcStride + (winX + x[i]); + GLushort pixel = *data16; + rgba[i][RCOMP] = FX_PixelToR(fxMesa, pixel); + rgba[i][GCOMP] = FX_PixelToG(fxMesa, pixel); + rgba[i][BCOMP] = FX_PixelToB(fxMesa, pixel); + rgba[i][ACOMP] = 255; + } + } + grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB); + } + END_BOARD_LOCK(fxMesa); +} + + +/* + * 24bpp span/pixel functions + */ + +static void +write_R8G8B8_rgb_span(const GLcontext *ctx, GLuint n, GLint x, GLint y, + const GLubyte rgb[][3], const GLubyte mask[]) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GrLfbWriteMode_t mode; + GrLfbInfo_t info; + + if (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) + mode = GR_LFBWRITEMODE_888; + else + mode = GR_LFBWRITEMODE_888; + + BEGIN_BOARD_LOCK(fxMesa); + info.size = sizeof(info); + if (grLfbLock(GR_LFB_WRITE_ONLY, + fxMesa->currentFB, + mode, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) { + const GLint winY = fxMesa->y_offset + fxMesa->height - 1; + const GLint winX = fxMesa->x_offset; + const GLint scrX = winX + x; + const GLint scrY = winY - y; + + if (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) { + /*GLint dstStride = fxMesa->screen_width * 3; */ + GLint dstStride = info.strideInBytes / 1; + GLubyte *dst = (GLubyte *) info.lfbPtr + + (winY - y) * dstStride + (winX + x) * 1; + GLuint *dst32 = (GLuint *) dst; + GLubyte visMask[MAX_WIDTH]; + GLuint i; + generate_vismask(fxMesa, scrX, scrY, n, visMask); + for (i = 0; i < n; i++) { + if (visMask[i] && (!mask || mask[i])) { + dst32[i] = + PACK_BGRA32(rgb[i][0], rgb[i][1], rgb[i][2], 255); + } + } + } + else { + /* back buffer */ + GLint dstStride = info.strideInBytes; + GLubyte *dst = (GLubyte *) info.lfbPtr + + (winY - y) * dstStride + (winX + x) * 4; + GLuint *dst32 = (GLuint *) dst; + if (mask) { + GLuint i; + for (i = 0; i < n; i++) { + if (mask[i]) { + dst32[i] = + PACK_RGBA32(rgb[i][0], rgb[i][1], rgb[i][2], 255); + } + } + } + else { + GLuint i; + for (i = 0; i < n; i++) { + dst32[i] = + PACK_RGBA32(rgb[i][0], rgb[i][1], rgb[i][2], 255); + } + } + } + grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->currentFB); + } + END_BOARD_LOCK(fxMesa); +} + + + +static void +write_R8G8B8_rgba_span(const GLcontext * ctx, GLuint n, GLint x, GLint y, + const GLubyte rgba[][4], const GLubyte mask[]) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GrLfbWriteMode_t mode; + GrLfbInfo_t info; + + if (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) + mode = GR_LFBWRITEMODE_8888; + else + mode = GR_LFBWRITEMODE_888; + + BEGIN_BOARD_LOCK(fxMesa); + info.size = sizeof(info); + if (grLfbLock(GR_LFB_WRITE_ONLY, + fxMesa->currentFB, + mode, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) { + const GLint winY = fxMesa->y_offset + fxMesa->height - 1; + const GLint winX = fxMesa->x_offset; + const GLint scrX = winX + x; + const GLint scrY = winY - y; + + if (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) { + /* XXX have to do cliprect clipping! */ + GLint dstStride = fxMesa->screen_width * 4; + GLubyte *dst = (GLubyte *) info.lfbPtr + + (winY - y) * dstStride + (winX + x) * 4; + GLuint *dst32 = (GLuint *) dst; + GLubyte visMask[MAX_WIDTH]; + GLuint i; + generate_vismask(fxMesa, scrX, scrY, n, visMask); + for (i = 0; i < n; i++) { + if (visMask[i] && (!mask || mask[i])) { + dst32[i] = + PACK_BGRA32(rgba[i][0], rgba[i][1], rgba[i][2], + rgba[i][3]); + } + } + } + else { + /* back buffer */ + GLint dstStride = info.strideInBytes; + GLubyte *dst = (GLubyte *) info.lfbPtr + + (winY - y) * dstStride + (winX + x) * 4; + if (mask) { + const GLuint *src32 = (const GLuint *) rgba; + GLuint *dst32 = (GLuint *) dst; + GLuint i; + for (i = 0; i < n; i++) { + if (mask[i]) { + dst32[i] = src32[i]; + } + } + } + else { + /* no mask, write all pixels */ + MEMCPY(dst, rgba, 4 * n); + } + } + grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->currentFB); + } + END_BOARD_LOCK(fxMesa); +} + + +static void +write_R8G8B8_mono_span(const GLcontext * ctx, GLuint n, GLint x, GLint y, + const GLubyte mask[]) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GLubyte rgba[MAX_WIDTH][4]; + GLuint *data = (GLuint *) rgba; + GLuint i; + + /* XXX this is a simple-minded implementation but good enough for now */ + for (i = 0; i < n; i++) { + data[i] = (GLuint) fxMesa->color; + } + write_R8G8B8_rgba_span(ctx, n, x, y, (const GLubyte(*)[4]) rgba, mask); +} + + +static void +read_R8G8B8_span(const GLcontext * ctx, GLuint n, GLint x, GLint y, + GLubyte rgba[][4]) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GrLfbInfo_t info; + + BEGIN_BOARD_LOCK(fxMesa); + info.size = sizeof(info); + if (grLfbLock(GR_LFB_READ_ONLY, fxMesa->currentFB, GR_LFBWRITEMODE_8888, + GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) { + const GLint winY = fxMesa->y_offset + fxMesa->height - 1; + const GLint winX = fxMesa->x_offset; + + if (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) { + GLint srcStride = fxMesa->screen_width * 4; + const GLubyte *src = (const GLubyte *) info.lfbPtr + + (winY - y) * srcStride + (winX + x) * 4; + GLuint i; + for (i = 0; i < n; i++) { + rgba[i][0] = src[i * 4 + 2]; + rgba[i][1] = src[i * 4 + 1]; + rgba[i][2] = src[i * 4 + 0]; + rgba[i][3] = src[i * 4 + 3]; + } + } + else { + /* back buffer */ + GLint srcStride = info.strideInBytes / 2; + const GLubyte *src = (const GLubyte *) info.lfbPtr + + (winY - y) * srcStride + (winX + x) * 4; + GLuint i; + for (i = 0; i < n; i++) { + rgba[i][0] = src[i * 4 + 2]; + rgba[i][1] = src[i * 4 + 1]; + rgba[i][2] = src[i * 4 + 0]; + rgba[i][3] = src[i * 4 + 3]; + } + } + grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB); + } + END_BOARD_LOCK(fxMesa); +} + + +static void +write_R8G8B8_pixels(const GLcontext * ctx, + GLuint n, const GLint x[], const GLint y[], + CONST GLubyte rgba[][4], const GLubyte mask[]) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GrLfbWriteMode_t mode; + GrLfbInfo_t info; + + if (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) + mode = GR_LFBWRITEMODE_8888; + else + mode = GR_LFBWRITEMODE_888 /*565 */ ; + + BEGIN_BOARD_LOCK(fxMesa); + info.size = sizeof(info); + if (grLfbLock(GR_LFB_WRITE_ONLY, + fxMesa->currentFB, + mode, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) { + if (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) { + GLuint i; + for (i = 0; i < n; i++) { + const GLint winY = fxMesa->y_offset + fxMesa->height - 1; + const GLint winX = fxMesa->x_offset; + const GLint scrX = winX + x[i]; + const GLint scrY = winY - y[i]; + if (mask[i] && visible_pixel(fxMesa, scrX, scrY)) { + GLint dstStride = fxMesa->screen_width * 4; + GLubyte *dst = + (GLubyte *) info.lfbPtr + scrY * dstStride + scrX * 4; + GLuint *dst32 = (GLuint *) dst; + *dst32 = PACK_BGRA32(rgba[i][0], rgba[i][1], + rgba[i][2], rgba[i][3]); + } + } + } + else { + /* back buffer */ + GLuint i; + for (i = 0; i < n; i++) { + const GLint winY = fxMesa->y_offset + fxMesa->height - 1; + const GLint winX = fxMesa->x_offset; + const GLint scrX = winX + x[i]; + const GLint scrY = winY - y[i]; + if (mask[i] && visible_pixel(fxMesa, scrX, scrY)) { + GLint dstStride = info.strideInBytes; + GLubyte *dst = + (GLubyte *) info.lfbPtr + scrY * dstStride + scrX * 4; + GLuint *dst32 = (GLuint *) dst; + *dst32 = PACK_BGRA32(rgba[i][0], rgba[i][1], + rgba[i][2], rgba[i][3]); + } + } + } + grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->currentFB); + } + END_BOARD_LOCK(fxMesa); +} + + +static void +write_R8G8B8_mono_pixels(const GLcontext * ctx, + GLuint n, const GLint x[], const GLint y[], + const GLubyte mask[]) +{ + printf("write_r8g8b8_mono_pixels\n"); +} + + +static void +read_R8G8B8_pixels(const GLcontext * ctx, + GLuint n, const GLint x[], const GLint y[], + GLubyte rgba[][4], const GLubyte mask[]) +{ + printf("read_R8G8B8_pixels %d\n", n); +} + + + +/* + * 32bpp span/pixel functions + */ + +static void +write_R8G8B8A8_rgb_span(const GLcontext * ctx, GLuint n, GLint x, GLint y, + const GLubyte rgb[][3], const GLubyte mask[]) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GrLfbInfo_t info; + + BEGIN_BOARD_LOCK(fxMesa); + info.size = sizeof(info); + if (grLfbLock(GR_LFB_WRITE_ONLY, fxMesa->currentFB, GR_LFBWRITEMODE_8888, + GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) { + const GLint winY = fxMesa->y_offset + fxMesa->height - 1; + const GLint winX = fxMesa->x_offset; + const GLint scrX = winX + x; + const GLint scrY = winY - y; + + if (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) { + GLint dstStride = fxMesa->screen_width * 4; + GLubyte *dst = (GLubyte *) info.lfbPtr + + (winY - y) * dstStride + (winX + x) * 4; + GLuint *dst32 = (GLuint *) dst; + GLubyte visMask[MAX_WIDTH]; + GLuint i; + generate_vismask(fxMesa, scrX, scrY, n, visMask); + for (i = 0; i < n; i++) { + if (visMask[i] && (!mask || mask[i])) { + dst32[i] = + PACK_BGRA32(rgb[i][0], rgb[i][1], rgb[i][2], 255); + } + } + } + else { + /* back buffer */ + GLint dstStride = info.strideInBytes; + GLubyte *dst = (GLubyte *) info.lfbPtr + + (winY - y) * dstStride + (winX + x) * 4; + GLuint *dst32 = (GLuint *) dst; + if (mask) { + GLuint i; + for (i = 0; i < n; i++) { + if (mask[i]) { + dst32[i] = + PACK_BGRA32(rgb[i][0], rgb[i][1], rgb[i][2], 255); + } + } + } + else { + GLuint i; + for (i = 0; i < n; i++) { + dst32[i] = + PACK_BGRA32(rgb[i][0], rgb[i][1], rgb[i][2], 255); + } + } + } + grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->currentFB); + } + END_BOARD_LOCK(fxMesa); +} + + +/* + *XXX test of grLfbWriteRegion in 32bpp mode. Doesn't seem to work! + */ +#if 0 +static void +write_R8G8B8A8_rgb_span2(const GLcontext * ctx, GLuint n, GLint x, GLint y, + const GLubyte rgb[][3], const GLubyte mask[]) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GLint bottom = fxMesa->height + fxMesa->y_offset - 1; + GLint x2 = fxMesa->x_offset + x; + GLint y2 = bottom - y; + + FX_grLfbWriteRegion(fxMesa->currentFB, x2, y2, GR_LFB_SRC_FMT_888, + n, 1, 0, rgb); +} +#endif + + +static void +write_R8G8B8A8_rgba_span(const GLcontext * ctx, GLuint n, GLint x, GLint y, + const GLubyte rgba[][4], const GLubyte mask[]) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GrLfbInfo_t info; + + BEGIN_BOARD_LOCK(fxMesa); + info.size = sizeof(info); + if (grLfbLock(GR_LFB_WRITE_ONLY, fxMesa->currentFB, GR_LFBWRITEMODE_8888, + GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) { + const GLint winY = fxMesa->y_offset + fxMesa->height - 1; + const GLint winX = fxMesa->x_offset; + const GLint scrX = winX + x; + const GLint scrY = winY - y; + + if (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) { + GLint dstStride = fxMesa->screen_width * 4; + GLubyte *dst = (GLubyte *) info.lfbPtr + + (winY - y) * dstStride + (winX + x) * 4; + GLuint *dst32 = (GLuint *) dst; + GLubyte visMask[MAX_WIDTH]; + GLuint i; + generate_vismask(fxMesa, scrX, scrY, n, visMask); + for (i = 0; i < n; i++) { + if (visMask[i] && (!mask || mask[i])) { + dst32[i] = + PACK_BGRA32(rgba[i][0], rgba[i][1], rgba[i][2], + rgba[i][3]); + } + } + } + else { + /* back buffer */ + GLint dstStride = info.strideInBytes; + GLubyte *dst = (GLubyte *) info.lfbPtr + + (winY - y) * dstStride + (winX + x) * 4; + GLuint *dst32 = (GLuint *) dst; + if (mask) { + GLuint i; + for (i = 0; i < n; i++) { + if (mask[i]) { + dst32[i] = PACK_BGRA32(rgba[i][0], rgba[i][1], + rgba[i][2], rgba[i][3]); + } + } + } + else { + /* no mask, write all pixels */ + GLuint i; + for (i = 0; i < n; i++) { + dst32[i] = PACK_BGRA32(rgba[i][0], rgba[i][1], + rgba[i][2], rgba[i][3]); + } + } + } + grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->currentFB); + } + else { + info.strideInBytes = -1; + } + END_BOARD_LOCK(fxMesa); +} + + +static void +write_R8G8B8A8_mono_span(const GLcontext * ctx, GLuint n, GLint x, GLint y, + const GLubyte mask[]) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GLubyte rgba[MAX_WIDTH][4]; + GLuint *data = (GLuint *) rgba; + GLuint i; + + /* XXX this is a simple-minded implementation but good enough for now */ + for (i = 0; i < n; i++) { + data[i] = (GLuint) fxMesa->color; + } + write_R8G8B8A8_rgba_span(ctx, n, x, y, (const GLubyte(*)[4]) rgba, mask); +} + + +static void +read_R8G8B8A8_span(const GLcontext * ctx, GLuint n, GLint x, GLint y, + GLubyte rgba[][4]) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GrLfbInfo_t info; + + BEGIN_BOARD_LOCK(fxMesa); + info.size = sizeof(info); + if (grLfbLock(GR_LFB_READ_ONLY, fxMesa->currentFB, GR_LFBWRITEMODE_ANY, + GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) { + const GLint winY = fxMesa->y_offset + fxMesa->height - 1; + const GLint winX = fxMesa->x_offset; + + if (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) { + GLint srcStride = fxMesa->screen_width; + const GLuint *src32 = (const GLuint *) info.lfbPtr + + (winY - y) * srcStride + (winX + x); + GLuint i; + GLuint *color = (GLuint*)rgba; + MEMCPY(color, src32, n * 4); + for (i = 0; i < n; i++) { + const GLuint p = *color; + *color++ = ((p & 0x00ff0000) >> 16) | + (p & 0xff00ff00) | + ((p & 0x000000ff) << 16); + } + } + else { + /* back buffer */ + GLint srcStride = info.strideInBytes / sizeof(GLuint); + const GLuint *src32 = (const GLuint *) info.lfbPtr + + (winY - y) * srcStride + (winX + x); + GLuint i; + GLuint *color = (GLuint*)rgba; + MEMCPY(color, src32, n * 4); + for (i = 0; i < n; i++) { + const GLuint p = *color; + *color++ = ((p & 0x00ff0000) >> 16) | + (p & 0xff00ff00) | + ((p & 0x000000ff) << 16); + } + } + grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB); + } + else + info.strideInBytes = -1; + END_BOARD_LOCK(fxMesa); +} + + +static void +write_R8G8B8A8_pixels(const GLcontext * ctx, + GLuint n, const GLint x[], const GLint y[], + CONST GLubyte rgba[][4], const GLubyte mask[]) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GrLfbInfo_t info; + + BEGIN_BOARD_LOCK(fxMesa); + info.size = sizeof(info); + if (grLfbLock(GR_LFB_WRITE_ONLY, fxMesa->currentFB, GR_LFBWRITEMODE_8888, + GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) { + if (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) { + GLuint i; + for (i = 0; i < n; i++) { + const GLint winY = fxMesa->y_offset + fxMesa->height - 1; + const GLint winX = fxMesa->x_offset; + const GLint scrX = winX + x[i]; + const GLint scrY = winY - y[i]; + if (mask[i] && visible_pixel(fxMesa, scrX, scrY)) { + GLint dstStride = fxMesa->screen_width * 4; + GLubyte *dst = + (GLubyte *) info.lfbPtr + scrY * dstStride + scrX * 4; + GLuint *dst32 = (GLuint *) dst; + *dst32 = PACK_BGRA32(rgba[i][0], rgba[i][1], + rgba[i][2], rgba[i][3]); + } + } + } + else { + /* back buffer */ + GLuint i; + for (i = 0; i < n; i++) { + const GLint winY = fxMesa->y_offset + fxMesa->height - 1; + const GLint winX = fxMesa->x_offset; + const GLint scrX = winX + x[i]; + const GLint scrY = winY - y[i]; + if (mask[i] && visible_pixel(fxMesa, scrX, scrY)) { + GLint dstStride = info.strideInBytes; + GLubyte *dst = + (GLubyte *) info.lfbPtr + scrY * dstStride + scrX * 4; + GLuint *dst32 = (GLuint *) dst; + *dst32 = PACK_BGRA32(rgba[i][0], rgba[i][1], + rgba[i][2], rgba[i][3]); + } + } + } + grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->currentFB); + } + END_BOARD_LOCK(fxMesa); +} + + +static void +write_R8G8B8A8_mono_pixels(const GLcontext * ctx, + GLuint n, const GLint x[], const GLint y[], + const GLubyte mask[]) +{ + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + GLuint i; + GLuint color = fxMesa->color; + for (i = 0; i < n; i++) { + if (mask[i]) { + write_R8G8B8A8_rgba_span(ctx, 1, x[i], y[i], + (const GLubyte(*)[4]) &color, mask + i); + } + } +} + + + +static void +read_R8G8B8A8_pixels(const GLcontext * ctx, + GLuint n, const GLint x[], const GLint y[], + GLubyte rgba[][4], const GLubyte mask[]) +{ + GLuint i; + for (i = 0; i < n; i++) { + if (mask[i]) { + read_R8G8B8A8_span(ctx, 1, x[i], y[i], rgba + i); + } + } +} + + + +/* + * Depth buffer read/write functions. + */ +/* + * To read the frame buffer, we need to lock and unlock it. The + * four macros {READ,WRITE}_FB_SPAN_{LOCK,UNLOCK} + * do this for us. + * + * Note that the lock must be matched with an unlock. These + * macros include a spare curly brace, so they must + * be syntactically matched. + * + * Note, also, that you can't lock a buffer twice with different + * modes. That is to say, you can't lock a buffer in both read + * and write modes. The strideInBytes and LFB pointer will be + * the same with read and write locks, so you can use either. + * o The HW has different state for reads and writes, so + * locking it twice may give screwy results. + * o The DRM won't let you lock twice. It hangs. This is probably + * because of the BEGIN_BOARD_LOCK IN THE *_FB_SPAN_LOCK macros, + * and could be eliminated with nonlocking lock routines. But + * what's the point after all. + */ +#define READ_FB_SPAN_LOCK(fxMesa, info, target_buffer) \ + BEGIN_BOARD_LOCK(fxMesa); \ + (info).size=sizeof(info); \ + if (grLfbLock(GR_LFB_READ_ONLY, \ + target_buffer, \ + GR_LFBWRITEMODE_ANY, \ + GR_ORIGIN_LOWER_LEFT, \ + FXFALSE, \ + &(info))) { + +#define READ_FB_SPAN_UNLOCK(fxMesa, target_buffer) \ + grLfbUnlock(GR_LFB_READ_ONLY, target_buffer); \ + } else { \ + fprintf(stderr, "fxDriver: Can't get %s (%d) read lock\n", \ + (target_buffer == GR_BUFFER_BACKBUFFER) \ + ? "back buffer" \ + : ((target_buffer == GR_BUFFER_AUXBUFFER) \ + ? "depth buffer" \ + : "unknown buffer"), \ + target_buffer); \ + } \ + END_BOARD_LOCK(fxMesa); + + +#define WRITE_FB_SPAN_LOCK(fxMesa, info, target_buffer, write_mode) \ + BEGIN_BOARD_LOCK(fxMesa); \ + info.size=sizeof(info); \ + if (grLfbLock(GR_LFB_WRITE_ONLY, \ + target_buffer, \ + write_mode, \ + GR_ORIGIN_LOWER_LEFT, \ + FXFALSE, \ + &info)) { + +#define WRITE_FB_SPAN_UNLOCK(fxMesa, target_buffer) \ + grLfbUnlock(GR_LFB_WRITE_ONLY, target_buffer); \ + } else { \ + fprintf(stderr, "fxDriver: Can't get %s (%d) write lock\n", \ + (target_buffer == GR_BUFFER_BACKBUFFER) \ + ? "back buffer" \ + : ((target_buffer == GR_BUFFER_AUXBUFFER) \ + ? "depth buffer" \ + : "unknown buffer"), \ + target_buffer); \ + } \ + END_BOARD_LOCK(fxMesa); + +/* + * Because the Linear Frame Buffer is not necessarily aligned + * with the depth buffer, we have to do some fiddling + * around to get the right addresses. + * + * Perhaps a picture is in order. The Linear Frame Buffer + * looks like this: + * + * |<----------------------info.strideInBytes------------->| + * |<-----physicalStrideInBytes------->| + * +-----------------------------------+xxxxxxxxxxxxxxxxxxx+ + * | | | + * | Legal Memory | Forbidden Zone | + * | | | + * +-----------------------------------+xxxxxxxxxxxxxxxxxxx+ + * + * You can only reliably read and write legal locations. Reads + * and writes from the Forbidden Zone will return undefined values, + * and may cause segmentation faults. + * + * Now, the depth buffer may not end up in a location such each + * scan line is an LFB line. For example, the depth buffer may + * look like this: + * + * wrapped ordinary. + * +-----------------------------------+xxxxxxxxxxxxxxxxxxx+ + * |0000000000000000000000 | | back + * |1111111111111111111111 | | buffer + * |2222222222222222222222 | | + * |4096b align. padxx00000000000000000| Forbidden Zone | depth + * |0000 11111111111111111| | buffer + * |1111 22222222222222222| | + * |2222 | | + * +-----------------------------------+xxxxxxxxxxxxxxxxxxx+ + * where each number is the scan line number. We know it will + * be aligned on 128 byte boundaries, at least. Aligning this + * on a scanline boundary causes the back and depth buffers to + * thrash in the SST1 cache. (Note that the back buffer is always + * allocated at the beginning of LFB memory, and so it is always + * properly aligned with the LFB stride.) + * + * We call the beginning of the line (which is the rightmost + * part of the depth line in the picture above) the *ordinary* part + * of the scanline, and the end of the line (which is the + * leftmost part, one line below) the *wrapped* part of the scanline. + * a.) We need to know what x value to subtract from the screen + * x coordinate to index into the wrapped part. + * b.) We also need to figure out if we need to read from the ordinary + * part scan line, or from the wrapped part of the scan line. + * + * [ad a] + * The first wrapped x coordinate is that coordinate such that + * depthBufferOffset&(info.strideInBytes) + x*elmentSize {*} + * > physicalStrideInBytes + * where depthBufferOffset is the LFB distance in bytes + * from the back buffer to the depth buffer. The expression + * depthBufferOffset&(info.strideInBytes) + * is then the offset (in bytes) from the beginining of (any) + * depth buffer line to first element in the line. + * Simplifying inequation {*} above we see that x is the smallest + * value such that + * x*elementSize > physicalStrideInBytes {**} + * - depthBufferOffset&(info.strideInBytes) + * Now, we know that both the summands on the right are multiples of + * 128, and elementSize <= 4, so if equality holds in {**}, x would + * be a multiple of 32. Thus we can set x to + * xwrapped = (physicalStrideInBytes + * - depthBufferOffset&(info.strideInBytes))/elementSize + * + 1 + * + * [ad b] + * Question b is now simple. We read from the wrapped scan line if + * x is greater than xwrapped. + */ +#define TILE_WIDTH_IN_BYTES 128 +#define TILE_WIDTH_IN_ZOXELS(bpz) (TILE_WIDTH_IN_BYTES/(bpz)) +#define TILE_HEIGHT_IN_LINES 32 +typedef struct +{ + void *lfbPtr; + void *lfbWrapPtr; + FxU32 LFBStrideInElts; + FxU32 firstWrappedX; +} +LFBParameters; + +static void GetFbParams(fxMesaContext fxMesa, + GrLfbInfo_t * info, + GrLfbInfo_t * backBufferInfo, + LFBParameters * ReadParams, FxU32 elementSize); + +/* + * We need information about the back buffer. Note that + * this function *cannot be called* while the aux buffer + * is locked, or the caller will hang. + * + * Only Glide knows the LFB address of the back and depth + * offsets. The upper levels of Mesa know the depth offset, + * but that is not in LFB space, it is tiled memory space, + * and is not useable for us. + */ +static void +GetBackBufferInfo(fxMesaContext fxMesa, GrLfbInfo_t * backBufferInfo) +{ + READ_FB_SPAN_LOCK(fxMesa, *backBufferInfo, GR_BUFFER_BACKBUFFER); + READ_FB_SPAN_UNLOCK(fxMesa, GR_BUFFER_BACKBUFFER); +} + +static void +GetFbParams(fxMesaContext fxMesa, + GrLfbInfo_t * info, + GrLfbInfo_t * backBufferInfo, + LFBParameters * ReadParamsp, FxU32 elementSize) +{ + FxU32 physicalStrideInBytes, bufferOffset; + FxU32 strideInBytes = info->strideInBytes; + FxU32 lfbPtr = (FxU32) (info->lfbPtr); + + /* + * These two come directly from the info structure. + */ + ReadParamsp->lfbPtr = (void *) lfbPtr; + ReadParamsp->LFBStrideInElts = strideInBytes / elementSize; + /* + * Now, calculate the value of firstWrappedX. + * + * The physical stride is the screen width in bytes rounded up to + * the next highest multiple of 128 bytes. Note that this fails + * when TILE_WIDTH_IN_BYTES is not a power of two. + * + * The buffer Offset is the distance between the beginning of + * the LFB space, which is the beginning of the back buffer, + * and the buffer we are gathering information about. + * We want to make this routine usable for operations on the + * back buffer, though we don't actually use it on the back + * buffer. Note, then, that if bufferOffset == 0, the firstWrappedX + * is in the forbidden zone, and is therefore never reached. + * + * Note that if + * physicalStrideInBytes + * < bufferOffset&(info->strideInBytes-1) + * the buffer begins in the forbidden zone. We assert for this. + */ + bufferOffset = lfbPtr - (FxU32) backBufferInfo->lfbPtr; + physicalStrideInBytes + = (fxMesa->screen_width * elementSize + TILE_WIDTH_IN_BYTES - 1) + & ~(TILE_WIDTH_IN_BYTES - 1); + assert(physicalStrideInBytes > (bufferOffset & (strideInBytes - 1))); + ReadParamsp->firstWrappedX + = (physicalStrideInBytes + - (bufferOffset & (strideInBytes - 1))) / elementSize; + /* + * This is the address of the next physical line. + */ + ReadParamsp->lfbWrapPtr + = (void *) ((FxU32) backBufferInfo->lfbPtr + + (bufferOffset & ~(strideInBytes - 1)) + + (TILE_HEIGHT_IN_LINES) * strideInBytes); +} + +/* + * These macros fetch data from the frame buffer. The type is + * the type of data we want to fetch. It should match the type + * whose size was used with GetFbParams to fill in the structure + * in *ReadParamsp. We have a macro to read the ordinary + * part, a second macro to read the wrapped part, and one which + * will do either. When we are reading a span, we will know + * when the ordinary part ends, so there's no need to test for + * it. However, when reading and writing pixels, we don't + * necessarily know. I suppose it's a matter of taste whether + * it's better in the macro or in the call. + * + * Recall that x and y are screen coordinates. + */ +#define GET_FB_DATA(ReadParamsp, type, x, y) \ + (((x) < (ReadParamsp)->firstWrappedX) \ + ? (((type *)((ReadParamsp)->lfbPtr)) \ + [(y) * ((ReadParamsp)->LFBStrideInElts) \ + + (x)]) \ + : (((type *)((ReadParamsp)->lfbWrapPtr)) \ + [((y)) * ((ReadParamsp)->LFBStrideInElts) \ + + ((x) - (ReadParamsp)->firstWrappedX)])) +#define GET_ORDINARY_FB_DATA(ReadParamsp, type, x, y) \ + (((type *)((ReadParamsp)->lfbPtr)) \ + [(y) * ((ReadParamsp)->LFBStrideInElts) \ + + (x)]) +#define GET_WRAPPED_FB_DATA(ReadParamsp, type, x, y) \ + (((type *)((ReadParamsp)->lfbWrapPtr)) \ + [((y)) * ((ReadParamsp)->LFBStrideInElts) \ + + ((x) - (ReadParamsp)->firstWrappedX)]) +#define PUT_FB_DATA(ReadParamsp, type, x, y, value) \ + (GET_FB_DATA(ReadParamsp, type, x, y) = (type)(value)) +#define PUT_ORDINARY_FB_DATA(ReadParamsp, type, x, y, value) \ + (GET_ORDINARY_FB_DATA(ReadParamsp, type, x, y) = (type)(value)) +#define PUT_WRAPPED_FB_DATA(ReadParamsp, type, x, y, value) \ + (GET_WRAPPED_FB_DATA(ReadParamsp, type, x, y) = (type)(value)) + +static void +fxDDWriteDepthSpan(GLcontext * ctx, + GLuint n, GLint x, GLint y, const GLdepth depth[], + const GLubyte mask[]) +{ + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + GLint bottom = fxMesa->y_offset + fxMesa->height - 1; + GLuint depth_size = fxMesa->glVis->DepthBits; + GLuint stencil_size = fxMesa->glVis->StencilBits; + GrLfbInfo_t info; + GLubyte visMask[MAX_WIDTH]; + + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: fxDDWriteDepthSpan(...)\n"); + } + + assert((depth_size == 16) || (depth_size == 24) || (depth_size == 32)); + /* + * Convert x and y to screen coordinates. + */ + x += fxMesa->x_offset; + y = bottom - y; + if (mask) { + GLint i; + GLushort d16; + GrLfbInfo_t backBufferInfo; + + switch (depth_size) { + case 16: + GetBackBufferInfo(fxMesa, &backBufferInfo); + /* + * Note that the _LOCK macro adds a curly brace, + * and the UNLOCK macro removes it. + */ + WRITE_FB_SPAN_LOCK(fxMesa, info, GR_BUFFER_AUXBUFFER, + GR_LFBWRITEMODE_ANY); + generate_vismask(fxMesa, x, y, n, visMask); + { + LFBParameters ReadParams; + int wrappedPartStart; + GetFbParams(fxMesa, &info, &backBufferInfo, + &ReadParams, sizeof(GLushort)); + if (ReadParams.firstWrappedX <= x) { + wrappedPartStart = 0; + } + else if (n <= (ReadParams.firstWrappedX - x)) { + wrappedPartStart = n; + } + else { + wrappedPartStart = n - (ReadParams.firstWrappedX - x); + } + for (i = 0; i < wrappedPartStart; i++) { + if (mask[i] && visMask[i]) { + d16 = depth[i]; + PUT_ORDINARY_FB_DATA(&ReadParams, GLushort, x + i, y, d16); + } + } + for (; i < n; i++) { + if (mask[i] && visMask[i]) { + d16 = depth[i]; + PUT_WRAPPED_FB_DATA(&ReadParams, GLushort, x + i, y, d16); + } + } + } + WRITE_FB_SPAN_UNLOCK(fxMesa, GR_BUFFER_AUXBUFFER); + break; + case 24: + case 32: + GetBackBufferInfo(fxMesa, &backBufferInfo); + /* + * Note that the _LOCK macro adds a curly brace, + * and the UNLOCK macro removes it. + */ + WRITE_FB_SPAN_LOCK(fxMesa, info, GR_BUFFER_AUXBUFFER, + GR_LFBWRITEMODE_ANY); + generate_vismask(fxMesa, x, y, n, visMask); + { + LFBParameters ReadParams; + int wrappedPartStart; + GetFbParams(fxMesa, &info, &backBufferInfo, + &ReadParams, sizeof(GLuint)); + if (ReadParams.firstWrappedX <= x) { + wrappedPartStart = 0; + } + else if (n <= (ReadParams.firstWrappedX - x)) { + wrappedPartStart = n; + } + else { + wrappedPartStart = n - (ReadParams.firstWrappedX - x); + } + for (i = 0; i < wrappedPartStart; i++) { + GLuint d32; + if (mask[i] && visMask[i]) { + if (stencil_size > 0) { + d32 = + GET_ORDINARY_FB_DATA(&ReadParams, GLuint, + x + i, y); + d32 = + (d32 & 0xFF000000) | (depth[i] & 0x00FFFFFF); + } + else { + d32 = depth[i]; + } + PUT_ORDINARY_FB_DATA(&ReadParams, GLuint, x + i, y, d32); + } + } + for (; i < n; i++) { + GLuint d32; + if (mask[i] && visMask[i]) { + if (stencil_size > 0) { + d32 = + GET_WRAPPED_FB_DATA(&ReadParams, GLuint, + x + i, y); + d32 = + (d32 & 0xFF000000) | (depth[i] & 0x00FFFFFF); + } + else { + d32 = depth[i]; + } + PUT_WRAPPED_FB_DATA(&ReadParams, GLuint, x + i, y, d32); + } + } + } + WRITE_FB_SPAN_UNLOCK(fxMesa, GR_BUFFER_AUXBUFFER); + break; + } + } + else { + GLint i; + GLuint d32; + GLushort d16; + GrLfbInfo_t backBufferInfo; + + switch (depth_size) { + case 16: + GetBackBufferInfo(fxMesa, &backBufferInfo); + /* + * Note that the _LOCK macro adds a curly brace, + * and the UNLOCK macro removes it. + */ + WRITE_FB_SPAN_LOCK(fxMesa, info, + GR_BUFFER_AUXBUFFER, GR_LFBWRITEMODE_ANY); + generate_vismask(fxMesa, x, y, n, visMask); + { + LFBParameters ReadParams; + GLuint wrappedPartStart; + GetFbParams(fxMesa, &info, &backBufferInfo, + &ReadParams, sizeof(GLushort)); + if (ReadParams.firstWrappedX <= x) { + wrappedPartStart = 0; + } + else if (n <= (ReadParams.firstWrappedX - x)) { + wrappedPartStart = n; + } + else { + wrappedPartStart = n - (ReadParams.firstWrappedX - x); + } + for (i = 0; i < wrappedPartStart; i++) { + if (visMask[i]) { + d16 = depth[i]; + PUT_ORDINARY_FB_DATA(&ReadParams, + GLushort, + x + i, y, + d16); + } + } + for (; i < n; i++) { + if (visMask[i]) { + d16 = depth[i]; + PUT_WRAPPED_FB_DATA(&ReadParams, + GLushort, + x + i, y, + d16); + } + } + } + WRITE_FB_SPAN_UNLOCK(fxMesa, GR_BUFFER_AUXBUFFER); + break; + case 24: + case 32: + GetBackBufferInfo(fxMesa, &backBufferInfo); + /* + * Note that the _LOCK macro adds a curly brace, + * and the UNLOCK macro removes it. + */ + WRITE_FB_SPAN_LOCK(fxMesa, info, + GR_BUFFER_AUXBUFFER, GR_LFBWRITEMODE_ANY); + generate_vismask(fxMesa, x, y, n, visMask); + { + LFBParameters ReadParams; + GLuint wrappedPartStart; + + GetFbParams(fxMesa, &info, &backBufferInfo, + &ReadParams, sizeof(GLuint)); + if (ReadParams.firstWrappedX <= x) { + wrappedPartStart = 0; + } + else if (n <= (ReadParams.firstWrappedX - x)) { + wrappedPartStart = n; + } + else { + wrappedPartStart = n - (ReadParams.firstWrappedX - x); + } + for (i = 0; i < wrappedPartStart; i++) { + if (visMask[i]) { + if (stencil_size > 0) { + d32 = GET_ORDINARY_FB_DATA(&ReadParams, GLuint, x + i, y); + d32 = + (d32 & 0xFF000000) | (depth[i] & 0x00FFFFFF); + } + else { + d32 = depth[i]; + } + PUT_ORDINARY_FB_DATA(&ReadParams, GLuint, x + i, y, d32); + } + } + for (; i < n; i++) { + if (visMask[i]) { + if (stencil_size > 0) { + d32 = GET_WRAPPED_FB_DATA(&ReadParams, GLuint, x + i, y); + d32 = + (d32 & 0xFF000000) | (depth[i] & 0x00FFFFFF); + } + else { + d32 = depth[i]; + } + PUT_WRAPPED_FB_DATA(&ReadParams, GLuint, x + i, y, d32); + } + } + } + WRITE_FB_SPAN_UNLOCK(fxMesa, GR_BUFFER_AUXBUFFER); + break; + } + } +} + +static void +fxDDReadDepthSpan(GLcontext * ctx, + GLuint n, GLint x, GLint y, GLdepth depth[]) +{ + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + GLint bottom = fxMesa->height + fxMesa->y_offset - 1; + GLushort depth16[MAX_WIDTH]; + GLuint i; + GLuint depth_size = fxMesa->glVis->DepthBits; + GLuint stencil_size = fxMesa->glVis->StencilBits; + GrLfbInfo_t info; + + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: fxDDReadDepthSpan(...)\n"); + } + + /* + * Convert to screen coordinates. + */ + x += fxMesa->x_offset; + y = bottom - y; + switch (depth_size) { + case 16: + FX_grLfbReadRegion(fxMesa, GR_BUFFER_AUXBUFFER, x, y, n, 1, 0, depth16); + for (i = 0; i < n; i++) { + depth[i] = depth16[i]; + } + break; + case 24: + case 32: + { + LFBParameters ReadParams; + GrLfbInfo_t backBufferInfo; + int wrappedPartStart; + GetBackBufferInfo(fxMesa, &backBufferInfo); + /* + * Note that the _LOCK macro adds a curly brace, + * and the UNLOCK macro removes it. + */ + READ_FB_SPAN_LOCK(fxMesa, info, GR_BUFFER_AUXBUFFER); + GetFbParams(fxMesa, &info, &backBufferInfo, + &ReadParams, sizeof(GLuint)); + if (ReadParams.firstWrappedX <= x) { + wrappedPartStart = 0; + } + else if (n <= (ReadParams.firstWrappedX - x)) { + wrappedPartStart = n; + } + else { + wrappedPartStart = (ReadParams.firstWrappedX - x); + } + /* + * Read the line. + */ + for (i = 0; i < wrappedPartStart; i++) { + const GLuint mask = + (stencil_size > 0) ? 0x00FFFFFF : 0xFFFFFFFF; + depth[i] = + GET_ORDINARY_FB_DATA(&ReadParams, GLuint, x + i, y); + depth[i] &= mask; + } + for (; i < n; i++) { + const GLuint mask = + (stencil_size > 0) ? 0x00FFFFFF : 0xFFFFFFFF; + depth[i] = GET_WRAPPED_FB_DATA(&ReadParams, GLuint, x + i, y); + depth[i] &= mask; + } + READ_FB_SPAN_UNLOCK(fxMesa, GR_BUFFER_AUXBUFFER); + break; + } + } +} + + +static void +fxDDWriteDepthPixels(GLcontext * ctx, + GLuint n, const GLint x[], const GLint y[], + const GLdepth depth[], const GLubyte mask[]) +{ + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + GLint bottom = fxMesa->height + fxMesa->y_offset - 1; + GLuint i; + GLushort d16; + GLuint d32; + GLuint depth_size = fxMesa->glVis->DepthBits; + GLuint stencil_size = fxMesa->glVis->StencilBits; + GrLfbInfo_t info; + int xpos; + int ypos; + GrLfbInfo_t backBufferInfo; + + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: fxDDWriteDepthPixels(...)\n"); + } + + switch (depth_size) { + case 16: + GetBackBufferInfo(fxMesa, &backBufferInfo); + /* + * Note that the _LOCK macro adds a curly brace, + * and the UNLOCK macro removes it. + */ + WRITE_FB_SPAN_LOCK(fxMesa, info, + GR_BUFFER_AUXBUFFER, GR_LFBWRITEMODE_ANY); + { + LFBParameters ReadParams; + GetFbParams(fxMesa, &info, &backBufferInfo, + &ReadParams, sizeof(GLushort)); + for (i = 0; i < n; i++) { + if (mask[i] && visible_pixel(fxMesa, x[i], y[i])) { + xpos = x[i] + fxMesa->x_offset; + ypos = bottom - y[i]; + d16 = depth[i]; + PUT_FB_DATA(&ReadParams, GLushort, xpos, ypos, d16); + } + } + } + WRITE_FB_SPAN_UNLOCK(fxMesa, GR_BUFFER_AUXBUFFER); + break; + case 24: + case 32: + GetBackBufferInfo(fxMesa, &backBufferInfo); + /* + * Note that the _LOCK macro adds a curly brace, + * and the UNLOCK macro removes it. + */ + WRITE_FB_SPAN_LOCK(fxMesa, info, + GR_BUFFER_AUXBUFFER, GR_LFBWRITEMODE_ANY); + { + LFBParameters ReadParams; + GetFbParams(fxMesa, &info, &backBufferInfo, + &ReadParams, sizeof(GLuint)); + for (i = 0; i < n; i++) { + if (mask[i]) { + if (visible_pixel(fxMesa, x[i], y[i])) { + xpos = x[i] + fxMesa->x_offset; + ypos = bottom - y[i]; + if (stencil_size > 0) { + d32 = + GET_FB_DATA(&ReadParams, GLuint, xpos, ypos); + d32 = (d32 & 0xFF000000) | (depth[i] & 0xFFFFFF); + } + else { + d32 = depth[i]; + } + PUT_FB_DATA(&ReadParams, GLuint, xpos, ypos, d32); + } + } + } + } + WRITE_FB_SPAN_UNLOCK(fxMesa, GR_BUFFER_AUXBUFFER); + break; + } +} + + +static void +fxDDReadDepthPixels(GLcontext * ctx, GLuint n, + const GLint x[], const GLint y[], GLdepth depth[]) +{ + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + GLint bottom = fxMesa->height + fxMesa->y_offset - 1; + GLuint i; + GLuint depth_size = fxMesa->glVis->DepthBits; + GLushort d16; + int xpos; + int ypos; + GrLfbInfo_t info; + GLuint stencil_size; + GrLfbInfo_t backBufferInfo; + + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: fxDDReadDepthPixels(...)\n"); + } + + assert((depth_size == 16) || (depth_size == 24) || (depth_size == 32)); + switch (depth_size) { + case 16: + GetBackBufferInfo(fxMesa, &backBufferInfo); + /* + * Note that the _LOCK macro adds a curly brace, + * and the UNLOCK macro removes it. + */ + READ_FB_SPAN_LOCK(fxMesa, info, GR_BUFFER_AUXBUFFER); + { + LFBParameters ReadParams; + GetFbParams(fxMesa, &info, &backBufferInfo, + &ReadParams, sizeof(GLuint)); + for (i = 0; i < n; i++) { + /* + * Convert to screen coordinates. + */ + xpos = x[i] + fxMesa->x_offset; + ypos = bottom - y[i]; + d16 = GET_FB_DATA(&ReadParams, GLuint, xpos, ypos); + depth[i] = d16; + } + } + READ_FB_SPAN_UNLOCK(fxMesa, GR_BUFFER_AUXBUFFER); + break; + case 24: + case 32: + GetBackBufferInfo(fxMesa, &backBufferInfo); + /* + * Note that the _LOCK macro adds a curly brace, + * and the UNLOCK macro removes it. + */ + READ_FB_SPAN_LOCK(fxMesa, info, GR_BUFFER_AUXBUFFER); + stencil_size = fxMesa->glVis->StencilBits; + { + LFBParameters ReadParams; + GetFbParams(fxMesa, &info, &backBufferInfo, + &ReadParams, sizeof(GLuint)); + for (i = 0; i < n; i++) { + GLuint d32; + + /* + * Convert to screen coordinates. + */ + xpos = x[i] + fxMesa->x_offset; + ypos = bottom - y[i]; + d32 = GET_FB_DATA(&ReadParams, GLuint, xpos, ypos); + if (stencil_size > 0) { + d32 &= 0x00FFFFFF; + } + depth[i] = d32; + } + } + READ_FB_SPAN_UNLOCK(fxMesa, GR_BUFFER_AUXBUFFER); + break; + default: + assert(0); + } +} + +/* + * Stencil buffer read/write functions. + */ +#define EXTRACT_S_FROM_ZS(zs) (((zs) >> 24) & 0xFF) +#define EXTRACT_Z_FROM_ZS(zs) ((zs) & 0xffffff) +#define BUILD_ZS(z, s) (((s) << 24) | (z)) + +static void +write_stencil_span(GLcontext * ctx, GLuint n, GLint x, GLint y, + const GLstencil stencil[], const GLubyte mask[]) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GrLfbInfo_t info; + GrLfbInfo_t backBufferInfo; + + GetBackBufferInfo(fxMesa, &backBufferInfo); + /* + * Note that the _LOCK macro adds a curly brace, + * and the UNLOCK macro removes it. + */ + WRITE_FB_SPAN_LOCK(fxMesa, info, GR_BUFFER_AUXBUFFER, GR_LFBWRITEMODE_ANY); + { + const GLint winY = fxMesa->y_offset + fxMesa->height - 1; + const GLint winX = fxMesa->x_offset; + const GLint scrX = winX + x; + const GLint scrY = winY - y; + LFBParameters ReadParams; + GLubyte visMask[MAX_WIDTH]; + GLuint i; + int wrappedPartStart; + + GetFbParams(fxMesa, &info, &backBufferInfo, &ReadParams, + sizeof(GLuint)); + if (ReadParams.firstWrappedX <= x) { + wrappedPartStart = 0; + } + else if (n <= (ReadParams.firstWrappedX - x)) { + wrappedPartStart = n; + } + else { + wrappedPartStart = (ReadParams.firstWrappedX - x); + } + generate_vismask(fxMesa, scrX, scrY, n, visMask); + for (i = 0; i < wrappedPartStart; i++) { + if (visMask[i] && (!mask || mask[i])) { + GLuint z = GET_ORDINARY_FB_DATA(&ReadParams, GLuint, + scrX + i, scrY) & 0x00FFFFFF; + z |= (stencil[i] & 0xFF) << 24; + PUT_ORDINARY_FB_DATA(&ReadParams, GLuint, scrX + i, scrY, z); + } + } + for (; i < n; i++) { + if (visMask[i] && (!mask || mask[i])) { + GLuint z = GET_WRAPPED_FB_DATA(&ReadParams, GLuint, + scrX + i, scrY) & 0x00FFFFFF; + z |= (stencil[i] & 0xFF) << 24; + PUT_WRAPPED_FB_DATA(&ReadParams, GLuint, scrX + i, scrY, z); + } + } + } + WRITE_FB_SPAN_UNLOCK(fxMesa, GR_BUFFER_AUXBUFFER); +} + + +static void +read_stencil_span(GLcontext * ctx, GLuint n, GLint x, GLint y, + GLstencil stencil[]) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GrLfbInfo_t info; + GrLfbInfo_t backBufferInfo; + + GetBackBufferInfo(fxMesa, &backBufferInfo); + /* + * Note that the _LOCK macro adds a curly brace, + * and the UNLOCK macro removes it. + */ + READ_FB_SPAN_LOCK(fxMesa, info, GR_BUFFER_AUXBUFFER); + { + const GLint winY = fxMesa->y_offset + fxMesa->height - 1; + const GLint winX = fxMesa->x_offset; + GLuint i; + LFBParameters ReadParams; + int wrappedPartStart; + + /* + * Convert to screen coordinates. + */ + x += winX; + y = winY - y; + GetFbParams(fxMesa, &info, &backBufferInfo, &ReadParams, + sizeof(GLuint)); + if (ReadParams.firstWrappedX <= x) { + wrappedPartStart = 0; + } + else if (n <= (ReadParams.firstWrappedX - x)) { + wrappedPartStart = n; + } + else { + wrappedPartStart = (ReadParams.firstWrappedX - x); + } + for (i = 0; i < wrappedPartStart; i++) { + stencil[i] = (GET_ORDINARY_FB_DATA(&ReadParams, GLuint, + x + i, y) >> 24) & 0xFF; + } + for (; i < n; i++) { + stencil[i] = (GET_WRAPPED_FB_DATA(&ReadParams, GLuint, + x + i, y) >> 24) & 0xFF; + } + } + READ_FB_SPAN_UNLOCK(fxMesa, GR_BUFFER_AUXBUFFER); +} + + +static void +write_stencil_pixels(GLcontext * ctx, GLuint n, + const GLint x[], const GLint y[], + const GLstencil stencil[], const GLubyte mask[]) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GrLfbInfo_t info; + GrLfbInfo_t backBufferInfo; + + GetBackBufferInfo(fxMesa, &backBufferInfo); + /* + * Note that the _LOCK macro adds a curly brace, + * and the UNLOCK macro removes it. + */ + WRITE_FB_SPAN_LOCK(fxMesa, info, GR_BUFFER_AUXBUFFER, GR_LFBWRITEMODE_ANY); + { + const GLint winY = fxMesa->y_offset + fxMesa->height - 1; + const GLint winX = fxMesa->x_offset; + LFBParameters ReadParams; + GLuint i; + + GetFbParams(fxMesa, &info, &backBufferInfo, &ReadParams, + sizeof(GLuint)); + for (i = 0; i < n; i++) { + const GLint scrX = winX + x[i]; + const GLint scrY = winY - y[i]; + if ((!mask || mask[i]) && visible_pixel(fxMesa, scrX, scrY)) { + GLuint z = + GET_FB_DATA(&ReadParams, GLuint, scrX, scrY) & 0x00FFFFFF; + z |= (stencil[i] & 0xFF) << 24; + PUT_FB_DATA(&ReadParams, GLuint, scrX, scrY, z); + } + } + } + WRITE_FB_SPAN_UNLOCK(fxMesa, GR_BUFFER_AUXBUFFER); +} + + +static void +read_stencil_pixels(GLcontext * ctx, GLuint n, const GLint x[], + const GLint y[], GLstencil stencil[]) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GrLfbInfo_t info; + GrLfbInfo_t backBufferInfo; + + GetBackBufferInfo(fxMesa, &backBufferInfo); + /* + * Note that the _LOCK macro adds a curly brace, + * and the UNLOCK macro removes it. + */ + READ_FB_SPAN_LOCK(fxMesa, info, GR_BUFFER_AUXBUFFER); + { + const GLint winY = fxMesa->y_offset + fxMesa->height - 1; + const GLint winX = fxMesa->x_offset; + GLuint i; + LFBParameters ReadParams; + + GetFbParams(fxMesa, &info, &backBufferInfo, &ReadParams, + sizeof(GLuint)); + for (i = 0; i < n; i++) { + const GLint scrX = winX + x[i]; + const GLint scrY = winY - y[i]; + stencil[i] = + (GET_FB_DATA(&ReadParams, GLuint, scrX, scrY) >> 24) & 0xFF; + } + } + READ_FB_SPAN_UNLOCK(fxMesa, GR_BUFFER_AUXBUFFER); +} + +void +fxSetupDDSpanPointers(GLcontext * ctx) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + + if (ctx->Visual->RedBits == 5 && + ctx->Visual->GreenBits == 6 && + ctx->Visual->BlueBits == 5 && ctx->Visual->AlphaBits == 0) { + /* 16bpp mode */ + ctx->Driver.WriteRGBASpan = write_R5G6B5_rgba_span; + ctx->Driver.WriteRGBSpan = write_R5G6B5_rgb_span; + ctx->Driver.WriteMonoRGBASpan = write_R5G6B5_mono_span; + ctx->Driver.WriteRGBAPixels = write_R5G6B5_pixels; + ctx->Driver.WriteMonoRGBAPixels = write_R5G6B5_mono_pixels; + ctx->Driver.ReadRGBASpan = read_R5G6B5_span; + ctx->Driver.ReadRGBAPixels = read_R5G6B5_pixels; + } + else if (ctx->Visual->RedBits == 8 && + ctx->Visual->GreenBits == 8 && + ctx->Visual->BlueBits == 8 && ctx->Visual->AlphaBits == 0) { + /* 24bpp mode */ + ctx->Driver.WriteRGBASpan = write_R8G8B8_rgba_span; + ctx->Driver.WriteRGBSpan = write_R8G8B8_rgb_span; + ctx->Driver.WriteMonoRGBASpan = write_R8G8B8_mono_span; + ctx->Driver.WriteRGBAPixels = write_R8G8B8_pixels; + ctx->Driver.WriteMonoRGBAPixels = write_R8G8B8_mono_pixels; + ctx->Driver.ReadRGBASpan = read_R8G8B8_span; + ctx->Driver.ReadRGBAPixels = read_R8G8B8_pixels; + } + else if (ctx->Visual->RedBits == 8 && + ctx->Visual->GreenBits == 8 && + ctx->Visual->BlueBits == 8 && ctx->Visual->AlphaBits == 8) { + /* 32bpp mode */ + ctx->Driver.WriteRGBASpan = write_R8G8B8A8_rgba_span; + ctx->Driver.WriteRGBSpan = write_R8G8B8A8_rgb_span; + ctx->Driver.WriteMonoRGBASpan = write_R8G8B8A8_mono_span; + ctx->Driver.WriteRGBAPixels = write_R8G8B8A8_pixels; + ctx->Driver.WriteMonoRGBAPixels = write_R8G8B8A8_mono_pixels; + ctx->Driver.ReadRGBASpan = read_R8G8B8A8_span; + ctx->Driver.ReadRGBAPixels = read_R8G8B8A8_pixels; + } + else { + abort(); + } + + if (fxMesa->haveHwStencil) { + ctx->Driver.WriteStencilSpan = write_stencil_span; + ctx->Driver.ReadStencilSpan = read_stencil_span; + ctx->Driver.WriteStencilPixels = write_stencil_pixels; + ctx->Driver.ReadStencilPixels = read_stencil_pixels; + } + + ctx->Driver.WriteDepthSpan = fxDDWriteDepthSpan; + ctx->Driver.WriteDepthPixels = fxDDWriteDepthPixels; + ctx->Driver.ReadDepthSpan = fxDDReadDepthSpan; + ctx->Driver.ReadDepthPixels = fxDDReadDepthPixels; + + ctx->Driver.WriteCI8Span = NULL; + ctx->Driver.WriteCI32Span = NULL; + ctx->Driver.WriteMonoCISpan = NULL; + ctx->Driver.WriteCI32Pixels = NULL; + ctx->Driver.WriteMonoCIPixels = NULL; + ctx->Driver.ReadCI32Span = NULL; + ctx->Driver.ReadCI32Pixels = NULL; +} diff --git a/xc/lib/GL/mesa/src/drv/tdfx/fxddtex.c b/xc/lib/GL/mesa/src/drv/tdfx/fxddtex.c new file mode 100644 index 000000000..11438f440 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/tdfx/fxddtex.c @@ -0,0 +1,1647 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/fxddtex.c,v 1.1 2000/09/24 13:51:14 alanh Exp $ */ +/* + * Mesa 3-D graphics library + * Version: 3.3 + * + * 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. + * + * + * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the + * terms stated above. + * + * Thank you for your contribution, David! + * + * Please make note of the above copyright/license statement. If you + * contributed code or bug fixes to this code under the previous (GNU + * Library) license and object to the new license, your code will be + * removed at your request. Please see the Mesa docs/COPYRIGHT file + * for more information. + * + * Additional Mesa/3Dfx driver developers: + * Daryll Strauss <daryll@precisioninsight.com> + * Keith Whitwell <keith@precisioninsight.com> + * + * See fxapi.h for more revision/author details. + */ + + +#include "fxdrv.h" +#include "fxddtex.h" +#include "fxtexman.h" +#include "fxsetup.h" +#include "image.h" +#include "texutil.h" + + +void +fxPrintTextureData(tfxTexInfo * ti) +{ + fprintf(stderr, "Texture Data:\n"); + if (ti->tObj) { + fprintf(stderr, "\tName: %d\n", ti->tObj->Name); + fprintf(stderr, "\tBaseLevel: %d\n", ti->tObj->BaseLevel); + fprintf(stderr, "\tSize: %d x %d\n", + ti->tObj->Image[ti->tObj->BaseLevel]->Width, + ti->tObj->Image[ti->tObj->BaseLevel]->Height); + } + else + fprintf(stderr, "\tName: UNNAMED\n"); + fprintf(stderr, "\tLast used: %d\n", ti->lastTimeUsed); + fprintf(stderr, "\tTMU: %ld\n", ti->whichTMU); + fprintf(stderr, "\t%s\n", (ti->isInTM) ? "In TMU" : "Not in TMU"); + if (ti->tm[0]) + fprintf(stderr, "\tMem0: %x-%x\n", (unsigned) ti->tm[0]->startAddr, + (unsigned) ti->tm[0]->endAddr); + if (ti->tm[1]) + fprintf(stderr, "\tMem1: %x-%x\n", (unsigned) ti->tm[1]->startAddr, + (unsigned) ti->tm[1]->endAddr); + fprintf(stderr, "\tMipmaps: %d-%d\n", ti->minLevel, ti->maxLevel); + fprintf(stderr, "\tFilters: min %d min %d\n", + (int) ti->minFilt, (int) ti->maxFilt); + fprintf(stderr, "\tClamps: s %d t %d\n", (int) ti->sClamp, + (int) ti->tClamp); + fprintf(stderr, "\tScales: s %f t %f\n", ti->sScale, ti->tScale); + fprintf(stderr, "\tInt Scales: s %d t %d\n", + ti->int_sScale / 0x800000, ti->int_tScale / 0x800000); + fprintf(stderr, "\t%s\n", + (ti->fixedPalette) ? "Fixed palette" : "Non fixed palette"); + fprintf(stderr, "\t%s\n", + (ti->validated) ? "Validated" : "Not validated"); +} + + +/************************************************************************/ +/*************************** Texture Mapping ****************************/ +/************************************************************************/ + +static void +fxTexInvalidate(GLcontext * ctx, struct gl_texture_object *tObj) +{ + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + tfxTexInfo *ti; + + ti = fxTMGetTexInfo(tObj); + if (ti->isInTM) + fxTMMoveOutTM(fxMesa, tObj); /* TO DO: SLOW but easy to write */ + + ti->validated = GL_FALSE; + fxMesa->new_state |= FX_NEW_TEXTURING; + ctx->Driver.RenderStart = fxSetupFXUnits; +} + +static tfxTexInfo * +fxAllocTexObjData(fxMesaContext fxMesa) +{ + tfxTexInfo *ti; + int i; + + if (!(ti = CALLOC(sizeof(tfxTexInfo)))) { + gl_problem(NULL, "fx Driver: out of memory !\n"); + return NULL; + } + + ti->validated = GL_FALSE; + ti->isInTM = GL_FALSE; + + ti->whichTMU = FX_TMU_NONE; + + ti->tm[FX_TMU0] = NULL; + ti->tm[FX_TMU1] = NULL; + + ti->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED; + ti->maxFilt = GR_TEXTUREFILTER_BILINEAR; + + ti->sClamp = GR_TEXTURECLAMP_WRAP; + ti->tClamp = GR_TEXTURECLAMP_WRAP; + + ti->mmMode = GR_MIPMAP_NEAREST; + ti->LODblend = FXFALSE; + + for (i = 0; i < MAX_TEXTURE_LEVELS; i++) { + ti->mipmapLevel[i].data = NULL; + } + + return ti; +} + + +/* + * Called via glBindTexture. + */ +void +fxDDTexBind(GLcontext * ctx, GLenum target, struct gl_texture_object *tObj) +{ + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + tfxTexInfo *ti; + + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: fxDDTexBind(%d,%x)\n", tObj->Name, + (GLuint) tObj->DriverData); + } + + if (target != GL_TEXTURE_2D) + return; + + if (!tObj->DriverData) { + tObj->DriverData = fxAllocTexObjData(fxMesa); + } + + ti = fxTMGetTexInfo(tObj); + + fxMesa->texBindNumber++; + ti->lastTimeUsed = fxMesa->texBindNumber; + + fxMesa->new_state |= FX_NEW_TEXTURING; + ctx->Driver.RenderStart = fxSetupFXUnits; +} + +void +fxDDTexEnv(GLcontext * ctx, GLenum target, GLenum pname, + const GLfloat * param) +{ + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + + if (MESA_VERBOSE & VERBOSE_DRIVER) { + if (param) + fprintf(stderr, "fxmesa: texenv(%x,%x)\n", pname, + (GLint) (*param)); + else + fprintf(stderr, "fxmesa: texenv(%x)\n", pname); + } + + /* apply any lod biasing right now */ + if (pname == GL_TEXTURE_LOD_BIAS_EXT) { + FX_grTexLodBiasValue(GR_TMU0, *param); + if (fxMesa->haveTwoTMUs) { + FX_grTexLodBiasValue(GR_TMU1, *param); + } + } + + /* invalidate currently bound texture(s) */ + { + int i; + for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { + struct gl_texture_object *tObj = ctx->Texture.Unit[i].CurrentD[2]; + if (!tObj->DriverData) { + tObj->DriverData = fxAllocTexObjData(fxMesa); + } + fxTexInvalidate(ctx, tObj); + } + } + + fxMesa->new_state |= FX_NEW_TEXTURING; + ctx->Driver.RenderStart = fxSetupFXUnits; +} + +void +fxDDTexParam(GLcontext * ctx, GLenum target, struct gl_texture_object *tObj, + GLenum pname, const GLfloat * params) +{ + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + GLenum param = (GLenum) (GLint) params[0]; + tfxTexInfo *ti; + + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: fxDDTexParam(%d,%x,%x,%x)\n", tObj->Name, + (GLuint) tObj->DriverData, pname, param); + } + + if (target != GL_TEXTURE_2D) + return; + + if (!tObj->DriverData) + tObj->DriverData = fxAllocTexObjData(fxMesa); + + ti = fxTMGetTexInfo(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_NEAREST: + ti->mmMode = GR_MIPMAP_NEAREST; + ti->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED; + ti->LODblend = FXFALSE; + break; + case GL_LINEAR_MIPMAP_NEAREST: + ti->mmMode = GR_MIPMAP_NEAREST; + ti->minFilt = GR_TEXTUREFILTER_BILINEAR; + ti->LODblend = FXFALSE; + break; + case GL_NEAREST_MIPMAP_LINEAR: + 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; + case GL_LINEAR_MIPMAP_LINEAR: + 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; + default: + break; + } + fxTexInvalidate(ctx, tObj); + break; + + case GL_TEXTURE_MAG_FILTER: + switch (param) { + case GL_NEAREST: + ti->maxFilt = GR_TEXTUREFILTER_POINT_SAMPLED; + break; + case GL_LINEAR: + ti->maxFilt = GR_TEXTUREFILTER_BILINEAR; + break; + default: + break; + } + fxTexInvalidate(ctx, tObj); + 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 |= FX_NEW_TEXTURING; + ctx->Driver.RenderStart = fxSetupFXUnits; + 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 |= FX_NEW_TEXTURING; + ctx->Driver.RenderStart = fxSetupFXUnits; + 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: + fxTexInvalidate(ctx, tObj); + break; + case GL_TEXTURE_MAX_LEVEL: + fxTexInvalidate(ctx, tObj); + break; + + default: + break; + } +} + + +/* + * Called via glDeleteTextures to delete a texture object. + * Here, we delete the Glide data associated with the texture. + */ +void +fxDDTexDel(GLcontext * ctx, struct gl_texture_object *tObj) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + tfxTexInfo *ti = fxTMGetTexInfo(tObj); + + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: fxDDTexDel(%d,%p)\n", tObj->Name, ti); + } + + if (!ti) + return; + + fxTMFreeTexture(fxMesa, tObj); + + FREE(ti); + tObj->DriverData = NULL; + + ctx->NewState |= NEW_TEXTURING; +} + + +/* + * Return true if texture is resident, false otherwise. + */ +GLboolean +fxDDIsTextureResident(GLcontext *ctx, struct gl_texture_object *tObj) +{ + tfxTexInfo *ti = fxTMGetTexInfo(tObj); + /*printf("resident %d\n", (int) (ti && ti->isInTM));*/ + return (GLboolean) (ti && ti->isInTM); +} + + + +/* + * 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; + } +} + + + +void +fxDDTexPalette(GLcontext * ctx, struct gl_texture_object *tObj) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + + if (tObj) { + /* per-texture palette */ + tfxTexInfo *ti; + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: fxDDTexPalette(%d,%x)\n", + tObj->Name, (GLuint) tObj->DriverData); + } + if (!tObj->DriverData) + tObj->DriverData = fxAllocTexObjData(fxMesa); + ti = fxTMGetTexInfo(tObj); + convertPalette(ti->palette.data, &tObj->Palette); + fxTexInvalidate(ctx, tObj); + } + else { + /* global texture palette */ + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: fxDDTexPalette(global)\n"); + } + convertPalette(fxMesa->glbPalette.data, &ctx->Texture.Palette); + fxMesa->new_state |= FX_NEW_TEXTURING; + ctx->Driver.RenderStart = fxSetupFXUnits; + } +} + + +void +fxDDTexUseGlbPalette(GLcontext * ctx, GLboolean state) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: fxDDTexUseGlbPalette(%d)\n", state); + } + + if (state) { + fxMesa->haveGlobalPaletteTexture = 1; + + FX_grTexDownloadTable(fxMesa, GR_TMU0, GR_TEXTABLE_PALETTE_6666_EXT, + &(fxMesa->glbPalette)); + if (fxMesa->haveTwoTMUs) + FX_grTexDownloadTable(fxMesa, GR_TMU1, GR_TEXTABLE_PALETTE_6666_EXT, + &(fxMesa->glbPalette)); + } + else { + fxMesa->haveGlobalPaletteTexture = 0; + + if ((ctx->Texture.Unit[0].Current == ctx->Texture.Unit[0].CurrentD[2]) + && (ctx->Texture.Unit[0].Current != NULL)) { + struct gl_texture_object *tObj = ctx->Texture.Unit[0].Current; + + if (!tObj->DriverData) + tObj->DriverData = fxAllocTexObjData(fxMesa); + + fxTexInvalidate(ctx, tObj); + } + } +} + + +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; + } +} + +/* Need different versions for different cpus. + */ +#define INT_TRICK(pow2) (0x800000 * (pow2)) + +/* + * Compute various texture image parameters. + * Input: w, h - source texture width and height + * Output: lodlevel - Glide lod level token + * aspectratio - Glide aspect ratio token + * sscale - S scale factor used during triangle setup + * tscale - T scale factor used during triangle setup + * i_sscale - integer S scale used during triangle setup + * i_tscale - integer T scale used during triangle setup + * wscale - OpenGL -> Glide image width scale factor + * hscale - OpenGL -> Glide image height scale factor + */ +void +fxTexGetInfo(const GLcontext *ctx, int w, int h, + GrLOD_t *lodlevel, GrAspectRatio_t *aspectratio, + float *sscale, float *tscale, + int *i_sscale, int *i_tscale, + int *wscale, int *hscale) +{ + int logw, logh, ar, lod, is, it, 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; +#if 1 + s = 256.0; + is = INT_TRICK(8); +#else + s = ctx->Const.MaxTextureSize; + is = INT_TRICK(ctx->Const.MaxTextureLevels - 1); +#endif + ws = 1; + if (ar < 3) { +#if 1 + t = 256 >> ar; + it = INT_TRICK(8 - ar); +#else + t = ctx->Const.MaxTextureSize >> ar; + it = INT_TRICK(ctx->Const.MaxTextureLevels - 1 - ar); +#endif + hs = 1; + } + else { + t = 32.0; + it = INT_TRICK(5); + hs = 1 << (ar - 3); + } + } + else { + ASSERT(width < height); + lod = logh; +#if 1 + t = 256.0; + it = INT_TRICK(8); +#else + t = ctx->Const.MaxTextureSize; + it = INT_TRICK(ctx->Const.MaxTextureLevels - 1); +#endif + hs = 1; + if (-ar < 3) { +#if 1 + s = 256 >> -ar; + is = INT_TRICK(8 + ar); +#else + s = ctx->Const.MaxTextureSize >> - ar; + is = INT_TRICK(ctx->Const.MaxTextureLevels - 1 + ar); +#endif + ws = 1; + } + else { + s = 32.0; + is = INT_TRICK(5); + ws = 1 << (-ar - 3); + } + } + if (ar < -3) + ar = -3; + if (ar > 3) + ar = 3; + + 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; + if (i_sscale) + *i_sscale = is; + if (i_tscale) + *i_tscale = it; +} + +/* + * Given an OpenGL internal texture format, return the corresponding + * Glide internal texture format and base texture format. + * If allow32bpp is true, we'll return 32-bit texel formats when + * appropriate. + */ +void +fxTexGetFormat(GLenum glformat, GrTextureFormat_t *glideFormat, + GLint *glFormat, MesaIntTexFormat *mesaFormat, + GLint *texelSize, GLboolean allow32bpp) +{ + switch (glformat) { + 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 (glFormat) + *glFormat = GL_LUMINANCE; + 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 (glFormat) + *glFormat = GL_LUMINANCE_ALPHA; + 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 (glFormat) + *glFormat = GL_INTENSITY; + 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 (glFormat) + *glFormat = GL_ALPHA; + 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 (glFormat) + *glFormat = GL_RGB; + 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 (glFormat) + *glFormat = GL_RGB; + if (mesaFormat) + *mesaFormat = MESA_FF_R8_G8_B8; + if (texelSize) + *texelSize = 4; + } + else { + if (glideFormat) + *glideFormat = GR_TEXFMT_RGB_565; + if (glFormat) + *glFormat = GL_RGB; + 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 (glFormat) + *glFormat = GL_RGBA; + 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 (glFormat) + *glFormat = GL_RGBA; + if (mesaFormat) + *mesaFormat = MESA_A8_R8_G8_B8; + if (texelSize) + *texelSize = 4; + } + else { + if (glideFormat) + *glideFormat = GR_TEXFMT_ARGB_4444; + if (glFormat) + *glFormat = GL_RGBA; + 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 (glFormat) + *glFormat = GL_RGBA; + 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 (glFormat) + *glFormat = GL_RGBA; /* XXX why is this RGBA? */ + 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 (glFormat) + *glFormat = GL_COMPRESSED_RGB_FXT1_3DFX; + 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 (glFormat) + *glFormat = GL_COMPRESSED_RGBA_FXT1_3DFX; + if (mesaFormat) + *mesaFormat = MESA_A8_R8_G8_B8; + if (texelSize) + *texelSize = 4; + break; + default: + gl_problem(NULL, "bad texture format in fxTexGetFormat()\n"); + break; + } +} + + +/**********************************************************************/ +/**** NEW TEXTURE IMAGE FUNCTIONS ****/ +/**********************************************************************/ + +static FxBool TexusFatalError = FXFALSE; +static FxBool TexusError = FXFALSE; + +#define TX_DITHER_NONE 0x00000000 + +static void +fxTexusError(const char *string, FxBool fatal) +{ + gl_problem(NULL, string); + /* + * Just propagate the fatal value up. + */ + TexusError = FXTRUE; + TexusFatalError = fatal; +} + +GLboolean +fxDDTexImage2D(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) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + const GLboolean allow32bpt = fxMesa->haveHwStencil; + GrTextureFormat_t gldformat; + tfxTexInfo *ti; + tfxMipMapLevel *mml; + GLint dstWidth, dstHeight, wScale, hScale, texelSize, dstStride; + MesaIntTexFormat intFormat; + GLboolean isCompressedFormat; + GLint texsize; + void *uncompressedImage; + + if (target == GL_PROXY_TEXTURE_2D) { + /* XXX not possible for now */ + + } + + isCompressedFormat = texImage->IsCompressed; + if (target != GL_TEXTURE_2D || texImage->Border > 0) + return GL_FALSE; + + if (!texObj->DriverData) + texObj->DriverData = fxAllocTexObjData(fxMesa); + + ti = fxTMGetTexInfo(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. + */ + fxTexGetFormat(texImage->IntFormat, &gldformat, NULL, &intFormat, + &texelSize, allow32bpt); + + /* Determine width and height scale factors for texture. + * Remember, Glide is limited to 8:1 aspect ratios. + */ + fxTexGetInfo(ctx, + texImage->Width, texImage->Height, + NULL, /* lod level */ + NULL, /* aspect ratio */ + NULL, NULL, /* sscale, tscale */ + NULL, NULL, /* i_sscale, i_tscale */ + &wScale, &hScale); + dstWidth = texImage->Width * wScale; + dstHeight = texImage->Height * hScale; + if (isCompressedFormat) { + texsize = fxDDCompressedImageSize(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; + fxTexInvalidate(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; + (*txErrorSetCallbackPtr)(fxTexusError, &oldErrorCallback); + (*txImgQuantizePtr)((char *)mml->data, + (char *)uncompressedImage, + texImage->Width, + texImage->Height, + gldformat, + TX_DITHER_NONE); + (*txErrorSetCallbackPtr)(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 = (unsigned short *)0; + TexusFatalError = FXFALSE; + return(GL_FALSE); + } + } + if (ti->validated && ti->isInTM) { + fxTMReloadMipMapLevel(ctx, texObj, level); + } + else { + fxTexInvalidate(ctx, texObj); + } + + *retainInternalCopy = GL_FALSE; + return GL_TRUE; +} + + +GLboolean +fxDDTexSubImage2D(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) +{ + tfxTexInfo *ti; + GLint wscale, hscale, dstStride = 0; + tfxMipMapLevel *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; + + ti = fxTMGetTexInfo(texObj); + mml = &ti->mipmapLevel[level]; + + fxTexGetInfo(ctx, texImage->Width, texImage->Height, NULL, NULL, + 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); + return GL_FALSE; + } + /* + * Now that we have converted the data, then compress it. + */ + (*txErrorSetCallbackPtr)(fxTexusError, &oldErrorCallback); + (*txImgQuantizePtr)((char *)mml->data, + (char *)uncompressedImage, + mml->width, + mml->height, + mml->glideFormat, + TX_DITHER_NONE); + (*txErrorSetCallbackPtr)(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; + } + + if (ti->validated && ti->isInTM) + /* Don't use this, it's very broken. Download whole image for now.*/ +#if 0 + fxTMReloadSubMipMapLevel(ctx, texObj, level, yoffset, height); +#else + fxTMReloadMipMapLevel(ctx, texObj, level); +#endif + else + fxTexInvalidate(ctx, texObj); + + return GL_TRUE; +} + + +/**********************************************************************/ +/**** COMPRESSED TEXTURE IMAGE FUNCTIONS ****/ +/**********************************************************************/ + +GLboolean +fxDDCompressedTexImage2D( GLcontext *ctx, GLenum target, + GLint level, GLsizei imageSize, + const GLvoid *data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage, + GLboolean *retainInternalCopy) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + const GLboolean allow32bpt = fxMesa->haveHwStencil; + GrTextureFormat_t gldformat; + tfxTexInfo *ti; + tfxMipMapLevel *mml; + GLint dstWidth, dstHeight, wScale, hScale, texelSize; + MesaIntTexFormat intFormat; + GLboolean isCompressedFormat; + GLsizei texsize; + + if (target == GL_PROXY_TEXTURE_2D) { + /* XXX not possible for now */ + + } + + if (target != GL_TEXTURE_2D || texImage->Border > 0) + return GL_FALSE; + + if (!texObj->DriverData) + texObj->DriverData = fxAllocTexObjData(fxMesa); + + ti = fxTMGetTexInfo(texObj); + mml = &ti->mipmapLevel[level]; + + isCompressedFormat = fxDDIsCompressedGlideFormatMacro(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. + */ + fxTexGetFormat(texImage->IntFormat, &gldformat, NULL, &intFormat, + &texelSize, allow32bpt); + + /* Determine width and height scale factors for texture. + * Remember, Glide is limited to 8:1 aspect ratios. + */ + fxTexGetInfo(ctx, + texImage->Width, texImage->Height, + NULL, /* lod level */ + NULL, /* aspect ratio */ + NULL, NULL, /* sscale, tscale */ + NULL, NULL, /* i_sscale, i_tscale */ + &wScale, &hScale); + dstWidth = texImage->Width * wScale; + dstHeight = texImage->Height * hScale; + /* housekeeping */ + _mesa_set_teximage_component_sizes(intFormat, texImage); + + texsize = fxDDCompressedImageSize(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; + fxTexInvalidate(ctx, texObj); + } + + MEMCPY(mml->data, data, imageSize); + if (ti->validated && ti->isInTM) { + fxTMReloadMipMapLevel(ctx, texObj, level); + } + else { + fxTexInvalidate(ctx, texObj); + } + + *retainInternalCopy = GL_FALSE; + return GL_TRUE; +} + +GLboolean +fxDDCompressedTexSubImage2D( 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 ) +{ + tfxTexInfo *ti; + tfxMipMapLevel *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 = fxTMGetTexInfo(texObj); + mml = &ti->mipmapLevel[level]; + if (imageSize != mml->dataSize) { + return(GL_FALSE); + } + MEMCPY(data, mml->data, imageSize); + return(GL_TRUE); +} + +#if 0 +static void +PrintTexture(int w, int h, int c, const GLubyte * data) +{ + 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 + + +/* + * Return a texture image to Mesa. This is either to satisfy + * a glGetTexImage() call or to prepare for software texturing. + */ +GLvoid * +fxDDGetTexImage(GLcontext * ctx, GLenum target, GLint level, + const struct gl_texture_object *texObj, + GLenum * formatOut, GLenum * typeOut, + GLboolean * freeImageOut) +{ + tfxTexInfo *ti; + tfxMipMapLevel *mml; + + if (target != GL_TEXTURE_2D) + return NULL; + + if (!texObj->DriverData) + return NULL; + + ti = fxTMGetTexInfo(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 fxDDGetTexImage"); + return(NULL); + } + (*txImgDequantizeFXT1Ptr)((FxU32 *)uncompressedImage, + (FxU32 *)mml->data, + mml->width, + mml->height); + break; + default: + gl_problem(NULL, "Bad glideFormat in fxDDGetTexImage"); + 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 +fxDDGetCompressedTexImage( GLcontext *ctx, GLenum target, + GLint lod, void *image, + const struct gl_texture_object *texObj, + struct gl_texture_image *texImage ) +{ + tfxTexInfo *ti; + tfxMipMapLevel *mml; + + if (target != GL_TEXTURE_2D) + return; + + if (!texObj->DriverData) + return; + + ti = fxTMGetTexInfo(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 +fxDDSpecificCompressedTexFormat(GLcontext *ctx, + GLint internalFormat, + GLint numDimensions) +{ + 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 (!txImgQuantizePtr || !txImgDequantizeFXT1Ptr) { + 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; +} + +/* + * Calculate a specific texture format given a generic + * texture format. + */ +GLint +fxDDBaseCompressedTexFormat(GLcontext *ctx, + GLint internalFormat) +{ + switch (internalFormat) { + case GL_COMPRESSED_RGB_FXT1_3DFX: + return(GL_RGB); + case GL_COMPRESSED_RGBA_FXT1_3DFX: + return(GL_RGBA); + } + return -1; +} + +/* + * 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. + */ +GLboolean +fxDDIsCompressedFormat(GLcontext *ctx, GLint internalFormat) +{ + return(fxDDIsCompressedFormatMacro(internalFormat)); +} + + +/* + * 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 +fxDDCompressedImageSize(GLcontext *ctx, + GLenum intFormat, + GLuint numDimensions, + GLuint width, + GLuint height, + GLuint depth) +{ + 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); +} diff --git a/xc/lib/GL/mesa/src/drv/tdfx/fxddtex.h b/xc/lib/GL/mesa/src/drv/tdfx/fxddtex.h new file mode 100644 index 000000000..24b63ed07 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/tdfx/fxddtex.h @@ -0,0 +1,99 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/fxddtex.h,v 1.1 2000/09/24 13:51:15 alanh Exp $ */ +#ifndef FXDDTEX_H +#define FXDDTEX_H + + +#include "texutil.h" + + +extern void fxPrintTextureData(tfxTexInfo * ti); + +extern void fxTexGetFormat(GLenum, GrTextureFormat_t *, GLint *, + MesaIntTexFormat *, GLint *, GLboolean); + +extern void fxTexGetInfo(const GLcontext *, int, int, GrLOD_t *, + GrAspectRatio_t *, + float *, float *, int *, int *, int *, int *); + +extern GLboolean fxDDTexImage2D(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 fxDDTexSubImage2D(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 GLvoid *fxDDGetTexImage(GLcontext * ctx, GLenum target, GLint level, + const struct gl_texture_object *texObj, + GLenum * formatOut, GLenum * typeOut, + GLboolean * freeImageOut); + +extern GLboolean fxDDCompressedTexImage2D( 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 fxDDCompressedTexSubImage2D( 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 void fxDDGetCompressedTexImage( GLcontext *ctx, GLenum target, + GLint lod, void *image, + const struct gl_texture_object *texObj, + struct gl_texture_image *texImage ); +extern GLint fxDDSpecificCompressedTexFormat(GLcontext *ctx, + GLint internalFormat, + GLint numDimensions); +extern GLint fxDDBaseCompressedTexFormat(GLcontext *ctx, + GLint internalFormat); + +#define fxDDIsCompressedFormatMacro(internalFormat) \ + (((internalFormat) == GL_COMPRESSED_RGB_FXT1_3DFX) || \ + ((internalFormat) == GL_COMPRESSED_RGBA_FXT1_3DFX)) +#define fxDDIsCompressedGlideFormatMacro(internalFormat) \ + ((internalFormat) == GR_TEXFMT_ARGB_CMP_FXT1) +extern GLboolean fxDDIsCompressedFormat(GLcontext *ctx, GLint internalFormat); + +extern void fxDDTexEnv(GLcontext *, GLenum, GLenum, const GLfloat *); + +extern void fxDDTexParam(GLcontext *, GLenum, struct gl_texture_object *, + GLenum, const GLfloat *); + +extern void fxDDTexBind(GLcontext *, GLenum, struct gl_texture_object *); + +extern void fxDDTexDel(GLcontext *, struct gl_texture_object *); + +extern GLboolean fxDDIsTextureResident(GLcontext *ctx, + struct gl_texture_object *t); + +extern void fxDDTexPalette(GLcontext *, struct gl_texture_object *); + +extern void fxDDTexUseGlbPalette(GLcontext *, GLboolean); + +/* + * Calculate the image size of a compressed texture. + * + * We return 0 if we can't calculate the size. + */ + +extern GLsizei fxDDCompressedImageSize(GLcontext *ctx, + GLenum internalFormat, + GLuint numDimensions, + GLuint width, + GLuint height, + GLuint depth); + +#endif diff --git a/xc/lib/GL/mesa/src/drv/tdfx/fxdrv.h b/xc/lib/GL/mesa/src/drv/tdfx/fxdrv.h new file mode 100644 index 000000000..08622ede1 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/tdfx/fxdrv.h @@ -0,0 +1,800 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/fxdrv.h,v 1.1 2000/09/24 13:51:15 alanh Exp $ */ +/************************************************************************** + +Copyright 1998-1999 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, 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 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: + * Daryll Strauss <daryll@precisioninsight.com> + * Brian Paul <brianp@valinux.com> + */ + + +#ifndef _FXDRV_H_ +#define _FXDRV_H_ + +#ifdef GLX_DIRECT_RENDERING + +#include <sys/time.h> +#include <glide.h> +#include "dri_tmm.h" +#include "dri_mesaint.h" +#include "dri_mesa.h" +#include "dri_xmesaapi.h" +#ifdef XFree86Server +#include "GL/xf86glx.h" +#else +#include "glheader.h" +#endif +#if defined(__linux__) +#include <signal.h> +#endif +#include "context.h" +#include "macros.h" +#include "matrix.h" +#include "mem.h" +#include "texture.h" +#include "types.h" +#include "vb.h" +#include "xform.h" +#include "clip.h" +#include "vbrender.h" +#include "fxglidew.h" + + +/*typedef struct tfxMesaContext *fxMesaContext;*/ + + +typedef struct +{ + drmHandle handle; + drmSize size; + drmAddress map; +} +tdfxRegion, *tdfxRegionPtr; + +typedef struct +{ + tdfxRegion regs; + int deviceID; + int width; + int height; + int mem; + int cpp; + int stride; + int fifoOffset; + int fifoSize; + int fbOffset; + int backOffset; + int depthOffset; + int textureOffset; + int textureSize; + __DRIscreenPrivate *driScrnPriv; +} +tdfxScreenPrivate; + +typedef struct +{ + volatile int fifoPtr; + volatile int fifoRead; + volatile int fifoOwner; + volatile int ctxOwner; + volatile int texOwner; +} +TDFXSAREAPriv; + + +extern void fx_sanity_triangle(fxMesaContext fxMesa, + GrVertex *, GrVertex *, GrVertex *); +#if defined(MESA_DEBUG) && 0 +#define grDrawTriangle fx_sanity_triangle +#endif + + +/* Define some shorter names for these things. + */ +#define XCOORD GR_VERTEX_X_OFFSET +#define YCOORD GR_VERTEX_Y_OFFSET +#define ZCOORD GR_VERTEX_OOZ_OFFSET +#define OOWCOORD GR_VERTEX_OOW_OFFSET + +#define RCOORD GR_VERTEX_R_OFFSET +#define GCOORD GR_VERTEX_G_OFFSET +#define BCOORD GR_VERTEX_B_OFFSET +#define ACOORD GR_VERTEX_A_OFFSET + +#define S0COORD GR_VERTEX_SOW_TMU0_OFFSET +#define T0COORD GR_VERTEX_TOW_TMU0_OFFSET +#define S1COORD GR_VERTEX_SOW_TMU1_OFFSET +#define T1COORD GR_VERTEX_TOW_TMU1_OFFSET + + +#define CLIP_XCOORD 0 /* normal place */ +#define CLIP_YCOROD 1 /* normal place */ +#define CLIP_ZCOORD 2 /* GR_VERTEX_Z_OFFSET */ +#define CLIP_WCOORD 3 /* GR_VERTEX_R_OFFSET */ +#define CLIP_GCOORD 4 /* normal place */ +#define CLIP_BCOORD 5 /* normal place */ +#define CLIP_RCOORD 6 /* GR_VERTEX_OOZ_OFFSET */ +#define CLIP_ACOORD 7 /* normal place */ + + +/* Should have size == 16 * sizeof(float). + */ +typedef struct +{ + GLfloat f[15]; /* Same layout as GrVertex */ + GLubyte mask; /* Unsued */ + GLubyte usermask; /* Unused */ +} +fxVertex; + + +#ifdef __i386__ +#define FXCOLOR4( c ) (* (int *)c) +#else +#define FXCOLOR4( c ) ( \ + ( ((unsigned int)(c[3]))<<24 ) | \ + ( ((unsigned int)(c[2]))<<16 ) | \ + ( ((unsigned int)(c[1]))<<8 ) | \ + ( (unsigned int)(c[0])) ) +#endif + + +#define FX_VB_COLOR(fxm, color) \ + do { \ + if (sizeof(GLint) == 4*sizeof(GLubyte)) { \ + if (fxm->constColor != *(GLuint*)color) { \ + fxm->constColor = *(GLuint*)color; \ + FX_grConstantColorValue(fxm, FXCOLOR4(color)); \ + } \ + } else { \ + FX_grConstantColorValue(fxm, FXCOLOR4(color)); \ + } \ + } while (0) + +#define GOURAUD(x) { \ + GLubyte *col = VB->ColorPtr->data[(x)]; \ + gWin[(x)].v.r=UBYTE_COLOR_TO_FLOAT_255_COLOR(col[0]); \ + gWin[(x)].v.g=UBYTE_COLOR_TO_FLOAT_255_COLOR(col[1]); \ + gWin[(x)].v.b=UBYTE_COLOR_TO_FLOAT_255_COLOR(col[2]); \ + gWin[(x)].v.a=UBYTE_COLOR_TO_FLOAT_255_COLOR(col[3]); \ +} + +#define GOURAUD2(v, c) { \ + GLubyte *col = c; \ + v->r=UBYTE_COLOR_TO_FLOAT_255_COLOR(col[0]); \ + v->g=UBYTE_COLOR_TO_FLOAT_255_COLOR(col[1]); \ + v->b=UBYTE_COLOR_TO_FLOAT_255_COLOR(col[2]); \ + v->a=UBYTE_COLOR_TO_FLOAT_255_COLOR(col[3]); \ +} + + +/* Mergable items first + */ +#define SETUP_RGBA 0x1 +#define SETUP_TMU0 0x2 +#define SETUP_TMU1 0x4 +#define SETUP_XY 0x8 +#define SETUP_Z 0x10 +#define SETUP_W 0x20 + +#define MAX_MERGABLE 0x8 + + +#define FX_NUM_TMU 2 + +#define FX_TMU0 GR_TMU0 +#define FX_TMU1 GR_TMU1 +#define FX_TMU_SPLIT 98 +#define FX_TMU_BOTH 99 +#define FX_TMU_NONE 100 + +/* Used for fxMesa->lastUnitsMode */ + +#define FX_UM_NONE 0x00000000 + +#define FX_UM_E0_REPLACE 0x00000001 +#define FX_UM_E0_MODULATE 0x00000002 +#define FX_UM_E0_DECAL 0x00000004 +#define FX_UM_E0_BLEND 0x00000008 +#define FX_UM_E0_ADD 0x00000010 + +#define FX_UM_E1_REPLACE 0x00000020 +#define FX_UM_E1_MODULATE 0x00000040 +#define FX_UM_E1_DECAL 0x00000080 +#define FX_UM_E1_BLEND 0x00000100 +#define FX_UM_E1_ADD 0x00000200 + +#define FX_UM_E_ENVMODE 0x000003ff + +#define FX_UM_E0_ALPHA 0x00001000 +#define FX_UM_E0_LUMINANCE 0x00002000 +#define FX_UM_E0_LUMINANCE_ALPHA 0x00004000 +#define FX_UM_E0_INTENSITY 0x00008000 +#define FX_UM_E0_RGB 0x00010000 +#define FX_UM_E0_RGBA 0x00020000 + +#define FX_UM_E1_ALPHA 0x00040000 +#define FX_UM_E1_LUMINANCE 0x00080000 +#define FX_UM_E1_LUMINANCE_ALPHA 0x00100000 +#define FX_UM_E1_INTENSITY 0x00200000 +#define FX_UM_E1_RGB 0x00400000 +#define FX_UM_E1_RGBA 0x00800000 + +#define FX_UM_E_IFMT 0x00fff000 + +#define FX_UM_COLOR_ITERATED 0x01000000 +#define FX_UM_COLOR_CONSTANT 0x02000000 +#define FX_UM_ALPHA_ITERATED 0x04000000 +#define FX_UM_ALPHA_CONSTANT 0x08000000 + + +#define PACK_BGRA32(R, G, B, A) \ + ( (((GLuint) (R)) << 16) | \ + (((GLuint) (G)) << 8) | \ + (((GLuint) (B)) ) | \ + (((GLuint) (A)) << 24) ) + +#define PACK_RGBA32(R, G, B, A) \ + ( (((GLuint) (R)) ) | \ + (((GLuint) (G)) << 8) | \ + (((GLuint) (B)) << 16) | \ + (((GLuint) (A)) << 24) ) + +/* + * The first two macros are to pack 8 bit color + * channel values into a 565 format. + */ +#define PACK_RGB16(R, G, B) \ + ((((GLuint) (R) & 0xF8) << 8) | \ + (((GLuint) (G) & 0xFC) << 3) | \ + (((GLuint) (B) & 0xFF) >> 3)) +#define PACK_BGR16(R, G, B) \ + ((((GLuint) (B) & 0xF8) << 8) | \ + (((GLuint) (G) & 0xFC) << 3) | \ + (((GLuint) (R) & 0xFF) >> 3)) +/* + * The second two macros pack 8 bit color channel values + * into 1555 values. + */ +#define PACK_RGBA16(R, G, B, A) \ + (((((GLuint) (A) & 0xFF) > 0) << 15)| \ + (((GLuint) (R) & 0xF8) << 7) | \ + (((GLuint) (G) & 0xF8) << 2) | \ + (((GLuint) (B) & 0xF8) >> 3)) +#define PACK_BGRA16(R, G, B, A) \ + (((((GLuint) (A) & 0xFF) > 0) << 15)| \ + (((GLuint) (B) & 0xF8) << 7) | \ + (((GLuint) (G) & 0xF8) << 2) | \ + (((GLuint) (R) & 0xF8) >> 3)) + +typedef void (*tfxRenderVBFunc) (GLcontext *); + +/* + Memory range from startAddr to endAddr-1 +*/ +typedef struct MemRange_t +{ + struct MemRange_t *next; + FxU32 startAddr, endAddr; +} +MemRange; + + +typedef struct +{ + GLsizei width, height; /* image size */ + GLint texelSize; /* How many bytes to a texel */ + GrTextureFormat_t glideFormat; /* Glide image format */ + unsigned short *data; /* Glide-formated texture image */ + FxU32 dataSize; /* Count of the data size */ +} +tfxMipMapLevel; + + +typedef struct tfxTexInfo_t +{ + struct tfxTexInfo *next; + struct gl_texture_object *tObj; + + GLuint lastTimeUsed; + FxU32 whichTMU; + GLboolean isInTM; + + GrAspectRatio_t aspectRatio; + tfxMipMapLevel mipmapLevel[MAX_TEXTURE_LEVELS]; + + MemRange *tm[FX_NUM_TMU]; + + GLint minLevel, maxLevel; + GLint baseLevelInternalFormat; + + GrTexInfo info; + + GrTextureFilterMode_t minFilt; + GrTextureFilterMode_t maxFilt; + FxBool LODblend; + + GrTextureClampMode_t sClamp; + GrTextureClampMode_t tClamp; + + GrMipMapMode_t mmMode; + + GLfloat sScale, tScale; + GLint int_sScale, int_tScale; /* x86 floating point trick for + * multiplication by powers of 2. + * Used in fxfasttmp.h + */ + GuTexPalette palette; + + GLboolean fixedPalette; + GLboolean validated; +} +tfxTexInfo; + + +typedef struct +{ + GLuint swapBuffer; + GLuint reqTexUpload; + GLuint texUpload; + GLuint memTexUpload; +} +tfxStats; + + +typedef void (*tfxTriViewClipFunc) (struct vertex_buffer * VB, + GLuint v[], GLubyte mask); + +typedef void (*tfxTriClipFunc) (struct vertex_buffer * VB, + GLuint v[], GLuint mask); + + +typedef void (*tfxLineClipFunc) (struct vertex_buffer * VB, + GLuint v1, GLuint v2, GLubyte mask); + + +extern tfxTriViewClipFunc fxTriViewClipTab[0x8]; +extern tfxTriClipFunc fxTriClipStrideTab[0x8]; +extern tfxLineClipFunc fxLineClipTab[0x8]; + +typedef struct +{ + /* Alpha test */ + GLboolean alphaTestEnabled; + GrCmpFnc_t alphaTestFunc; + GrAlpha_t alphaTestRefValue; + + /* Blend function */ + GLboolean blendEnabled; + GrAlphaBlendFnc_t blendSrcFuncRGB; + GrAlphaBlendFnc_t blendDstFuncRGB; + GrAlphaBlendFnc_t blendSrcFuncAlpha; + GrAlphaBlendFnc_t blendDstFuncAlpha; +} +tfxUnitsState; + + + +/* Flags for render_index. + */ +#define FX_OFFSET 0x1 +#define FX_TWOSIDE 0x2 +#define FX_FRONT_BACK 0x4 +#define FX_FLAT 0x8 +#define FX_ANTIALIAS 0x10 +#define FX_FALLBACK 0x20 + + +/* Flags for fxMesa->new_state + */ +#define FX_NEW_TEXTURING 0x1 +#define FX_NEW_BLEND 0x2 +#define FX_NEW_ALPHA 0x4 +#define FX_NEW_DEPTH 0x8 +#define FX_NEW_FOG 0x10 +#define FX_NEW_SCISSOR 0x20 +#define FX_NEW_COLOR_MASK 0x40 +#define FX_NEW_CULL 0x80 +#define FX_NEW_STENCIL 0x100 + +/* FX struct stored in VB->driver_data. + */ +struct tfxMesaVertexBuffer +{ + GLvector1ui clipped_elements; + + fxVertex *verts; + fxVertex *last_vert; + void *vert_store; +#if defined(FX_GLIDE3) + GrVertex **triangle_b; /* Triangle buffer */ + GrVertex **strips_b; /* Strips buffer */ +#endif + + GLuint size; +}; + +#define FX_DRIVER_DATA(vb) ((struct tfxMesaVertexBuffer *)((vb)->driver_data)) +#define FX_CONTEXT(ctx) ((fxMesaContext)((ctx)->DriverCtx)) +#define FX_TEXTURE_DATA(t) fxTMGetTexInfo((t)->Current) + + +#if !defined(FX_PXCONV_TABULAR) \ + && !defined(FX_PXCONV_APPROXIMATION) \ + && !defined(FX_PXCONV_EXACT) +#define FX_PXCONV_TABULAR +#endif +/* These lookup table are used to extract RGB values in [0,255] from + * 16-bit pixel values. + * + * In general, we want to convert 5 or 6 bit numbers to 8 + * bit numbers. + * o In the FX_PXCONV_TABULAR case, we do the numerically + * correct calculation at initialization time, and store + * the results in three large tables. + * o In the FX_PXCONV_APPROXIMATION method we approximate + * the numerically correct value by using the upper bits + * of the 5 or 6 bit value. That is, + * 8bitvalue = 5bitvalue << 3 | (5bitvalue >> 2) + * o In the FX_PXCONV_EXACT method, we calculate the + * exact value at runtime every time, using a floating + * point calculation. + */ +#define FX_PXCONV_INT_FIELD(v, w, s) (((v) >> (s)) & ((1 << (w)) - 1)) +#if defined(FX_PXCONV_TABULAR) +/* These lookup table are used to extract RGB values in [0,255] from + * 16-bit pixel values. + */ +extern GLubyte FX_PixelToRArray[0x10000]; +extern GLubyte FX_PixelToGArray[0x10000]; +extern GLubyte FX_PixelToBArray[0x10000]; +#define FX_PixelToB(fxMesa, v) (FX_PixelToBArray[(v)]) +#define FX_PixelToR(fxMesa, v) (FX_PixelToRArray[(v)]) +#define FX_PixelToG(fxMesa, v) (FX_PixelToGArray[(v)]) +#elif defined(FX_PXCONV_APPROXIMATION) +#define FX_PixelToR(fxMesa, v) \ + ((fxMesa)->bgrOrder \ + ? (FX_PXCONV_INT_FIELD(v, 5, 0) << 3) | FX_PXCONV_INT_FIELD(v, 3, 2) \ + : (FX_PXCONV_INT_FIELD(v, 5, 11) << 3) | FX_PXCONV_INT_FIELD(v, 3, 13)) +#define FX_PixelToG(fxMesa, v) \ + ((FX_PXCONV_INT_FIELD(v, 6, 5) << 2) | FX_PXCONV_INT_FIELD(v, 2, 7)) +#define FX_PixelToB(fxMesa, v) \ + ((fxMesa)->bgrOrder \ + ? (FX_PXCONV_INT_FIELD(v, 5, 11) << 3) | FX_PXCONV_INT_FIELD(v, 3, 13)\ + : (FX_PXCONV_INT_FIELD(v, 5, 0) << 3) | FX_PXCONV_INT_FIELD(v, 3, 2)) +#elif defined(FX_PXCONV_EXACT) +#define FX_PixelToR(fxMesa, v) \ + ((((fxMesa)->bgrOrder \ + ? FX_PXCONV_INT_FIELD(v, 5, 0) + : FX_PXCONV_INT_FIELD(v, 5, 11)) * 8 * 255) / 0xF8) +#define FX_PixelToG(fxMesa, v) \ + ((FX_PXCONV_INT_FIELD(v, 6, 5) * 4 * 255) / 0xFC) +#define FX_PixelToB(fxMesa, v) \ + ((((fxMesa)->bgrOrder \ + ? FX_PXCONV_INT_FIELD(v, 5, 11) + : FX_PXCONV_INT_FIELD(v, 5, 0)) * 8 * 255) / 0xF8) +#else +#error Need to define pixel a conversion method. +#endif + +struct tfxMesaContext +{ + GLcontext *glCtx; /* the core Mesa context */ + GLvisual *glVis; /* describes the color buffer */ + + GLint board; /* the board used for this context */ + GLint width, height; /* size of color buffer */ + + GrBuffer_t currentFB; + + GLboolean bgrOrder; + GLuint depthClear; + GrColor_t color; + GrColor_t clearC; + GrAlpha_t clearA; + GLuint constColor; + GrCullMode_t cullMode; + + tfxUnitsState unitsState; + tfxUnitsState restoreUnitsState; /* saved during multipass */ + + GuTexPalette glbPalette; + + GLuint tmu_source[FX_NUM_TMU]; + GLuint tex_dest[MAX_TEXTURE_UNITS]; + GLuint setupindex; + GLuint partial_setup_index; + GLuint setupdone; + GLuint mergeindex; + GLuint mergeinputs; + GLuint render_index; + GLuint last_tri_caps; + GLuint stw_hint_state; /* for grHints */ + GLuint is_in_hardware; + GLuint new_state; + GLuint using_fast_path, passes, multipass; + + tfxLineClipFunc clip_line; + tfxTriClipFunc clip_tri_stride; + tfxTriViewClipFunc view_clip_tri; + + + /* Texture Memory Manager Data */ + GLboolean umaTexMemory; + GLuint texBindNumber; + GLint tmuSrc; + GLuint freeTexMem[FX_NUM_TMU]; + MemRange *tmPool; + MemRange *tmFree[FX_NUM_TMU]; + + GLenum fogTableMode; + GLfloat fogDensity; + GLfloat fogStart, fogEnd; + GrFog_t *fogTable; + GLint textureAlign; + + /* Acc. functions */ + + points_func PointsFunc; + line_func LineFunc; + triangle_func TriangleFunc; + quad_func QuadFunc; + + render_func **RenderVBTables; + + render_func *RenderVBClippedTab; + render_func *RenderVBCulledTab; + render_func *RenderVBRawTab; + + + tfxStats stats; + + void *state; + + /* Options */ + + GLboolean verbose; + GLboolean haveTwoTMUs; /* True if we really have 2 tmu's */ + GLboolean emulateTwoTMUs; /* True if we present 2 tmu's to mesa. */ + GLboolean haveAlphaBuffer; + GLboolean haveHwStencil; + GLboolean haveGlobalPaletteTexture; + GLboolean isNapalm; + GLint swapInterval; + GLint maxPendingSwapBuffers; + + FX_GrContext_t glideContext; + + int x_offset; + int y_offset; + int y_delta; + int screen_width; + int screen_height; + int initDone; + int clipMinX; + int clipMaxX; + int clipMinY; + int clipMaxY; + int needClip; + + /* stuff added for DRI */ + __DRIcontextPrivate *driContextPriv; + drmContext hHWContext; + int numClipRects; + XF86DRIClipRectPtr pClipRects; + tdfxScreenPrivate *tdfxScrnPriv; +}; + + +typedef void (*tfxSetupFunc) (struct vertex_buffer *, GLuint, GLuint); + +extern int texSwaps; + +extern void fxPrintSetupFlags(const char *msg, GLuint flags); +extern void fxSetupDDPointers(GLcontext *); + +extern void fxDDSetupInit(void); +extern void fxDDCvaInit(void); +extern void fxDDTrifuncInit(void); +extern void fxDDFastPathInit(void); + +extern void fxDDRenderInitGlide3(GLcontext * ctx); + +extern void fxDDChooseRenderState(GLcontext * ctx); + +extern void fxRenderClippedLine(struct vertex_buffer *VB, + GLuint v1, GLuint v2); + +extern void fxRenderClippedTriangle(struct vertex_buffer *VB, + GLuint n, GLuint vlist[]); + + +extern tfxSetupFunc fxDDChooseSetupFunction(GLcontext *); + +extern points_func fxDDChoosePointsFunction(GLcontext *); +extern line_func fxDDChooseLineFunction(GLcontext *); +extern triangle_func fxDDChooseTriangleFunction(GLcontext *); +extern quad_func fxDDChooseQuadFunction(GLcontext *); +extern render_func **fxDDChooseRenderVBTables(GLcontext *); + +extern void fxDDRenderInit(GLcontext *); +extern void fxDDClipInit(void); + +extern void fxSetupDDSpanPointers(GLcontext *); + + +extern void fxDDRegisterVB(struct vertex_buffer *VB); +extern void fxDDUnregisterVB(struct vertex_buffer *VB); +extern void fxDDResizeVB(struct vertex_buffer *VB, GLuint size); + +extern void fxDDMergeAndRender(struct vertex_buffer *VB); + +extern void fxDDCheckPartialRasterSetup(GLcontext * ctx, + struct gl_pipeline_stage *d); + +extern void fxDDPartialRasterSetup(struct vertex_buffer *VB); + +extern void fxDDDoRasterSetup(struct vertex_buffer *VB); + +extern void fxDDRenderElementsDirect(struct vertex_buffer *VB); +extern void fxDDRenderVBIndirectDirect(struct vertex_buffer *VB); + +extern void fxDDFastPath(struct vertex_buffer *VB); + +extern void fxPrintRenderState(const char *msg, GLuint state); +extern void fxPrintHintState(const char *msg, GLuint state); + +extern void fxDDDoRenderVB(struct vertex_buffer *VB); + +extern int fxDDInitFxMesaContext(fxMesaContext fxMesa); + + +extern void fxSetScissorValues(GLcontext * ctx); +extern void fxTMMoveInTM_NoLock(fxMesaContext fxMesa, + struct gl_texture_object *tObj, GLint where); +extern void fxInitPixelTables(fxMesaContext fxMesa, GLboolean bgrOrder); + + + +extern GLboolean tdfxMapAllRegions(__DRIscreenPrivate * driScrnPriv); +extern void tdfxUnmapAllRegions(__DRIscreenPrivate * driScrnPriv); +extern GLboolean tdfxInitHW(__DRIdrawablePrivate * driDrawPrivate, + fxMesaContext cPriv); + +extern void XMesaUpdateState(fxMesaContext fxMesa); + + +/* This is the private interface between Glide and DRI */ +extern void grDRIOpen(char *pFB, char *pRegs, int deviceID, + int width, int height, + int mem, int cpp, int stride, + int fifoOffset, int fifoSize, + int fbOffset, int backOffset, int depthOffset, + int textureOffset, int textureSize, + volatile int *fifoPtr, volatile int *fifoRead); +extern void grDRIPosition(int x, int y, int w, int h, + int numClip, XF86DRIClipRectPtr pClip); +extern void grDRILostContext(void); +extern void grDRIImportFifo(int fifoPtr, int fifoRead); +extern void grDRIInvalidateAll(void); +extern void grDRIResetSAREA(void); +extern void grDRIBufferSwap(FxU32 swapInterval); +extern void grDRISwapClipRects(FxU32 swapInterval, + int numClip, + const XF86DRIClipRectPtr pClip); + + + +/* You can turn this on to find locking conflicts. +#define DEBUG_LOCKING +*/ + +#ifdef DEBUG_LOCKING +extern char *prevLockFile; +extern int prevLockLine; +#define DEBUG_LOCK() \ + do { \ + prevLockFile=(__FILE__); \ + prevLockLine=(__LINE__); \ + } while (0) +#define DEBUG_RESET() \ + do { \ + prevLockFile=0; \ + prevLockLine=0; \ + } while (0) +#define DEBUG_CHECK_LOCK() \ + do { \ + if (prevLockFile) { \ + fprintf(stderr, "LOCK SET!\n\tPrevious %s:%d\n\tCurrent: %s:%d\n", \ + prevLockFile, prevLockLine, __FILE__, __LINE__); \ + exit(1); \ + } \ + } while (0) +#else +#define DEBUG_LOCK() +#define DEBUG_RESET() +#define DEBUG_CHECK_LOCK() +#endif /* DEBUG_LOCKING */ + + +/* !!! We may want to separate locks from locks with validation. + This could be used to improve performance for those things + commands that do not do any drawing !!! */ + +#define DRM_LIGHT_LOCK_RETURN(fd,lock,context,__ret) \ + do { \ + DRM_CAS(lock,context,DRM_LOCK_HELD|context,__ret); \ + if (__ret) drmGetLock(fd,context,0); \ + } while(0) + +#define LOCK_HARDWARE(fxMesa) XMesaUpdateState(fxMesa) + +/* Unlock the hardware using the global current context */ +#define UNLOCK_HARDWARE(fxMesa) \ + do { \ + __DRIcontextPrivate *cPriv = fxMesa->driContextPriv; \ + __DRIdrawablePrivate *dPriv = cPriv->driDrawablePriv; \ + __DRIscreenPrivate *sPriv = dPriv->driScreenPriv; \ + DRM_UNLOCK(sPriv->fd, &sPriv->pSAREA->lock, \ + dPriv->driContextPriv->hHWContext); \ + DEBUG_RESET(); \ + } while (0) + +#define BEGIN_BOARD_LOCK(fxMesa) LOCK_HARDWARE(fxMesa) +#define END_BOARD_LOCK(fxMesa) UNLOCK_HARDWARE(fxMesa) + +/* + This pair of macros makes a loop over the drawing operations + so it is not self contained and doesn't have the nice single + statement semantics of most macros +*/ +#define BEGIN_CLIP_LOOP(fxMesa) \ + do { \ + __DRIcontextPrivate *cPriv = fxMesa->driContextPriv; \ + __DRIdrawablePrivate *dPriv = cPriv->driDrawablePriv; \ + int _nc; \ + LOCK_HARDWARE(fxMesa); \ + _nc = dPriv->numClipRects; \ + while (_nc--) { \ + if (fxMesa->needClip) { \ + fxMesa->clipMinX = dPriv->pClipRects[_nc].x1; \ + fxMesa->clipMaxX = dPriv->pClipRects[_nc].x2; \ + fxMesa->clipMinY = dPriv->pClipRects[_nc].y1; \ + fxMesa->clipMaxY = dPriv->pClipRects[_nc].y2; \ + fxSetScissorValues(fxMesa->glCtx); \ + } + +#define END_CLIP_LOOP(fxMesa) \ + } \ + UNLOCK_HARDWARE(fxMesa); \ + } while (0) + + +#endif /* GLX_DIRECT_RENDERING */ + +#endif /* _FXDRV_H_ */ diff --git a/xc/lib/GL/mesa/src/drv/tdfx/fxfastpath.c b/xc/lib/GL/mesa/src/drv/tdfx/fxfastpath.c new file mode 100644 index 000000000..f1c669e9a --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/tdfx/fxfastpath.c @@ -0,0 +1,405 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/fxfastpath.c,v 1.1 2000/09/24 13:51:15 alanh Exp $ */ +/* + * Mesa 3-D graphics library + * Version: 3.3 + * + * 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. + * + * + * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the + * terms stated above. + * + * Thank you for your contribution, David! + * + * Please make note of the above copyright/license statement. If you + * contributed code or bug fixes to this code under the previous (GNU + * Library) license and object to the new license, your code will be + * removed at your request. Please see the Mesa docs/COPYRIGHT file + * for more information. + * + * Additional Mesa/3Dfx driver developers: + * Daryll Strauss <daryll@precisioninsight.com> + * Keith Whitwell <keith@precisioninsight.com> + * + * See fxapi.h for more revision/author details. + */ + + +#include "types.h" +#include "cva.h" +#include "mmath.h" +#include "fxdrv.h" +#include "fxtexman.h" +#include "vertices.h" +#ifdef __i386__ +#include "X86/common_x86asm.h" +#endif + + +#if 0 && defined(__i386__) +#define NEGATIVE(f) ((*(int *)&f) < 0) +#define DIFFERENT_SIGNS(a,b) (((*(int *)&a)^(*(int *)&b)) < 0) +#else +#define NEGATIVE(f) (f < 0) +#define DIFFERENT_SIGNS(a,b) ((a*b) < 0) +#endif + +#define LINTERP( T, A, B ) ( (A) + (T) * ( (B) - (A) ) ) + + +#define CLIP(sgn,v,PLANE) \ +if (mask & PLANE) { \ + GLuint *indata = inlist[in]; \ + GLuint *outdata = inlist[in ^= 1]; \ + GLuint nr = n; \ + GLfloat *J = verts[indata[nr-1]].f; \ + GLfloat dpJ = (sgn J[v]) + J[CLIP_WCOORD]; \ + \ + inlist[0] = vlist1; \ + for (i = n = 0 ; i < nr ; i++) { \ + GLuint elt_i = indata[i]; \ + GLfloat *I = verts[elt_i].f; \ + GLfloat dpI = (sgn I[v]) + I[CLIP_WCOORD]; \ + \ + if (DIFFERENT_SIGNS(dpI, dpJ)) { \ + GLfloat *O = verts[next_vert].f; \ + GLfloat t = dpI / (dpI - dpJ); \ + GLuint j; \ + \ + clipmask[next_vert] = 0; \ + outdata[n++] = next_vert++; \ + \ + for (j = 0 ; j < SIZE ; j += 2) { \ + O[j] = LINTERP(t, I[j], J[j]); \ + O[j+1] = LINTERP(t, I[j+1], J[j+1]); \ + } \ + } \ + \ + clipmask[elt_i] |= PLANE; /* don't set up */ \ + \ + if (!NEGATIVE(dpI)) { \ + outdata[n++] = elt_i; \ + clipmask[elt_i] &= ~PLANE; /* set up after all */ \ + } \ + \ + J = I; \ + dpJ = dpI; \ + } \ + \ + if (n < 3) return; \ +} + +#define LINE_CLIP(x,y,z,w,PLANE) \ +if (mask & PLANE) { \ + GLfloat dpI = DOT4V(I,x,y,z,w); \ + GLfloat dpJ = DOT4V(J,x,y,z,w); \ + \ + if (DIFFERENT_SIGNS(dpI, dpJ)) { \ + GLfloat *O = verts[next_vert].f; \ + GLfloat t = dpI / (dpI - dpJ); \ + GLuint j; \ + \ + for (j = 0 ; j < SIZE ; j += 2) { \ + O[j] = LINTERP(t, I[j], J[j]); \ + O[j+1] = LINTERP(t, I[j+1], J[j+1]); \ + } \ + \ + clipmask[next_vert] = 0; \ + \ + if (NEGATIVE(dpI)) { \ + clipmask[elts[0]] |= PLANE; \ + I = O; elts[0] = next_vert++; \ + } else { \ + clipmask[elts[1]] |= PLANE; \ + J = O; elts[1] = next_vert++; \ + } \ + } \ + else if (NEGATIVE(dpI)) \ + return; \ +} + + +#define CLIP_POINT( e ) \ + if (mask[e]) \ + *out++ = e + +#define CLIP_LINE( e1, e0 ) \ +do { \ + GLubyte ormask = mask[e0] | mask[e1]; \ + out[0] = e1; \ + out[1] = e0; \ + out+=2; \ + if (ormask) { \ + out-=2; \ + if (!(mask[e0] & mask[e1])) { \ + TAG(fx_line_clip)( &out, verts, mask, &next_vert, ormask); \ + } \ + } \ +} while (0) + +#define CLIP_TRIANGLE( e2, e1, e0 ) \ +do { \ + GLubyte ormask; \ + out[0] = e2; \ + out[1] = e1; \ + out[2] = e0; \ + out += 3; \ + ormask = mask[e2] | mask[e1] | mask[e0]; \ + if (ormask) { \ + out -= 3; \ + if ( !(mask[e2] & mask[e1] & mask[e0])) { \ + TAG(fx_tri_clip)( &out, verts, mask, &next_vert, ormask ); \ + } \ + } \ +} while (0) + +#if defined(FX_V2) || defined(DRIVERTS) + +#define VARS_XYZ \ + GLfloat vsx = mat[MAT_SX]; \ + GLfloat vsy = mat[MAT_SY]; \ + GLfloat vsz = mat[MAT_SZ]; \ + GLfloat vtx = mat[MAT_TX]; \ + GLfloat vty = mat[MAT_TY]; \ + GLfloat vtz = mat[MAT_TZ]; + +#define DO_SETUP_XYZ \ + f[XCOORD] = f[0] * oow * vsx + vtx; \ + f[YCOORD] = f[1] * oow * vsy + vty; \ + f[ZCOORD] = f[2] * oow * vsz + vtz; + +#else +#if defined(HAVE_FAST_MATH) + +#define VARS_XYZ \ + GLfloat vsx = mat[MAT_SX]; \ + GLfloat vsy = mat[MAT_SY]; \ + GLfloat vsz = mat[MAT_SZ]; \ + const GLfloat snapper = (3L << 18); \ + GLfloat vtx = mat[MAT_TX] + snapper; \ + GLfloat vty = mat[MAT_TY] + snapper; \ + GLfloat vtz = mat[MAT_TZ]; + +#define DO_SETUP_XYZ \ + f[XCOORD] = f[0] * oow * vsx + vtx; \ + f[XCOORD] -= snapper; \ + f[YCOORD] = f[1] * oow * vsy + vty; \ + f[YCOORD] -= snapper; \ + f[ZCOORD] = f[2] * oow * vsz + vtz; + +#else + +#define VARS_XYZ \ + GLfloat vsx = mat[MAT_SX] * 16.0f; \ + GLfloat vsy = mat[MAT_SY] * 16.0f; \ + GLfloat vsz = mat[MAT_SZ]; \ + GLfloat vtx = mat[MAT_TX] * 16.0f; \ + GLfloat vty = mat[MAT_TY] * 16.0f; \ + GLfloat vtz = mat[MAT_TZ]; + +#define DO_SETUP_XYZ \ + f[XCOORD] = ((int)(f[0]*oow*vsx+vtx)) * (1.0f/16.0f); \ + f[YCOORD] = ((int)(f[1]*oow*vsy+vty)) * (1.0f/16.0f); \ + f[ZCOORD] = f[2]*oow*vsz + vtz; + + +#endif +#endif + + + +struct fx_fast_tab +{ + void (*build_vertices) (struct vertex_buffer * VB, GLuint do_clip); + + void (*clip[GL_POLYGON + 1]) (struct vertex_buffer * VB, + GLuint start, GLuint count, GLuint parity); + + void (*project_clipped_vertices) (GLfloat * first, + GLfloat * last, + const GLfloat * mat, + GLuint stride, const GLubyte * mask); + + void (*project_vertices) (GLfloat * first, + GLfloat * last, + const GLfloat * mat, GLuint stride); +}; + +/* Pack either rgba or texture into the remaining half of a 32 byte vertex. + */ +#define CLIP_R CLIP_RCOORD +#define CLIP_G CLIP_GCOORD +#define CLIP_B CLIP_BCOORD +#define CLIP_A CLIP_ACOORD +#define CLIP_S0 4 +#define CLIP_T0 5 +#define CLIP_S1 6 +#define CLIP_T1 7 + +#define SIZE 4 +#define TYPE (0) +#define TAG(x) x +#include "fxfasttmp.h" + +#define SIZE 8 +#define TYPE (SETUP_RGBA) +#define TAG(x) x##_RGBA +#include "fxfasttmp.h" + +#define SIZE 6 +#define TYPE (SETUP_TMU0) +#define TAG(x) x##_TMU0 +#include "fxfasttmp.h" + +#define SIZE 8 +#define TYPE (SETUP_TMU0|SETUP_TMU1) +#define TAG(x) x##_TMU0_TMU1 +#include "fxfasttmp.h" + +#undef CLIP_S1 +#undef CLIP_T1 +#define CLIP_S1 4 +#define CLIP_T1 5 + +#define SIZE 6 +#define TYPE (SETUP_TMU1) +#define TAG(x) x##_TMU1 +#include "fxfasttmp.h" + +/* These three need to use a full 64 byte clip-space vertex. + */ +#undef CLIP_S0 +#undef CLIP_T0 +#undef CLIP_S1 +#undef CLIP_T1 + +#define CLIP_S0 8 +#define CLIP_T0 9 +#define CLIP_S1 10 +#define CLIP_T1 11 + +#define SIZE 10 +#define TYPE (SETUP_RGBA|SETUP_TMU0) +#define TAG(x) x##_RGBA_TMU0 +#include "fxfasttmp.h" + +#define SIZE 12 +#define TYPE (SETUP_RGBA|SETUP_TMU0|SETUP_TMU1) +#define TAG(x) x##_RGBA_TMU0_TMU1 +#include "fxfasttmp.h" + +#undef CLIP_S1 +#undef CLIP_T1 +#define CLIP_S1 8 +#define CLIP_T1 9 + +#define SIZE 10 +#define TYPE (SETUP_RGBA|SETUP_TMU1) +#define TAG(x) x##_RGBA_TMU1 +#include "fxfasttmp.h" + +static struct fx_fast_tab fxFastTab[0x8]; + +void +fxDDFastPathInit() +{ + fx_init_fastpath(&fxFastTab[0]); + fx_init_fastpath_RGBA(&fxFastTab[SETUP_RGBA]); + fx_init_fastpath_TMU0(&fxFastTab[SETUP_TMU0]); + fx_init_fastpath_TMU1(&fxFastTab[SETUP_TMU1]); + fx_init_fastpath_RGBA_TMU0(&fxFastTab[SETUP_RGBA | SETUP_TMU0]); + fx_init_fastpath_RGBA_TMU1(&fxFastTab[SETUP_RGBA | SETUP_TMU1]); + fx_init_fastpath_TMU0_TMU1(&fxFastTab[SETUP_TMU0 | SETUP_TMU1]); + fx_init_fastpath_RGBA_TMU0_TMU1(&fxFastTab[SETUP_RGBA | SETUP_TMU0 | + SETUP_TMU1]); +} + + + +void +fxDDFastPath(struct vertex_buffer *VB) +{ + GLcontext *ctx = VB->ctx; + GLenum prim = ctx->CVA.elt_mode; + struct tfxMesaContext *fxMesa = FX_CONTEXT(ctx); + struct fx_fast_tab *tab = &fxFastTab[fxMesa->setupindex & 0x7]; + GLuint do_clip = 1; + struct tfxMesaVertexBuffer *fxVB = FX_DRIVER_DATA(VB); +#ifdef DRIVERTS + GLfloat tx, ty; +#endif + + fxVertex *first; + GLfloat *mat = ctx->Viewport.WindowMap.m; + + gl_prepare_arrays_cva(VB); /* still need this */ + + if (VB->EltPtr->count * 12 > fxVB->size) { + fxDDResizeVB(VB, VB->EltPtr->count * 12); + do_clip = 1; + } + + tab->build_vertices(VB, do_clip); /* object->clip space */ + + first = FX_DRIVER_DATA(VB)->verts; + +#ifdef DRIVERTS + tx = mat[MAT_TX]; + ty = mat[MAT_TY]; + mat[MAT_TX] = tx + fxMesa->x_offset; + mat[MAT_TY] = ty + fxMesa->y_delta; +#endif + + if (VB->ClipOrMask) { + if (!VB->ClipAndMask) { + GLubyte tmp = VB->ClipOrMask; + + tab->clip[prim] (VB, 0, VB->EltPtr->count, 0); /* clip */ + + tab->project_clipped_vertices(fxVB->verts->f, + fxVB->last_vert->f, + mat, 16 * 4, VB->ClipMask); + + ctx->CVA.elt_mode = gl_reduce_prim[prim]; + VB->EltPtr = &(FX_DRIVER_DATA(VB)->clipped_elements); + + VB->ClipOrMask = 0; + fxDDRenderElementsDirect(VB); /* render using new list */ + VB->ClipOrMask = tmp; + } + } + else { + tab->project_vertices(fxVB->verts->f, fxVB->last_vert->f, mat, + 16 * 4); + + fxDDRenderElementsDirect(VB); /* render using orig list */ + } + +#ifdef DRIVERTS + mat[MAT_TX] = tx; + mat[MAT_TY] = ty; +#endif + + /* This indicates that there is no cached data to reuse. + */ + VB->pipeline->data_valid = 0; + VB->pipeline->pipeline_valid = 0; +} + diff --git a/xc/lib/GL/mesa/src/drv/tdfx/fxfasttmp.h b/xc/lib/GL/mesa/src/drv/tdfx/fxfasttmp.h new file mode 100644 index 000000000..6f15462c4 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/tdfx/fxfasttmp.h @@ -0,0 +1,363 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/fxfasttmp.h,v 1.1 2000/09/24 13:51:15 alanh Exp $ */ +/* + * Mesa 3-D graphics library + * Version: 3.3 + * + * 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. + * + * + * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the + * terms stated above. + * + * Thank you for your contribution, David! + * + * Please make note of the above copyright/license statement. If you + * contributed code or bug fixes to this code under the previous (GNU + * Library) license and object to the new license, your code will be + * removed at your request. Please see the Mesa docs/COPYRIGHT file + * for more information. + * + * Additional Mesa/3Dfx driver developers: + * Daryll Strauss <daryll@precisioninsight.com> + * Keith Whitwell <keith@precisioninsight.com> + * + * See fxapi.h for more revision/author details. + */ + + +/* Build clip space vertices from object space data. + */ +static void TAG(fx_setup_full) (struct vertex_buffer * VB, GLuint do_clip) +{ + GLcontext *ctx = VB->ctx; + GLfloat *f = (GLfloat *) FX_DRIVER_DATA(VB)->verts; + fxMesaContext fxMesa = FX_CONTEXT(VB->ctx); + GLuint count = VB->Count; + GLuint i; + + const GLfloat *const m = ctx->ModelProjectMatrix.m; + +#if (TYPE & SETUP_RGBA) + GLubyte *color = (GLubyte *) VB->ColorPtr->data; + GLuint color_stride = VB->ColorPtr->stride; +#endif + +#if (TYPE & SETUP_TMU0) + GLuint tmu0_source = fxMesa->tmu_source[0]; + struct gl_texture_unit *t0 = &ctx->Texture.Unit[tmu0_source]; + GLint s0scale = FX_TEXTURE_DATA(t0)->int_sScale; + GLint t0scale = FX_TEXTURE_DATA(t0)->int_tScale; + GLint *tmu0_int_data = (GLint *) VB->TexCoordPtr[tmu0_source]->data; + GLuint tmu0_stride = VB->TexCoordPtr[tmu0_source]->stride; +#endif + +#if (TYPE & SETUP_TMU1) + GLuint tmu1_source = fxMesa->tmu_source[1]; + struct gl_texture_unit *t1 = &ctx->Texture.Unit[tmu1_source]; + GLint s1scale = FX_TEXTURE_DATA(t1)->int_sScale; + GLint t1scale = FX_TEXTURE_DATA(t1)->int_tScale; + GLint *tmu1_int_data = (GLint *) VB->TexCoordPtr[tmu1_source]->data; + GLuint tmu1_stride = VB->TexCoordPtr[tmu1_source]->stride; +#endif + + (void) fxMesa; + (void) ctx; + (void) i; + (void) f; + + /* Use 3 seperate loops because it's easier for assembly. A + * best-case solution might be to do all three in a single assembly + * loop. + */ + gl_xform_points3_v16_general(FX_DRIVER_DATA(VB)->verts[0].f, + m, + VB->ObjPtr->start, VB->ObjPtr->stride, + count); + + if (do_clip) { + VB->ClipAndMask = ~0; + VB->ClipOrMask = 0; + gl_cliptest_points4_v16(FX_DRIVER_DATA(VB)->verts[0].f, + FX_DRIVER_DATA(VB)->verts[count].f, + &(VB->ClipOrMask), + &(VB->ClipAndMask), VB->ClipMask); + } + + +#if (TYPE) + for (i = 0; i < count; i++, f += 16) { +#if (TYPE & SETUP_RGBA) + GLubyte *col = color; + color += color_stride; + UBYTE_COLOR_TO_FLOAT_255_COLOR2(f[CLIP_R], col[0]); + UBYTE_COLOR_TO_FLOAT_255_COLOR2(f[CLIP_G], col[1]); + UBYTE_COLOR_TO_FLOAT_255_COLOR2(f[CLIP_B], col[2]); + UBYTE_COLOR_TO_FLOAT_255_COLOR2(f[CLIP_A], col[3]); +#endif +#if (TYPE & SETUP_TMU0) + *(int *) &f[CLIP_S0] = s0scale + tmu0_int_data[0]; + *(int *) &f[CLIP_T0] = t0scale + tmu0_int_data[1]; + STRIDE_T(tmu0_int_data, GLint, tmu0_stride); +#endif +#if (TYPE & SETUP_TMU1) + *(int *) &f[CLIP_S1] = s1scale + tmu1_int_data[0]; + *(int *) &f[CLIP_T1] = t1scale + tmu1_int_data[1]; + STRIDE_T(tmu1_int_data, GLint, tmu1_stride); +#endif + } +#endif + + FX_DRIVER_DATA(VB)->last_vert = &(FX_DRIVER_DATA(VB)->verts[count]); +} + + +/* Do viewport map, device scale and perspective projection. + * + * Rearrange fxVertices to look like grVertices. + */ +static void TAG(fx_project_vertices) (GLfloat * first, + GLfloat * last, + const GLfloat * mat, GLuint stride) +{ + GLfloat *f; + VARS_XYZ; + + for (f = first; f != last; STRIDE_F(f, stride)) { + GLfloat oow = 1.0f / f[CLIP_WCOORD]; /* urp! */ + +#if FX_USE_PARGB + if (TYPE & SETUP_RGBA) { + PACK_4F_ARGB(GET_PARGB(f), f[CLIP_A], f[CLIP_R], f[CLIP_G], + f[CLIP_B]); + } +#else + if (TYPE & SETUP_RGBA) { + f[RCOORD] = f[CLIP_R]; + } +#endif + if (TYPE & SETUP_TMU1) { + f[S1COORD] = f[CLIP_S1] * oow; + f[T1COORD] = f[CLIP_T1] * oow; + } + + if (TYPE & SETUP_TMU0) { + f[T0COORD] = f[CLIP_T0] * oow; + f[S0COORD] = f[CLIP_S0] * oow; + } + + DO_SETUP_XYZ; + + f[OOWCOORD] = oow; + } +} + +static void TAG(fx_project_clipped_vertices) (GLfloat * first, + GLfloat * last, + const GLfloat * mat, + GLuint stride, + const GLubyte * mask) +{ + GLfloat *f; + VARS_XYZ; + + for (f = first; f != last; STRIDE_F(f, stride), mask++) { + if (!*mask) { + + GLfloat oow = 1.0f / f[CLIP_WCOORD]; +#if FX_USE_PARGB + if (TYPE & SETUP_RGBA) { + const GLuint r = f[CLIP_R]; + const GLuint g = f[CLIP_G]; + const GLuint b = f[CLIP_B]; + const GLuint a = f[CLIP_A]; + /* ToDo Optimize */ + GET_PARGB(f) = a << 24 | r << 16 | g << 8 | b; + } +#else + if (TYPE & SETUP_RGBA) { + f[RCOORD] = f[CLIP_R]; + } +#endif + + if (TYPE & SETUP_TMU1) { + f[S1COORD] = f[CLIP_S1] * oow; + f[T1COORD] = f[CLIP_T1] * oow; + } + + if (TYPE & SETUP_TMU0) { + f[T0COORD] = f[CLIP_T0] * oow; + f[S0COORD] = f[CLIP_S0] * oow; + } + + DO_SETUP_XYZ; + + f[OOWCOORD] = oow; + } + } +} + + +static +#if (SIZE <= 8) + INLINE +#endif +void TAG(fx_tri_clip) (GLuint ** p_elts, + fxVertex * verts, + GLubyte * clipmask, GLuint * p_next_vert, GLubyte mask) +{ + GLuint *elts = *p_elts; + GLuint next_vert = *p_next_vert; + GLuint vlist1[VB_MAX_CLIPPED_VERTS]; + GLuint vlist2[VB_MAX_CLIPPED_VERTS]; + GLuint *inlist[2]; + GLuint *out; + GLuint in = 0; + GLuint n = 3; + GLuint i; + + inlist[0] = elts; + inlist[1] = vlist2; + + CLIP(-, 0, CLIP_RIGHT_BIT); + CLIP(+, 0, CLIP_LEFT_BIT); + CLIP(-, 1, CLIP_TOP_BIT); + CLIP(+, 1, CLIP_BOTTOM_BIT); + CLIP(-, 2, CLIP_FAR_BIT); + CLIP(+, 2, CLIP_NEAR_BIT); + + /* Convert the planar polygon to a list of triangles. + */ + out = inlist[in]; + + for (i = 2; i < n; i++) { + elts[0] = out[0]; + elts[1] = out[i - 1]; + elts[2] = out[i]; + elts += 3; + } + + *p_next_vert = next_vert; + *p_elts = elts; +} + + +static INLINE void TAG(fx_line_clip) (GLuint ** p_elts, + fxVertex * verts, + GLubyte * clipmask, + GLuint * p_next_vert, GLubyte mask) +{ + GLuint *elts = *p_elts; + GLfloat *I = verts[elts[0]].f; + GLfloat *J = verts[elts[1]].f; + GLuint next_vert = *p_next_vert; + + LINE_CLIP(1, 0, 0, -1, CLIP_LEFT_BIT); + LINE_CLIP(-1, 0, 0, 1, CLIP_RIGHT_BIT); + LINE_CLIP(0, 1, 0, -1, CLIP_TOP_BIT); + LINE_CLIP(0, -1, 0, 1, CLIP_BOTTOM_BIT); + LINE_CLIP(0, 0, 1, -1, CLIP_FAR_BIT); + LINE_CLIP(0, 0, -1, 1, CLIP_NEAR_BIT); + + *p_next_vert = next_vert; + *p_elts += 2; +} + + +/* Build a table of functions to clip each primitive type. + */ +#define LOCAL_VARS \ + GLuint *elt = VB->EltPtr->data; \ + fxVertex *verts = FX_DRIVER_DATA(VB)->verts; \ + GLuint next_vert = VB->Count; \ + GLuint *out = FX_DRIVER_DATA(VB)->clipped_elements.data; \ + GLubyte *mask = VB->ClipMask; \ + + +#define POSTFIX \ + FX_DRIVER_DATA(VB)->clipped_elements.count = \ + out - FX_DRIVER_DATA(VB)->clipped_elements.data; \ + FX_DRIVER_DATA(VB)->last_vert = &verts[next_vert]; + +#define INIT(x) + +#define RENDER_POINTS(start, count) \ +do { \ + GLuint i; \ + for (i = start ; i < count ; i++ ) \ + CLIP_POINT( elt[i] ); \ +} while (0) + +#define RENDER_LINE(i1, i0) \ + CLIP_LINE(elt[i1], elt[i0]) + +#define RENDER_TRI(i2, i1, i0, pv, parroty) \ +do { \ + GLuint e2 = elt[i2], e1 = elt[i1], e0 = elt[i0]; \ + if (parroty) e2 = elt[i1], e1 = elt[i2]; \ + CLIP_TRIANGLE( e2, e1, e0 ); \ +} while (0) + +#define RENDER_QUAD(i3, i2, i1, i0, pv) \ + CLIP_TRIANGLE(elt[i3], elt[i2], elt[i0]); \ + CLIP_TRIANGLE(elt[i2], elt[i1], elt[i0]) + +#define PRESERVE_TAG +#include "render_tmp.h" + + +static void TAG(fx_init_fastpath) (struct fx_fast_tab * tab) +{ + GLuint i; + + /* Use the render templates to do clipping. + */ + TAG(render_init) (); + for (i = 0; i < GL_POLYGON + 2; i++) + tab->clip[i] = TAG(render_tab)[i]; + + tab->build_vertices = TAG(fx_setup_full); + tab->project_vertices = TAG(fx_project_vertices); + tab->project_clipped_vertices = TAG(fx_project_clipped_vertices); + +#if defined(USE_3DNOW_ASM) + if (gl_x86_cpu_features & GL_CPU_3Dnow) { + extern void TAG(fx_3dnow_project_vertices) (GLfloat * first, + GLfloat * last, + const GLfloat * mat, + GLuint stride); + + extern void TAG(fx_3dnow_project_clipped_vertices) (GLfloat * first, + GLfloat * last, + const GLfloat * + mat, + GLuint stride, + const GLubyte * + mask); + + tab->project_vertices = TAG(fx_3dnow_project_vertices); + tab->project_clipped_vertices = + TAG(fx_3dnow_project_clipped_vertices); + } +#endif +} + +#undef TYPE +#undef TAG +#undef SIZE diff --git a/xc/lib/GL/mesa/src/drv/tdfx/fxglidew.c b/xc/lib/GL/mesa/src/drv/tdfx/fxglidew.c new file mode 100644 index 000000000..c88d7ca3f --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/tdfx/fxglidew.c @@ -0,0 +1,483 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/fxglidew.c,v 1.1 2000/09/24 13:51:15 alanh Exp $ */ +/* + * Mesa 3-D graphics library + * Version: 3.3 + * + * 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. + * + * + * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the + * terms stated above. + * + * Thank you for your contribution, David! + * + * Please make note of the above copyright/license statement. If you + * contributed code or bug fixes to this code under the previous (GNU + * Library) license and object to the new license, your code will be + * removed at your request. Please see the Mesa docs/COPYRIGHT file + * for more information. + * + * Additional Mesa/3Dfx driver developers: + * Daryll Strauss <daryll@precisioninsight.com> + * Keith Whitwell <keith@precisioninsight.com> + * + * See fxapi.h for more revision/author details. + */ + + +#include <stdlib.h> +#include <string.h> +#include "glide.h" +#include "fxdrv.h" +#include "fxglidew.h" + + +grStencilFunc_t grStencilFuncPtr = NULL; +grStencilMask_t grStencilMaskPtr = NULL; +grStencilOp_t grStencilOpPtr = NULL; +grBufferClearExt_t grBufferClearExtPtr = NULL; +grColorMaskExt_t grColorMaskExtPtr = NULL; +txImgQuantize_t txImgQuantizePtr = NULL; +txImgDeQuantize_t txImgDequantizeFXT1Ptr = NULL; +txErrorSetCallback_t txErrorSetCallbackPtr = NULL; + +FxI32 +FX_grGetInteger_NoLock(FxU32 pname) +{ + switch (pname) { + case FX_FOG_TABLE_ENTRIES: + case FX_GLIDE_STATE_SIZE: + case FX_LFB_PIXEL_PIPE: + case FX_PENDING_BUFFERSWAPS: + case FX_TEXTURE_ALIGN: + case GR_STATS_PIXELS_DEPTHFUNC_FAIL: + case GR_STATS_PIXELS_IN: + case GR_STATS_PIXELS_OUT: + { + FxI32 result; + FxU32 grname = pname; + grGet(grname, 4, &result); + return result; + } + case FX_ZDEPTH_MAX: + { + FxI32 zvals[2]; + grGet(GR_ZDEPTH_MIN_MAX, 8, zvals); + return zvals[0]; + } + default: + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "Wrong parameter in FX_grGetInteger!\n"); + } + } + + return 0; +} + + +FxI32 +FX_grGetInteger(fxMesaContext fxMesa, FxU32 pname) +{ + int result; + BEGIN_BOARD_LOCK(fxMesa); + result = FX_grGetInteger_NoLock(pname); + END_BOARD_LOCK(fxMesa); + return result; +} + + +const char * +FX_grGetString(fxMesaContext fxMesa, FxU32 pname) +{ + const char *s; + BEGIN_BOARD_LOCK(fxMesa); + s = grGetString(pname); + END_BOARD_LOCK(fxMesa); + return s; +} + + + +/* Wrapper for grColorMask() and grColorMaskExt(). + */ +void +FX_grColorMask(GLcontext *ctx, GLboolean r, GLboolean g, + GLboolean b, GLboolean a) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + BEGIN_BOARD_LOCK(fxMesa); + if (ctx->Visual->RedBits == 8) { + /* 32bpp mode */ + ASSERT(grColorMaskExtPtr); + (*grColorMaskExtPtr)(r, g, b, a); + } + else { + /* 16 bpp mode */ + /* we never have an alpha buffer */ + grColorMask(r || g || b, GL_FALSE); + } + END_BOARD_LOCK(fxMesa); +} + + +/* As above, but pass the mask as an array + */ +void +FX_grColorMaskv(GLcontext *ctx, const GLboolean rgba[4]) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + BEGIN_BOARD_LOCK(fxMesa); + if (ctx->Visual->RedBits == 8) { + /* 32bpp mode */ + ASSERT(grColorMaskExtPtr); + (*grColorMaskExtPtr)(rgba[RCOMP], rgba[GCOMP], + rgba[BCOMP], rgba[ACOMP]); + } + else { + /* 16 bpp mode */ + /* we never have an alpha buffer */ + grColorMask(rgba[RCOMP] || rgba[GCOMP] || rgba[BCOMP], GL_FALSE); + } + END_BOARD_LOCK(fxMesa); +} + + + +FxBool +FX_grLfbLock(fxMesaContext fxMesa, GrLock_t type, GrBuffer_t buffer, + GrLfbWriteMode_t writeMode, GrOriginLocation_t origin, + FxBool pixelPipeline, GrLfbInfo_t * info) +{ + FxBool result; + + BEGIN_BOARD_LOCK(fxMesa); + result = grLfbLock(type, buffer, writeMode, origin, pixelPipeline, info); + END_BOARD_LOCK(fxMesa); + return result; +} + +FxU32 +FX_grTexTextureMemRequired(fxMesaContext fxMesa, FxU32 evenOdd, GrTexInfo * info) +{ + FxU32 result; + + BEGIN_BOARD_LOCK(fxMesa); + result = grTexTextureMemRequired(evenOdd, info); + END_BOARD_LOCK(fxMesa); + return result; +} + +FxU32 +FX_grTexMinAddress(fxMesaContext fxMesa, GrChipID_t tmu) +{ + FxU32 result; + + BEGIN_BOARD_LOCK(fxMesa); + result = grTexMinAddress(tmu); + END_BOARD_LOCK(fxMesa); + return result; +} + +extern FxU32 +FX_grTexMaxAddress(fxMesaContext fxMesa, GrChipID_t tmu) +{ + FxU32 result; + + BEGIN_BOARD_LOCK(fxMesa); + result = grTexMaxAddress(tmu); + END_BOARD_LOCK(fxMesa); + return result; +} + + +#if defined(FX_GLIDE3) + +void +FX_grGammaCorrectionValue(float val) +{ + (void) val; +/* ToDo */ +} + +int +FX_getFogTableSize(fxMesaContext fxMesa) +{ + int result; + BEGIN_BOARD_LOCK(fxMesa); + grGet(GR_FOG_TABLE_ENTRIES, sizeof(int), (void *) &result); + END_BOARD_LOCK(fxMesa); + return result; +} + +int +FX_getGrStateSize(fxMesaContext fxMesa) +{ + int result; + BEGIN_BOARD_LOCK(fxMesa); + grGet(GR_GLIDE_STATE_SIZE, sizeof(int), (void *) &result); + END_BOARD_LOCK(fxMesa); + return result; +} + + +void +FX_grGlideGetVersion(fxMesaContext fxMesa, char *buf) +{ + BEGIN_BOARD_LOCK(fxMesa); + strcpy(buf, grGetString(GR_VERSION)); + END_BOARD_LOCK(fxMesa); +} + +void +FX_grSstPerfStats(GrSstPerfStats_t * st) +{ + FxI32 n; + grGet(GR_STATS_PIXELS_IN, 4, &n); + st->pixelsIn = n; + grGet(GR_STATS_PIXELS_CHROMA_FAIL, 4, &n); + st->chromaFail = n; + grGet(GR_STATS_PIXELS_DEPTHFUNC_FAIL, 4, &n); + st->zFuncFail = n; + grGet(GR_STATS_PIXELS_AFUNC_FAIL, 4, &n); + st->aFuncFail = n; + grGet(GR_STATS_PIXELS_OUT, 4, &n); + st->pixelsOut = n; +} + +void +FX_grAADrawLine(fxMesaContext fxMesa, GrVertex * a, GrVertex * b) +{ + /* ToDo */ + BEGIN_CLIP_LOOP(fxMesa); + grDrawLine(a, b); + END_CLIP_LOOP(fxMesa); +} + +void +FX_grAADrawPoint(fxMesaContext fxMesa, GrVertex * a) +{ + BEGIN_CLIP_LOOP(fxMesa); + grDrawPoint(a); + END_CLIP_LOOP(fxMesa); +} + +void +FX_grDrawPolygonVertexList(fxMesaContext fxMesa, int n, GrVertex * verts) +{ + BEGIN_CLIP_LOOP(fxMesa); + grDrawVertexArrayContiguous(GR_POLYGON, n, verts, sizeof(GrVertex)); + END_CLIP_LOOP(fxMesa); +} + +#if FX_USE_PARGB +void +FX_setupGrVertexLayout(void) +{ + BEGIN_BOARD_LOCK(fxMesa); + grReset(GR_VERTEX_PARAMETER); + + grCoordinateSpace(GR_WINDOW_COORDS); + grVertexLayout(GR_PARAM_XY, GR_VERTEX_X_OFFSET << 2, GR_PARAM_ENABLE); + grVertexLayout(GR_PARAM_PARGB, GR_VERTEX_PARGB_OFFSET << 2, + GR_PARAM_ENABLE); + grVertexLayout(GR_PARAM_Q, GR_VERTEX_OOW_OFFSET << 2, GR_PARAM_ENABLE); + grVertexLayout(GR_PARAM_Z, GR_VERTEX_OOZ_OFFSET << 2, GR_PARAM_ENABLE); + grVertexLayout(GR_PARAM_ST0, GR_VERTEX_SOW_TMU0_OFFSET << 2, + GR_PARAM_ENABLE); + grVertexLayout(GR_PARAM_Q0, GR_VERTEX_OOW_TMU0_OFFSET << 2, + GR_PARAM_DISABLE); + grVertexLayout(GR_PARAM_ST1, GR_VERTEX_SOW_TMU1_OFFSET << 2, + GR_PARAM_DISABLE); + grVertexLayout(GR_PARAM_Q1, GR_VERTEX_OOW_TMU1_OFFSET << 2, + GR_PARAM_DISABLE); + END_BOARD_LOCK(fxMesa); +} +#else /* FX_USE_PARGB */ +void +FX_setupGrVertexLayout(fxMesaContext fxMesa) +{ + BEGIN_BOARD_LOCK(fxMesa); + grReset(GR_VERTEX_PARAMETER); + + grCoordinateSpace(GR_WINDOW_COORDS); + grVertexLayout(GR_PARAM_XY, GR_VERTEX_X_OFFSET << 2, GR_PARAM_ENABLE); + grVertexLayout(GR_PARAM_RGB, GR_VERTEX_R_OFFSET << 2, GR_PARAM_ENABLE); + grVertexLayout(GR_PARAM_A, GR_VERTEX_A_OFFSET << 2, GR_PARAM_ENABLE); + grVertexLayout(GR_PARAM_Q, GR_VERTEX_OOW_OFFSET << 2, GR_PARAM_ENABLE); + grVertexLayout(GR_PARAM_Z, GR_VERTEX_OOZ_OFFSET << 2, GR_PARAM_ENABLE); + grVertexLayout(GR_PARAM_ST0, GR_VERTEX_SOW_TMU0_OFFSET << 2, + GR_PARAM_ENABLE); + grVertexLayout(GR_PARAM_Q0, GR_VERTEX_OOW_TMU0_OFFSET << 2, + GR_PARAM_DISABLE); + grVertexLayout(GR_PARAM_ST1, GR_VERTEX_SOW_TMU1_OFFSET << 2, + GR_PARAM_DISABLE); + grVertexLayout(GR_PARAM_Q1, GR_VERTEX_OOW_TMU1_OFFSET << 2, + GR_PARAM_DISABLE); + END_BOARD_LOCK(fxMesa); +} +#endif + +void +FX_grHints_NoLock(GrHint_t hintType, FxU32 hintMask) +{ + switch (hintType) { + case GR_HINT_STWHINT: + { + if (hintMask & GR_STWHINT_W_DIFF_TMU0) + grVertexLayout(GR_PARAM_Q0, GR_VERTEX_OOW_TMU0_OFFSET << 2, + GR_PARAM_ENABLE); + else + grVertexLayout(GR_PARAM_Q0, GR_VERTEX_OOW_TMU0_OFFSET << 2, + GR_PARAM_DISABLE); + + if (hintMask & GR_STWHINT_ST_DIFF_TMU1) + grVertexLayout(GR_PARAM_ST1, GR_VERTEX_SOW_TMU1_OFFSET << 2, + GR_PARAM_ENABLE); + else + grVertexLayout(GR_PARAM_ST1, GR_VERTEX_SOW_TMU1_OFFSET << 2, + GR_PARAM_DISABLE); + + if (hintMask & GR_STWHINT_W_DIFF_TMU1) + grVertexLayout(GR_PARAM_Q1, GR_VERTEX_OOW_TMU1_OFFSET << 2, + GR_PARAM_ENABLE); + else + grVertexLayout(GR_PARAM_Q1, GR_VERTEX_OOW_TMU1_OFFSET << 2, + GR_PARAM_DISABLE); + + } + } +} + +void +FX_grHints(fxMesaContext fxMesa, GrHint_t hintType, FxU32 hintMask) +{ + BEGIN_BOARD_LOCK(fxMesa); + FX_grHints_NoLock(hintType, hintMask); + END_BOARD_LOCK(fxMesa); +} + +int +FX_grSstQueryHardware(fxMesaContext fxMesa, GrHwConfiguration * config) +{ + int i, j; + int numFB; + + BEGIN_BOARD_LOCK(fxMesa); + grGet(GR_NUM_BOARDS, 4, (void *) &(config->num_sst)); + if (config->num_sst == 0) + return 0; + for (i = 0; i < config->num_sst; i++) { + config->SSTs[i].type = GR_SSTTYPE_VOODOO; + grSstSelect(i); + grGet(GR_MEMORY_FB, 4, + (void *) &(config->SSTs[i].sstBoard.VoodooConfig.fbRam)); + config->SSTs[i].sstBoard.VoodooConfig.fbRam /= 1024 * 1024; + + grGet(GR_NUM_TMU, 4, + (void *) &(config->SSTs[i].sstBoard.VoodooConfig.nTexelfx)); + + + grGet(GR_NUM_FB, 4, (void *) &numFB); + if (numFB > 1) + config->SSTs[i].sstBoard.VoodooConfig.sliDetect = FXTRUE; + else + config->SSTs[i].sstBoard.VoodooConfig.sliDetect = FXFALSE; + for (j = 0; j < config->SSTs[i].sstBoard.VoodooConfig.nTexelfx; j++) { + grGet(GR_MEMORY_TMU, 4, + (void *) &(config->SSTs[i].sstBoard. + VoodooConfig.tmuConfig[j].tmuRam)); + config->SSTs[i].sstBoard.VoodooConfig. + tmuConfig[j].tmuRam /= 1024 * 1024; + } + } + END_BOARD_LOCK(fxMesa); + return 1; +} + +#else + +int +FX_grSstScreenWidth() +{ + int i; + BEGIN_BOARD_LOCK(fxMesa); + i = grSstScreenWidth(); + END_BOARD_LOCK(fxMesa); + return i; +} + +int +FX_grSstScreenHeight() +{ + int i; + BEGIN_BOARD_LOCK(fxMesa); + i = grSstScreenHeight(); + END_BOARD_LOCK(fxMesa); + return i; +} + +int +FX_grSstQueryHardware(GrHwConfiguration * c) +{ + int i; + BEGIN_BOARD_LOCK(fxMesa); + i = grSstQueryHardware(c); + END_BOARD_LOCK(fxMesa); + return i; +} + + +#endif /* FX_GLIDE3 */ + +/* It appears to me that this function is needed either way. */ +FX_GrContext_t +FX_grSstWinOpen(fxMesaContext fxMesa, + FxU32 hWnd, + GrScreenResolution_t screen_resolution, + GrScreenRefresh_t refresh_rate, + GrColorFormat_t color_format, + GrOriginLocation_t origin_location, + int nColBuffers, int nAuxBuffers) +{ + FX_GrContext_t i; + BEGIN_BOARD_LOCK(fxMesa); + i = grSstWinOpen(hWnd, + screen_resolution, + refresh_rate, + color_format, origin_location, nColBuffers, nAuxBuffers); + + /* + fprintf(stderr, + "grSstWinOpen( win %d res %d ref %d fmt %d\n" + " org %d ncol %d naux %d )\n" + " ==> %d\n", + hWnd, + screen_resolution, + refresh_rate, + color_format, + origin_location, + nColBuffers, + nAuxBuffers, + i); + */ + END_BOARD_LOCK(fxMesa); + return i; +} + diff --git a/xc/lib/GL/mesa/src/drv/tdfx/fxglidew.h b/xc/lib/GL/mesa/src/drv/tdfx/fxglidew.h new file mode 100644 index 000000000..388ca2d7c --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/tdfx/fxglidew.h @@ -0,0 +1,987 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/fxglidew.h,v 1.1 2000/09/24 13:51:16 alanh Exp $ */ +/* + * Mesa 3-D graphics library + * Version: 3.3 + * + * 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. + * + * + * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the + * terms stated above. + * + * Thank you for your contribution, David! + * + * Please make note of the above copyright/license statement. If you + * contributed code or bug fixes to this code under the previous (GNU + * Library) license and object to the new license, your code will be + * removed at your request. Please see the Mesa docs/COPYRIGHT file + * for more information. + * + * Additional Mesa/3Dfx driver developers: + * Daryll Strauss <daryll@precisioninsight.com> + * Keith Whitwell <keith@precisioninsight.com> + * + * See fxapi.h for more revision/author details. + */ + + +#ifndef __FX_GLIDE_WARPER__ +#define __FX_GLIDE_WARPER__ + +#include <glide.h> +#include <g3ext.h> + +typedef struct tfxMesaContext *fxMesaContext; + + +/* + * These are glide extension definitions. These are not + * defined in glide.h. They should really be defined in + * g3ext.h, but they are not. + */ +#if 0 +FX_ENTRY void FX_CALL +grStencilFunc(GrCmpFnc_t fnc, GrStencil_t ref, GrStencil_t mask); + +FX_ENTRY void FX_CALL grStencilMask(GrStencil_t write_mask); + +FX_ENTRY void FX_CALL +grStencilOp(GrStencilOp_t stencil_fail, + GrStencilOp_t depth_fail, GrStencilOp_t depth_pass); + +FX_ENTRY void FX_CALL +grBufferClearExt(GrColor_t color, + GrAlpha_t alpha, FxU32 depth, GrStencil_t stencil); + +FX_ENTRY void FX_CALL +grColorMaskExt(FxBool r, FxBool g, FxBool b, FxBool a); +#endif + + +typedef void (*grStencilFunc_t) (GrCmpFnc_t fnc, GrStencil_t ref, + GrStencil_t mask); +typedef void (*grStencilMask_t) (GrStencil_t write_mask); +typedef void (*grStencilOp_t) (GrStencilOp_t stencil_fail, + GrStencilOp_t depth_fail, + GrStencilOp_t depth_pass); +typedef void (*grBufferClearExt_t) (GrColor_t color, GrAlpha_t alpha, + FxU32 depth, GrStencil_t stencil); +typedef void (*grColorMaskExt_t) (FxBool r, FxBool g, FxBool b, FxBool a); +/* + * These are functions to compress and decompress images. + * The types of the first and second parameters are not exactly + * right. The texus library declares them to be "char *", not + * "void *". However, "void *" is more correct, and more convenient. + */ +typedef void (*txImgQuantize_t) (void *dst, void *src, + int w, int h, + FxU32 format, FxU32 dither); +typedef void (*txImgDeQuantize_t)(void *dst, void *src, + int w, int h); +/* + * These next three declarations should probably be taken from + * texus.h. However, there are duplicate declarations in g3ext.h + * and texus.h which make it hard to include them both. + */ +typedef void (*TxErrorCallbackFnc_t)( const char *string, FxBool fatal ); +typedef void (*txErrorSetCallback_t)(TxErrorCallbackFnc_t fnc, + TxErrorCallbackFnc_t *old_fnc); + +extern grStencilFunc_t grStencilFuncPtr; +extern grStencilMask_t grStencilMaskPtr; +extern grStencilOp_t grStencilOpPtr; +extern grBufferClearExt_t grBufferClearExtPtr; +extern grColorMaskExt_t grColorMaskExtPtr; +extern txImgQuantize_t txImgQuantizePtr; +extern txImgDeQuantize_t txImgDequantizeFXT1Ptr; +extern txErrorSetCallback_t txErrorSetCallbackPtr; + +FX_ENTRY void FX_CALL grEnable(GrEnableMode_t mode); + +FX_ENTRY void FX_CALL grEnable(GrEnableMode_t mode); +/* + * General context: + */ +#if !defined(FX_GLIDE3) +typedef FxU32 FX_GrContext_t; /* Not used in Glide2 */ +#else +typedef GrContext_t FX_GrContext_t; +#endif + +/* + * Glide3 emulation on Glide2: + */ +#if !defined(FX_GLIDE3) + /* Constanst for FX_grGetInteger( ) */ +#define FX_FOG_TABLE_ENTRIES 0x0004 /* The number of entries in the hardware fog table. */ +#define FX_GLIDE_STATE_SIZE 0x0006 /* Size of buffer, in bytes, needed to save Glide state. */ +#define FX_LFB_PIXEL_PIPE 0x0009 /* 1 if LFB writes can go through the 3D pixel pipe. */ +#define FX_PENDING_BUFFERSWAPS 0x0014 /* The number of buffer swaps pending. */ +#define FX_TEXTURE_ALIGN 0x0024 /* The required alignment for textures */ +#else +#define FX_FOG_TABLE_ENTRIES GR_FOG_TABLE_ENTRIES +#define FX_GLIDE_STATE_SIZE GR_GLIDE_STATE_SIZE +#define FX_LFB_PIXEL_PIPE GR_LFB_PIXEL_PIPE +#define FX_PENDING_BUFFERSWAPS GR_PENDING_BUFFERSWAPS +#define FX_TEXTURE_ALIGN GR_TEXTURE_ALIGN +#endif +#define FX_ZDEPTH_MAX 0x100 + +/* + * General warper functions for Glide2/Glide3: + */ +extern FxI32 FX_grGetInteger_NoLock(FxU32 pname); +extern FxI32 FX_grGetInteger(fxMesaContext fxMesa, FxU32 pname); + +extern const char *FX_grGetString(fxMesaContext fxMesa, FxU32 pname); + +/* + * Glide2 emulation on Glide3: + */ +#if defined(FX_GLIDE3) + +#define GR_ASPECT_1x1 GR_ASPECT_LOG2_1x1 +#define GR_ASPECT_2x1 GR_ASPECT_LOG2_2x1 +#define GR_ASPECT_4x1 GR_ASPECT_LOG2_4x1 +#define GR_ASPECT_8x1 GR_ASPECT_LOG2_8x1 +#define GR_ASPECT_1x2 GR_ASPECT_LOG2_1x2 +#define GR_ASPECT_1x4 GR_ASPECT_LOG2_1x4 +#define GR_ASPECT_1x8 GR_ASPECT_LOG2_1x8 + +#define GR_LOD_256 GR_LOD_LOG2_256 +#define GR_LOD_128 GR_LOD_LOG2_128 +#define GR_LOD_64 GR_LOD_LOG2_64 +#define GR_LOD_32 GR_LOD_LOG2_32 +#define GR_LOD_16 GR_LOD_LOG2_16 +#define GR_LOD_8 GR_LOD_LOG2_8 +#define GR_LOD_4 GR_LOD_LOG2_4 +#define GR_LOD_2 GR_LOD_LOG2_2 +#define GR_LOD_1 GR_LOD_LOG2_1 + +#define GR_FOG_WITH_TABLE GR_FOG_WITH_TABLE_ON_Q + +typedef int GrSstType; + +#define MAX_NUM_SST 4 + +#define GR_SSTTYPE_VOODOO 0 +#define GR_SSTTYPE_SST96 1 +#define GR_SSTTYPE_AT3D 2 +#define GR_SSTTYPE_Voodoo2 3 + +typedef struct GrTMUConfig_St +{ + int tmuRev; /* Rev of Texelfx chip */ + int tmuRam; /* 1, 2, or 4 MB */ +} +GrTMUConfig_t; + +typedef struct GrVoodooConfig_St +{ + int fbRam; /* 1, 2, or 4 MB */ + int fbiRev; /* Rev of Pixelfx chip */ + int nTexelfx; /* How many texelFX chips are there? */ + FxBool sliDetect; /* Is it a scan-line interleaved board? */ + GrTMUConfig_t tmuConfig[GLIDE_NUM_TMU]; /* Configuration of the Texelfx chips */ +} +GrVoodooConfig_t; + +typedef struct GrSst96Config_St +{ + int fbRam; /* How much? */ + int nTexelfx; + GrTMUConfig_t tmuConfig; +} +GrSst96Config_t; + +typedef GrVoodooConfig_t GrVoodoo2Config_t; + +typedef struct GrAT3DConfig_St +{ + int rev; +} +GrAT3DConfig_t; + +typedef struct +{ + int num_sst; /* # of HW units in the system */ + struct + { + GrSstType type; /* Which hardware is it? */ + union SstBoard_u + { + GrVoodooConfig_t VoodooConfig; + GrSst96Config_t SST96Config; + GrAT3DConfig_t AT3DConfig; + GrVoodoo2Config_t Voodoo2Config; + } + sstBoard; + } + SSTs[MAX_NUM_SST]; /* configuration for each board */ +} +GrHwConfiguration; + +typedef FxU32 GrHint_t; +#define GR_HINTTYPE_MIN 0 +#define GR_HINT_STWHINT 0 + +typedef FxU32 GrSTWHint_t; +#define GR_STWHINT_W_DIFF_FBI FXBIT(0) +#define GR_STWHINT_W_DIFF_TMU0 FXBIT(1) +#define GR_STWHINT_ST_DIFF_TMU0 FXBIT(2) +#define GR_STWHINT_W_DIFF_TMU1 FXBIT(3) +#define GR_STWHINT_ST_DIFF_TMU1 FXBIT(4) +#define GR_STWHINT_W_DIFF_TMU2 FXBIT(5) +#define GR_STWHINT_ST_DIFF_TMU2 FXBIT(6) + +#define GR_CONTROL_ACTIVATE 1 +#define GR_CONTROL_DEACTIVATE 0 + +#define GrState void + +/* +** move the vertex layout defintion to application +*/ +typedef struct +{ + float sow; /* s texture ordinate (s over w) */ + float tow; /* t texture ordinate (t over w) */ + float oow; /* 1/w (used mipmapping - really 0xfff/w) */ +} +GrTmuVertex; + + +#if FX_USE_PARGB + +typedef struct +{ + float x, y; /* X and Y in screen space */ + float ooz; /* 65535/Z (used for Z-buffering) */ + float oow; /* 1/W (used for W-buffering, texturing) */ + FxU32 argb; /* R, G, B, A [0..255.0] */ + GrTmuVertex tmuvtx[GLIDE_NUM_TMU]; + float z; /* Z is ignored */ +} +GrVertex; + +#define GR_VERTEX_X_OFFSET 0 +#define GR_VERTEX_Y_OFFSET 1 +#define GR_VERTEX_OOZ_OFFSET 2 +#define GR_VERTEX_OOW_OFFSET 3 +#define GR_VERTEX_PARGB_OFFSET 4 +#define GR_VERTEX_SOW_TMU0_OFFSET 5 +#define GR_VERTEX_TOW_TMU0_OFFSET 6 +#define GR_VERTEX_OOW_TMU0_OFFSET 7 +#define GR_VERTEX_SOW_TMU1_OFFSET 8 +#define GR_VERTEX_TOW_TMU1_OFFSET 9 +#define GR_VERTEX_OOW_TMU1_OFFSET 10 +#define GR_VERTEX_Z_OFFSET 11 + +#define GET_PARGB(v) ((FxU32*)(v))[GR_VERTEX_PARGB_OFFSET] +/* GET_PA: returns the alpha component */ +#if GLIDE_ENDIAN == GLIDE_ENDIAN_BIG +#define GET_PA(v) ((FxU8*)(v))[GR_VERTEX_PARGB_OFFSET*4] +#else +#define GET_PA(v) ((FxU8*)(v))[GR_VERTEX_PARGB_OFFSET*4+3] +#endif +#define MESACOLOR2PARGB(c) (c[ACOMP] << 24 | c[GCOMP] << 16 | c[GCOMP] << 8 | c[BCOMP]) +#define PACK_4F_ARGB(dest,a,r,g,b) { \ + const GLuint cr = (int)r; \ + const GLuint cg = (int)g; \ + const GLuint ca = (int)a; \ + const GLuint cb = (int)b; \ + dest = ca << 24 | cr << 16 | cg << 8 | cb; \ + } + +#else /* FX_USE_PARGB */ + +typedef struct +{ + float x, y, z; /* X, Y, and Z of scrn space -- Z is ignored */ + float r, g, b; /* R, G, B, ([0..255.0]) */ + float ooz; /* 65535/Z (used for Z-buffering) */ + float a; /* Alpha [0..255.0] */ + float oow; /* 1/W (used for W-buffering, texturing) */ + GrTmuVertex tmuvtx[GLIDE_NUM_TMU]; +} +GrVertex; + +#define GR_VERTEX_X_OFFSET 0 +#define GR_VERTEX_Y_OFFSET 1 +#define GR_VERTEX_Z_OFFSET 2 +#define GR_VERTEX_R_OFFSET 3 +#define GR_VERTEX_G_OFFSET 4 +#define GR_VERTEX_B_OFFSET 5 +#define GR_VERTEX_OOZ_OFFSET 6 +#define GR_VERTEX_A_OFFSET 7 +#define GR_VERTEX_OOW_OFFSET 8 +#define GR_VERTEX_SOW_TMU0_OFFSET 9 +#define GR_VERTEX_TOW_TMU0_OFFSET 10 +#define GR_VERTEX_OOW_TMU0_OFFSET 11 +#define GR_VERTEX_SOW_TMU1_OFFSET 12 +#define GR_VERTEX_TOW_TMU1_OFFSET 13 +#define GR_VERTEX_OOW_TMU1_OFFSET 14 +#endif /* FX_USE_PARGB */ + +#endif + +/* + * Glide2 functions for Glide3 + */ +#if defined(FX_GLIDE3) + +#define FX_grTexDownloadTable(fxMesa, TMU, type, data) \ + do { \ + BEGIN_BOARD_LOCK(fxMesa); \ + grTexDownloadTable(type,data); \ + END_BOARD_LOCK(fxMesa); \ + } while (0); + +#define FX_grTexDownloadTable_NoLock(TMU, type, data) \ + grTexDownloadTable(type, data) + +#else +#define FX_grTexDownloadTable(TMU,type,data) \ + do { \ + BEGIN_BOARD_LOCK(); \ + grTexDownloadTable(TMU,type,data); \ + END_BOARD_LOCK(); \ + } while (0); +#define FX_grTexDownloadTable_NoLock grTexDownloadTable +#endif + +/* + * Flush + */ +#if defined(FX_GLIDE3) +#define FX_grFlush(fxMesa) \ + do { \ + BEGIN_BOARD_LOCK(fxMesa); \ + grFlush(); \ + END_BOARD_LOCK(fxMesa); \ + } while (0) +#else +#define FX_grFlush(fxMesa) \ + do { \ + BEGIN_BOARD_LOCK(fxMesa); \ + grSstIdle(); \ + END_BOARD_LOCK(fxMesa); \ + } while (0) +#endif + +#define FX_grFinish(fxMesa) \ + do { \ + BEGIN_BOARD_LOCK(fxMesa); \ + grFinish(); \ + END_BOARD_LOCK(fxMesa); \ + } while (0) + +/* + * Write region: ToDo possible exploit the PixelPipe parameter. + */ +#if defined(FX_GLIDE3) + +#define FX_grLfbWriteRegion(fxMesa,dst_buffer,dst_x,dst_y,src_format,src_width,src_height,src_stride,src_data) \ + do { \ + BEGIN_BOARD_LOCK(fxMesa); \ + grLfbWriteRegion(dst_buffer,dst_x,dst_y,src_format,src_width,src_height,FXFALSE,src_stride,src_data); \ + END_BOARD_LOCK(fxMesa); \ + } while(0) + +#else + +#define FX_grLfbWriteRegion(dst_buffer,dst_x,dst_y,src_format,src_width,src_height,src_stride,src_data) \ + do { \ + BEGIN_BOARD_LOCK(); \ + grLfbWriteRegion(dst_buffer,dst_x,dst_y,src_format,src_width,src_height,src_stride,src_data); \ + END_BOARD_LOCK(); \ + } while (0) +#endif + +/* + * Read region + */ +#define FX_grLfbReadRegion(fxMesa,src_buffer,src_x,src_y,src_width,src_height,dst_stride,dst_data) \ + do { \ + BEGIN_BOARD_LOCK(fxMesa); \ + grLfbReadRegion(src_buffer,src_x,src_y,src_width,src_height,dst_stride,dst_data); \ + END_BOARD_LOCK(fxMesa); \ + } while (0); + +/* + * Draw triangle + */ +#define FX_grDrawTriangle_NoLock(a,b,c) grDrawTriangle(a,b,c) +#define FX_grDrawTriangle(fxMesa, a,b,c) \ + do { \ + BEGIN_CLIP_LOOP(fxMesa); \ + FX_grDrawTriangle_NoLock(a,b,c); \ + END_CLIP_LOOP(fxMesa); \ + } while (0) + +/* + * For Lod/LodLog2 conversion. + */ +#if defined(FX_GLIDE3) +#define FX_largeLodLog2(info) (info).largeLodLog2 +#else +#define FX_largeLodLog2(info) (info).largeLod +#endif + +#if defined(FX_GLIDE3) +#define FX_aspectRatioLog2(info) (info).aspectRatioLog2 +#else +#define FX_aspectRatioLog2(info) (info).aspectRatio +#endif + +#if defined(FX_GLIDE3) +#define FX_smallLodLog2(info) (info).smallLodLog2 +#else +#define FX_smallLodLog2(info) (info).smallLod +#endif + +#if defined(FX_GLIDE3) +#define FX_lodToValue(val) ((int)(GR_LOD_256-val)) +#else +#define FX_lodToValue(val) ((int)(val)) +#endif + +#if defined(FX_GLIDE3) +#define FX_largeLodValue(info) ((int)(GR_LOD_256-(info).largeLodLog2)) +#else +#define FX_largeLodValue(info) ((int)(info).largeLod) +#endif +#define FX_largeLodValue_NoLock FX_largeLodValue + +#if defined(FX_GLIDE3) +#define FX_smallLodValue(info) ((int)(GR_LOD_256-(info).smallLodLog2)) +#else +#define FX_smallLodValue(info) ((int)(info).smallLod) +#endif +#define FX_smallLodValue_NoLock FX_smallLodValue + +#if defined(FX_GLIDE3) +#define FX_valueToLod(val) ((GrLOD_t)(GR_LOD_256-val)) +#else +#define FX_valueToLod(val) ((GrLOD_t)(val)) +#endif + + + +/* + * Version string. + */ +#if defined(FX_GLIDE3) +extern void FX_grGlideGetVersion(fxMesaContext fxMesa, char *buf); +#else +#define FX_grGlideGetVersion(b) \ + do { \ + BEGIN_BOARD_LOCK(); \ + grGlideGetVersion(b); \ + END_BOARD_LOCK(); \ + } while (0) +#endif + +/* + * Performance statistics + */ +#if defined(FX_GLIDE3) +extern void FX_grSstPerfStats(GrSstPerfStats_t * st); +#else +#define FX_grSstPerfStats(s) \ + do { \ + BEGIN_BOARD_LOCK(); \ + grSstPerfStats(s); \ + END_BOARD_LOCK(); \ + } while (0) +#endif + +/* + * Hardware Query + */ +extern int FX_grSstQueryHardware(fxMesaContext fxMesa, + GrHwConfiguration * config); + +/* + * GrHints + */ +#if defined(FX_GLIDE3) +extern void FX_grHints_NoLock(GrHint_t hintType, FxU32 hintMask); +extern void FX_grHints(fxMesaContext fxMesa, GrHint_t hintType, FxU32 hintMask); +#else +#define FX_grHints(t,m) \ + do { \ + BEGIN_BOARD_LOCK(); \ + grHints(t, m); \ + END_BOARD_LOCK(); \ + } while(0) +#define FX_grHints_NoLock grHints +#endif +/* + * Antialiashed line+point drawing. + */ +#if defined(FX_GLIDE3) +extern void FX_grAADrawLine(fxMesaContext fxMesa, GrVertex * a, GrVertex * b); +#else +#define FX_grAADrawLine(a,b) \ + do { \ + BEGIN_CLIP_LOOP(); \ + grAADrawLine(a,b); \ + END_CLIP_LOOP(); \ + } while (0) +#endif + +#if defined(FX_GLIDE3) +extern void FX_grAADrawPoint(fxMesaContext fxMesa, GrVertex * a); +#else +#define FX_grAADrawPoint(a) \ + do { \ + BEGIN_CLIP_LOOP(); \ + grAADrawPoint(a); \ + END_CLIP_LOOP(); \ + } while (0) +#endif + +/* + * Needed for Glide3 only, to set up Glide2 compatible vertex layout. + */ +#if defined(FX_GLIDE3) +extern void FX_setupGrVertexLayout(fxMesaContext fxMesa); +#else +#define FX_setupGrVertexLayout() do {} while (0) +#endif + + +/* + * grGammaCorrectionValue + */ +#if defined(FX_GLIDE3) +extern void FX_grGammaCorrectionValue(float val); +#else +#define FX_grGammaCorrectionValue(v) \ + do { \ + BEGIN_BOARD_LOCK(); \ + grGammaCorrectionValue(v) \ + END_BOARD_LOCK(); \ + } while (0) +#endif + +#if defined(FX_GLIDE3) +#define FX_grSstWinClose(fxMesa, w) \ + do { \ + BEGIN_BOARD_LOCK(fxMesa); \ + grSstWinClose(w); \ + END_BOARD_LOCK(fxMesa); \ + } while (0) +#else +#define FX_grSstWinClose(w) \ + do { \ + BEGIN_BOARD_LOCK(); \ + grSstWinClose(); \ + END_BOARD_LOCK(); \ + } while (0) +#endif + + +extern FX_GrContext_t FX_grSstWinOpen(fxMesaContext fxMesa, + FxU32 hWnd, + GrScreenResolution_t screen_resolution, + GrScreenRefresh_t refresh_rate, + GrColorFormat_t color_format, + GrOriginLocation_t origin_location, + int nColBuffers, int nAuxBuffers); + + +#define FX_grDrawLine_NoLock(v1, v2) grDrawLine(v1, v2) +#define FX_grDrawLine(fxMesa, v1, v2) \ + do { \ + BEGIN_CLIP_LOOP(fxMesa); \ + FX_grDrawLine_NoLock(v1, v2); \ + END_CLIP_LOOP(fxMesa); \ + } while (0) + +#define FX_grDrawPoint_NoLock(p) grDrawPoint(p) +#define FX_grDrawPoint(fxMesa, p) \ + do { \ + BEGIN_CLIP_LOOP(fxMesa); \ + FX_grDrawPoint_NoLock(p); \ + END_CLIP_LOOP(fxMesa); \ + } while (0) + +#if defined(FX_GLIDE3) +extern void FX_grDrawPolygonVertexList(fxMesaContext fxMesa, + int n, GrVertex * v); +#else +#define FX_grDrawPolygonVertexList(n, v) \ + do { \ + BEGIN_CLIP_LOOP(); \ + grDrawPolygonVertexList(n, v); \ + END_CLIP_LOOP(); \ + } while (0) +#endif + +#define FX_grDitherMode(fxMesa, m) \ + do { \ + BEGIN_BOARD_LOCK(fxMesa); \ + grDitherMode(m); \ + END_BOARD_LOCK(fxMesa); \ + } while (0) + +#define FX_grRenderBuffer(fxMesa, b) \ + do { \ + BEGIN_BOARD_LOCK(fxMesa); \ + grRenderBuffer(b); \ + END_BOARD_LOCK(fxMesa); \ + } while (0) + +#define FX_grBufferClear(fxMesa, c, a, d) \ + do { \ + BEGIN_CLIP_LOOP(fxMesa); \ + grBufferClear(c, a, d); \ + END_CLIP_LOOP(fxMesa); \ + } while (0) + +#define FX_grBufferClearExt(fxMesa, c, a, d, s) \ + do { \ + BEGIN_CLIP_LOOP(fxMesa); \ + (*grBufferClearExtPtr)(c, a, d, s); \ + END_CLIP_LOOP(fxMesa); \ + } while (0) + +/* + * Enable/Disable + */ +#define FX_grEnable(fxMesa, m) \ + do { \ + BEGIN_BOARD_LOCK(fxMesa); \ + grEnable(m); \ + END_BOARD_LOCK(fxMesa); \ + } while (0) + +#define FX_grDisable(fxMesa, m) \ + do { \ + BEGIN_BOARD_LOCK(fxMesa); \ + grDisable(m); \ + END_BOARD_LOCK(fxMesa); \ + } while (0) + +/* + * Stencil operations. + */ +#define FX_grStencilFunc(fxMesa, fnc, ref, mask) \ + do { \ + BEGIN_BOARD_LOCK(fxMesa); \ + (*grStencilFuncPtr)((fnc), (ref), (mask)); \ + END_BOARD_LOCK(fxMesa); \ + } while (0) + +#define FX_grStencilMask(fxMesa, write_mask) \ + do { \ + BEGIN_BOARD_LOCK(fxMesa); \ + (*grStencilMaskPtr)(write_mask); \ + END_BOARD_LOCK(fxMesa); \ + } while (0) + + +#define FX_grStencilOp(fxMesa, stencil_fail, depth_fail, depth_pass) \ + do { \ + BEGIN_BOARD_LOCK(fxMesa); \ + (*grStencilOpPtr)((stencil_fail), (depth_fail), (depth_pass)); \ + END_BOARD_LOCK(fxMesa); \ + } while (0) + +#define FX_grDepthMask(fxMesa, m) \ + do { \ + BEGIN_BOARD_LOCK(fxMesa); \ + grDepthMask(m); \ + END_BOARD_LOCK(fxMesa); \ + } while (0) + + +extern void FX_grColorMask(GLcontext *ctx, GLboolean r, GLboolean g, + GLboolean b, GLboolean a); + +extern void FX_grColorMaskv(GLcontext *ctx, const GLboolean rgba[4]); + +extern FxBool FX_grLfbLock(fxMesaContext fxMesa, + GrLock_t type, GrBuffer_t buffer, + GrLfbWriteMode_t writeMode, + GrOriginLocation_t origin, FxBool pixelPipeline, + GrLfbInfo_t * info); + +#define FX_grLfbUnlock(fxMesa, t, b) \ + do { \ + BEGIN_BOARD_LOCK(fxMesa); \ + grLfbUnlock(t, b); \ + END_BOARD_LOCK(fxMesa); \ + } while (0) + +#define FX_grConstantColorValue(fxMesa, v) \ + do { \ + BEGIN_BOARD_LOCK(fxMesa); \ + grConstantColorValue(v); \ + END_BOARD_LOCK(fxMesa); \ + } while (0) + +#define FX_grConstantColorValue_NoLock grConstantColorValue + +#define FX_grAADrawTriangle(fxMesa, a, b, c, ab, bc, ca) \ + do { \ + BEGIN_CLIP_LOOP(fxMesa); \ + grAADrawTriangle(a, b, c, ab, bc, ca); \ + END_CLIP_LOOP(fxMesa); \ + } while (0) + +#define FX_grAlphaBlendFunction(rs, rd, as, ad) \ + do { \ + BEGIN_BOARD_LOCK(fxMesa); \ + grAlphaBlendFunction(rs, rd, as, ad); \ + END_BOARD_LOCK(fxMesa); \ + } while (0) + +#define FX_grAlphaCombine(func, fact, loc, oth, inv) \ + do { \ + BEGIN_BOARD_LOCK(fxMesa); \ + grAlphaCombine(func, fact, loc, oth, inv); \ + END_BOARD_LOCK(fxMesa); \ + } while (0) + +#define FX_grAlphaCombine_NoLock grAlphaCombine + +#define FX_grAlphaTestFunction(fxMesa, f) \ + do { \ + BEGIN_BOARD_LOCK(fxMesa); \ + grAlphaTestFunction(f); \ + END_BOARD_LOCK(fxMesa); \ + } while (0) + +#define FX_grAlphaTestReferenceValue(fxMesa, v) \ + do { \ + BEGIN_BOARD_LOCK(fxMesa); \ + grAlphaTestReferenceValue(v); \ + END_BOARD_LOCK(fxMesa); \ + } while (0) + +#define FX_grClipWindow(fxMesa, minx, miny, maxx, maxy) \ + do { \ + BEGIN_BOARD_LOCK(fxMesa); \ + grClipWindow(minx, miny, maxx, maxy); \ + END_BOARD_LOCK(fxMesa); \ + } while (0) + +#define FX_grClipWindow_NoLock grClipWindow + +#define FX_grColorCombine(fxMesa, func, fact, loc, oth, inv) \ + do { \ + BEGIN_BOARD_LOCK(fxMesa); \ + grColorCombine(func, fact, loc, oth, inv); \ + END_BOARD_LOCK(fxMesa); \ + } while (0) + +#define FX_grColorCombine_NoLock grColorCombine + +#define FX_grCullMode(fxMesa, m) \ + do { \ + BEGIN_BOARD_LOCK(fxMesa); \ + grCullMode(m); \ + END_BOARD_LOCK(fxMesa); \ + } while (0) + +#define FX_grDepthBiasLevel(fxMesa, lev) \ + do { \ + BEGIN_BOARD_LOCK(fxMesa); \ + grDepthBiasLevel(lev); \ + END_BOARD_LOCK(fxMesa); \ + } while (0) + +#define FX_grDepthBufferFunction(fxMesa, func) \ + do { \ + BEGIN_BOARD_LOCK(fxMesa); \ + grDepthBufferFunction(func); \ + END_BOARD_LOCK(fxMesa); \ + } while (0) + +#define FX_grFogColorValue(fxMesa, c) \ + do { \ + BEGIN_BOARD_LOCK(fxMesa); \ + grFogColorValue(c); \ + END_BOARD_LOCK(fxMesa); \ + } while (0) + +#define FX_grFogMode(fxMesa, m) \ + do { \ + BEGIN_BOARD_LOCK(fxMesa); \ + grFogMode(m); \ + END_BOARD_LOCK(fxMesa); \ + } while (0) + +#define FX_grFogTable(fxMesa, t)\ + do { \ + BEGIN_BOARD_LOCK(fxMesa); \ + grFogTable(t); \ + END_BOARD_LOCK(fxMesa); \ + } while (0) + +#define FX_grTexClampMode(fxMesa, t, sc, tc) \ + do { \ + BEGIN_BOARD_LOCK(fxMesa); \ + grTexClampMode(t, sc, tc); \ + END_BOARD_LOCK(fxMesa); \ + } while (0) + +#define FX_grTexClampMode_NoLock grTexClampMode + +#define FX_grTexCombine(fxMesa, t, rfunc, rfact, afunc, afact, rinv, ainv) \ + do { \ + BEGIN_BOARD_LOCK(fxMesa); \ + grTexCombine(t, rfunc, rfact, afunc, afact, rinv, ainv); \ + END_BOARD_LOCK(fxMesa); \ + } while (0) + +#define FX_grTexCombine_NoLock grTexCombine + +#define FX_grTexDownloadMipMapLevel(fxMesa, t, sa, tlod, llod, ar, f, eo, d) \ + do { \ + BEGIN_BOARD_LOCK(fxMesa); \ + grTexDownloadMipMapLevel(t, sa, tlod, llod, ar, f, eo, d); \ + END_BOARD_LOCK(fxMesa); \ + } while (0) + +#define FX_grTexDownloadMipMapLevel_NoLock grTexDownloadMipMapLevel + +#define FX_grTexDownloadMipMapLevelPartial(fxMesa, t, sa, tlod, llod, ar, f, eo, d, s, e); \ + do { \ + BEGIN_BOARD_LOCK(fxMesa); \ + grTexDownloadMipMapLevelPartial(t, sa, tlod, llod, ar, f, eo, d, s, e); \ + END_BOARD_LOCK(fxMesa); \ + } while (0) + +#define FX_grTexFilterMode(fxMesa, t, minf, magf) \ + do { \ + BEGIN_BOARD_LOCK(fxMesa); \ + grTexFilterMode(t, minf, magf); \ + END_BOARD_LOCK(fxMesa); \ + } while (0) + +#define FX_grTexFilterMode_NoLock grTexFilterMode + +extern FxU32 FX_grTexMinAddress(fxMesaContext fxMesa, GrChipID_t tmu); +extern FxU32 FX_grTexMaxAddress(fxMesaContext fxMesa, GrChipID_t tmu); + +#define FX_grTexMipMapMode(t, m, lod) \ + do { \ + BEGIN_BOARD_LOCK(fxMesa); \ + grTexMipMapMode(t, m, lod); \ + END_BOARD_LOCK(fxMesa); \ + } while (0) + +#define FX_grTexMipMapMode_NoLock grTexMipMapMode + +#define FX_grTexSource(t, sa, eo, i) \ + do { \ + BEGIN_BOARD_LOCK(fxMesa); \ + grTexSource(t, sa, eo, i); \ + END_BOARD_LOCK(fxMesa); \ + } while (0) + +#define FX_grTexSource_NoLock grTexSource + +extern FxU32 FX_grTexTextureMemRequired(fxMesaContext fxMesa, + FxU32 evenOdd, GrTexInfo * info); + +#define FX_grTexTextureMemRequired_NoLock grTexTextureMemRequired + +#define FX_grGlideGetState(fxMesa, s) \ + do { \ + BEGIN_BOARD_LOCK(fxMesa); \ + grGlideGetState(s); \ + END_BOARD_LOCK(fxMesa); \ + } while (0) +#define FX_grGlideGetState_NoLock(s) grGlideGetState(s); + +#define FX_grDRIBufferSwap(fxMesa, i) \ + do { \ + BEGIN_BOARD_LOCK(fxMesa); \ + grDRIBufferSwap(i); \ + END_BOARD_LOCK(fxMesa); \ + } while (0) + +#define FX_grSstSelect(fxMesa, b) \ + do { \ + BEGIN_BOARD_LOCK(fxMesa); \ + grSstSelect(b); \ + END_BOARD_LOCK(fxMesa); \ + } while (0) + +#define FX_grSstSelect_NoLock grSstSelect + +#define FX_grGlideSetState(fxMesa, s) \ + do { \ + BEGIN_BOARD_LOCK(fxMesa); \ + grGlideSetState(s); \ + END_BOARD_LOCK(fxMesa); \ + } while (0) +#define FX_grGlideSetState_NoLock(s) grGlideSetState(s); + +#define FX_grDepthBufferMode(fxMesa, m) \ + do { \ + BEGIN_BOARD_LOCK(fxMesa); \ + grDepthBufferMode(m); \ + END_BOARD_LOCK(fxMesa); \ + } while (0) + +#define FX_grLfbWriteColorFormat(fxMesa, f) \ + do { \ + BEGIN_BOARD_LOCK(fxMesa); \ + grLfbWriteColorFormat(f); \ + END_BOARD_LOCK(fxMesa); \ + } while (0) + +#define FX_grDrawVertexArray(fxMesa, m, c, p) \ + do { \ + BEGIN_CLIP_LOOP(fxMesa); \ + grDrawVertexArray(m, c, p); \ + END_CLIP_LOOP(fxMesa); \ + } while (0) + +#define FX_grGlideShutdown(fxMesa) \ + do { \ + BEGIN_BOARD_LOCK(fxMesa); \ + grGlideShutdown(); \ + END_BOARD_LOCK(fxMesa); \ + } while (0) + +#define FX_grTexLodBiasValue_NoLock(t, v) grTexLodBiasValue(t, v) + +#define FX_grTexLodBiasValue(t, v) \ + do { \ + BEGIN_BOARD_LOCK(fxMesa); \ + grTexLodBiasValue(t, v); \ + END_BOARD_LOCK(fxMesa); \ + } while (0) + +#define FX_grGlideInit_NoLock grGlideInit +#define FX_grSstWinOpen_NoLock grSstWinOpen + +extern int FX_getFogTableSize(fxMesaContext fxMesa); + +extern int FX_getGrStateSize(fxMesaContext fxMesa); + +#endif /* __FX_GLIDE_WARPER__ */ diff --git a/xc/lib/GL/mesa/src/drv/tdfx/fxpipeline.c b/xc/lib/GL/mesa/src/drv/tdfx/fxpipeline.c new file mode 100644 index 000000000..eaa2ab962 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/tdfx/fxpipeline.c @@ -0,0 +1,293 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/fxpipeline.c,v 1.1 2000/09/24 13:51:16 alanh Exp $ */ +/* + * Mesa 3-D graphics library + * Version: 3.3 + * + * 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. + * + * + * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the + * terms stated above. + * + * Thank you for your contribution, David! + * + * Please make note of the above copyright/license statement. If you + * contributed code or bug fixes to this code under the previous (GNU + * Library) license and object to the new license, your code will be + * removed at your request. Please see the Mesa docs/COPYRIGHT file + * for more information. + * + * Additional Mesa/3Dfx driver developers: + * Daryll Strauss <daryll@precisioninsight.com> + * Keith Whitwell <keith@precisioninsight.com> + * + * See fxapi.h for more revision/author details. + */ + + +#include "fxdrv.h" +#include "fxcva.h" +#include "fxpipeline.h" +#include "vbindirect.h" + + +/* We don't handle texcoord-4 in the safe clip routines - maybe we should. + */ +static void +fxDDRenderElements(struct vertex_buffer *VB) +{ + GLcontext *ctx = VB->ctx; + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + + if (fxMesa->render_index != 0 || + ((ctx->Texture.ReallyEnabled & 0xf) && VB->TexCoordPtr[0]->size > 2) + || ((ctx->Texture.ReallyEnabled & 0xf0) + && VB->TexCoordPtr[1]->size > 2) || (VB->ClipPtr->size != 4)) /* Brokes clipping otherwise */ + gl_render_elts(VB); + else + fxDDRenderElementsDirect(VB); +} + +static void +fxDDCheckRenderVBIndirect(GLcontext * ctx, struct gl_pipeline_stage *d) +{ + d->type = 0; + + if ((ctx->IndirectTriangles & DD_SW_SETUP) == 0 && + ctx->Driver.MultipassFunc == 0) { + d->type = PIPE_IMMEDIATE; + d->inputs = VERT_SETUP_FULL | VERT_ELT | VERT_PRECALC_DATA; + } +} + +static void +fxDDRenderVBIndirect(struct vertex_buffer *VB) +{ + GLcontext *ctx = VB->ctx; + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + struct vertex_buffer *cvaVB = ctx->CVA.VB; + + if (fxMesa->render_index != 0 || ((ctx->Texture.ReallyEnabled & 0xf) + && cvaVB->TexCoordPtr[0]->size > 2) + || ((ctx->Texture.ReallyEnabled & 0xf0) + && cvaVB->TexCoordPtr[1]->size > 2) || (VB->ClipPtr->size != 4)) /* Brokes clipping otherwise */ + gl_render_vb_indirect(VB); + else + fxDDRenderVBIndirectDirect(VB); +} + + +static void +fxDDRenderVB(struct vertex_buffer *VB) +{ + GLcontext *ctx = VB->ctx; + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + + if ((fxMesa->render_index != 0) || + ((ctx->Texture.ReallyEnabled & 0xf) && VB->TexCoordPtr[0]->size > 2) + || ((ctx->Texture.ReallyEnabled & 0xf0) + && VB->TexCoordPtr[1]->size > 2)) + gl_render_vb(VB); + else + fxDDDoRenderVB(VB); +} + + + + +/* This sort of driver-based reconfiguration of the pipeline could be + * used to support accelerated transformation and lighting on capable + * hardware. + * + */ +GLuint +fxDDRegisterPipelineStages(struct gl_pipeline_stage *out, + const struct gl_pipeline_stage *in, GLuint nr) +{ + GLuint i, o; + + for (i = o = 0; i < nr; i++) { + switch (in[i].ops) { + case PIPE_OP_RAST_SETUP_1 | PIPE_OP_RENDER: + out[o] = in[i]; + out[o].state_change = NEW_CLIENT_STATE; + out[o].check = fxDDCheckMergeAndRender; + out[o].run = fxDDMergeAndRender; + o++; + break; + case PIPE_OP_RAST_SETUP_0: + out[o] = in[i]; + out[o].cva_state_change = + NEW_LIGHTING | NEW_TEXTURING | NEW_RASTER_OPS; + out[o].state_change = ~0; + out[o].check = fxDDCheckPartialRasterSetup; + out[o].run = fxDDPartialRasterSetup; + o++; + break; + case PIPE_OP_RAST_SETUP_0 | PIPE_OP_RAST_SETUP_1: + out[o] = in[i]; + out[o].run = fxDDDoRasterSetup; + o++; + break; + case PIPE_OP_RENDER: + out[o] = in[i]; + if (in[i].run == gl_render_elts) { + out[o].run = fxDDRenderElements; + } + else if (in[i].run == gl_render_vb_indirect) { + out[o].check = fxDDCheckRenderVBIndirect; + out[o].run = fxDDRenderVBIndirect; + } + else if (in[i].run == gl_render_vb) { + out[o].run = fxDDRenderVB; + } + + o++; + break; + default: + out[o++] = in[i]; + break; + } + } + + return o; +} + +#define ILLEGAL_ENABLES (TEXTURE0_3D| \ + TEXTURE1_3D| \ + ENABLE_TEXMAT0 | \ + ENABLE_TEXMAT1 | \ + ENABLE_TEXGEN0 | \ + ENABLE_TEXGEN1 | \ + ENABLE_USERCLIP | \ + ENABLE_LIGHT | \ + ENABLE_FOG) + + + +/* Because this is slotted in by the OptimizePipeline function, most + * of the information here is just for gl_print_pipeline(). Only the + * run member is required. + */ +static struct gl_pipeline_stage fx_fast_stage = { + "FX combined vertex transform, setup and rasterization stage", + PIPE_OP_VERT_XFORM | PIPE_OP_RAST_SETUP_0 | PIPE_OP_RAST_SETUP_1 | + PIPE_OP_RENDER, + PIPE_PRECALC, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, /* never called */ + fxDDFastPath +}; + + + + +/* Better than optimizing the pipeline, we can do the whole build very + * quickly with the aid of a new flags member. + */ +GLboolean +fxDDBuildPrecalcPipeline(GLcontext * ctx) +{ + struct gl_pipeline *pipe = &ctx->CVA.pre; + fxMesaContext fxMesa = FX_CONTEXT(ctx); + + + if (fxMesa->is_in_hardware && + fxMesa->render_index == 0 && + (ctx->Enabled & ILLEGAL_ENABLES) == 0 && + (ctx->Array.Flags & (VERT_OBJ_234 | + VERT_TEX0_4 | + VERT_TEX1_4 | + VERT_ELT)) == (VERT_OBJ_23 | VERT_ELT)) { + if (MESA_VERBOSE & (VERBOSE_STATE | VERBOSE_DRIVER)) + if (!fxMesa->using_fast_path) + fprintf(stderr, "fxMesa: using fast path\n"); + + pipe->stages[0] = &fx_fast_stage; + pipe->stages[1] = 0; + pipe->new_inputs = ctx->RenderFlags & VERT_DATA; + pipe->ops = pipe->stages[0]->ops; + fxMesa->using_fast_path = 1; + return 1; + } + + if (fxMesa->using_fast_path) { + if (MESA_VERBOSE & (VERBOSE_STATE | VERBOSE_DRIVER)) + fprintf(stderr, + "fxMesa: fall back to full pipeline %x %x %x %x %x\n", + fxMesa->is_in_hardware, fxMesa->render_index, + (ctx->Enabled & ILLEGAL_ENABLES), + (ctx->Array.Summary & (VERT_OBJ_23)), + (ctx->Array.Summary & (VERT_OBJ_4 | VERT_TEX0_4 | + VERT_TEX1_4))); + + fxMesa->using_fast_path = 0; + ctx->CVA.VB->ClipOrMask = 0; + ctx->CVA.VB->ClipAndMask = CLIP_ALL_BITS; + ctx->Array.NewArrayState |= ctx->Array.Summary; + return 0; + } + + return 0; +} + + + + + + +/* Perform global optimizations to the pipeline. The fx driver + * implements a single such fast path, which corresponds to the standard + * quake3 cva pipeline. + * + * This is now handled by the 'build' function above. + */ +void +fxDDOptimizePrecalcPipeline(GLcontext * ctx, struct gl_pipeline *pipe) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + + if (fxMesa->is_in_hardware && + fxMesa->render_index == 0 && + (ctx->Enabled & ILLEGAL_ENABLES) == 0 && + (ctx->Array.Summary & VERT_ELT)) { + pipe->stages[0] = &fx_fast_stage; + pipe->stages[1] = 0; + } +} + + + +/* unused? +void +fxDDOptimizeEltPipeline( GLcontext *ctx, struct gl_pipeline *pipe ) +{ + (void) ctx; + (void) pipe; +} +*/ + diff --git a/xc/lib/GL/mesa/src/drv/tdfx/fxpipeline.h b/xc/lib/GL/mesa/src/drv/tdfx/fxpipeline.h new file mode 100644 index 000000000..49a98320d --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/tdfx/fxpipeline.h @@ -0,0 +1,16 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/fxpipeline.h,v 1.1 2000/09/24 13:51:16 alanh Exp $ */ +#ifndef FXPIPELINE_H +#define FXPIPELINE_H + + +extern GLuint fxDDRegisterPipelineStages(struct gl_pipeline_stage *out, + const struct gl_pipeline_stage *in, + GLuint nr); + +extern GLboolean fxDDBuildPrecalcPipeline(GLcontext * ctx); + +extern void fxDDOptimizePrecalcPipeline(GLcontext * ctx, + struct gl_pipeline *pipe); + + +#endif diff --git a/xc/lib/GL/mesa/src/drv/tdfx/fxrender.c b/xc/lib/GL/mesa/src/drv/tdfx/fxrender.c new file mode 100644 index 000000000..7bcfae237 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/tdfx/fxrender.c @@ -0,0 +1,780 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/fxrender.c,v 1.1 2000/09/24 13:51:16 alanh Exp $ */ +/* + * Mesa 3-D graphics library + * Version: 3.3 + * + * 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. + * + * + * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the + * terms stated above. + * + * Thank you for your contribution, David! + * + * Please make note of the above copyright/license statement. If you + * contributed code or bug fixes to this code under the previous (GNU + * Library) license and object to the new license, your code will be + * removed at your request. Please see the Mesa docs/COPYRIGHT file + * for more information. + * + * Additional Mesa/3Dfx driver developers: + * Daryll Strauss <daryll@precisioninsight.com> + * Keith Whitwell <keith@precisioninsight.com> + * + * See fxapi.h for more revision/author details. + */ + + +/* fxrender.c - 3Dfx VooDoo RenderVB driver function support */ + +#include "fxdrv.h" +#include "vbcull.h" +#include "fxsetup.h" + + + +/* + * Render a line segment from VB[v1] to VB[v2] when either one or both + * endpoints must be clipped. + */ +#if !defined(__MWERKS__) +INLINE +#endif + void +fxRenderClippedLine(struct vertex_buffer *VB, GLuint v1, GLuint v2) +{ + fxMesaContext fxMesa = FX_CONTEXT(VB->ctx); + fxVertex *gWin = FX_DRIVER_DATA(VB)->verts; + GLubyte mask = VB->ClipMask[v1] | VB->ClipMask[v2]; + + if (!mask || (VB->ctx->line_clip_tab[VB->ClipPtr->size]) (VB, &v1, &v2, + mask)) + FX_grDrawLine(fxMesa, (GrVertex *) gWin[v1].f, (GrVertex *) gWin[v2].f); +} + + + + +/* This is legal for Quads as well as triangles, hence the 'n' parameter. + */ +INLINE void +fxRenderClippedTriangle(struct vertex_buffer *VB, GLuint n, GLuint vlist[]) +{ + fxMesaContext fxMesa = FX_CONTEXT(VB->ctx); + GLubyte mask = 0; + GLuint i; + + for (i = 0; i < n; i++) + mask |= VB->ClipMask[vlist[i]]; + + if (mask & CLIP_USER_BIT) { + GLubyte *userclipmask = VB->UserClipMask; + if (userclipmask[vlist[0]] & userclipmask[vlist[1]] & + userclipmask[vlist[2]]) + return; + } + + n = (VB->ctx->poly_clip_tab[VB->ClipPtr->size]) (VB, n, vlist, mask); + if (n >= 3) { + fxVertex *gWin = FX_DRIVER_DATA(VB)->verts; + GrVertex *i0 = (GrVertex *) gWin[vlist[0]].f; + GrVertex *i1 = (GrVertex *) gWin[vlist[1]].f; + GrVertex *i2 = (GrVertex *) gWin[vlist[2]].f; + GLuint i; + + for (i = 2; i < n; i++, i1 = i2, i2 = (GrVertex *) gWin[vlist[i]].f) { + FX_grDrawTriangle(fxMesa, i0, i1, i2); + } + } +} + + + + + +static INLINE void +fxSafeClippedLine(struct vertex_buffer *VB, GLuint v1, GLuint v2) +{ + GLubyte mask = VB->ClipMask[v1] | VB->ClipMask[v2]; + fxMesaContext fxMesa = FX_CONTEXT(VB->ctx); + + if (!mask) { + fxVertex *gWin = FX_DRIVER_DATA(VB)->verts; + FX_grDrawLine(fxMesa, (GrVertex *) gWin[v1].f, (GrVertex *) gWin[v2].f); + } + else { + fxMesaContext fxMesa = (fxMesaContext) VB->ctx->DriverCtx; + fxLineClipTab[fxMesa->setupindex & 0x7] (VB, v1, v2, mask); + } +} + + +static INLINE void +fxSafeClippedTriangle(struct vertex_buffer *VB, + fxVertex * gWin, + tfxTriClipFunc cliptri, GLuint v2, GLuint v1, GLuint v) +{ + GLubyte *clipmask = VB->ClipMask; + GLubyte mask = clipmask[v2] | clipmask[v1] | clipmask[v]; + fxMesaContext fxMesa = FX_CONTEXT(VB->ctx); + + if (!mask) { + FX_grDrawTriangle(fxMesa, (GrVertex *) gWin[v2].f, + (GrVertex *) gWin[v1].f, (GrVertex *) gWin[v].f); + return; + } + + if (!(clipmask[v2] & clipmask[v1] & clipmask[v] & CLIP_ALL_BITS)) { + GLuint vl[3]; + GLuint imask = mask; + + if (imask & CLIP_USER_BIT) { + GLubyte *userclipmask = VB->UserClipMask; + if (userclipmask[v2] & userclipmask[v1] & userclipmask[v]) + return; + imask |= + (userclipmask[v2] | userclipmask[v1] | userclipmask[v]) << 8; + } + + ASSIGN_3V(vl, v2, v1, v); + cliptri(VB, vl, imask); + } +} + + +static INLINE void +fxSafeClippedTriangle2(struct vertex_buffer *VB, + fxVertex * gWin, + tfxTriViewClipFunc cliptri, + GLuint v2, GLuint v1, GLuint v) +{ + fxMesaContext fxMesa = FX_CONTEXT(VB->ctx); + GLubyte *clipmask = VB->ClipMask; + GLubyte mask = clipmask[v2] | clipmask[v1] | clipmask[v]; + + if (!mask) { + FX_grDrawTriangle(fxMesa, + (GrVertex *) gWin[v2].f, (GrVertex *) gWin[v1].f, + (GrVertex *) gWin[v].f); + } + else if (!(clipmask[v2] & clipmask[v1] & clipmask[v])) { + GLuint vl[3]; + ASSIGN_3V(vl, v2, v1, v); + cliptri(VB, vl, mask); + } +} + + +static INLINE void +fxSafeClippedTriangle3(struct vertex_buffer *VB, + fxVertex * gWin, + tfxTriClipFunc cliptri, GLuint v2, GLuint v1, GLuint v) +{ + GLubyte *clipmask = VB->ClipMask; + GLubyte mask = clipmask[v2] | clipmask[v1] | clipmask[v]; + GLuint imask = mask; + + if (imask & CLIP_USER_BIT) { + GLubyte *userclipmask = VB->UserClipMask; + if (userclipmask[v2] & userclipmask[v1] & userclipmask[v]) + return; + imask |= (userclipmask[v2] | userclipmask[v1] | userclipmask[v]) << 8; + } + + { + GLuint vl[3]; + ASSIGN_3V(vl, v2, v1, v); + cliptri(VB, vl, imask); + } +} + + + + + +/************************************************************************/ +/************************ RenderVB functions ****************************/ +/************************************************************************/ + + +/* Render front-facing, non-clipped primitives. + */ + +#define RENDER_POINTS( start, count ) \ + (void) gWin; \ + (void) VB; \ + (VB->ctx->Driver.PointsFunc)( VB->ctx, start, count-1 ) + +#define RENDER_LINE( i1, i ) \ + do { \ + RVB_COLOR(i); \ + FX_grDrawLine(fxMesa, (GrVertex *)gWin[i1].f, \ + (GrVertex *)gWin[i].f); \ + } while (0) + +#define RENDER_TRI( i2, i1, i, pv, parity ) \ + do { \ + RVB_COLOR(pv); \ + if (parity) { \ + FX_grDrawTriangle(fxMesa, (GrVertex *)gWin[i1].f, \ + (GrVertex *)gWin[i2].f, \ + (GrVertex *)gWin[i].f); \ + } else { \ + FX_grDrawTriangle(fxMesa, (GrVertex *)gWin[i2].f, \ + (GrVertex *)gWin[i1].f, \ + (GrVertex *)gWin[i].f); \ + } \ + } while (0) + +#define RENDER_QUAD( i3, i2, i1, i, pv ) \ + do { \ + RVB_COLOR(pv); \ + FX_grDrawTriangle(fxMesa, (GrVertex *)gWin[i3].f, \ + (GrVertex *)gWin[i2].f, \ + (GrVertex *)gWin[i].f); \ + FX_grDrawTriangle(fxMesa, (GrVertex *)gWin[i2].f, \ + (GrVertex *)gWin[i1].f, \ + (GrVertex *)gWin[i].f); \ + } while (0) + + + +#define LOCAL_VARS \ + fxMesaContext fxMesa=(fxMesaContext)VB->ctx->DriverCtx; \ + fxVertex *gWin = FX_DRIVER_DATA(VB)->verts; \ + (void) fxMesa; + +#define INIT(x) + +#define TAG(x) x##_fx_flat_raw +#undef RVB_COLOR +#define RVB_COLOR(pv) FX_VB_COLOR(fxMesa, VB->ColorPtr->data[pv]) +#define PRESERVE_VB_DEFS + +#include "render_tmp.h" + +#define TAG(x) x##_fx_smooth_raw +#undef RVB_COLOR +#define RVB_COLOR(x) + +#include "render_tmp.h" + + + +/* Render with clipped and/or culled primitives with cullmask information. + */ +#define RENDER_POINTS( start, count ) \ + (void) gWin; \ + (void) cullmask; \ + (VB->ctx->Driver.PointsFunc)( VB->ctx, start, count-1 ) + + +#define RENDER_LINE( i1, i ) \ + do { \ + const GLubyte flags = cullmask[i]; \ + \ + if (!(flags & PRIM_NOT_CULLED)) \ + continue; \ + \ + RVB_COLOR(i); \ + if (flags & PRIM_ANY_CLIP) \ + fxRenderClippedLine( VB, i1, i ); \ + else \ + FX_grDrawLine( fxMesa, (GrVertex *)gWin[i1].f, (GrVertex *)gWin[i].f ); \ + } while (0) + + +#define RENDER_TRI( i2, i1, i, pv, parity) \ + do { \ + const GLubyte flags = cullmask[i]; \ + GLuint e2,e1; \ + \ + if (!(flags & PRIM_NOT_CULLED)) \ + continue; \ + \ + e2=i2, e1=i1; \ + if (parity) { e2=i1; e1=i2; } \ + \ + RVB_COLOR(pv); \ + if (flags & PRIM_ANY_CLIP) { \ + fxSafeClippedTriangle3(VB,gWin,cliptri,e2,e1,i); \ + } else { \ + FX_grDrawTriangle(fxMesa, (GrVertex *)gWin[e2].f, \ + (GrVertex *)gWin[e1].f, \ + (GrVertex *)gWin[i].f); \ + } \ + } while (0) + + +#define RENDER_QUAD(i3, i2, i1, i, pv) \ + do { \ + const GLubyte flags = cullmask[i]; \ + \ + if (!(flags & PRIM_NOT_CULLED)) \ + continue; \ + \ + RVB_COLOR(pv); \ + if (flags&PRIM_ANY_CLIP) { \ + fxSafeClippedTriangle3(VB,gWin,cliptri,i3,i2,i); \ + fxSafeClippedTriangle3(VB,gWin,cliptri,i2,i1,i); \ + } else { \ + FX_grDrawTriangle(fxMesa, (GrVertex *)gWin[i3].f, \ + (GrVertex *)gWin[i2].f, \ + (GrVertex *)gWin[i].f); \ + FX_grDrawTriangle(fxMesa, (GrVertex *)gWin[i2].f, \ + (GrVertex *)gWin[i1].f, \ + (GrVertex *)gWin[i].f); \ + } \ + } while (0) + + + + + +#define LOCAL_VARS \ + fxMesaContext fxMesa=(fxMesaContext)VB->ctx->DriverCtx; \ + fxVertex *gWin = FX_DRIVER_DATA(VB)->verts; \ + const GLubyte *cullmask = VB->CullMask; \ + tfxTriClipFunc cliptri = fxMesa->clip_tri_stride; + + + + +#define INIT(x) (void) cliptri; (void) fxMesa; + +#define TAG(x) x##_fx_smooth_culled +#undef RVB_COLOR +#define RVB_COLOR(x) +#define PRESERVE_VB_DEFS +#include "render_tmp.h" + +#define TAG(x) x##_fx_flat_culled +#undef RVB_COLOR +#define RVB_COLOR(pv) FX_VB_COLOR(fxMesa, VB->ColorPtr->data[pv]) + +#include "render_tmp.h" + + + + +/* Direct, with the possibility of clipping. + */ +#define RENDER_POINTS( start, count ) \ + do { \ + fxVertex *gWin = FX_DRIVER_DATA(VB)->verts; \ + GLubyte *clipmask = VB->ClipMask; \ + GLuint i; \ + for (i = start ; i <= count ; i++) \ + if (clipmask[i] == 0) { \ + RVB_COLOR(i); \ + FX_grDrawPoint( fxMesa, (GrVertex *)gWin[i].f );\ + } \ + } while (0) + +#define RENDER_LINE( i1, i ) \ + do { \ + RVB_COLOR(i); \ + fxSafeClippedLine( VB, i1, i ); \ + } while (0) + +#define RENDER_TRI( i2, i1, i, pv, parity) \ + do { \ + GLuint e2=i2, e1=i1; \ + if (parity) { GLuint t=e2; e2=e1; e1=t; } \ + RVB_COLOR(pv); \ + fxSafeClippedTriangle(VB,gWin,cliptri,e2,e1,i); \ + } while (0) + +#define RENDER_QUAD( i3, i2, i1, i, pv) \ + do { \ + RVB_COLOR(pv); \ + fxSafeClippedTriangle(VB,gWin,cliptri,i3,i2,i); \ + fxSafeClippedTriangle(VB,gWin,cliptri,i2,i1,i); \ + } while (0) + +#define LOCAL_VARS \ + fxMesaContext fxMesa=(fxMesaContext)VB->ctx->DriverCtx; \ + fxVertex *gWin = FX_DRIVER_DATA(VB)->verts; \ + tfxTriClipFunc cliptri = fxMesa->clip_tri_stride; + +#define INIT(x) (void) cliptri; (void) gWin; + +#define TAG(x) x##_fx_smooth_clipped +#undef RVB_COLOR +#define RVB_COLOR(x) +#define PRESERVE_VB_DEFS +#include "render_tmp.h" + + +#define TAG(x) x##_fx_flat_clipped +#undef RVB_COLOR +#define RVB_COLOR(pv) FX_VB_COLOR(fxMesa, VB->ColorPtr->data[pv]) +#include "render_tmp.h" + + + + + + +/* Indirect, with the possibility of clipping. + */ +#define RENDER_POINTS( start, count ) \ + do { \ + fxVertex *gWin = FX_DRIVER_DATA(VB)->verts; \ + GLuint e; \ + GLubyte *clipmask = VB->ClipMask; \ + for(e=start;e<=count;e++) \ + if(clipmask[elt[e]]==0) { \ + FX_grDrawPoint(fxMesa, (GrVertex *)gWin[elt[e]].f); \ + } \ + } while (0) + +#define RENDER_LINE( i1, i ) \ + do { \ + GLuint e1 = elt[i1], e = elt[i]; \ + RVB_COLOR(e); \ + fxSafeClippedLine( VB, e1, e ); \ + } while (0) + +#define RENDER_TRI( i2, i1, i, pv, parity) \ + do { \ + GLuint e2 = elt[i2], e1 = elt[i1], e = elt[i]; \ + if (parity) { GLuint t=e2; e2=e1; e1=t; } \ + fxSafeClippedTriangle(VB,gWin,cliptri,e2,e1,e); \ + } while (0) + +#define RENDER_QUAD( i3, i2, i1, i, pv) \ + do { \ + GLuint e3 = elt[i3], e2 = elt[i2], e1 = elt[i1], e = elt[i];\ + fxSafeClippedTriangle(VB,gWin,cliptri,e3,e2,e); \ + fxSafeClippedTriangle(VB,gWin,cliptri,e2,e1,e); \ + } while (0) + +#define LOCAL_VARS const GLuint *elt = VB->EltPtr->data; \ + fxMesaContext fxMesa = (fxMesaContext)VB->ctx->DriverCtx; \ + fxVertex *gWin = FX_DRIVER_DATA(VB)->verts; \ + tfxTriClipFunc cliptri = fxMesa->clip_tri_stride; + +#define INIT(x) (void) cliptri; (void) gWin; + +#define TAG(x) x##_fx_smooth_indirect_clipped +#undef RVB_COLOR +#define RVB_COLOR(x) +#include "render_tmp.h" + + +/* Indirect, clipped, but no user clip. + */ +#define RENDER_POINTS( start, count ) \ + do { \ + fxVertex *gWin = FX_DRIVER_DATA(VB)->verts; \ + GLuint e; \ + GLubyte *clipmask = VB->ClipMask; \ + for(e=start;e<=count;e++) \ + if(clipmask[elt[e]]==0) { \ + FX_grDrawPoint(fxMesa, (GrVertex *)gWin[elt[e]].f); \ + } \ + } while (0) + +#define RENDER_LINE( i1, i ) \ + do { \ + GLuint e1 = elt[i1], e = elt[i]; \ + RVB_COLOR(e); \ + fxSafeClippedLine( VB, e1, e ); \ + } while (0) + +#define RENDER_TRI( i2, i1, i, pv, parity) \ + do { \ + GLuint e2 = elt[i2], e1 = elt[i1], e = elt[i]; \ + if (parity) { GLuint t=e2; e2=e1; e1=t; } \ + fxSafeClippedTriangle2(VB,gWin,cliptri,e2,e1,e); \ + } while (0) + +#define RENDER_QUAD( i3, i2, i1, i, pv) \ + do { \ + GLuint e3 = elt[i3], e2 = elt[i2], e1 = elt[i1], e = elt[i];\ + fxSafeClippedTriangle2(VB,gWin,cliptri,e3,e2,e); \ + fxSafeClippedTriangle2(VB,gWin,cliptri,e2,e1,e); \ + } while (0) + +#define LOCAL_VARS const GLuint *elt = VB->EltPtr->data; \ + fxMesaContext fxMesa = (fxMesaContext)VB->ctx->DriverCtx; \ + fxVertex *gWin = FX_DRIVER_DATA(VB)->verts; \ + tfxTriViewClipFunc cliptri = fxMesa->view_clip_tri; + +#define INIT(x) (void) cliptri; (void) gWin; + +#define TAG(x) x##_fx_smooth_indirect_view_clipped +#undef RVB_COLOR +#define RVB_COLOR(x) +#include "render_tmp.h" + + + + + + + +/* Indirect, and no clipping required. + */ +#define RENDER_POINTS( start, count ) \ + do { \ + GLuint e; \ + for(e=start;e<=count;e++) { \ + FX_grDrawPoint_NoLock((GrVertex *)gWin[elt[e]].f);\ + } \ + } while (0) + +#define RENDER_LINE( i1, i ) \ + do { \ + GLuint e1 = elt[i1], e = elt[i]; \ + FX_grDrawLine_NoLock((GrVertex *)gWin[e1].f, (GrVertex *)gWin[e].f);\ + } while (0) + + +#define RENDER_TRI( i2, i1, i, pv, parity) \ + do { \ + GLuint e2 = elt[i2], e1 = elt[i1], e = elt[i]; \ + if (parity) {GLuint tmp = e2; e2 = e1; e1 = tmp;} \ + FX_grDrawTriangle_NoLock((GrVertex *)gWin[e2].f, \ + (GrVertex *)gWin[e1].f, \ + (GrVertex *)gWin[e].f); \ + } while (0) + + +#define RENDER_QUAD( i3, i2, i1, i, pv) \ + do { \ + GLuint e3 = elt[i3], e2 = elt[i2], e1 = elt[i1], e = elt[i];\ + FX_grDrawTriangle_NoLock((GrVertex *)gWin[e3].f, \ + (GrVertex *)gWin[e2].f, \ + (GrVertex *)gWin[e].f); \ + FX_grDrawTriangle_NoLock((GrVertex *)gWin[e2].f, \ + (GrVertex *)gWin[e1].f, \ + (GrVertex *)gWin[e].f); \ + } while (0) + +#define LOCAL_VARS \ + fxVertex *gWin = FX_DRIVER_DATA(VB)->verts; \ + const GLuint *elt = VB->EltPtr->data; \ + fxMesaContext fxMesa = FX_CONTEXT(VB->ctx); + +#define INIT(x) BEGIN_CLIP_LOOP(fxMesa); +#define POSTFIX END_CLIP_LOOP(fxMesa); + +#define TAG(x) x##_fx_smooth_indirect +#undef RVB_COLOR +#define RVB_COLOR(x) +#include "render_tmp.h" + + + + + +/* Direct in this context means that triangles, lines, points can be + * rendered simply by calling grDrawTriangle, etc., without any + * additional setup (such as calling grConstantColor). We also use a + * 'safe' set of clipping routines which don't require write-access to + * the arrays in the vertex buffer, and don't care about array + * stride. + * + * Thus there is no call to gl_import_arrays() in this function. + * + * This safe clipping should be generalized to call driver->trianglefunc + * under the appropriate conditions. + * + * We don't handle texcoord-4 in the safe clip routines - maybe we should. + * + */ +void +fxDDRenderElementsDirect(struct vertex_buffer *VB) +{ + GLcontext *ctx = VB->ctx; + struct vertex_buffer *saved_vb = ctx->VB; + GLenum prim = ctx->CVA.elt_mode; + GLuint nr = VB->EltPtr->count; + render_func func = render_tab_fx_smooth_indirect[prim]; + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + GLuint p = 0; + + if (!nr) + return; + + if (fxMesa->new_state) + fxSetupFXUnits(ctx); + + if (!nr) + return; + + if (VB->ClipOrMask) { + func = render_tab_fx_smooth_indirect_view_clipped[prim]; + if (VB->ClipOrMask & CLIP_USER_BIT) + func = render_tab_fx_smooth_indirect_clipped[prim]; + } + + ctx->VB = VB; /* kludge */ + + do { + func(VB, 0, nr, 0); + } while (ctx->Driver.MultipassFunc && ctx->Driver.MultipassFunc(VB, ++p)); + + + ctx->VB = saved_vb; +} + + +void +fxDDRenderVBIndirectDirect(struct vertex_buffer *VB) +{ + GLcontext *ctx = VB->ctx; + struct vertex_buffer *cvaVB = ctx->CVA.VB; + struct vertex_buffer *saved_vb = ctx->VB; + GLuint i, next, count = VB->Count; + render_func *tab = render_tab_fx_smooth_indirect; + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + GLuint p = 0; + + if (cvaVB->ClipOrMask) + tab = render_tab_fx_smooth_indirect_clipped; + + if (!VB->CullDone) + gl_fast_copy_vb(VB); + + if (fxMesa->new_state) + fxSetupFXUnits(ctx); + + ctx->VB = cvaVB; + cvaVB->EltPtr = VB->EltPtr; + + do { + GLuint parity = VB->Parity; + + for (i = VB->CopyStart; i < count; parity = 0, i = next) { + GLuint prim = VB->Primitive[i]; + next = VB->NextPrimitive[i]; + tab[prim] (cvaVB, i, next, parity); + } + /* loop never taken */ + } while (ctx->Driver.MultipassFunc && + ctx->Driver.MultipassFunc(cvaVB, ++p)); + + cvaVB->EltPtr = 0; + ctx->VB = saved_vb; +} + + +static render_func *fxDDRenderVBSmooth_tables[3] = { + render_tab_fx_smooth_clipped, + render_tab_fx_smooth_culled, + render_tab_fx_smooth_raw +}; + +static render_func *fxDDRenderVBFlat_tables[3] = { + render_tab_fx_flat_clipped, + render_tab_fx_flat_culled, + render_tab_fx_flat_raw +}; + + +static render_func *null_tables[3] = { + 0, + 0, + 0 +}; + +#if defined(FX_GLIDE3) +#include "fxstripdet.c" +#endif + +void +fxDDRenderInit(GLcontext * ctx) +{ + render_init_fx_smooth_indirect_view_clipped(); + render_init_fx_smooth_indirect_clipped(); + render_init_fx_smooth_indirect(); + render_init_fx_smooth_raw(); + render_init_fx_smooth_culled(); + render_init_fx_smooth_clipped(); + render_init_fx_flat_raw(); + render_init_fx_flat_culled(); + render_init_fx_flat_clipped(); +#if defined(FX_GLIDE3) + fxDDRenderInitGlide3(ctx); +#endif +} + + +/* Now used to set an internal var in fxMesa - we hook out at the + * level of gl_render_vb() instead. + */ +render_func ** +fxDDChooseRenderVBTables(GLcontext * ctx) +{ + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + + if (ctx->IndirectTriangles & DD_SW_SETUP) + return null_tables; + + switch (fxMesa->render_index) { +/* case FX_FLAT: */ +/* return fxDDRenderVBFlat_tables; */ + case 0: + return fxDDRenderVBSmooth_tables; + default: + return null_tables; + } +} + + +void +fxDDDoRenderVB(struct vertex_buffer *VB) +{ + GLcontext *ctx = VB->ctx; + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + GLuint i, next, prim; + GLuint parity = VB->Parity; + render_func *tab; + GLuint count = VB->Count; + GLint p = 0; + + if (fxMesa->new_state) + fxSetupFXUnits(ctx); + + if (VB->Indirect) { + return; + } + else if (VB->CullMode & CLIP_MASK_ACTIVE) { + tab = fxMesa->RenderVBClippedTab; + } + else { + tab = fxMesa->RenderVBRawTab; + } + + if (!VB->CullDone) + gl_fast_copy_vb(VB); + + do { + for (i = VB->CopyStart; i < count; parity = 0, i = next) { + prim = VB->Primitive[i]; + next = VB->NextPrimitive[i]; + tab[prim] (VB, i, next, parity); + } + + } while (ctx->Driver.MultipassFunc && ctx->Driver.MultipassFunc(VB, ++p)); +} diff --git a/xc/lib/GL/mesa/src/drv/tdfx/fxsanity.c b/xc/lib/GL/mesa/src/drv/tdfx/fxsanity.c new file mode 100644 index 000000000..f614e8fae --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/tdfx/fxsanity.c @@ -0,0 +1,110 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/fxsanity.c,v 1.1 2000/09/24 13:51:17 alanh Exp $ */ +/* + * Mesa 3-D graphics library + * Version: 3.3 + * + * 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. + * + * + * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the + * terms stated above. + * + * Thank you for your contribution, David! + * + * Please make note of the above copyright/license statement. If you + * contributed code or bug fixes to this code under the previous (GNU + * Library) license and object to the new license, your code will be + * removed at your request. Please see the Mesa docs/COPYRIGHT file + * for more information. + * + * Additional Mesa/3Dfx driver developers: + * Daryll Strauss <daryll@precisioninsight.com> + * Keith Whitwell <keith@precisioninsight.com> + * + * See fxapi.h for more revision/author details. + */ + + +#include "fxdrv.h" + +/* I have found this quite useful in tracking down transformation & + * clipping bugs. If you get a random graphics card freeze, running + * your triangles through this will probably catch the problem. + */ + +#define WID 640 +#define HI 480 + +#undef grDrawTriangle + +void +fx_sanity_triangle(fxMesaContext fxMesa, + GrVertex * v1, GrVertex * v2, GrVertex * v3) +{ + GLuint rv = 1, print = 0; + + GLfloat area = ((v1->x - v3->x) * (v2->y - v3->y) - + (v1->y - v3->y) * (v2->x - v3->x)); + + if (v1->x < 0 || v1->y < 0 || v1->x > WID || v1->y > HI || + v2->x < 0 || v2->y < 0 || v2->x > WID || v2->y > HI || + v3->x < 0 || v3->y < 0 || v3->x > WID || v3->y > HI) { + fprintf(stderr, "not clipped/set up!!!!!\n"); + rv = 0; + print = 1; + } + + if (area > (WID * HI)) { + fprintf(stderr, "too big\n"); + rv = 0; + } + if (v1->oow == 0 || v2->oow == 0 || v3->oow == 0) { + fprintf(stderr, "zero oow\n"); + rv = 0; + } + if (0 && area == 0) { + fprintf(stderr, "zero area %p %p %p\n", v1, v2, v3); + rv = 0; + } + + if (print) { + fprintf(stderr, + "v1: %f %f %f %f col %.0f %.0f %.0f %.0f t0 %f %f %f t1 %f %f %f\n", + v1->x, v1->y, v1->ooz, v1->oow, v1->r, v1->g, v1->b, v1->a, + v1->tmuvtx[0].sow, v1->tmuvtx[0].tow, v1->tmuvtx[0].oow, + v1->tmuvtx[1].sow, v1->tmuvtx[1].tow, v1->tmuvtx[1].oow); + fprintf(stderr, + "v2: %f %f %f %f col %.0f %.0f %.0f %.0f t0 %f %f %f t1 %f %f %f\n", + v2->x, v2->y, v2->ooz, v2->oow, v2->r, v2->g, v2->b, v2->a, + v2->tmuvtx[0].sow, v2->tmuvtx[0].tow, v2->tmuvtx[0].oow, + v2->tmuvtx[1].sow, v2->tmuvtx[1].tow, v2->tmuvtx[1].oow); + fprintf(stderr, + "v3: %f %f %f %f col %.0f %.0f %.0f %.0f t0 %f %f %f t1 %f %f %f\n", + v3->x, v3->y, v3->ooz, v3->oow, v3->r, v3->g, v3->b, v3->a, + v3->tmuvtx[0].sow, v3->tmuvtx[0].tow, v3->tmuvtx[0].oow, + v3->tmuvtx[1].sow, v3->tmuvtx[1].tow, v3->tmuvtx[1].oow); + } + + if (1) + FX_grDrawTriangle(fxMesa, v1, v2, v3); + else + fprintf(stderr, "\n\n\n"); +} + diff --git a/xc/lib/GL/mesa/src/drv/tdfx/fxsdettmp.h b/xc/lib/GL/mesa/src/drv/tdfx/fxsdettmp.h new file mode 100644 index 000000000..95794538c --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/tdfx/fxsdettmp.h @@ -0,0 +1,154 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/fxsdettmp.h,v 1.1 2000/09/24 13:51:19 alanh Exp $ */ +/* + * Mesa 3-D graphics library + * Version: 3.3 + * + * 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. + * + * + * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the + * terms stated above. + * + * Thank you for your contribution, David! + * + * Please make note of the above copyright/license statement. If you + * contributed code or bug fixes to this code under the previous (GNU + * Library) license and object to the new license, your code will be + * removed at your request. Please see the Mesa docs/COPYRIGHT file + * for more information. + * + * Additional Mesa/3Dfx driver developers: + * Daryll Strauss <daryll@precisioninsight.com> + * Keith Whitwell <keith@precisioninsight.com> + * + * See fxapi.h for more revision/author details. + */ + + +/* + * Notes: the folowing code works only if count is > start. + * Corrently we are looking for the pattern: + * v0,v1,v2 v2,v1,v3, v2,v3,v4.... + * + * For this: + * #define STRIP0 ((u1 == v1) && (u2 == v0)) + * #define STRIP1 ((u0 == v0) && (u2 == v1)) + * + */ + + +static void TAG(render_vb_triangles_smooth_indirect_sd) + (struct vertex_buffer * VB, GLuint start, GLuint count, GLuint parity) +{ + GLint u0, u1, u2; + GLint v0, v1, v2; + GLuint *elt = VB->EltPtr->data; + + int i; + LOCAL_VARS INIT(GL_TRIANGLES); + + elt = &elt[start - 1]; + u0 = *(++elt); + u1 = *(++elt); + u2 = *(++elt); + i = start + 3; + while (i < count) { + v0 = *(++elt); + v1 = *(++elt); + v2 = *(++elt); + + if (CLIPPED(u0, u1, u2)) { + if (!CULLED(u0, u1, u2)) + SENDCLIPTRI(u0, u1, u2); + } + else { + if (STRIP0(u, v)) { + int is_strips = 1; + int parity = 0; + STRIPSLOCAL_VAR FLUSHTRI(); + STARTSTRIPS(u0, u1, u2); + while (is_strips && i < count) { + SENDSTRIPS(v2); + + u0 = v0; + u1 = v1; + u2 = v2; + i += 3; + v0 = *(++elt); + v1 = *(++elt); + v2 = *(++elt); + + if (parity) { + is_strips = STRIP0(u, v); + parity = 0; + } + else { + is_strips = STRIP1(u, v); + parity = 1; + } + } + FLUSHSTRIPS(); + + if (i >= count) + return; + } + else { + SENDTRI(u0, u1, u2); + } + } + u0 = v0; + u1 = v1; + u2 = v2; + i += 3; + } + if (CLIPPED(u0, u1, u2)) { + if (!CULLED(u0, u1, u2)) + SENDCLIPTRI(u0, u1, u2); + } + else { + SENDTRI(u0, u1, u2); + } + FLUSHTRI(); + +} + +#ifndef PRESERVE_VB_DEFS +#undef SENDTRI +#undef STRIP0 +#undef STRIP1 +#undef LOCAL_VARS +#undef STRIPSLOCAL_VAR +#undef INIT +#undef SENDTRI +#undef FLUSHTRI +#undef STARTSTRIPS +#undef SENDSTRIPS +#undef FLUSHSTRIPS +#undef CLIPPED +#undef CULLED +#undef SENDCLIPTRI +#endif + +#ifndef PRESERVE_TAG +#undef TAG +#endif + +#undef PRESERVE_VB_DEFS +#undef PRESERVE_TAG diff --git a/xc/lib/GL/mesa/src/drv/tdfx/fxsetup.c b/xc/lib/GL/mesa/src/drv/tdfx/fxsetup.c new file mode 100644 index 000000000..a84a6ee15 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/tdfx/fxsetup.c @@ -0,0 +1,2077 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/fxsetup.c,v 1.1 2000/09/24 13:51:19 alanh Exp $ */ +/* + * Mesa 3-D graphics library + * Version: 3.3 + * + * 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. + * + * + * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the + * terms stated above. + * + * Thank you for your contribution, David! + * + * Please make note of the above copyright/license statement. If you + * contributed code or bug fixes to this code under the previous (GNU + * Library) license and object to the new license, your code will be + * removed at your request. Please see the Mesa docs/COPYRIGHT file + * for more information. + * + * Additional Mesa/3Dfx driver developers: + * Daryll Strauss <daryll@precisioninsight.com> + * Keith Whitwell <keith@precisioninsight.com> + * + * See fxapi.h for more revision/author details. + */ + + +/* fxsetup.c - 3Dfx VooDoo rendering mode setup functions */ + +#include "fxdrv.h" +#include "fxddtex.h" +#include "fxtexman.h" +#include "fxsetup.h" +#include "enums.h" + + +static GLboolean fxMultipassTexture(struct vertex_buffer *, GLuint); + + + +static void +fxTexValidate(GLcontext * ctx, struct gl_texture_object *tObj) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + tfxTexInfo *ti = fxTMGetTexInfo(tObj); + GLint minl, maxl; + + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: fxTexValidate(...) Start\n"); + } + + if (ti->validated) { + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, + "fxmesa: fxTexValidate(...) End (validated=GL_TRUE)\n"); + } + return; + } + + ti->tObj = tObj; + minl = ti->minLevel = tObj->BaseLevel; + maxl = ti->maxLevel = MIN2(tObj->MaxLevel, tObj->Image[0]->MaxLog2); + + fxTexGetInfo(ctx, tObj->Image[minl]->Width, tObj->Image[minl]->Height, + &(FX_largeLodLog2(ti->info)), + &(FX_aspectRatioLog2(ti->info)), &(ti->sScale), + &(ti->tScale), &(ti->int_sScale), &(ti->int_tScale), NULL, + NULL); + + if ((tObj->MinFilter != GL_NEAREST) && (tObj->MinFilter != GL_LINEAR)) + fxTexGetInfo(ctx, tObj->Image[maxl]->Width, tObj->Image[maxl]->Height, + &(FX_smallLodLog2(ti->info)), NULL, + NULL, NULL, NULL, NULL, NULL, NULL); + else + FX_smallLodLog2(ti->info) = FX_largeLodLog2(ti->info); + + fxTexGetFormat(tObj->Image[minl]->IntFormat, &(ti->info.format), + &(ti->baseLevelInternalFormat), NULL, NULL, + fxMesa->haveHwStencil); + + switch (tObj->WrapS) { + case GL_CLAMP_TO_EDGE: + case GL_CLAMP: + ti->sClamp = 1; + break; + case GL_REPEAT: + ti->sClamp = 0; + break; + default: + ; /* silence compiler warning */ + } + switch (tObj->WrapT) { + case GL_CLAMP_TO_EDGE: + case GL_CLAMP: + ti->tClamp = 1; + break; + case GL_REPEAT: + ti->tClamp = 0; + break; + default: + ; /* silence compiler warning */ + } + + ti->validated = GL_TRUE; + + ti->info.data = NULL; + + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: fxTexValidate(...) End\n"); + } +} + +static void +fxPrintUnitsMode(const char *msg, GLuint mode) +{ + fprintf(stderr, + "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", + msg, + mode, + (mode & FX_UM_E0_REPLACE) ? "E0_REPLACE, " : "", + (mode & FX_UM_E0_MODULATE) ? "E0_MODULATE, " : "", + (mode & FX_UM_E0_DECAL) ? "E0_DECAL, " : "", + (mode & FX_UM_E0_BLEND) ? "E0_BLEND, " : "", + (mode & FX_UM_E1_REPLACE) ? "E1_REPLACE, " : "", + (mode & FX_UM_E1_MODULATE) ? "E1_MODULATE, " : "", + (mode & FX_UM_E1_DECAL) ? "E1_DECAL, " : "", + (mode & FX_UM_E1_BLEND) ? "E1_BLEND, " : "", + (mode & FX_UM_E0_ALPHA) ? "E0_ALPHA, " : "", + (mode & FX_UM_E0_LUMINANCE) ? "E0_LUMINANCE, " : "", + (mode & FX_UM_E0_LUMINANCE_ALPHA) ? "E0_LUMINANCE_ALPHA, " : "", + (mode & FX_UM_E0_INTENSITY) ? "E0_INTENSITY, " : "", + (mode & FX_UM_E0_RGB) ? "E0_RGB, " : "", + (mode & FX_UM_E0_RGBA) ? "E0_RGBA, " : "", + (mode & FX_UM_E1_ALPHA) ? "E1_ALPHA, " : "", + (mode & FX_UM_E1_LUMINANCE) ? "E1_LUMINANCE, " : "", + (mode & FX_UM_E1_LUMINANCE_ALPHA) ? "E1_LUMINANCE_ALPHA, " : "", + (mode & FX_UM_E1_INTENSITY) ? "E1_INTENSITY, " : "", + (mode & FX_UM_E1_RGB) ? "E1_RGB, " : "", + (mode & FX_UM_E1_RGBA) ? "E1_RGBA, " : "", + (mode & FX_UM_COLOR_ITERATED) ? "COLOR_ITERATED, " : "", + (mode & FX_UM_COLOR_CONSTANT) ? "COLOR_CONSTANT, " : "", + (mode & FX_UM_ALPHA_ITERATED) ? "ALPHA_ITERATED, " : "", + (mode & FX_UM_ALPHA_CONSTANT) ? "ALPHA_CONSTANT, " : ""); +} + +static GLuint +fxGetTexSetConfiguration(GLcontext * ctx, + struct gl_texture_object *tObj0, + struct gl_texture_object *tObj1) +{ + GLuint unitsmode = 0; + GLuint envmode = 0; + GLuint ifmt = 0; + + if ((ctx->Light.ShadeModel == GL_SMOOTH) || 1 || + (ctx->Point.SmoothFlag) || + (ctx->Line.SmoothFlag) || + (ctx->Polygon.SmoothFlag)) + unitsmode |= FX_UM_ALPHA_ITERATED; + else + unitsmode |= FX_UM_ALPHA_CONSTANT; + + if (ctx->Light.ShadeModel == GL_SMOOTH || 1) + unitsmode |= FX_UM_COLOR_ITERATED; + else + unitsmode |= FX_UM_COLOR_CONSTANT; + + + + /* + OpenGL Feeds Texture 0 into Texture 1 + Glide Feeds Texture 1 into Texture 0 + */ + if (tObj0) { + tfxTexInfo *ti0 = fxTMGetTexInfo(tObj0); + + switch (ti0->baseLevelInternalFormat) { + case GL_ALPHA: + ifmt |= FX_UM_E0_ALPHA; + break; + case GL_LUMINANCE: + ifmt |= FX_UM_E0_LUMINANCE; + break; + case GL_LUMINANCE_ALPHA: + ifmt |= FX_UM_E0_LUMINANCE_ALPHA; + break; + case GL_INTENSITY: + ifmt |= FX_UM_E0_INTENSITY; + break; + case GL_RGB: + ifmt |= FX_UM_E0_RGB; + break; + case GL_RGBA: + ifmt |= FX_UM_E0_RGBA; + break; + } + + switch (ctx->Texture.Unit[0].EnvMode) { + case GL_DECAL: + envmode |= FX_UM_E0_DECAL; + break; + case GL_MODULATE: + envmode |= FX_UM_E0_MODULATE; + break; + case GL_REPLACE: + envmode |= FX_UM_E0_REPLACE; + break; + case GL_BLEND: + envmode |= FX_UM_E0_BLEND; + break; + case GL_ADD: + envmode |= FX_UM_E0_ADD; + break; + default: + /* do nothing */ + break; + } + } + + if (tObj1) { + tfxTexInfo *ti1 = fxTMGetTexInfo(tObj1); + + switch (ti1->baseLevelInternalFormat) { + case GL_ALPHA: + ifmt |= FX_UM_E1_ALPHA; + break; + case GL_LUMINANCE: + ifmt |= FX_UM_E1_LUMINANCE; + break; + case GL_LUMINANCE_ALPHA: + ifmt |= FX_UM_E1_LUMINANCE_ALPHA; + break; + case GL_INTENSITY: + ifmt |= FX_UM_E1_INTENSITY; + break; + case GL_RGB: + ifmt |= FX_UM_E1_RGB; + break; + case GL_RGBA: + ifmt |= FX_UM_E1_RGBA; + break; + default: + /* do nothing */ + break; + } + + switch (ctx->Texture.Unit[1].EnvMode) { + case GL_DECAL: + envmode |= FX_UM_E1_DECAL; + break; + case GL_MODULATE: + envmode |= FX_UM_E1_MODULATE; + break; + case GL_REPLACE: + envmode |= FX_UM_E1_REPLACE; + break; + case GL_BLEND: + envmode |= FX_UM_E1_BLEND; + break; + case GL_ADD: + envmode |= FX_UM_E1_ADD; + break; + default: + /* do nothing */ + break; + } + } + + unitsmode |= (ifmt | envmode); + + if (MESA_VERBOSE & (VERBOSE_DRIVER | VERBOSE_TEXTURE)) + fxPrintUnitsMode("unitsmode", unitsmode); + + return unitsmode; +} + +/************************************************************************/ +/************************* Rendering Mode SetUp *************************/ +/************************************************************************/ + +/************************* Single Texture Set ***************************/ + +static void +fxSetupSingleTMU_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj) +{ + tfxTexInfo *ti = fxTMGetTexInfo(tObj); + int tmu; + + /* Make sure we're not loaded incorrectly */ + if (ti->isInTM) { + if (ti->LODblend) { + if (ti->whichTMU != FX_TMU_SPLIT) + fxTMMoveOutTM(fxMesa, tObj); + } + else { + if (ti->whichTMU == FX_TMU_SPLIT) + fxTMMoveOutTM(fxMesa, tObj); + } + } + + /* Make sure we're loaded correctly */ + if (!ti->isInTM) { + if (ti->LODblend) + fxTMMoveInTM_NoLock(fxMesa, tObj, FX_TMU_SPLIT); + else { + if (fxMesa->haveTwoTMUs) { + if (fxMesa->freeTexMem[FX_TMU0] > + FX_grTexTextureMemRequired_NoLock(GR_MIPMAPLEVELMASK_BOTH, + &(ti->info))) { + fxTMMoveInTM_NoLock(fxMesa, tObj, FX_TMU0); + } + else { + fxTMMoveInTM_NoLock(fxMesa, tObj, FX_TMU1); + } + } + else + fxTMMoveInTM_NoLock(fxMesa, tObj, FX_TMU0); + } + } + + if (ti->LODblend && ti->whichTMU == FX_TMU_SPLIT) { + if ((ti->info.format == GR_TEXFMT_P_8) + && (!fxMesa->haveGlobalPaletteTexture)) { + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: uploading texture palette\n"); + } + FX_grTexDownloadTable_NoLock(GR_TMU0, GR_TEXTABLE_PALETTE_6666_EXT, + &(ti->palette)); + FX_grTexDownloadTable_NoLock(GR_TMU1, GR_TEXTABLE_PALETTE_6666_EXT, + &(ti->palette)); + } + + FX_grTexClampMode_NoLock(GR_TMU0, ti->sClamp, ti->tClamp); + FX_grTexClampMode_NoLock(GR_TMU1, ti->sClamp, ti->tClamp); + FX_grTexFilterMode_NoLock(GR_TMU0, ti->minFilt, ti->maxFilt); + FX_grTexFilterMode_NoLock(GR_TMU1, ti->minFilt, ti->maxFilt); + FX_grTexMipMapMode_NoLock(GR_TMU0, ti->mmMode, ti->LODblend); + FX_grTexMipMapMode_NoLock(GR_TMU1, ti->mmMode, ti->LODblend); + + FX_grTexSource_NoLock(GR_TMU0, ti->tm[FX_TMU0]->startAddr, + GR_MIPMAPLEVELMASK_ODD, &(ti->info)); + FX_grTexSource_NoLock(GR_TMU1, ti->tm[FX_TMU1]->startAddr, + GR_MIPMAPLEVELMASK_EVEN, &(ti->info)); + } + else { + if (ti->whichTMU == FX_TMU_BOTH) + tmu = FX_TMU0; + else + tmu = ti->whichTMU; + + if ((ti->info.format == GR_TEXFMT_P_8) + && (!fxMesa->haveGlobalPaletteTexture)) { + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: uploading texture palette\n"); + } + FX_grTexDownloadTable_NoLock(tmu, GR_TEXTABLE_PALETTE_6666_EXT, + &(ti->palette)); + } + + /* KW: The alternative is to do the download to the other tmu. If + * we get to this point, I think it means we are thrashing the + * texture memory, so perhaps it's not a good idea. + */ + if (ti->LODblend && (MESA_VERBOSE & VERBOSE_DRIVER)) + fprintf(stderr, + "fxmesa: not blending texture - only on one tmu\n"); + + FX_grTexClampMode_NoLock(tmu, ti->sClamp, ti->tClamp); + FX_grTexFilterMode_NoLock(tmu, ti->minFilt, ti->maxFilt); + FX_grTexMipMapMode_NoLock(tmu, ti->mmMode, FXFALSE); + + if (ti->tm[tmu]) { + FX_grTexSource_NoLock(tmu, ti->tm[tmu]->startAddr, + GR_MIPMAPLEVELMASK_BOTH, &(ti->info)); + } + } +} + +static void +fxSelectSingleTMUSrc_NoLock(fxMesaContext fxMesa, GLint tmu, FxBool LODblend) +{ + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: fxSelectSingleTMUSrc(%d,%d)\n", tmu, + LODblend); + } + + if (LODblend) { + FX_grTexCombine_NoLock(GR_TMU0, + GR_COMBINE_FUNCTION_BLEND, + GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION, + GR_COMBINE_FUNCTION_BLEND, + GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION, + FXFALSE, FXFALSE); + + if (fxMesa->haveTwoTMUs) + FX_grTexCombine_NoLock(GR_TMU1, + GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, FXFALSE, FXFALSE); + fxMesa->tmuSrc = FX_TMU_SPLIT; + } + else { + if (tmu != FX_TMU1) { + FX_grTexCombine_NoLock(GR_TMU0, + GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, FXFALSE, FXFALSE); + if (fxMesa->haveTwoTMUs) { + FX_grTexCombine_NoLock(GR_TMU1, + GR_COMBINE_FUNCTION_ZERO, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_FUNCTION_ZERO, + GR_COMBINE_FACTOR_NONE, FXFALSE, + FXFALSE); + } + fxMesa->tmuSrc = FX_TMU0; + } + else { + FX_grTexCombine_NoLock(GR_TMU1, + GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, FXFALSE, FXFALSE); + + /* GR_COMBINE_FUNCTION_SCALE_OTHER doesn't work ?!? */ + + FX_grTexCombine_NoLock(GR_TMU0, + GR_COMBINE_FUNCTION_BLEND, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_FUNCTION_BLEND, + GR_COMBINE_FACTOR_ONE, FXFALSE, FXFALSE); + + fxMesa->tmuSrc = FX_TMU1; + } + } +} + +static void +fxSetupTextureSingleTMU_NoLock(GLcontext * ctx, GLuint textureset) +{ + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + GrCombineLocal_t localc, locala; + GLuint unitsmode; + GLint ifmt; + tfxTexInfo *ti; + struct gl_texture_object *tObj = + ctx->Texture.Unit[textureset].CurrentD[2]; + int tmu; + + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: fxSetupTextureSingleTMU(...) Start\n"); + } + + ti = fxTMGetTexInfo(tObj); + + fxTexValidate(ctx, tObj); + + fxSetupSingleTMU_NoLock(fxMesa, tObj); + + if (ti->whichTMU == FX_TMU_BOTH) + tmu = FX_TMU0; + else + tmu = ti->whichTMU; + if (fxMesa->tmuSrc != tmu) + fxSelectSingleTMUSrc_NoLock(fxMesa, tmu, ti->LODblend); + + if (textureset == 0 || !fxMesa->haveTwoTMUs) + unitsmode = fxGetTexSetConfiguration(ctx, tObj, NULL); + else + unitsmode = fxGetTexSetConfiguration(ctx, NULL, tObj); + + fxMesa->stw_hint_state = 0; + FX_grHints_NoLock(GR_HINT_STWHINT, 0); + + ifmt = ti->baseLevelInternalFormat; + + if (unitsmode & FX_UM_ALPHA_ITERATED) + locala = GR_COMBINE_LOCAL_ITERATED; + else + locala = GR_COMBINE_LOCAL_CONSTANT; + + if (unitsmode & FX_UM_COLOR_ITERATED) + localc = GR_COMBINE_LOCAL_ITERATED; + else + localc = GR_COMBINE_LOCAL_CONSTANT; + + if (MESA_VERBOSE & (VERBOSE_DRIVER | VERBOSE_TEXTURE)) + fprintf(stderr, "fxMesa: fxSetupTextureSingleTMU, envmode is %s\n", + gl_lookup_enum_by_nr(ctx->Texture.Unit[textureset].EnvMode)); + + switch (ctx->Texture.Unit[textureset].EnvMode) { + case GL_DECAL: + FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + locala, GR_COMBINE_OTHER_NONE, FXFALSE); + + FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_BLEND, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + localc, GR_COMBINE_OTHER_TEXTURE, FXFALSE); + break; + case GL_MODULATE: + FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + locala, GR_COMBINE_OTHER_TEXTURE, FXFALSE); + + if (ifmt == GL_ALPHA) + FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + localc, GR_COMBINE_OTHER_NONE, FXFALSE); + else + FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + localc, GR_COMBINE_OTHER_TEXTURE, + FXFALSE); + break; + case GL_BLEND: +#if 0 + FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + locala, GR_COMBINE_OTHER_TEXTURE, FXFALSE); + if (ifmt == GL_ALPHA) + FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + localc, GR_COMBINE_OTHER_NONE, FXFALSE); + else + FX_grColorCombine_NoLock + (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_LOCAL, localc, GR_COMBINE_OTHER_TEXTURE, + FXTRUE); + ctx->Driver.MultipassFunc = fxMultipassBlend; +#else + if (MESA_VERBOSE & VERBOSE_DRIVER) + fprintf(stderr, "fx Driver: GL_BLEND not yet supported\n"); +#endif + break; + case GL_REPLACE: + if ((ifmt == GL_RGB) || (ifmt == GL_LUMINANCE)) + FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + locala, GR_COMBINE_OTHER_NONE, FXFALSE); + else + FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + locala, GR_COMBINE_OTHER_TEXTURE, + FXFALSE); + + if (ifmt == GL_ALPHA) + FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + localc, GR_COMBINE_OTHER_NONE, FXFALSE); + else + FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + localc, GR_COMBINE_OTHER_TEXTURE, + FXFALSE); + break; + case GL_ADD: + if (ifmt == GL_ALPHA || + ifmt == GL_LUMINANCE_ALPHA || + ifmt == GL_RGBA) { + /* product of texel and fragment alpha */ + FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + locala, GR_COMBINE_OTHER_TEXTURE, FXFALSE); + } + else if (ifmt == GL_LUMINANCE || ifmt == GL_RGB) { + /* fragment alpha is unchanged */ + FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + locala, GR_COMBINE_OTHER_NONE, FXFALSE); + } + else { + ASSERT(ifmt == GL_INTENSITY); + /* sum of texel and fragment alpha */ + FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + locala, GR_COMBINE_OTHER_TEXTURE, + FXFALSE); + } + if (ifmt == GL_ALPHA) { + /* rgb unchanged */ + FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + localc, GR_COMBINE_OTHER_NONE, FXFALSE); + } + else { + /* sum of texel and fragment rgb */ + FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + localc, GR_COMBINE_OTHER_TEXTURE, + FXFALSE); + } + break; + default: + if (MESA_VERBOSE & VERBOSE_DRIVER) + fprintf(stderr, + "fx Driver: %x Texture.EnvMode not yet supported\n", + ctx->Texture.Unit[textureset].EnvMode); + break; + } + + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: fxSetupTextureSingleTMU(...) End\n"); + } +} + +static void +fxSetupTextureSingleTMU(GLcontext * ctx, GLuint textureset) +{ + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + BEGIN_BOARD_LOCK(fxMesa); + fxSetupTextureSingleTMU_NoLock(ctx, textureset); + END_BOARD_LOCK(fxMesa); +} + +/************************* Double Texture Set ***************************/ + +static void +fxSetupDoubleTMU_NoLock(fxMesaContext fxMesa, + struct gl_texture_object *tObj0, + struct gl_texture_object *tObj1) +{ +#define T0_NOT_IN_TMU 0x01 +#define T1_NOT_IN_TMU 0x02 +#define T0_IN_TMU0 0x04 +#define T1_IN_TMU0 0x08 +#define T0_IN_TMU1 0x10 +#define T1_IN_TMU1 0x20 + + tfxTexInfo *ti0 = fxTMGetTexInfo(tObj0); + tfxTexInfo *ti1 = fxTMGetTexInfo(tObj1); + GLuint tstate = 0; + int tmu0 = 0, tmu1 = 1; + + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: fxSetupDoubleTMU(...)\n"); + } + + /* We shouldn't need to do this. There is something wrong with + mutlitexturing when the TMUs are swapped. So, we're forcing + them to always be loaded correctly. !!! */ + if (ti0->whichTMU == FX_TMU1) + fxTMMoveOutTM_NoLock(fxMesa, tObj0); + if (ti1->whichTMU == FX_TMU0) + fxTMMoveOutTM_NoLock(fxMesa, tObj1); + + if (ti0->isInTM) { + switch (ti0->whichTMU) { + case FX_TMU0: + tstate |= T0_IN_TMU0; + break; + case FX_TMU1: + tstate |= T0_IN_TMU1; + break; + case FX_TMU_BOTH: + tstate |= T0_IN_TMU0 | T0_IN_TMU1; + break; + case FX_TMU_SPLIT: + tstate |= T0_NOT_IN_TMU; + break; + } + } + else + tstate |= T0_NOT_IN_TMU; + + if (ti1->isInTM) { + switch (ti1->whichTMU) { + case FX_TMU0: + tstate |= T1_IN_TMU0; + break; + case FX_TMU1: + tstate |= T1_IN_TMU1; + break; + case FX_TMU_BOTH: + tstate |= T1_IN_TMU0 | T1_IN_TMU1; + break; + case FX_TMU_SPLIT: + tstate |= T1_NOT_IN_TMU; + break; + } + } + else + tstate |= T1_NOT_IN_TMU; + + ti0->lastTimeUsed = fxMesa->texBindNumber; + ti1->lastTimeUsed = fxMesa->texBindNumber; + + /* Move texture maps into TMUs */ + + if (!(((tstate & T0_IN_TMU0) && (tstate & T1_IN_TMU1)) || + ((tstate & T0_IN_TMU1) && (tstate & T1_IN_TMU0)))) { + if (tObj0 == tObj1) + fxTMMoveInTM_NoLock(fxMesa, tObj1, FX_TMU_BOTH); + else { + /* Find the minimal way to correct the situation */ + if ((tstate & T0_IN_TMU0) || (tstate & T1_IN_TMU1)) { + /* We have one in the standard order, setup the other */ + if (tstate & T0_IN_TMU0) { /* T0 is in TMU0, put T1 in TMU1 */ + fxTMMoveInTM_NoLock(fxMesa, tObj1, FX_TMU1); + } + else { + fxTMMoveInTM_NoLock(fxMesa, tObj0, FX_TMU0); + } + /* tmu0 and tmu1 are setup */ + } + else if ((tstate & T0_IN_TMU1) || (tstate & T1_IN_TMU0)) { + /* we have one in the reverse order, setup the other */ + if (tstate & T1_IN_TMU0) { /* T1 is in TMU0, put T0 in TMU1 */ + fxTMMoveInTM_NoLock(fxMesa, tObj0, FX_TMU1); + } + else { + fxTMMoveInTM_NoLock(fxMesa, tObj1, FX_TMU0); + } + tmu0 = 1; + tmu1 = 0; + } + else { /* Nothing is loaded */ + fxTMMoveInTM_NoLock(fxMesa, tObj0, FX_TMU0); + fxTMMoveInTM_NoLock(fxMesa, tObj1, FX_TMU1); + /* tmu0 and tmu1 are setup */ + } + } + } + + if (!fxMesa->haveGlobalPaletteTexture) { + if (ti0->info.format == GR_TEXFMT_P_8) { + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: uploading texture palette TMU0\n"); + } + FX_grTexDownloadTable_NoLock(tmu0, GR_TEXTABLE_PALETTE_6666_EXT, + &(ti0->palette)); + } + + if (ti1->info.format == GR_TEXFMT_P_8) { + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: uploading texture palette TMU1\n"); + } + FX_grTexDownloadTable_NoLock(tmu1, GR_TEXTABLE_PALETTE_6666_EXT, + &(ti1->palette)); + } + } + + FX_grTexSource_NoLock(tmu0, ti0->tm[tmu0]->startAddr, + GR_MIPMAPLEVELMASK_BOTH, &(ti0->info)); + FX_grTexClampMode_NoLock(tmu0, ti0->sClamp, ti0->tClamp); + FX_grTexFilterMode_NoLock(tmu0, ti0->minFilt, ti0->maxFilt); + FX_grTexMipMapMode_NoLock(tmu0, ti0->mmMode, FXFALSE); + + FX_grTexSource_NoLock(tmu1, ti1->tm[tmu1]->startAddr, + GR_MIPMAPLEVELMASK_BOTH, &(ti1->info)); + FX_grTexClampMode_NoLock(tmu1, ti1->sClamp, ti1->tClamp); + FX_grTexFilterMode_NoLock(tmu1, ti1->minFilt, ti1->maxFilt); + FX_grTexMipMapMode_NoLock(tmu1, ti1->mmMode, FXFALSE); + +#undef T0_NOT_IN_TMU +#undef T1_NOT_IN_TMU +#undef T0_IN_TMU0 +#undef T1_IN_TMU0 +#undef T0_IN_TMU1 +#undef T1_IN_TMU1 +} + +static void +fxSetupTextureDoubleTMU_NoLock(GLcontext * ctx) +{ + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + GrCombineLocal_t localc, locala; + tfxTexInfo *ti0, *ti1; + struct gl_texture_object *tObj0 = ctx->Texture.Unit[0].CurrentD[2]; + struct gl_texture_object *tObj1 = ctx->Texture.Unit[1].CurrentD[2]; + GLuint envmode, ifmt, unitsmode; + int tmu0 = 0, tmu1 = 1; + + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: fxSetupTextureDoubleTMU(...) Start\n"); + } + + ti0 = fxTMGetTexInfo(tObj0); + fxTexValidate(ctx, tObj0); + + ti1 = fxTMGetTexInfo(tObj1); + fxTexValidate(ctx, tObj1); + + fxSetupDoubleTMU_NoLock(fxMesa, tObj0, tObj1); + + unitsmode = fxGetTexSetConfiguration(ctx, tObj0, tObj1); + + fxMesa->stw_hint_state |= GR_STWHINT_ST_DIFF_TMU1; + FX_grHints_NoLock(GR_HINT_STWHINT, fxMesa->stw_hint_state); + + envmode = unitsmode & FX_UM_E_ENVMODE; + ifmt = unitsmode & FX_UM_E_IFMT; + + if (unitsmode & FX_UM_ALPHA_ITERATED) + locala = GR_COMBINE_LOCAL_ITERATED; + else + locala = GR_COMBINE_LOCAL_CONSTANT; + + if (unitsmode & FX_UM_COLOR_ITERATED) + localc = GR_COMBINE_LOCAL_ITERATED; + else + localc = GR_COMBINE_LOCAL_CONSTANT; + + + if (MESA_VERBOSE & (VERBOSE_DRIVER | VERBOSE_TEXTURE)) + fprintf(stderr, "fxMesa: fxSetupTextureDoubleTMU, envmode is %s/%s\n", + gl_lookup_enum_by_nr(ctx->Texture.Unit[0].EnvMode), + gl_lookup_enum_by_nr(ctx->Texture.Unit[1].EnvMode)); + + + if ((ti0->whichTMU == FX_TMU1) || (ti1->whichTMU == FX_TMU0)) { + tmu0 = 1; + tmu1 = 0; + } + fxMesa->tmuSrc = FX_TMU_BOTH; + switch (envmode) { + case (FX_UM_E0_MODULATE | FX_UM_E1_MODULATE): + { + GLboolean isalpha[FX_NUM_TMU]; + + if (ti0->baseLevelInternalFormat == GL_ALPHA) + isalpha[tmu0] = GL_TRUE; + else + isalpha[tmu0] = GL_FALSE; + + if (ti1->baseLevelInternalFormat == GL_ALPHA) + isalpha[tmu1] = GL_TRUE; + else + isalpha[tmu1] = GL_FALSE; + + if (isalpha[FX_TMU1]) + FX_grTexCombine_NoLock(GR_TMU1, + GR_COMBINE_FUNCTION_ZERO, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, FXTRUE, + FXFALSE); + else + FX_grTexCombine_NoLock(GR_TMU1, GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, FXFALSE, + FXFALSE); + + if (isalpha[FX_TMU0]) + FX_grTexCombine_NoLock(GR_TMU0, + GR_COMBINE_FUNCTION_BLEND_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_FUNCTION_BLEND_OTHER, + GR_COMBINE_FACTOR_LOCAL, FXFALSE, + FXFALSE); + else + FX_grTexCombine_NoLock(GR_TMU0, + GR_COMBINE_FUNCTION_BLEND_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_FUNCTION_BLEND_OTHER, + GR_COMBINE_FACTOR_LOCAL, FXFALSE, + FXFALSE); + + FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + localc, GR_COMBINE_OTHER_TEXTURE, + FXFALSE); + + FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + locala, GR_COMBINE_OTHER_TEXTURE, + FXFALSE); + break; + } + case (FX_UM_E0_REPLACE | FX_UM_E1_BLEND): /* Only for GLQuake */ + if (tmu1 == FX_TMU1) { + FX_grTexCombine_NoLock(GR_TMU1, + GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, FXTRUE, FXFALSE); + + FX_grTexCombine_NoLock(GR_TMU0, + GR_COMBINE_FUNCTION_BLEND_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_FUNCTION_BLEND_OTHER, + GR_COMBINE_FACTOR_LOCAL, FXFALSE, FXFALSE); + } + else { + FX_grTexCombine_NoLock(GR_TMU1, + GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, FXFALSE, FXFALSE); + + FX_grTexCombine_NoLock(GR_TMU0, + GR_COMBINE_FUNCTION_BLEND_OTHER, + GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, + GR_COMBINE_FUNCTION_BLEND_OTHER, + GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, + FXFALSE, FXFALSE); + } + + FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + locala, GR_COMBINE_OTHER_NONE, FXFALSE); + + FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + localc, GR_COMBINE_OTHER_TEXTURE, FXFALSE); + break; + case (FX_UM_E0_REPLACE | FX_UM_E1_MODULATE): /* Quake 2 and 3 */ + if (tmu1 == FX_TMU1) { + FX_grTexCombine_NoLock(GR_TMU1, + GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_FUNCTION_ZERO, + GR_COMBINE_FACTOR_NONE, FXFALSE, FXTRUE); + + FX_grTexCombine_NoLock(GR_TMU0, + GR_COMBINE_FUNCTION_BLEND_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_FUNCTION_BLEND_OTHER, + GR_COMBINE_FACTOR_LOCAL, FXFALSE, FXFALSE); + + } + else { + FX_grTexCombine_NoLock(GR_TMU1, + GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, FXFALSE, FXFALSE); + + FX_grTexCombine_NoLock(GR_TMU0, + GR_COMBINE_FUNCTION_BLEND_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_FUNCTION_BLEND_OTHER, + GR_COMBINE_FACTOR_ONE, FXFALSE, FXFALSE); + } + + if (ti0->baseLevelInternalFormat == GL_RGB) + FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + locala, GR_COMBINE_OTHER_NONE, FXFALSE); + else + FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + locala, GR_COMBINE_OTHER_NONE, FXFALSE); + + + FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + localc, GR_COMBINE_OTHER_TEXTURE, FXFALSE); + break; + + + case (FX_UM_E0_MODULATE | FX_UM_E1_ADD): /* Quake 3 Sky */ + { + GLboolean isalpha[FX_NUM_TMU]; + + if (ti0->baseLevelInternalFormat == GL_ALPHA) + isalpha[tmu0] = GL_TRUE; + else + isalpha[tmu0] = GL_FALSE; + + if (ti1->baseLevelInternalFormat == GL_ALPHA) + isalpha[tmu1] = GL_TRUE; + else + isalpha[tmu1] = GL_FALSE; + + if (isalpha[FX_TMU1]) + FX_grTexCombine_NoLock(GR_TMU1, + GR_COMBINE_FUNCTION_ZERO, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, FXTRUE, + FXFALSE); + else + FX_grTexCombine_NoLock(GR_TMU1, GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, FXFALSE, + FXFALSE); + + if (isalpha[FX_TMU0]) + FX_grTexCombine_NoLock(GR_TMU0, + GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, FXFALSE, + FXFALSE); + else + FX_grTexCombine_NoLock(GR_TMU0, + GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, FXFALSE, + FXFALSE); + + FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + localc, GR_COMBINE_OTHER_TEXTURE, + FXFALSE); + + FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + locala, GR_COMBINE_OTHER_TEXTURE, + FXFALSE); + break; + } + default: + fprintf(stderr, "Unexpected dual texture mode encountered\n"); + break; + } + + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: fxSetupTextureDoubleTMU(...) End\n"); + } +} + +/************************* No Texture ***************************/ + +static void +fxSetupTextureNone_NoLock(GLcontext * ctx) +{ + /*fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;*/ + GrCombineLocal_t localc, locala; + + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: fxSetupTextureNone(...)\n"); + } + + if ((ctx->Light.ShadeModel == GL_SMOOTH) || 1 || + (ctx->Point.SmoothFlag) || + (ctx->Line.SmoothFlag) || + (ctx->Polygon.SmoothFlag)) locala = GR_COMBINE_LOCAL_ITERATED; + else + locala = GR_COMBINE_LOCAL_CONSTANT; + + if (ctx->Light.ShadeModel == GL_SMOOTH || 1) + localc = GR_COMBINE_LOCAL_ITERATED; + else + localc = GR_COMBINE_LOCAL_CONSTANT; + + FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + locala, GR_COMBINE_OTHER_NONE, FXFALSE); + + FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + localc, GR_COMBINE_OTHER_NONE, FXFALSE); +} + +/************************************************************************/ +/************************** Texture Mode SetUp **************************/ +/************************************************************************/ + +static void +fxSetupTexture_NoLock(GLcontext * ctx) +{ + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + GLuint tex2Denabled; + + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: fxSetupTexture(...)\n"); + } + + /* Disable multipass texturing. + */ + ctx->Driver.MultipassFunc = 0; + + /* Texture Combine, Color Combine and Alpha Combine. + */ + tex2Denabled = (ctx->Texture.ReallyEnabled & TEXTURE0_2D); + + if (fxMesa->emulateTwoTMUs) + tex2Denabled |= (ctx->Texture.ReallyEnabled & TEXTURE1_2D); + + switch (tex2Denabled) { + case TEXTURE0_2D: + fxSetupTextureSingleTMU_NoLock(ctx, 0); + break; + case TEXTURE1_2D: + fxSetupTextureSingleTMU_NoLock(ctx, 1); + break; + case (TEXTURE0_2D | TEXTURE1_2D): + if (fxMesa->haveTwoTMUs) + fxSetupTextureDoubleTMU_NoLock(ctx); + else { + if (MESA_VERBOSE & VERBOSE_DRIVER) + fprintf(stderr, "fxmesa: enabling fake multitexture\n"); + + fxSetupTextureSingleTMU_NoLock(ctx, 0); + ctx->Driver.MultipassFunc = fxMultipassTexture; + } + break; + default: + fxSetupTextureNone_NoLock(ctx); + break; + } +} + +static void +fxSetupTexture(GLcontext * ctx) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + BEGIN_BOARD_LOCK(fxMesa); + fxSetupTexture_NoLock(ctx); + END_BOARD_LOCK(fxMesa); +} + +/************************************************************************/ +/**************************** Blend SetUp *******************************/ +/************************************************************************/ + +void +fxDDBlendFunc(GLcontext * ctx, GLenum sfactor, GLenum dfactor) +{ + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + tfxUnitsState *us = &fxMesa->unitsState; + GrAlphaBlendFnc_t sfact, dfact, asfact, adfact; + + /* From the Glide documentation: + For alpha source and destination blend function factor + parameters, Voodoo Graphics supports only + GR_BLEND_ZERO and GR_BLEND_ONE. + */ + + switch (sfactor) { + case GL_ZERO: + asfact = sfact = GR_BLEND_ZERO; + break; + case GL_ONE: + asfact = sfact = GR_BLEND_ONE; + break; + case GL_DST_COLOR: + sfact = GR_BLEND_DST_COLOR; + asfact = GR_BLEND_ONE; + break; + case GL_ONE_MINUS_DST_COLOR: + sfact = GR_BLEND_ONE_MINUS_DST_COLOR; + asfact = GR_BLEND_ONE; + break; + case GL_SRC_ALPHA: + sfact = GR_BLEND_SRC_ALPHA; + asfact = GR_BLEND_ONE; + break; + case GL_ONE_MINUS_SRC_ALPHA: + sfact = GR_BLEND_ONE_MINUS_SRC_ALPHA; + asfact = GR_BLEND_ONE; + break; + case GL_DST_ALPHA: + sfact = GR_BLEND_DST_ALPHA; + asfact = GR_BLEND_ONE; + break; + case GL_ONE_MINUS_DST_ALPHA: + sfact = GR_BLEND_ONE_MINUS_DST_ALPHA; + asfact = GR_BLEND_ONE; + break; + case GL_SRC_ALPHA_SATURATE: + sfact = GR_BLEND_ALPHA_SATURATE; + asfact = GR_BLEND_ONE; + break; + case GL_SRC_COLOR: + case GL_ONE_MINUS_SRC_COLOR: + /* USELESS */ + asfact = sfact = GR_BLEND_ONE; + break; + default: + asfact = sfact = GR_BLEND_ONE; + break; + } + + if ((sfact != us->blendSrcFuncRGB) || (asfact != us->blendSrcFuncAlpha)) { + us->blendSrcFuncRGB = sfact; + us->blendSrcFuncAlpha = asfact; + fxMesa->new_state |= FX_NEW_BLEND; + ctx->Driver.RenderStart = fxSetupFXUnits; + } + + switch (dfactor) { + case GL_ZERO: + adfact = dfact = GR_BLEND_ZERO; + break; + case GL_ONE: + adfact = dfact = GR_BLEND_ONE; + break; + case GL_SRC_COLOR: + dfact = GR_BLEND_SRC_COLOR; + adfact = GR_BLEND_ZERO; + break; + case GL_ONE_MINUS_SRC_COLOR: + dfact = GR_BLEND_ONE_MINUS_SRC_COLOR; + adfact = GR_BLEND_ZERO; + break; + case GL_SRC_ALPHA: + dfact = GR_BLEND_SRC_ALPHA; + adfact = GR_BLEND_ZERO; + break; + case GL_ONE_MINUS_SRC_ALPHA: + dfact = GR_BLEND_ONE_MINUS_SRC_ALPHA; + adfact = GR_BLEND_ZERO; + break; + case GL_DST_ALPHA: + /* dfact=GR_BLEND_DST_ALPHA; */ + /* We can't do DST_ALPHA */ + dfact = GR_BLEND_ONE; + adfact = GR_BLEND_ZERO; + break; + case GL_ONE_MINUS_DST_ALPHA: + /* dfact=GR_BLEND_ONE_MINUS_DST_ALPHA; */ + /* We can't do DST_ALPHA */ + dfact = GR_BLEND_ZERO; + adfact = GR_BLEND_ZERO; + break; + case GL_SRC_ALPHA_SATURATE: + case GL_DST_COLOR: + case GL_ONE_MINUS_DST_COLOR: + /* USELESS */ + adfact = dfact = GR_BLEND_ZERO; + break; + default: + adfact = dfact = GR_BLEND_ZERO; + break; + } + + if ((dfact != us->blendDstFuncRGB) || (adfact != us->blendDstFuncAlpha)) { + us->blendDstFuncRGB = dfact; + us->blendDstFuncAlpha = adfact; + fxMesa->new_state |= FX_NEW_BLEND; + ctx->Driver.RenderStart = fxSetupFXUnits; + } +} + + +/* XXX not done yet, but it looks do-able in the hardware */ +void +fxDDBlendFuncSeparate(GLcontext *ctx, + GLenum sfactorRGB, GLenum sfactorA, + GLenum dfactorRGB, GLenum dfactorA) +{ +#if 000 + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + tfxUnitsState *us = &fxMesa->unitsState; + GrAlphaBlendFnc_t sfact, dfact, asfact, adfact; + + /* From the Glide documentation: + For alpha source and destination blend function factor + parameters, Voodoo Graphics supports only + GR_BLEND_ZERO and GR_BLEND_ONE. + */ + + switch (sfactor) { + case GL_ZERO: + asfact = sfact = GR_BLEND_ZERO; + break; + case GL_ONE: + asfact = sfact = GR_BLEND_ONE; + break; + case GL_DST_COLOR: + sfact = GR_BLEND_DST_COLOR; + asfact = GR_BLEND_ONE; + break; + case GL_ONE_MINUS_DST_COLOR: + sfact = GR_BLEND_ONE_MINUS_DST_COLOR; + asfact = GR_BLEND_ONE; + break; + case GL_SRC_ALPHA: + sfact = GR_BLEND_SRC_ALPHA; + asfact = GR_BLEND_ONE; + break; + case GL_ONE_MINUS_SRC_ALPHA: + sfact = GR_BLEND_ONE_MINUS_SRC_ALPHA; + asfact = GR_BLEND_ONE; + break; + case GL_DST_ALPHA: + sfact = GR_BLEND_DST_ALPHA; + asfact = GR_BLEND_ONE; + break; + case GL_ONE_MINUS_DST_ALPHA: + sfact = GR_BLEND_ONE_MINUS_DST_ALPHA; + asfact = GR_BLEND_ONE; + break; + case GL_SRC_ALPHA_SATURATE: + sfact = GR_BLEND_ALPHA_SATURATE; + asfact = GR_BLEND_ONE; + break; + case GL_SRC_COLOR: + case GL_ONE_MINUS_SRC_COLOR: + /* USELESS */ + asfact = sfact = GR_BLEND_ONE; + break; + default: + asfact = sfact = GR_BLEND_ONE; + break; + } + + if ((sfact != us->blendSrcFuncRGB) || (asfact != us->blendSrcFuncAlpha)) { + us->blendSrcFuncRGB = sfact; + us->blendSrcFuncAlpha = asfact; + fxMesa->new_state |= FX_NEW_BLEND; + ctx->Driver.RenderStart = fxSetupFXUnits; + } + + switch (dfactor) { + case GL_ZERO: + adfact = dfact = GR_BLEND_ZERO; + break; + case GL_ONE: + adfact = dfact = GR_BLEND_ONE; + break; + case GL_SRC_COLOR: + dfact = GR_BLEND_SRC_COLOR; + adfact = GR_BLEND_ZERO; + break; + case GL_ONE_MINUS_SRC_COLOR: + dfact = GR_BLEND_ONE_MINUS_SRC_COLOR; + adfact = GR_BLEND_ZERO; + break; + case GL_SRC_ALPHA: + dfact = GR_BLEND_SRC_ALPHA; + adfact = GR_BLEND_ZERO; + break; + case GL_ONE_MINUS_SRC_ALPHA: + dfact = GR_BLEND_ONE_MINUS_SRC_ALPHA; + adfact = GR_BLEND_ZERO; + break; + case GL_DST_ALPHA: + /* dfact=GR_BLEND_DST_ALPHA; */ + /* We can't do DST_ALPHA */ + dfact = GR_BLEND_ONE; + adfact = GR_BLEND_ZERO; + break; + case GL_ONE_MINUS_DST_ALPHA: + /* dfact=GR_BLEND_ONE_MINUS_DST_ALPHA; */ + /* We can't do DST_ALPHA */ + dfact = GR_BLEND_ZERO; + adfact = GR_BLEND_ZERO; + break; + case GL_SRC_ALPHA_SATURATE: + case GL_DST_COLOR: + case GL_ONE_MINUS_DST_COLOR: + /* USELESS */ + adfact = dfact = GR_BLEND_ZERO; + break; + default: + adfact = dfact = GR_BLEND_ZERO; + break; + } + + if ((dfact != us->blendDstFuncRGB) || (adfact != us->blendDstFuncAlpha)) { + us->blendDstFuncRGB = dfact; + us->blendDstFuncAlpha = adfact; + fxMesa->new_state |= FX_NEW_BLEND; + ctx->Driver.RenderStart = fxSetupFXUnits; + } +#endif +} + + +static void +fxSetupBlend(GLcontext * ctx) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + tfxUnitsState *us = &fxMesa->unitsState; + + if (us->blendEnabled) + FX_grAlphaBlendFunction(us->blendSrcFuncRGB, us->blendDstFuncRGB, + us->blendSrcFuncAlpha, us->blendDstFuncAlpha); + else + FX_grAlphaBlendFunction(GR_BLEND_ONE, GR_BLEND_ZERO, + GR_BLEND_ONE, GR_BLEND_ZERO); +} + + +/************************************************************************/ +/************************** Alpha Test SetUp ****************************/ +/************************************************************************/ + +void +fxDDAlphaFunc(GLcontext * ctx, GLenum func, GLclampf ref) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + tfxUnitsState *us = &fxMesa->unitsState; + GrCmpFnc_t newfunc; + + switch (func) { + case GL_NEVER: + newfunc = GR_CMP_NEVER; + break; + case GL_LESS: + newfunc = GR_CMP_LESS; + break; + case GL_EQUAL: + newfunc = GR_CMP_EQUAL; + break; + case GL_LEQUAL: + newfunc = GR_CMP_LEQUAL; + break; + case GL_GREATER: + newfunc = GR_CMP_GREATER; + break; + case GL_NOTEQUAL: + newfunc = GR_CMP_NOTEQUAL; + break; + case GL_GEQUAL: + newfunc = GR_CMP_GEQUAL; + break; + case GL_ALWAYS: + newfunc = GR_CMP_ALWAYS; + break; + default: + gl_problem(ctx, "fx Driver: internal error in fxDDAlphaFunc()\n"); + return; + } + + if (newfunc != us->alphaTestFunc) { + us->alphaTestFunc = newfunc; + fxMesa->new_state |= FX_NEW_ALPHA; + ctx->Driver.RenderStart = fxSetupFXUnits; + } + + if (ctx->Color.AlphaRef != us->alphaTestRefValue) { + us->alphaTestRefValue = ctx->Color.AlphaRef; + fxMesa->new_state |= FX_NEW_ALPHA; + ctx->Driver.RenderStart = fxSetupFXUnits; + } +} + +static void +fxSetupAlphaTest(GLcontext * ctx) +{ + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + tfxUnitsState *us = &fxMesa->unitsState; + + if (us->alphaTestEnabled) { + FX_grAlphaTestFunction(fxMesa, us->alphaTestFunc); + FX_grAlphaTestReferenceValue(fxMesa, us->alphaTestRefValue); + } + else + FX_grAlphaTestFunction(fxMesa, GR_CMP_ALWAYS); +} + + +/* + * Evaluate all depth-test state and make the Glide calls. + */ +static void +fxSetupDepthTest(GLcontext * ctx) +{ + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + if (ctx->Depth.Test) { + GrCmpFnc_t dfunc; + switch (ctx->Depth.Func) { + case GL_NEVER: + dfunc = GR_CMP_NEVER; + break; + case GL_LESS: + dfunc = GR_CMP_LESS; + break; + case GL_GEQUAL: + dfunc = GR_CMP_GEQUAL; + break; + case GL_LEQUAL: + dfunc = GR_CMP_LEQUAL; + break; + case GL_GREATER: + dfunc = GR_CMP_GREATER; + break; + case GL_NOTEQUAL: + dfunc = GR_CMP_NOTEQUAL; + break; + case GL_EQUAL: + dfunc = GR_CMP_EQUAL; + break; + case GL_ALWAYS: + dfunc = GR_CMP_ALWAYS; + break; + default: + gl_problem(ctx, "bad depth mode in fxSetupDepthTest"); + dfunc = GR_CMP_ALWAYS; + } + FX_grDepthBufferFunction(fxMesa, dfunc); + FX_grDepthMask(fxMesa, ctx->Depth.Mask); + } + else { + /* depth test always passes, don't update Z buffer */ + FX_grDepthBufferFunction(fxMesa, GR_CMP_ALWAYS); + FX_grDepthMask(fxMesa, FXFALSE); + } +} + + +/* + * Evaluate all stencil state and make the Glide calls. + */ +GrStencil_t +fxConvertGLStencilOp(GLenum op) +{ + switch (op) { + case GL_KEEP: + return GR_STENCILOP_KEEP; + case GL_ZERO: + return GR_STENCILOP_ZERO; + case GL_REPLACE: + return GR_STENCILOP_REPLACE; + case GL_INCR: + return GR_STENCILOP_INCR_CLAMP; + case GL_DECR: + return GR_STENCILOP_DECR_CLAMP; + case GL_INVERT: + return GR_STENCILOP_INVERT; + default: + gl_problem(NULL, "bad stencil op in fxConvertGLStencilOp"); + } + return GR_STENCILOP_KEEP; /* never get, silence compiler warning */ +} + +/* + * This function is called just before any rendering is done. + * It will validate the stencil parameters. + */ +static void +fxSetupStencilTest(GLcontext * ctx) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + if (fxMesa->haveHwStencil) { + if (ctx->Stencil.Enabled) { + GrStencil_t sfail = fxConvertGLStencilOp(ctx->Stencil.FailFunc); + GrStencil_t zfail = fxConvertGLStencilOp(ctx->Stencil.ZFailFunc); + GrStencil_t zpass = fxConvertGLStencilOp(ctx->Stencil.ZPassFunc); + FX_grStencilOp(fxMesa, sfail, zfail, zpass); + FX_grStencilFunc(fxMesa, ctx->Stencil.Function - GL_NEVER, + ctx->Stencil.Ref, ctx->Stencil.ValueMask); + FX_grStencilMask(fxMesa, ctx->Stencil.WriteMask); + FX_grEnable(fxMesa, GR_STENCIL_MODE_EXT); + } + else { + FX_grDisable(fxMesa, GR_STENCIL_MODE_EXT); + } + } +} + + +/* + * Set the state so that stencil is either enabled or disabled. + * This is called from Mesa only. Glide is invoked at + * setup time, not now. + */ +static void +fxDDEnableStencil(GLcontext * ctx, GLboolean state) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + (void) state; + fxMesa->new_state |= FX_NEW_STENCIL; + ctx->Driver.RenderStart = fxSetupFXUnits; +} + + +/************************************************************************/ +/**************************** Color Mask SetUp **************************/ +/************************************************************************/ + +GLboolean +fxDDColorMask(GLcontext *ctx, + GLboolean r, GLboolean g, GLboolean b, GLboolean a) +{ + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + fxMesa->new_state |= FX_NEW_COLOR_MASK; + ctx->Driver.RenderStart = fxSetupFXUnits; + (void) r; + (void) g; + (void) b; + (void) a; + return GL_FALSE; +} + +static void +fxSetupColorMask(GLcontext *ctx) +{ + if (ctx->Color.DrawBuffer == GL_NONE) { + FX_grColorMask(ctx, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + } + else { + fxMesaContext fxMesa = FX_CONTEXT(ctx); + /* XXX need to call grRenderBuffer to work around strange mask bug */ + FX_grRenderBuffer(fxMesa, fxMesa->currentFB); + FX_grColorMaskv(ctx, ctx->Color.ColorMask); + } +} + + +/************************************************************************/ +/**************************** Fog Mode SetUp ****************************/ +/************************************************************************/ + +/* + * This is called during state update in order to update the Glide fog state. + */ +static void +fxSetupFog(GLcontext * ctx) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + if (ctx->Fog.Enabled && ctx->FogMode == FOG_FRAGMENT) { + + /* update fog color */ + GLubyte col[4]; + col[0] = (unsigned int) (255 * ctx->Fog.Color[0]); + col[1] = (unsigned int) (255 * ctx->Fog.Color[1]); + col[2] = (unsigned int) (255 * ctx->Fog.Color[2]); + col[3] = (unsigned int) (255 * ctx->Fog.Color[3]); + FX_grFogColorValue(fxMesa, FXCOLOR4(col)); + + if (fxMesa->fogTableMode != ctx->Fog.Mode || + fxMesa->fogDensity != ctx->Fog.Density || + fxMesa->fogStart != ctx->Fog.Start || + fxMesa->fogEnd != ctx->Fog.End) { + /* reload the fog table */ + switch (ctx->Fog.Mode) { + case GL_LINEAR: + guFogGenerateLinear(fxMesa->fogTable, ctx->Fog.Start, + ctx->Fog.End); + break; + case GL_EXP: + guFogGenerateExp(fxMesa->fogTable, ctx->Fog.Density); + break; + case GL_EXP2: + guFogGenerateExp2(fxMesa->fogTable, ctx->Fog.Density); + break; + default: + ; + } + fxMesa->fogTableMode = ctx->Fog.Mode; + fxMesa->fogDensity = ctx->Fog.Density; + fxMesa->fogStart = ctx->Fog.Start; + fxMesa->fogEnd = ctx->Fog.End; + } + + FX_grFogTable(fxMesa, fxMesa->fogTable); + FX_grFogMode(fxMesa, GR_FOG_WITH_TABLE); + } + else { + FX_grFogMode(fxMesa, GR_FOG_DISABLE); + } +} + +void +fxDDFogfv(GLcontext * ctx, GLenum pname, const GLfloat * params) +{ + FX_CONTEXT(ctx)->new_state |= FX_NEW_FOG; + ctx->Driver.RenderStart = fxSetupFXUnits; /* XXX why is this here? */ +} + +/************************************************************************/ +/************************** Scissor Test SetUp **************************/ +/************************************************************************/ + +/* This routine is used in managing the lock state, and therefore can't lock */ +void +fxSetScissorValues(GLcontext * ctx) +{ + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + int xmin, xmax, ymin, ymax; + + if (ctx->Scissor.Enabled) { + xmin = ctx->Scissor.X; + xmax = ctx->Scissor.X + ctx->Scissor.Width; + ymin = ctx->Scissor.Y; + ymax = ctx->Scissor.Y + ctx->Scissor.Height; + } + else { + xmin = 0; + ymin = 0; + xmax = fxMesa->width; + ymax = fxMesa->height; + } + /* translate to screen coords */ + xmin += fxMesa->x_offset; + xmax += fxMesa->x_offset; + ymin += fxMesa->y_delta; + ymax += fxMesa->y_delta; + + /* intersect scissor region with first clip rect */ + if (xmin < fxMesa->clipMinX) + xmin = fxMesa->clipMinX; + else if (xmin > fxMesa->clipMaxX) + xmin = fxMesa->clipMaxX; + + if (xmax > fxMesa->clipMaxX) + xmax = fxMesa->clipMaxX; + + if (ymin < fxMesa->screen_height - fxMesa->clipMaxY) + ymin = fxMesa->screen_height - fxMesa->clipMaxY; + else if (ymin > fxMesa->screen_height - fxMesa->clipMinY) + ymin = fxMesa->screen_height - fxMesa->clipMinY; + + if (ymax > fxMesa->screen_height - fxMesa->clipMinY) + ymax = fxMesa->screen_height - fxMesa->clipMinY; + + /* prevent wrap-around problems */ + if (xmax < xmin) + xmax = xmin; + if (ymax < ymin) + ymax = ymin; + + FX_grClipWindow_NoLock(xmin, ymin, xmax, ymax); +} + +static void +fxSetupScissor(GLcontext * ctx) +{ + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + if (!fxMesa->needClip) { + BEGIN_BOARD_LOCK(fxMesa); + fxSetScissorValues(ctx); + END_BOARD_LOCK(fxMesa); + } +} + +void +fxDDScissor(GLcontext * ctx, GLint x, GLint y, GLsizei w, GLsizei h) +{ + FX_CONTEXT(ctx)->new_state |= FX_NEW_SCISSOR; + ctx->Driver.RenderStart = fxSetupFXUnits; +} + +/************************************************************************/ +/*************************** Cull mode setup ****************************/ +/************************************************************************/ + + +void +fxDDCullFace(GLcontext * ctx, GLenum mode) +{ + (void) mode; + FX_CONTEXT(ctx)->new_state |= FX_NEW_CULL; + ctx->Driver.RenderStart = fxSetupFXUnits; +} + +void +fxDDFrontFace(GLcontext * ctx, GLenum mode) +{ + (void) mode; + FX_CONTEXT(ctx)->new_state |= FX_NEW_CULL; + ctx->Driver.RenderStart = fxSetupFXUnits; +} + + +static void +fxSetupCull(GLcontext * ctx) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + if (ctx->Polygon.CullFlag) { + switch (ctx->Polygon.CullFaceMode) { + case GL_BACK: + if (ctx->Polygon.FrontFace == GL_CCW) + FX_CONTEXT(ctx)->cullMode = GR_CULL_NEGATIVE; + else + FX_CONTEXT(ctx)->cullMode = GR_CULL_POSITIVE; + break; + case GL_FRONT: + if (ctx->Polygon.FrontFace == GL_CCW) + FX_CONTEXT(ctx)->cullMode = GR_CULL_POSITIVE; + else + FX_CONTEXT(ctx)->cullMode = GR_CULL_NEGATIVE; + break; + case GL_FRONT_AND_BACK: + FX_CONTEXT(ctx)->cullMode = GR_CULL_DISABLE; + break; + default: + break; + } + } + else { + FX_CONTEXT(ctx)->cullMode = GR_CULL_DISABLE; + } + FX_grCullMode(fxMesa, FX_CONTEXT(ctx)->cullMode); +} + + +/************************************************************************/ +/****************************** DD Enable ******************************/ +/************************************************************************/ + +void +fxDDEnable(GLcontext * ctx, GLenum cap, GLboolean state) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + tfxUnitsState *us = &fxMesa->unitsState; + + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: fxDDEnable(...)\n"); + } + + switch (cap) { + case GL_ALPHA_TEST: + if (state != us->alphaTestEnabled) { + us->alphaTestEnabled = state; + fxMesa->new_state |= FX_NEW_ALPHA; + ctx->Driver.RenderStart = fxSetupFXUnits; + } + break; + case GL_BLEND: + if (state != us->blendEnabled) { + us->blendEnabled = state; + fxMesa->new_state |= FX_NEW_BLEND; + ctx->Driver.RenderStart = fxSetupFXUnits; + } + break; + case GL_DEPTH_TEST: + fxMesa->new_state |= FX_NEW_DEPTH; + ctx->Driver.RenderStart = fxSetupFXUnits; + break; + case GL_DITHER: + if (state) + FX_grDitherMode(fxMesa, GR_DITHER_4x4); + else + FX_grDitherMode(fxMesa, GR_DITHER_DISABLE); + break; + case GL_SCISSOR_TEST: + fxMesa->new_state |= FX_NEW_SCISSOR; + ctx->Driver.RenderStart = fxSetupFXUnits; + break; + case GL_SHARED_TEXTURE_PALETTE_EXT: + fxDDTexUseGlbPalette(ctx, state); + break; + case GL_FOG: + fxMesa->new_state |= FX_NEW_FOG; + ctx->Driver.RenderStart = fxSetupFXUnits; + break; + case GL_CULL_FACE: + fxMesa->new_state |= FX_NEW_CULL; + ctx->Driver.RenderStart = fxSetupFXUnits; + break; + case GL_LINE_SMOOTH: + case GL_LINE_STIPPLE: + case GL_POINT_SMOOTH: + case GL_POLYGON_SMOOTH: + case GL_TEXTURE_2D: + fxMesa->new_state |= FX_NEW_TEXTURING; + ctx->Driver.RenderStart = fxSetupFXUnits; + break; + case GL_STENCIL_TEST: + fxMesa->new_state |= FX_NEW_STENCIL; + ctx->Driver.RenderStart = fxSetupFXUnits; + break; + default: + ; /* no-op */ + } +} + + +#if 0 +/* + Multipass to do GL_BLEND texture functions + Cf*(1-Ct) has already been written to the buffer during the first pass + Cc*Ct gets written during the second pass (in this function) + Everything gets reset in the third call (in this function) +*/ +static GLboolean +fxMultipassBlend(struct vertex_buffer *VB, GLuint pass) +{ + GLcontext *ctx = VB->ctx; + fxMesaContext fxMesa = FX_CONTEXT(ctx); + + switch (pass) { + case 1: + /* Add Cc*Ct */ + fxMesa->restoreUnitsState = fxMesa->unitsState; + if (ctx->Depth.Mask) { + /* We don't want to check or change the depth buffers */ + switch (ctx->Depth.Func) { + case GL_NEVER: + case GL_ALWAYS: + break; + default: + fxDDDepthFunc(ctx, GL_EQUAL); + break; + } + fxDDDepthMask(ctx, FALSE); + } + /* + * Disable stencil as well. + */ + if (ctx->Stencil.Enabled) { + fxDDEnableStencil(ctx, GL_FALSE); + } + /* Enable Cc*Ct mode */ + /* XXX Set the Constant Color ? */ + fxDDEnable(ctx, GL_BLEND, GL_TRUE); + fxDDBlendFunc(ctx, XXX, XXX); + fxSetupTextureSingleTMU(ctx, XXX); + fxSetupBlend(ctx); + fxSetupDepthTest(ctx); + break; + + case 2: + /* Reset everything back to normal */ + fxMesa->unitsState = fxMesa->restoreUnitsState; + fxMesa->setupdone &= XXX; + fxSetupTextureSingleTMU(ctx, XXX); + fxSetupBlend(ctx); + fxSetupDepthTest(ctx); + fxSetupStencilText(ctx); + break; + } + + return pass == 1; +} +#endif + +/************************************************************************/ +/******************** Fake Multitexture Support *************************/ +/************************************************************************/ + +/* Its considered cheeky to try to fake ARB multitexture by doing + * multipass rendering, because it is not possible to emulate the full + * spec in this way. The fact is that the voodoo 2 supports only a + * subset of the possible multitexturing modes, and it is possible to + * support almost the same subset using multipass blending on the + * voodoo 1. In all other cases for both voodoo 1 and 2, we fall back + * to software rendering, satisfying the spec if not the user. + */ +static GLboolean +fxMultipassTexture(struct vertex_buffer *VB, GLuint pass) +{ + GLcontext *ctx = VB->ctx; + fxVertex *v = FX_DRIVER_DATA(VB)->verts; + fxVertex *last = FX_DRIVER_DATA(VB)->last_vert; + fxMesaContext fxMesa = FX_CONTEXT(ctx); + + switch (pass) { + case 1: + if (MESA_VERBOSE & + (VERBOSE_DRIVER | VERBOSE_PIPELINE | VERBOSE_TEXTURE)) + fprintf(stderr, "fxmesa: Second texture pass\n"); + + for (; v != last; v++) { + v->f[S0COORD] = v->f[S1COORD]; + v->f[T0COORD] = v->f[T1COORD]; + } + + fxMesa->restoreUnitsState = fxMesa->unitsState; + fxMesa->tmu_source[0] = 1; + + if (ctx->Depth.Mask) { + switch (ctx->Depth.Func) { + case GL_NEVER: + case GL_ALWAYS: + break; + default: + /*fxDDDepthFunc( ctx, GL_EQUAL ); */ + FX_grDepthBufferFunction(fxMesa, GR_CMP_EQUAL); + break; + } + + /*fxDDDepthMask( ctx, GL_FALSE ); */ + FX_grDepthMask(fxMesa, FXFALSE); + } + fxDDEnableStencil(ctx, GL_FALSE); + if (ctx->Texture.Unit[1].EnvMode == GL_MODULATE) { + fxDDEnable(ctx, GL_BLEND, GL_TRUE); + fxDDBlendFunc(ctx, GL_DST_COLOR, GL_ZERO); + } + + fxSetupTextureSingleTMU(ctx, 1); + fxSetupBlend(ctx); + fxSetupDepthTest(ctx); + break; + + case 2: + /* Restore original state. + */ + fxMesa->tmu_source[0] = 0; + fxMesa->unitsState = fxMesa->restoreUnitsState; + fxMesa->setupdone &= ~SETUP_TMU0; + fxSetupTextureSingleTMU(ctx, 0); + fxSetupBlend(ctx); + fxSetupDepthTest(ctx); + fxSetupStencilTest(ctx); + break; + } + + return pass == 1; +} + + +/************************************************************************/ +/************************** Changes to units state **********************/ +/************************************************************************/ + + +/* All units setup is handled under texture setup. + */ +void +fxDDShadeModel(GLcontext * ctx, GLenum mode) +{ + FX_CONTEXT(ctx)->new_state |= FX_NEW_TEXTURING; + ctx->Driver.RenderStart = fxSetupFXUnits; +} + + + +/************************************************************************/ +/****************************** Units SetUp *****************************/ +/************************************************************************/ +static void +gl_print_fx_state_flags(const char *msg, GLuint flags) +{ + fprintf(stderr, + "%s: (0x%x) %s%s%s%s%s%s%s\n", + msg, + flags, + (flags & FX_NEW_TEXTURING) ? "texture, " : "", + (flags & FX_NEW_BLEND) ? "blend, " : "", + (flags & FX_NEW_ALPHA) ? "alpha, " : "", + (flags & FX_NEW_FOG) ? "fog, " : "", + (flags & FX_NEW_SCISSOR) ? "scissor, " : "", + (flags & FX_NEW_COLOR_MASK) ? "colormask, " : "", + (flags & FX_NEW_CULL) ? "cull, " : ""); +} + +void +fxSetupFXUnits(GLcontext * ctx) +{ + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + GLuint newstate = fxMesa->new_state; + + if (MESA_VERBOSE & VERBOSE_DRIVER) + gl_print_fx_state_flags("fxmesa: fxSetupFXUnits", newstate); + + if (newstate) { + if (newstate & FX_NEW_TEXTURING) + fxSetupTexture(ctx); + + if (newstate & FX_NEW_BLEND) + fxSetupBlend(ctx); + + if (newstate & FX_NEW_ALPHA) + fxSetupAlphaTest(ctx); + + if (newstate & FX_NEW_DEPTH) + fxSetupDepthTest(ctx); + + if (newstate & FX_NEW_STENCIL) + fxSetupStencilTest(ctx); + + if (newstate & FX_NEW_FOG) + fxSetupFog(ctx); + + if (newstate & FX_NEW_SCISSOR) + fxSetupScissor(ctx); + + if (newstate & FX_NEW_COLOR_MASK) + fxSetupColorMask(ctx); + + if (newstate & FX_NEW_CULL) + fxSetupCull(ctx); + fxMesa->new_state = 0; +/* ctx->Driver.RenderStart = 0; */ + } +} diff --git a/xc/lib/GL/mesa/src/drv/tdfx/fxsetup.h b/xc/lib/GL/mesa/src/drv/tdfx/fxsetup.h new file mode 100644 index 000000000..b79d96ce9 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/tdfx/fxsetup.h @@ -0,0 +1,35 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/fxsetup.h,v 1.1 2000/09/24 13:51:19 alanh Exp $ */ +#ifndef FXSETUP_H +#define FXSETUP_H + + +extern void fxDDEnable(GLcontext *, GLenum, GLboolean); + +extern void fxDDAlphaFunc(GLcontext *, GLenum, GLclampf); + +extern void fxDDBlendFunc(GLcontext *, GLenum, GLenum); + +extern void fxDDBlendFuncSeparate(GLcontext *ctx, + GLenum sfactorRGB, GLenum sfactorA, + GLenum dfactorRGB, GLenum dfactorA); + +extern GrStencil_t fxConvertGLStencilOp(GLenum op); + +extern void fxDDScissor(GLcontext *ctx, + GLint x, GLint y, GLsizei w, GLsizei h); + +extern void fxDDFogfv(GLcontext *ctx, GLenum pname, const GLfloat * params); + +extern GLboolean fxDDColorMask(GLcontext *ctx, + GLboolean r, GLboolean g, + GLboolean b, GLboolean a); + +extern void fxDDShadeModel(GLcontext * ctx, GLenum mode); + +extern void fxDDCullFace(GLcontext * ctx, GLenum mode); + +extern void fxDDFrontFace(GLcontext * ctx, GLenum mode); + +extern void fxSetupFXUnits(GLcontext *); + +#endif diff --git a/xc/lib/GL/mesa/src/drv/tdfx/fxstripdet.c b/xc/lib/GL/mesa/src/drv/tdfx/fxstripdet.c new file mode 100644 index 000000000..98e62b1ff --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/tdfx/fxstripdet.c @@ -0,0 +1,161 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/fxstripdet.c,v 1.1 2000/09/24 13:51:19 alanh Exp $ */ +/* + * Mesa 3-D graphics library + * Version: 3.3 + * + * 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. + * + * + * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the + * terms stated above. + * + * Thank you for your contribution, David! + * + * Please make note of the above copyright/license statement. If you + * contributed code or bug fixes to this code under the previous (GNU + * Library) license and object to the new license, your code will be + * removed at your request. Please see the Mesa docs/COPYRIGHT file + * for more information. + * + * Additional Mesa/3Dfx driver developers: + * Daryll Strauss <daryll@precisioninsight.com> + * Keith Whitwell <keith@precisioninsight.com> + * + * See fxapi.h for more revision/author details. + */ + + +#include "fxdrv.h" +#include "vbcull.h" + + +#define STRIP0(u,v) ((u1 == v1) && (u2 == v0)) +#define STRIP1(u,v) ((u0 == v0) && (u2 == v1)) + +#define LOCAL_VARS fxVertex* gWin = FX_DRIVER_DATA(VB)->verts; \ + GrVertex** sb = FX_DRIVER_DATA(VB)->strips_b;\ + fxMesaContext fxMesa = FX_CONTEXT(VB->ctx); + + +#define STRIPSLOCAL_VAR int sc = 0; + +#define INIT(a) + +#define SENDTRI(u0,u1,u2) FX_grDrawTriangle(fxMesa, (GrVertex*)&(gWin[u0].f),(GrVertex*)&(gWin[u1].f),(GrVertex*)&(gWin[u2].f)) +#define FLUSHTRI() /* No-Op */ +#define STARTSTRIPS(u0,u1,u2) { sb[sc++] = (GrVertex*)&(gWin[u0].f); sb[sc++] = (GrVertex*)&(gWin[u1].f); sb[sc++] = (GrVertex*)&(gWin[u2].f); } +#define SENDSTRIPS(v2) { sb[sc++] = (GrVertex*)&(gWin[v2].f); } +#define FLUSHSTRIPS() FX_grDrawVertexArray(fxMesa, GR_TRIANGLE_STRIP,sc,sb) + +#define CLIPPED(a,b,c) 0 +#define CULLED(a,b,c) 0 +#define SENDCLIPTRI(a,b,c) /* NoOp */ + +#define TAG(x) x##_fx + +#include "fxsdettmp.h" + + +/* Clipped but no userclip */ +#define STRIP0(u,v) ((u1 == v1) && (u2 == v0)) && !clipmask[v2] +#define STRIP1(u,v) ((u0 == v0) && (u2 == v1)) && !clipmask[v2] + +#define LOCAL_VARS fxVertex* gWin = FX_DRIVER_DATA(VB)->verts; \ + GrVertex** sb = FX_DRIVER_DATA(VB)->strips_b; \ + const GLubyte *const clipmask = VB->ClipMask; \ + const fxMesaContext fxMesa=(fxMesaContext)VB->ctx->DriverCtx; \ + const tfxTriClipFunc cliptri = fxMesa->clip_tri_stride; + +#define STRIPSLOCAL_VAR int sc = 0; + +#define INIT(a) + +#define SENDTRI(u0,u1,u2) FX_grDrawTriangle(fxMesa, (GrVertex*)&(gWin[u0].f),(GrVertex*)&(gWin[u1].f),(GrVertex*)&(gWin[u2].f)) +#define FLUSHTRI() /* No-Op */ +#define STARTSTRIPS(u0,u1,u2) { sb[sc++] = (GrVertex*)&(gWin[u0].f); sb[sc++] = (GrVertex*)&(gWin[u1].f); sb[sc++] = (GrVertex*)&(gWin[u2].f); } +#define SENDSTRIPS(v2) { sb[sc++] = (GrVertex*)&(gWin[v2].f); } +#define FLUSHSTRIPS() FX_grDrawVertexArray(fxMesa, GR_TRIANGLE_STRIP,sc,sb) + +#define CLIPPED(u0,u1,u2) (clipmask[u0] | clipmask[u1] | clipmask[u2]) +#define CULLED(u0,u1,u2) (clipmask[u0] & clipmask[u1] & clipmask[u2]) +#define SENDCLIPTRI(u0,u1,u2) { \ + GLuint vl[3]; \ + ASSIGN_3V(vl, u0, u1, u2 ); \ + cliptri(VB,vl,clipmask[u0] | clipmask[u1] | clipmask[u2]); \ + } + +#define TAG(x) x##_fx_view_clipped + +#include "fxsdettmp.h" + +/* Clipped and might be userclip */ +#define STRIP0(u,v) ((u1 == v1) && (u2 == v0)) && !clipmask[v2] +#define STRIP1(u,v) ((u0 == v0) && (u2 == v1)) && !clipmask[v2] + +#define LOCAL_VARS fxVertex* gWin = FX_DRIVER_DATA(VB)->verts; \ + GrVertex** sb = FX_DRIVER_DATA(VB)->strips_b; \ + const GLubyte *const clipmask = VB->ClipMask; \ + const GLubyte *userclipmask = VB->UserClipMask; \ + const fxMesaContext fxMesa=(fxMesaContext)VB->ctx->DriverCtx; \ + const tfxTriClipFunc cliptri = fxMesa->clip_tri_stride; + +#define STRIPSLOCAL_VAR int sc = 0; + +#define INIT(a) + +#define SENDTRI(u0,u1,u2) FX_grDrawTriangle(fxMesa, (GrVertex*)&(gWin[u0].f),(GrVertex*)&(gWin[u1].f),(GrVertex*)&(gWin[u2].f)) +#define FLUSHTRI() /* No-Op */ +#define STARTSTRIPS(u0,u1,u2) { sb[sc++] = (GrVertex*)&(gWin[u0].f); sb[sc++] = (GrVertex*)&(gWin[u1].f); sb[sc++] = (GrVertex*)&(gWin[u2].f); } +#define SENDSTRIPS(v2) { sb[sc++] = (GrVertex*)&(gWin[v2].f); } +#define FLUSHSTRIPS() FX_grDrawVertexArray(fxMesa, GR_TRIANGLE_STRIP,sc,sb) + +#define CLIPPED(u0,u1,u2) (clipmask[u0] | clipmask[u1] | clipmask[u2]) +#define CULLED(u0,u1,u2) (clipmask[u0] & clipmask[u1] & clipmask[u2] & CLIP_ALL_BITS) +#define SENDCLIPTRI(u0,u1,u2) { \ + GLuint vl[3]; \ + GLuint imask = (clipmask[u0] | clipmask[u1] | clipmask[u2]); \ + \ + if (imask & CLIP_USER_BIT) { \ + if (!(userclipmask[u2] & userclipmask[u1] & userclipmask[u0])) \ + { ASSIGN_3V(vl, u2, u1, u0 ); \ + imask |= (userclipmask[u2] | userclipmask[u1] | userclipmask[u0]) << 8; \ + cliptri( VB, vl, imask );} \ + } \ + else { ASSIGN_3V(vl, u2, u1, u0 ); \ + cliptri( VB, vl, imask ); } \ + } + +#define TAG(x) x##_fx_clipped + +#include "fxsdettmp.h" + + +void +fxDDRenderInitGlide3(GLcontext * ctx) +{ +#if 0 + render_tab_fx_smooth_indirect[GL_TRIANGLES] = + render_vb_triangles_smooth_indirect_sd_fx; + render_tab_fx_smooth_indirect_view_clipped[GL_TRIANGLES] = + render_vb_triangles_smooth_indirect_sd_fx_view_clipped; + render_tab_fx_smooth_indirect_clipped[GL_TRIANGLES] = + render_vb_triangles_smooth_indirect_sd_fx_clipped; +#endif +} diff --git a/xc/lib/GL/mesa/src/drv/tdfx/fxtexman.c b/xc/lib/GL/mesa/src/drv/tdfx/fxtexman.c new file mode 100644 index 000000000..c1d01b3d7 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/tdfx/fxtexman.c @@ -0,0 +1,845 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/fxtexman.c,v 1.1 2000/09/24 13:51:20 alanh Exp $ */ +/* + * Mesa 3-D graphics library + * Version: 3.3 + * + * 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. + * + * + * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the + * terms stated above. + * + * Thank you for your contribution, David! + * + * Please make note of the above copyright/license statement. If you + * contributed code or bug fixes to this code under the previous (GNU + * Library) license and object to the new license, your code will be + * removed at your request. Please see the Mesa docs/COPYRIGHT file + * for more information. + * + * Additional Mesa/3Dfx driver developers: + * Daryll Strauss <daryll@precisioninsight.com> + * Keith Whitwell <keith@precisioninsight.com> + * + * See fxapi.h for more revision/author details. + */ + + +/* fxtexman.c - 3Dfx VooDoo texture memory functions */ + + +#include "fxdrv.h" +#include "fxtexman.h" +#include "fxddtex.h" + + +#define BAD_ADDRESS ((FxU32) -1) + +int texSwaps = 0; + + + +#ifdef TEXSANITY +static void +fubar(void) +{ +} + +/* + * Sanity Check + */ +static void +sanity(fxMesaContext fxMesa) +{ + MemRange *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; + } +} +#endif + + +/* + * Allocate and initialize a new MemRange struct. + * Try to allocate it from the pool of free MemRange nodes rather than malloc. + */ +static MemRange * +fxTMNewRangeNode(fxMesaContext fxMesa, FxU32 start, FxU32 end) +{ + MemRange *result; + + if (fxMesa->tmPool) { + result = fxMesa->tmPool; + fxMesa->tmPool = fxMesa->tmPool->next; + } + else { + result = MALLOC(sizeof(MemRange)); + if (!result) { + /*fprintf(stderr, "fxDriver: out of memory!\n");*/ + return NULL; + } + } + result->startAddr = start; + result->endAddr = end; + result->next = NULL; + return result; +} + + +/* + * Delete a MemRange struct. + * We keep a linked list of free/available MemRange structs to + * avoid extra malloc/free calls. + */ +static void +fxTMDeleteRangeNode(fxMesaContext fxMesa, MemRange *range) +{ + range->next = fxMesa->tmPool; + fxMesa->tmPool = range; +} + + +/* + * 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 * +fxTMFindOldestObject(fxMesaContext fxMesa, int tmu) +{ + 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) { + tfxTexInfo *info = fxTMGetTexInfo(obj); + + if (info && info->isInTM && + ((info->whichTMU == tmu) || (info->whichTMU == FX_TMU_BOTH) || + (info->whichTMU == FX_TMU_SPLIT))) { + GLuint age, lasttime; + + 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; + } +} + + +/* + * Find the address (offset?) at which we can store a new texture. + * <tmu> is the texture unit. + * <size> is the texture size in bytes. + */ +static FxU32 +fxTMFindStartAddr(fxMesaContext fxMesa, GLint tmu, FxU32 size) +{ + MemRange *prev, *block; + FxU32 result; + struct gl_texture_object *obj; + + while (1) { + prev = NULL; + block = fxMesa->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 { + fxMesa->tmFree[tmu] = block->next; + } + fxTMDeleteRangeNode(fxMesa, block); + } + fxMesa->freeTexMem[tmu] -= size; + return result; + } + prev = block; + block = block->next; + } + /* No free space. Discard oldest */ + obj = fxTMFindOldestObject(fxMesa, tmu); + if (!obj) { + /*gl_problem(NULL, "fx Driver: No space for texture\n");*/ + return BAD_ADDRESS; + } + fxTMMoveOutTM(fxMesa, obj); + texSwaps++; + } +} + + +/* + * Remove the given MemRange node from hardware texture memory. + */ +static void +fxTMRemoveRange(fxMesaContext fxMesa, GLint tmu, MemRange *range) +{ + MemRange *block, *prev; + + if (!range) + return; + + if (range->startAddr == range->endAddr) { + fxTMDeleteRangeNode(fxMesa, range); + return; + } + fxMesa->freeTexMem[tmu] += range->endAddr - range->startAddr; + + /* find position in linked list to insert this MemRange node */ + prev = NULL; + block = fxMesa->tmFree[tmu]; + while (block) { + 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; + fxTMDeleteRangeNode(fxMesa, range); + range = block; + } + } + if (prev) { + if (prev->endAddr == range->startAddr) { + /* Combine */ + prev->endAddr = range->endAddr; + prev->next = range->next; + fxTMDeleteRangeNode(fxMesa, range); + } + else { + prev->next = range; + } + } + else { + fxMesa->tmFree[tmu] = range; + } +} + + +/* + * Allocate space for a texture image. + * <tmu> is the texture unit + * <texmemsize> is the number of bytes to allocate + */ +static MemRange * +fxTMAllocTexMem(fxMesaContext fxMesa, GLint tmu, FxU32 texmemsize) +{ + FxU32 startAddr = fxTMFindStartAddr(fxMesa, tmu, texmemsize); + if (startAddr == BAD_ADDRESS) { + return NULL; + } + else { + MemRange *range; + range = fxTMNewRangeNode(fxMesa, startAddr, startAddr + texmemsize); + return range; + } +} + + + +/* + * Move the given texture back into hardare texture memory. + */ +void +fxTMMoveInTM_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj, + GLint where) +{ + tfxTexInfo *ti = fxTMGetTexInfo(tObj); + int i, l; + FxU32 texmemsize; + + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: fxTMMoveInTM(%d)\n", tObj->Name); + } + + fxMesa->stats.reqTexUpload++; + + if (!ti->validated) { + gl_problem(NULL, + "fx Driver: internal error in fxTMMoveInTM() -> not validated\n"); + return; /* used to abort here */ + } + + if (ti->isInTM) { + if (ti->whichTMU == where) + return; + if (where == FX_TMU_SPLIT || ti->whichTMU == FX_TMU_SPLIT) { + fxTMMoveOutTM_NoLock(fxMesa, tObj); + } + else { + if (ti->whichTMU == FX_TMU_BOTH) + return; + where = FX_TMU_BOTH; + } + } + + if (MESA_VERBOSE & (VERBOSE_DRIVER | VERBOSE_TEXTURE)) { + fprintf(stderr, + "fxmesa: downloading %x (%d) in texture memory in %d\n", + (GLuint) tObj, tObj->Name, where); + } + + ti->whichTMU = (FxU32) where; + + switch (where) { + case FX_TMU0: + case FX_TMU1: + texmemsize = FX_grTexTextureMemRequired_NoLock(GR_MIPMAPLEVELMASK_BOTH, + &(ti->info)); + ti->tm[where] = fxTMAllocTexMem(fxMesa, where, texmemsize); + if (ti->tm[where]) { + fxMesa->stats.memTexUpload += texmemsize; + + for (i = FX_largeLodValue(ti->info), l = ti->minLevel; + i <= FX_smallLodValue(ti->info); i++, l++) + FX_grTexDownloadMipMapLevel_NoLock(where, + ti->tm[where]->startAddr, + FX_valueToLod(i), + FX_largeLodLog2(ti->info), + FX_aspectRatioLog2(ti->info), + ti->info.format, + GR_MIPMAPLEVELMASK_BOTH, + ti->mipmapLevel[l].data); + } + break; + case FX_TMU_SPLIT: + texmemsize = FX_grTexTextureMemRequired_NoLock(GR_MIPMAPLEVELMASK_ODD, + &(ti->info)); + ti->tm[FX_TMU0] = fxTMAllocTexMem(fxMesa, FX_TMU0, texmemsize); + if (ti->tm[FX_TMU0]) + fxMesa->stats.memTexUpload += texmemsize; + + texmemsize = FX_grTexTextureMemRequired_NoLock(GR_MIPMAPLEVELMASK_EVEN, + &(ti->info)); + ti->tm[FX_TMU1] = fxTMAllocTexMem(fxMesa, FX_TMU1, texmemsize); + if (ti->tm[FX_TMU0] && ti->tm[FX_TMU1]) { + fxMesa->stats.memTexUpload += texmemsize; + + for (i = FX_largeLodValue(ti->info), l = ti->minLevel; + i <= FX_smallLodValue(ti->info); i++, l++) { + FX_grTexDownloadMipMapLevel_NoLock(GR_TMU0, + ti->tm[FX_TMU0]->startAddr, + FX_valueToLod(i), + FX_largeLodLog2(ti->info), + FX_aspectRatioLog2(ti->info), + ti->info.format, + GR_MIPMAPLEVELMASK_ODD, + ti->mipmapLevel[l].data); + + FX_grTexDownloadMipMapLevel_NoLock(GR_TMU1, + ti->tm[FX_TMU1]->startAddr, + FX_valueToLod(i), + FX_largeLodLog2(ti->info), + FX_aspectRatioLog2(ti->info), + ti->info.format, + GR_MIPMAPLEVELMASK_EVEN, + ti->mipmapLevel[l].data); + } + } + break; + case FX_TMU_BOTH: + texmemsize = FX_grTexTextureMemRequired_NoLock(GR_MIPMAPLEVELMASK_BOTH, + &(ti->info)); + ti->tm[FX_TMU0] = fxTMAllocTexMem(fxMesa, FX_TMU0, texmemsize); + if (ti->tm[FX_TMU0]) + fxMesa->stats.memTexUpload += texmemsize; + + texmemsize = FX_grTexTextureMemRequired_NoLock(GR_MIPMAPLEVELMASK_BOTH, + &(ti->info)); + ti->tm[FX_TMU1] = fxTMAllocTexMem(fxMesa, FX_TMU1, texmemsize); + if (ti->tm[FX_TMU0] && ti->tm[FX_TMU1]) { + fxMesa->stats.memTexUpload += texmemsize; + + for (i = FX_largeLodValue(ti->info), l = ti->minLevel; + i <= FX_smallLodValue(ti->info); i++, l++) { + FX_grTexDownloadMipMapLevel_NoLock(GR_TMU0, + ti->tm[FX_TMU0]->startAddr, + FX_valueToLod(i), + FX_largeLodLog2(ti->info), + FX_aspectRatioLog2(ti->info), + ti->info.format, + GR_MIPMAPLEVELMASK_BOTH, + ti->mipmapLevel[l].data); + + FX_grTexDownloadMipMapLevel_NoLock(GR_TMU1, + ti->tm[FX_TMU1]->startAddr, + FX_valueToLod(i), + FX_largeLodLog2(ti->info), + FX_aspectRatioLog2(ti->info), + ti->info.format, + GR_MIPMAPLEVELMASK_BOTH, + ti->mipmapLevel[l].data); + } + } + break; + default: + fprintf(stderr, + "fx Driver: internal error in fxTMMoveInTM() -> wrong tmu (%d)\n", + where); + return; /* used to abort here */ + } + + fxMesa->stats.texUpload++; + + ti->isInTM = GL_TRUE; +} + + +void +fxTMMoveInTM(fxMesaContext fxMesa, struct gl_texture_object *tObj, + GLint where) +{ + BEGIN_BOARD_LOCK(fxMesa); + fxTMMoveInTM_NoLock(fxMesa, tObj, where); + END_BOARD_LOCK(fxMesa); +} + + +void +fxTMReloadMipMapLevel(GLcontext *ctx, struct gl_texture_object *tObj, + GLint level) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + tfxTexInfo *ti = fxTMGetTexInfo(tObj); + GrLOD_t lodlevel; + GLint tmu; + + if (!ti->validated) { + gl_problem(ctx, "internal error in fxTMReloadMipMapLevel() -> not validated\n"); + return; + } + + tmu = (int) ti->whichTMU; + fxTMMoveInTM(fxMesa, tObj, tmu); + + fxTexGetInfo(ctx, ti->mipmapLevel[0].width, ti->mipmapLevel[0].height, + &lodlevel, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + +#ifdef FX_GLIDE3 + lodlevel -= level; +#else + lodlevel += level; +#endif + switch (tmu) { + case FX_TMU0: + case FX_TMU1: + FX_grTexDownloadMipMapLevel(fxMesa, tmu, + ti->tm[tmu]->startAddr, + FX_valueToLod(FX_lodToValue(lodlevel)), + FX_largeLodLog2(ti->info), + FX_aspectRatioLog2(ti->info), + ti->info.format, + GR_MIPMAPLEVELMASK_BOTH, + ti->mipmapLevel[level].data); + break; + case FX_TMU_SPLIT: + FX_grTexDownloadMipMapLevel(fxMesa, GR_TMU0, + ti->tm[GR_TMU0]->startAddr, + FX_valueToLod(FX_lodToValue(lodlevel)), + FX_largeLodLog2(ti->info), + FX_aspectRatioLog2(ti->info), + ti->info.format, + GR_MIPMAPLEVELMASK_ODD, + ti->mipmapLevel[level].data); + + FX_grTexDownloadMipMapLevel(fxMesa, GR_TMU1, + ti->tm[GR_TMU1]->startAddr, + FX_valueToLod(FX_lodToValue(lodlevel)), + FX_largeLodLog2(ti->info), + FX_aspectRatioLog2(ti->info), + ti->info.format, + GR_MIPMAPLEVELMASK_EVEN, + ti->mipmapLevel[level].data); + break; + case FX_TMU_BOTH: + FX_grTexDownloadMipMapLevel(fxMesa, GR_TMU0, + ti->tm[GR_TMU0]->startAddr, + FX_valueToLod(FX_lodToValue(lodlevel)), + FX_largeLodLog2(ti->info), + FX_aspectRatioLog2(ti->info), + ti->info.format, + GR_MIPMAPLEVELMASK_BOTH, + ti->mipmapLevel[level].data); + + FX_grTexDownloadMipMapLevel(fxMesa, GR_TMU1, + ti->tm[GR_TMU1]->startAddr, + FX_valueToLod(FX_lodToValue(lodlevel)), + FX_largeLodLog2(ti->info), + FX_aspectRatioLog2(ti->info), + ti->info.format, + GR_MIPMAPLEVELMASK_BOTH, + ti->mipmapLevel[level].data); + break; + + default: + fprintf(stderr, + "fx Driver: internal error in fxTMReloadMipMapLevel() -> wrong tmu (%d)\n", + tmu); + break; + } +} + +#if 0 +/* + * This doesn't work. It can't work for compressed textures. + */ +void +fxTMReloadSubMipMapLevel(GLcontext *ctx, + struct gl_texture_object *tObj, + GLint level, GLint yoffset, GLint height) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + tfxTexInfo *ti = fxTMGetTexInfo(tObj); + GrLOD_t lodlevel; + unsigned short *data; + GLint tmu; + + if (!ti->validated) { + gl_problem(ctx, "fx Driver: internal error in fxTMReloadSubMipMapLevel() -> not validated\n"); + return; + } + + tmu = (int) ti->whichTMU; + fxTMMoveInTM(fxMesa, tObj, tmu); + + fxTexGetInfo(ctx, ti->mipmapLevel[0].width, ti->mipmapLevel[0].height, + &lodlevel, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + + data = ti->mipmapLevel[level].data + + yoffset * ti->mipmapLevel[level].width * + ti->mipmapLevel[level].texelSize; + + switch (tmu) { + case FX_TMU0: + case FX_TMU1: + FX_grTexDownloadMipMapLevelPartial(fxMesa, tmu, + ti->tm[tmu]->startAddr, + FX_valueToLod(FX_lodToValue + (lodlevel) + level), + FX_largeLodLog2(ti->info), + FX_aspectRatioLog2(ti->info), + ti->info.format, + GR_MIPMAPLEVELMASK_BOTH, data, + yoffset, yoffset + height - 1); + break; + case FX_TMU_SPLIT: + FX_grTexDownloadMipMapLevelPartial(fxMesa, GR_TMU0, + ti->tm[FX_TMU0]->startAddr, + FX_valueToLod(FX_lodToValue + (lodlevel) + level), + FX_largeLodLog2(ti->info), + FX_aspectRatioLog2(ti->info), + ti->info.format, + GR_MIPMAPLEVELMASK_ODD, data, + yoffset, yoffset + height - 1); + + FX_grTexDownloadMipMapLevelPartial(fxMesa, GR_TMU1, + ti->tm[FX_TMU1]->startAddr, + FX_valueToLod(FX_lodToValue + (lodlevel) + level), + FX_largeLodLog2(ti->info), + FX_aspectRatioLog2(ti->info), + ti->info.format, + GR_MIPMAPLEVELMASK_EVEN, data, + yoffset, yoffset + height - 1); + break; + case FX_TMU_BOTH: + FX_grTexDownloadMipMapLevelPartial(fxMesa, GR_TMU0, + ti->tm[FX_TMU0]->startAddr, + FX_valueToLod(FX_lodToValue + (lodlevel) + level), + FX_largeLodLog2(ti->info), + FX_aspectRatioLog2(ti->info), + ti->info.format, + GR_MIPMAPLEVELMASK_BOTH, data, + yoffset, yoffset + height - 1); + + FX_grTexDownloadMipMapLevelPartial(fxMesa, GR_TMU1, + ti->tm[FX_TMU1]->startAddr, + FX_valueToLod(FX_lodToValue + (lodlevel) + level), + FX_largeLodLog2(ti->info), + FX_aspectRatioLog2(ti->info), + ti->info.format, + GR_MIPMAPLEVELMASK_BOTH, data, + yoffset, yoffset + height - 1); + break; + default: + fprintf(stderr, + "fx Driver: internal error in fxTMReloadSubMipMapLevel() -> wrong tmu (%d)\n", + tmu); + return; + } +} +#endif + +/* + * Move the given texture out of hardware texture memory. + */ +void +fxTMMoveOutTM(fxMesaContext fxMesa, struct gl_texture_object *tObj) +{ + tfxTexInfo *ti = fxTMGetTexInfo(tObj); + + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: fxTMMoveOutTM(%x (%d))\n", (GLuint) tObj, + tObj->Name); + } + + if (!ti->isInTM) + return; + + switch (ti->whichTMU) { + case FX_TMU0: + case FX_TMU1: + fxTMRemoveRange(fxMesa, (int) ti->whichTMU, ti->tm[ti->whichTMU]); + break; + case FX_TMU_SPLIT: + case FX_TMU_BOTH: + fxTMRemoveRange(fxMesa, FX_TMU0, ti->tm[FX_TMU0]); + fxTMRemoveRange(fxMesa, FX_TMU1, ti->tm[FX_TMU1]); + break; + default: + fprintf(stderr, "fx Driver: internal error in fxTMMoveOutTM()\n"); + return; + } + + ti->isInTM = GL_FALSE; + ti->whichTMU = FX_TMU_NONE; +} + + +/* + * Called via glDeleteTexture to delete a texture object. + */ +void +fxTMFreeTexture(fxMesaContext fxMesa, struct gl_texture_object *tObj) +{ + tfxTexInfo *ti = fxTMGetTexInfo(tObj); + int i; + + fxTMMoveOutTM(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; + } + } + switch (ti->whichTMU) { + case FX_TMU0: + case FX_TMU1: + fxTMDeleteRangeNode(fxMesa, ti->tm[ti->whichTMU]); + break; + case FX_TMU_SPLIT: + case FX_TMU_BOTH: + fxTMDeleteRangeNode(fxMesa, ti->tm[FX_TMU0]); + fxTMDeleteRangeNode(fxMesa, ti->tm[FX_TMU1]); + break; + } +} + + +/* + * Initialize texture memory. + * We take care of one or both TMU's here. + */ +void +fxTMInit(fxMesaContext fxMesa) +{ + const char *extensions = FX_grGetString(fxMesa, GR_EXTENSION); + + fxMesa->texBindNumber = 0; + fxMesa->tmPool = NULL; + + /* On Voodoo4 and later there's a UMA texture memory instead of + * separate TMU0 and TMU1 segments. We setup UMA mode here if + * possible. + */ + if (strstr(extensions, " TEXUMA disabled for now")) { + FxU32 start, end; + fxMesa->umaTexMemory = GL_TRUE; + FX_grEnable(fxMesa, GR_TEXTURE_UMA_EXT); + start = FX_grTexMinAddress(fxMesa, 0); + end = FX_grTexMaxAddress(fxMesa, 0); + fxMesa->freeTexMem[0] = end - start; + fxMesa->tmFree[0] = fxTMNewRangeNode(fxMesa, start, end); + } + else { + const int numTMUs = fxMesa->haveTwoTMUs ? 2 : 1; + int tmu; + fxMesa->umaTexMemory = GL_FALSE; + for (tmu = 0; tmu < numTMUs; tmu++) { + FxU32 start = FX_grTexMinAddress(fxMesa, tmu); + FxU32 end = FX_grTexMaxAddress(fxMesa, tmu); + fxMesa->freeTexMem[tmu] = end - start; + fxMesa->tmFree[tmu] = fxTMNewRangeNode(fxMesa, start, end); + } + } + +} + + +/* + * Clean-up texture memory before destroying context. + */ +void +fxTMClose(fxMesaContext fxMesa) +{ + const int numTMUs = fxMesa->haveTwoTMUs ? 2 : 1; + int tmu; + MemRange *tmp, *next; + + /* Deallocate the pool of free MemRange nodes */ + tmp = fxMesa->tmPool; + while (tmp) { + next = tmp->next; + FREE(tmp); + tmp = next; + } + + /* Delete the texture memory block MemRange nodes */ + for (tmu = 0; tmu < numTMUs; tmu++) { + tmp = fxMesa->tmFree[tmu]; + while (tmp) { + next = tmp->next; + FREE(tmp); + tmp = next; + } + } +} + + +/* + * After a context switch this function will be called to restore + * texture memory for the new context. + */ +void +fxTMRestoreTextures_NoLock(fxMesaContext ctx) +{ + tfxTexInfo *ti; + struct gl_texture_object *tObj; + int i, where; + + tObj = ctx->glCtx->Shared->TexObjectList; + while (tObj) { + ti = fxTMGetTexInfo(tObj); + if (ti && ti->isInTM) { + for (i = 0; i < MAX_TEXTURE_UNITS; i++) + if (ctx->glCtx->Texture.Unit[i].Current == tObj) { + /* Force the texture onto the board, as it could be in use */ + where = ti->whichTMU; + fxTMMoveOutTM_NoLock(ctx, tObj); + fxTMMoveInTM_NoLock(ctx, tObj, where); + break; + } + if (i == MAX_TEXTURE_UNITS) /* Mark the texture as off the board */ + fxTMMoveOutTM_NoLock(ctx, tObj); + } + tObj = tObj->Next; + } +} diff --git a/xc/lib/GL/mesa/src/drv/tdfx/fxtexman.h b/xc/lib/GL/mesa/src/drv/tdfx/fxtexman.h new file mode 100644 index 000000000..37fedcbb3 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/tdfx/fxtexman.h @@ -0,0 +1,29 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/fxtexman.h,v 1.1 2000/09/24 13:51:20 alanh Exp $ */ +#ifndef FXTEXMAN_H +#define FXTEXMAN_H + + +#define fxTMGetTexInfo(o) ((tfxTexInfo*)((o)->DriverData)) + +#define fxTMMoveOutTM_NoLock fxTMMoveOutTM + +extern void fxTMReloadMipMapLevel(GLcontext *, struct gl_texture_object *, + GLint); +extern void fxTMReloadSubMipMapLevel(GLcontext *, + struct gl_texture_object *, GLint, GLint, + GLint); + +extern void fxTMInit(fxMesaContext ctx); + +extern void fxTMClose(fxMesaContext ctx); + +extern void fxTMRestoreTextures_NoLock(fxMesaContext ctx); + +extern void fxTMMoveInTM(fxMesaContext, struct gl_texture_object *, GLint); + +extern void fxTMMoveOutTM(fxMesaContext, struct gl_texture_object *); + +extern void fxTMFreeTexture(fxMesaContext, struct gl_texture_object *); + + +#endif diff --git a/xc/lib/GL/mesa/src/drv/tdfx/fxtrifuncs.c b/xc/lib/GL/mesa/src/drv/tdfx/fxtrifuncs.c new file mode 100644 index 000000000..0980a7ad7 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/tdfx/fxtrifuncs.c @@ -0,0 +1,365 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/fxtrifuncs.c,v 1.1 2000/09/24 13:51:20 alanh Exp $ */ +/* + * Mesa 3-D graphics library + * Version: 3.3 + * + * 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. + * + * + * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the + * terms stated above. + * + * Thank you for your contribution, David! + * + * Please make note of the above copyright/license statement. If you + * contributed code or bug fixes to this code under the previous (GNU + * Library) license and object to the new license, your code will be + * removed at your request. Please see the Mesa docs/COPYRIGHT file + * for more information. + * + * Additional Mesa/3Dfx driver developers: + * Daryll Strauss <daryll@precisioninsight.com> + * Keith Whitwell <keith@precisioninsight.com> + * + * See fxapi.h for more revision/author details. + */ + + +/* fxtris.c - 3Dfx VooDoo triangle functions */ + + +#include "fxdrv.h" +#include "../mmath.h" + + + +/* Is this enough? Do we need more triangle funcs? + */ +static triangle_func tri_tab[0x40]; /* only 0x20 actually used */ +static quad_func quad_tab[0x40]; /* only 0x20 actually used */ +static line_func line_tab[0x40]; /* less than 0x20 used */ +static points_func points_tab[0x40]; /* less than 0x20 used */ + +#define IND (0) +#define TAG(x) x +#include "fxtritmp.h" + +#define IND (FX_OFFSET) +#define TAG(x) x##_offset +#include "fxtritmp.h" + +#define IND (FX_TWOSIDE) +#define TAG(x) x##_twoside +#include "fxtritmp.h" + +#define IND (FX_TWOSIDE|FX_OFFSET) +#define TAG(x) x##_twoside_offset +#include "fxtritmp.h" + +#define IND (FX_FRONT_BACK) +#define TAG(x) x##_front_back +#include "fxtritmp.h" + +#define IND (FX_FRONT_BACK|FX_OFFSET) +#define TAG(x) x##_front_back_offset +#include "fxtritmp.h" + +#define IND (FX_FRONT_BACK|FX_TWOSIDE) +#define TAG(x) x##_front_back_twoside +#include "fxtritmp.h" + +#define IND (FX_FRONT_BACK|FX_TWOSIDE|FX_OFFSET) +#define TAG(x) x##_front_back_twoside_offset +#include "fxtritmp.h" + +#define IND (FX_FLAT) +#define TAG(x) x##_flat +#include "fxtritmp.h" + +#define IND (FX_FLAT|FX_OFFSET) +#define TAG(x) x##_flat_offset +#include "fxtritmp.h" + +#define IND (FX_FLAT|FX_TWOSIDE) +#define TAG(x) x##_flat_twoside +#include "fxtritmp.h" + +#define IND (FX_FLAT|FX_TWOSIDE|FX_OFFSET) +#define TAG(x) x##_flat_twoside_offset +#include "fxtritmp.h" + +#define IND (FX_FLAT|FX_FRONT_BACK) +#define TAG(x) x##_flat_front_back +#include "fxtritmp.h" + +#define IND (FX_FLAT|FX_FRONT_BACK|FX_OFFSET) +#define TAG(x) x##_flat_front_back_offset +#include "fxtritmp.h" + +#define IND (FX_FLAT|FX_FRONT_BACK|FX_TWOSIDE) +#define TAG(x) x##_flat_front_back_twoside +#include "fxtritmp.h" + +#define IND (FX_FLAT|FX_FRONT_BACK|FX_TWOSIDE|FX_OFFSET) +#define TAG(x) x##_flat_front_back_twoside_offset +#include "fxtritmp.h" + +/* We don't actually do antialiasing correctly. Geometry has to be + sorted for glide's antialiasing to operate */ +#if 0 +#define IND (FX_ANTIALIAS) +#define TAG(x) x##_aa +#include "fxtritmp.h" + +#define IND (FX_ANTIALIAS|FX_OFFSET) +#define TAG(x) x##_aa_offset +#include "fxtritmp.h" + +#define IND (FX_ANTIALIAS|FX_TWOSIDE) +#define TAG(x) x##_aa_twoside +#include "fxtritmp.h" + +#define IND (FX_ANTIALIAS|FX_TWOSIDE|FX_OFFSET) +#define TAG(x) x##_aa_twoside_offset +#include "fxtritmp.h" + +#define IND (FX_ANTIALIAS|FX_FRONT_BACK) +#define TAG(x) x##_aa_front_back +#include "fxtritmp.h" + +#define IND (FX_ANTIALIAS|FX_FRONT_BACK|FX_OFFSET) +#define TAG(x) x##_aa_front_back_offset +#include "fxtritmp.h" + +#define IND (FX_ANTIALIAS|FX_FRONT_BACK|FX_TWOSIDE) +#define TAG(x) x##_aa_front_back_twoside +#include "fxtritmp.h" + +#define IND (FX_ANTIALIAS|FX_FRONT_BACK|FX_TWOSIDE|FX_OFFSET) +#define TAG(x) x##_aa_front_back_twoside_offset +#include "fxtritmp.h" + +#define IND (FX_ANTIALIAS|FX_FLAT) +#define TAG(x) x##_aa_flat +#include "fxtritmp.h" + +#define IND (FX_ANTIALIAS|FX_FLAT|FX_OFFSET) +#define TAG(x) x##_aa_flat_offset +#include "fxtritmp.h" + +#define IND (FX_ANTIALIAS|FX_FLAT|FX_TWOSIDE) +#define TAG(x) x##_aa_flat_twoside +#include "fxtritmp.h" + +#define IND (FX_ANTIALIAS|FX_FLAT|FX_TWOSIDE|FX_OFFSET) +#define TAG(x) x##_aa_flat_twoside_offset +#include "fxtritmp.h" + +#define IND (FX_ANTIALIAS|FX_FLAT|FX_FRONT_BACK) +#define TAG(x) x##_aa_flat_front_back +#include "fxtritmp.h" + +#define IND (FX_ANTIALIAS|FX_FLAT|FX_FRONT_BACK|FX_OFFSET) +#define TAG(x) x##_aa_flat_front_back_offset +#include "fxtritmp.h" + +#define IND (FX_ANTIALIAS|FX_FLAT|FX_FRONT_BACK|FX_TWOSIDE) +#define TAG(x) x##_aa_flat_front_back_twoside +#include "fxtritmp.h" + +#define IND (FX_ANTIALIAS|FX_FLAT|FX_FRONT_BACK|FX_TWOSIDE|FX_OFFSET) +#define TAG(x) x##_aa_flat_front_back_twoside_offset +#include "fxtritmp.h" +#endif + +void +fxDDTrifuncInit() +{ + init(); + init_offset(); + init_twoside(); + init_twoside_offset(); + init_front_back(); + init_front_back_offset(); + init_front_back_twoside(); + init_front_back_twoside_offset(); + init_flat(); + init_flat_offset(); + init_flat_twoside(); + init_flat_twoside_offset(); + init_flat_front_back(); + init_flat_front_back_offset(); + init_flat_front_back_twoside(); + init_flat_front_back_twoside_offset(); +#if 0 + init_aa(); + init_aa_offset(); + init_aa_twoside(); + init_aa_twoside_offset(); + init_aa_front_back(); + init_aa_front_back_offset(); + init_aa_front_back_twoside(); + init_aa_front_back_twoside_offset(); + init_aa_flat(); + init_aa_flat_offset(); + init_aa_flat_twoside(); + init_aa_flat_twoside_offset(); + init_aa_flat_front_back(); + init_aa_flat_front_back_offset(); + init_aa_flat_front_back_twoside(); + init_aa_flat_front_back_twoside_offset(); +#endif +} + +void +fxPrintRenderState(const char *msg, GLuint state) +{ + fprintf(stderr, "%s: (%x) %s%s%s%s%s%s\n", + msg, state, + (state & FX_ANTIALIAS) ? "antialias, " : "", + (state & FX_FLAT) ? "flat, " : "", + (state & FX_TWOSIDE) ? "twoside, " : "", + (state & FX_OFFSET) ? "offset, " : "", + (state & FX_FRONT_BACK) ? "front-back, " : "", + (state & FX_FALLBACK) ? "fallback" : ""); +} + + +void +fxPrintHintState(const char *msg, GLuint state) +{ + fprintf(stderr, "%s: (%x) %s %s%s %s%s\n", + msg, state, + (state & GR_STWHINT_W_DIFF_FBI) ? "w-fbi, " : "", + (state & GR_STWHINT_W_DIFF_TMU0) ? "w-tmu0, " : "", + (state & GR_STWHINT_ST_DIFF_TMU0) ? "st-tmu0, " : "", + (state & GR_STWHINT_W_DIFF_TMU1) ? "w-tmu1, " : "", + (state & GR_STWHINT_ST_DIFF_TMU1) ? "st-tmu1, " : ""); + +} + + +void +fxDDChooseRenderState(GLcontext * ctx) +{ + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + GLuint ind = 0; + GLuint flags = ctx->TriangleCaps; + + ctx->IndirectTriangles &= ~DD_SW_RASTERIZE; + + if (flags) { + if (fxMesa->render_index & FX_OFFSET) + FX_grDepthBiasLevel(fxMesa, 0); + + if (flags & (DD_SELECT | DD_FEEDBACK)) { + fxMesa->PointsFunc = 0; + fxMesa->LineFunc = 0; + fxMesa->TriangleFunc = 0; + fxMesa->QuadFunc = 0; + fxMesa->render_index = FX_FALLBACK; + ctx->IndirectTriangles |= DD_SW_RASTERIZE; +#if 0 + fprintf(stderr, "Fallback select|feeback\n"); +#endif + return; + } + + if (flags & DD_FLATSHADE) + ind |= FX_FLAT; + if (flags & DD_TRI_LIGHT_TWOSIDE) + ind |= FX_TWOSIDE; +#if 000 + /* XXX this is rather broken, don't use it. */ + if (flags & DD_MULTIDRAW) + ind |= FX_FRONT_BACK; +#else + if (flags & DD_MULTIDRAW) + ctx->IndirectTriangles |= DD_SW_RASTERIZE; +#endif + + if (flags & (DD_POINT_ATTEN | DD_POINT_SMOOTH)) { + ind |= FX_FALLBACK; +#if 0 + if (flags & DD_POINT_ATTEN) + fprintf(stderr, "Fallback point atten\n"); + if (flags & DD_POINT_SMOOTH) + fprintf(stderr, "Fallback point smooth\n"); +#endif + } + + fxMesa->render_index = ind; + fxMesa->PointsFunc = points_tab[ind]; + if (ind & FX_FALLBACK) + ctx->IndirectTriangles |= DD_POINT_SW_RASTERIZE; + ind &= ~(FX_ANTIALIAS | FX_FALLBACK); + + if (flags & (DD_LINE_STIPPLE | DD_LINE_SMOOTH)) { + ind |= FX_FALLBACK; +#if 0 + if (flags & DD_LINE_STIPPLE) + fprintf(stderr, "Fallback line stipple\n"); + if (flags & DD_LINE_SMOOTH) + fprintf(stderr, "Fallback line smooth\n"); +#endif + } + + fxMesa->render_index |= ind; + fxMesa->LineFunc = line_tab[ind]; + if (ind & FX_FALLBACK) + ctx->IndirectTriangles |= DD_LINE_SW_RASTERIZE; + ind &= ~(FX_ANTIALIAS | FX_FALLBACK); + + if (flags & DD_TRI_OFFSET) + ind |= FX_OFFSET; + if (flags & (DD_TRI_UNFILLED | DD_TRI_STIPPLE | DD_TRI_SMOOTH)) { + ind |= FX_FALLBACK; +#if 0 + if (flags & DD_TRI_UNFILLED) + fprintf(stderr, "Fallback tri unfilled\n"); + if (flags & DD_TRI_STIPPLE) + fprintf(stderr, "Fallback tri stippled\n"); + if (flags & DD_TRI_SMOOTH) + fprintf(stderr, "Fallback tri smooth\n"); +#endif + } + + fxMesa->render_index |= ind; + fxMesa->TriangleFunc = tri_tab[ind]; + fxMesa->QuadFunc = quad_tab[ind]; + + if (ind & FX_FALLBACK) + ctx->IndirectTriangles |= + DD_TRI_SW_RASTERIZE | DD_QUAD_SW_RASTERIZE; + } + else if (fxMesa->render_index) { + if (fxMesa->render_index & FX_OFFSET) + FX_grDepthBiasLevel(fxMesa, 0); + + fxMesa->render_index = 0; + fxMesa->PointsFunc = points_tab[0]; + fxMesa->LineFunc = line_tab[0]; + fxMesa->TriangleFunc = tri_tab[0]; + fxMesa->QuadFunc = quad_tab[0]; + } + + if (MESA_VERBOSE & (VERBOSE_STATE | VERBOSE_DRIVER)) + fxPrintRenderState("fxmesa: Render state", fxMesa->render_index); +} diff --git a/xc/lib/GL/mesa/src/drv/tdfx/fxtritmp.h b/xc/lib/GL/mesa/src/drv/tdfx/fxtritmp.h new file mode 100644 index 000000000..8e068bd9b --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/tdfx/fxtritmp.h @@ -0,0 +1,446 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/fxtritmp.h,v 1.1 2000/09/24 13:51:20 alanh Exp $ */ +/* + * Mesa 3-D graphics library + * Version: 3.3 + * + * 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. + * + * + * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the + * terms stated above. + * + * Thank you for your contribution, David! + * + * Please make note of the above copyright/license statement. If you + * contributed code or bug fixes to this code under the previous (GNU + * Library) license and object to the new license, your code will be + * removed at your request. Please see the Mesa docs/COPYRIGHT file + * for more information. + * + * Additional Mesa/3Dfx driver developers: + * Daryll Strauss <daryll@precisioninsight.com> + * Keith Whitwell <keith@precisioninsight.com> + * + * See fxapi.h for more revision/author details. + */ + + +static void TAG(fx_tri) (GLcontext * ctx, GLuint e1, GLuint e2, GLuint e3, + GLuint pv) +{ + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + struct vertex_buffer *VB = ctx->VB; + fxVertex *gWin = FX_DRIVER_DATA(VB)->verts; + GrVertex *v1 = (GrVertex *) gWin[e1].f; + GrVertex *v2 = (GrVertex *) gWin[e2].f; + GrVertex *v3 = (GrVertex *) gWin[e3].f; + + (void) fxMesa; + + if (IND & (FX_TWOSIDE | FX_OFFSET)) { + GLfloat ex = v1->x - v3->x; + GLfloat ey = v1->y - v3->y; + GLfloat fx = v2->x - v3->x; + GLfloat fy = v2->y - v3->y; + GLfloat c = ex * fy - ey * fx; + + if (IND & FX_TWOSIDE) { + GLuint facing = (c < 0.0) ^ ctx->Polygon.FrontBit; + GLubyte(*color)[4] = VB->Color[facing]->data; + if (IND & FX_FLAT) { + GOURAUD2(v1, color[pv]); + GOURAUD2(v2, color[pv]); + GOURAUD2(v3, color[pv]); + } + else { + GOURAUD2(v1, color[e1]); + GOURAUD2(v2, color[e2]); + GOURAUD2(v3, color[e3]); + } + } + + /* Should apply a factor to ac to compensate for different x/y + * scaling introduced in the Viewport matrix. + * + * The driver should supply scaling factors for 'factor' and 'units'. + */ + if (IND & FX_OFFSET) { + GLfloat offset = ctx->Polygon.OffsetUnits; + + if (c * c > 1e-16) { + GLfloat factor = ctx->Polygon.OffsetFactor; + GLfloat ez = v1->ooz - v3->ooz; + GLfloat fz = v2->ooz - v3->ooz; + GLfloat a = ey * fz - ez * fy; + GLfloat b = ez * fx - ex * fz; + GLfloat ic = 1.0 / c; + GLfloat ac = a * ic; + GLfloat bc = b * ic; + if (ac < 0.0F) + ac = -ac; + if (bc < 0.0F) + bc = -bc; + offset += MAX2(ac, bc) * factor; + } + /* Probably a lot quicker just to nudge the z values and put + * them back afterwards. + */ + FX_grDepthBiasLevel(fxMesa, (int) offset); + } + } + else if (IND & FX_FLAT) { + GLubyte(*color)[4] = VB->Color[0]->data; + GOURAUD2(v1, color[pv]); + GOURAUD2(v2, color[pv]); + GOURAUD2(v3, color[pv]); + } + + if (IND & FX_FRONT_BACK) { + FX_grColorMaskv(ctx, ctx->Color.ColorMask); + FX_grDepthMask(fxMesa, FXFALSE); + FX_grRenderBuffer(fxMesa, GR_BUFFER_BACKBUFFER); + } + + if (IND & FX_ANTIALIAS) + FX_grAADrawTriangle(fxMesa, v1, v2, v3, FXTRUE, FXTRUE, FXTRUE); + else + FX_grDrawTriangle(fxMesa, v1, v2, v3); + + /* Might be quicker to do two passes, one for each buffer? + */ + if (IND & FX_FRONT_BACK) { + FX_grColorMaskv(ctx, ctx->Color.ColorMask); + + if (ctx->Depth.Mask) + FX_grDepthMask(fxMesa, FXTRUE); + + FX_grRenderBuffer(fxMesa, GR_BUFFER_FRONTBUFFER); + + if (IND & FX_ANTIALIAS) + FX_grAADrawTriangle(fxMesa, v1, v2, v3, FXTRUE, FXTRUE, FXTRUE); + else + FX_grDrawTriangle(fxMesa, v1, v2, v3); + } +} + + +/* Not worth the space? + */ +static void TAG(fx_quad) (GLcontext * ctx, GLuint e1, GLuint e2, GLuint e3, + GLuint e4, GLuint pv) +{ + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + struct vertex_buffer *VB = ctx->VB; + fxVertex *gWin = FX_DRIVER_DATA(VB)->verts; + GrVertex *v1 = (GrVertex *) gWin[e1].f; + GrVertex *v2 = (GrVertex *) gWin[e2].f; + GrVertex *v3 = (GrVertex *) gWin[e3].f; + GrVertex *v4 = (GrVertex *) gWin[e4].f; + + (void) fxMesa; + + if (IND & (FX_TWOSIDE | FX_OFFSET)) { + GLfloat ex = v3->x - v1->x; + GLfloat ey = v3->y - v1->y; + GLfloat fx = v4->x - v2->x; + GLfloat fy = v4->y - v2->y; + GLfloat c = ex * fy - ey * fx; + + if (IND & FX_TWOSIDE) { + GLuint facing = (c < 0.0) ^ ctx->Polygon.FrontBit; + GLubyte(*color)[4] = VB->Color[facing]->data; + if (IND & FX_FLAT) { + GOURAUD2(v1, color[pv]); + GOURAUD2(v2, color[pv]); + GOURAUD2(v3, color[pv]); + GOURAUD2(v4, color[pv]); + } + else { + GOURAUD2(v1, color[e1]); + GOURAUD2(v2, color[e2]); + GOURAUD2(v3, color[e3]); + GOURAUD2(v4, color[e4]); + } + } + + /* Should apply a factor to ac to compensate for different x/y + * scaling introduced in the Viewport matrix. + * + * The driver should supply scaling factors for 'factor' and 'units'. + */ + if (IND & FX_OFFSET) { + GLfloat offset = ctx->Polygon.OffsetUnits; + + if (c * c > 1e-16) { + GLfloat factor = ctx->Polygon.OffsetFactor; + GLfloat ez = v3->ooz - v1->ooz; + GLfloat fz = v4->ooz - v2->ooz; + GLfloat a = ey * fz - ez * fy; + GLfloat b = ez * fx - ex * fz; + GLfloat ic = 1.0 / c; + GLfloat ac = a * ic; + GLfloat bc = b * ic; + if (ac < 0.0F) + ac = -ac; + if (bc < 0.0F) + bc = -bc; + offset += MAX2(ac, bc) * factor; + } + /* Probably a lot quicker just to nudge the z values and put + * them back afterwards. + */ + FX_grDepthBiasLevel(fxMesa, (int) offset); + } + } + else if (IND & FX_FLAT) { + GLubyte(*color)[4] = VB->Color[0]->data; + GOURAUD2(v1, color[pv]); + GOURAUD2(v2, color[pv]); + GOURAUD2(v3, color[pv]); + GOURAUD2(v4, color[pv]); + } + + if (IND & FX_FRONT_BACK) { + FX_grColorMaskv(ctx, ctx->Color.ColorMask); + FX_grDepthMask(fxMesa, FXFALSE); + FX_grRenderBuffer(fxMesa, GR_BUFFER_BACKBUFFER); + } + + if (IND & FX_ANTIALIAS) { + FX_grAADrawTriangle(fxMesa, v1, v2, v4, FXTRUE, FXTRUE, FXTRUE); + FX_grAADrawTriangle(fxMesa, v2, v3, v4, FXTRUE, FXTRUE, FXTRUE); + } + else { + FX_grDrawTriangle(fxMesa, v1, v2, v4); + FX_grDrawTriangle(fxMesa, v2, v3, v4); + } + + /* Might be quicker to do two passes, one for each buffer? + */ + if (IND & FX_FRONT_BACK) { + FX_grColorMaskv(ctx, ctx->Color.ColorMask); + + if (ctx->Depth.Mask) + FX_grDepthMask(fxMesa, FXTRUE); + + FX_grRenderBuffer(fxMesa, GR_BUFFER_FRONTBUFFER); + + if (IND & FX_ANTIALIAS) { + FX_grAADrawTriangle(fxMesa, v1, v2, v4, FXTRUE, FXTRUE, FXTRUE); + FX_grAADrawTriangle(fxMesa, v2, v3, v4, FXTRUE, FXTRUE, FXTRUE); + } + else { + FX_grDrawTriangle(fxMesa, v1, v2, v4); + FX_grDrawTriangle(fxMesa, v2, v3, v4); + } + } +} + +#define DRAW_LINE(fxMesa, tmp0, tmp1, width) \ + if (width <= 1.0) { \ + FX_grDrawLine(fxMesa, tmp0, tmp1); \ + } \ + else { \ + GrVertex verts[4]; \ + float dx, dy, ix, iy; \ + \ + dx = tmp0->x - tmp1->x; \ + dy = tmp0->y - tmp1->y; \ + \ + if (dx * dx > dy * dy) { \ + iy = width * .5; \ + ix = 0; \ + } \ + else { \ + iy = 0; \ + ix = width * .5; \ + } \ + \ + verts[0] = *tmp0; \ + verts[1] = *tmp0; \ + verts[2] = *tmp1; \ + verts[3] = *tmp1; \ + \ + verts[0].x = tmp0->x - ix; \ + verts[0].y = tmp0->y - iy; \ + \ + verts[1].x = tmp0->x + ix; \ + verts[1].y = tmp0->y + iy; \ + \ + verts[2].x = tmp1->x + ix; \ + verts[2].y = tmp1->y + iy; \ + \ + verts[3].x = tmp1->x - ix; \ + verts[3].y = tmp1->y - iy; \ + \ + FX_grDrawPolygonVertexList(fxMesa, 4, verts); \ + } + + +#if (IND & FX_OFFSET) == 0 +static void TAG(fx_line) (GLcontext * ctx, GLuint e1, GLuint e2, GLuint pv) +{ + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + struct vertex_buffer *VB = ctx->VB; + fxVertex *gWin = FX_DRIVER_DATA(VB)->verts; + GLubyte(*const color)[4] = VB->ColorPtr->data; + GrVertex *v1 = (GrVertex *) gWin[e1].f; + GrVertex *v2 = (GrVertex *) gWin[e2].f; + GLfloat w = ctx->Line.Width * .5; + + if (IND & FX_FLAT) { + v1->r = v2->r = UBYTE_COLOR_TO_FLOAT_255_COLOR(color[pv][0]); + v1->g = v2->g = UBYTE_COLOR_TO_FLOAT_255_COLOR(color[pv][1]); + v1->b = v2->b = UBYTE_COLOR_TO_FLOAT_255_COLOR(color[pv][2]); + v1->a = v2->a = UBYTE_COLOR_TO_FLOAT_255_COLOR(color[pv][3]); + } + else if (IND & FX_TWOSIDE) { + /* XXX use signed area of the polygon to determine front/back color choice */ + GOURAUD2(v1, color[e1]); + GOURAUD2(v2, color[e2]); + } + + if (IND & FX_FRONT_BACK) { + FX_grColorMaskv(ctx, ctx->Color.ColorMask); + FX_grDepthMask(fxMesa, FXFALSE); + FX_grRenderBuffer(fxMesa, GR_BUFFER_BACKBUFFER); + } + + if (IND & FX_ANTIALIAS) + FX_grAADrawLine(fxMesa, v1, v2); + else + DRAW_LINE(fxMesa, v1, v2, w); + + if (IND & FX_FRONT_BACK) { + FX_grColorMaskv(ctx, ctx->Color.ColorMask); + + if (ctx->Depth.Mask) + FX_grDepthMask(fxMesa, FXTRUE); + + FX_grRenderBuffer(fxMesa, GR_BUFFER_FRONTBUFFER); + + if (IND & FX_ANTIALIAS) + FX_grAADrawLine(fxMesa, v1, v2); + else + DRAW_LINE(fxMesa, v1, v2, w); + } +} +#endif + + +#if (IND & FX_OFFSET) == 0 + +/* + * Draw large points (size > 1) with a polygon. + */ +#define DRAW_POINT(i, radius, color) \ + do { \ + GrVertex verts[4], *tmp; \ + tmp = (GrVertex *) gWin[i].f; \ + tmp->r = UBYTE_COLOR_TO_FLOAT_255_COLOR(color[0]); \ + tmp->g = UBYTE_COLOR_TO_FLOAT_255_COLOR(color[1]); \ + tmp->b = UBYTE_COLOR_TO_FLOAT_255_COLOR(color[2]); \ + tmp->a = UBYTE_COLOR_TO_FLOAT_255_COLOR(color[3]); \ + verts[0] = *tmp; \ + verts[1] = *tmp; \ + verts[2] = *tmp; \ + verts[3] = *tmp; \ + verts[0].x = verts[3].x = tmp->x + radius; \ + verts[0].y = verts[1].y = tmp->y + radius; \ + verts[2].x = verts[1].x = tmp->x - radius; \ + verts[2].y = verts[3].y = tmp->y - radius; \ + FX_grDrawPolygonVertexList(fxMesa, 4, verts); \ + } while (0) + + +static void TAG(fx_points) (GLcontext * ctx, GLuint first, GLuint last) +{ + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + const struct vertex_buffer *VB = ctx->VB; + const fxVertex *gWin = FX_DRIVER_DATA(VB)->verts; + GLubyte (*color)[4] = VB->ColorPtr->data; + GLuint i; + const GLfloat radius = ctx->Point.Size * .5; + + (void) color; + (void) fxMesa; + + if (IND & FX_FRONT_BACK) { + FX_grColorMaskv(ctx, ctx->Color.ColorMask); + FX_grDepthMask(fxMesa, FXFALSE); + FX_grRenderBuffer(fxMesa, GR_BUFFER_BACKBUFFER); + } + + if (!VB->ClipOrMask) { + for (i = first; i <= last; i++) { + DRAW_POINT(i, radius, color[i]); + } + } + else { + for (i = first; i <= last; i++) { + if (VB->ClipMask[i] == 0) { + DRAW_POINT(i, radius, color[i]); + } + } + } + + if (IND & FX_FRONT_BACK) { + FX_grColorMaskv(ctx, ctx->Color.ColorMask); + if (ctx->Depth.Mask) + FX_grDepthMask(fxMesa, FXTRUE); + FX_grRenderBuffer(fxMesa, GR_BUFFER_FRONTBUFFER); + + if (!VB->ClipOrMask) { + for (i = first; i <= last; i++) { + DRAW_POINT(i, radius, color[i]); + } + } + else { + for (i = first; i <= last; i++) { + if (VB->ClipMask[i] == 0) { + DRAW_POINT(i, radius, color[i]); + } + } + } + } +} + +#endif + + + +static void TAG(init) (void) +{ + tri_tab[IND] = TAG(fx_tri); + quad_tab[IND] = TAG(fx_quad); + +#if ((IND & FX_OFFSET) == 0) + line_tab[IND] = TAG(fx_line); + points_tab[IND] = TAG(fx_points); +#else + line_tab[IND] = line_tab[IND & ~FX_OFFSET]; + points_tab[IND] = points_tab[IND & ~FX_OFFSET]; +#endif +} + +#undef IND +#undef TAG +#undef FLAT_COLOR +#undef DRAW_POINT diff --git a/xc/lib/GL/mesa/src/drv/tdfx/fxvs_tmp.h b/xc/lib/GL/mesa/src/drv/tdfx/fxvs_tmp.h new file mode 100644 index 000000000..bc7621aa1 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/tdfx/fxvs_tmp.h @@ -0,0 +1,215 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/fxvs_tmp.h,v 1.1 2000/09/24 13:51:20 alanh Exp $ */ +/* + * Mesa 3-D graphics library + * Version: 3.3 + * + * 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. + * + * + * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the + * terms stated above. + * + * Thank you for your contribution, David! + * + * Please make note of the above copyright/license statement. If you + * contributed code or bug fixes to this code under the previous (GNU + * Library) license and object to the new license, your code will be + * removed at your request. Please see the Mesa docs/COPYRIGHT file + * for more information. + * + * Additional Mesa/3Dfx driver developers: + * Daryll Strauss <daryll@precisioninsight.com> + * Keith Whitwell <keith@precisioninsight.com> + * + * See fxapi.h for more revision/author details. + */ + + +#if (IND & (SETUP_XY|SETUP_W|SETUP_Z)) +#define V1 VARS_XY +#define I1 , INCR_XY +#else +#define V1 +#define I1 +#endif + +#if (IND & SETUP_XY) +#define S1 DO_SETUP_XY +#else +#define S1 +#endif + +#if (IND & SETUP_W) +#define S2 S1 DO_SETUP_W +#define V2 V1 VARS_W +#else +#define S2 S1 +#define V2 V1 +#endif + +#if (IND & SETUP_Z) +#define S3 S2 DO_SETUP_Z +#else +#define S3 S2 +#endif + +#if (IND & SETUP_RGBA) +#define V4 V2 VARS_RGBA +#define S4 S3 DO_SETUP_RGBA +#define I4 I1 , INCR_RGBA +#else +#define V4 V2 +#define S4 S3 +#define I4 I1 +#endif + +#if (IND & SETUP_TMU0) +#define V5 V4 VARS_TMU0 +#define S5 S4 DO_SETUP_TMU0 +#define I5 I4 , INCR_TMU0 +#define F5 FIXUP_TMU0 +#else +#define V5 V4 +#define S5 S4 +#define I5 I4 +#define F5 +#endif + +#if (IND & SETUP_TMU1) +#define V6 V5 VARS_TMU1 +#define S6 S5 DO_SETUP_TMU1 +#define I6 I5 , INCR_TMU1 +#define F6 F5 FIXUP_TMU1 +#else +#define V6 V5 +#define S6 S5 +#define I6 I5 +#define F6 F5 +#endif + +#if (IND & SETUP_TMU0) && (IND & SETUP_TMU1) +#define F7 FIXUP_TMU01 +#else +#define F7 F6 +#endif + +#define VARS V6 +#define DO_SETUP S6 +#define INCR I6 +#define FIXUP F7 + +static void +NAME(struct vertex_buffer *VB, GLuint start, GLuint end) +{ + GLcontext *ctx = VB->ctx; + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + + if (fxMesa->new_state) + fxSetupFXUnits(ctx); + + { + const float snapper = (3L << 18); + fxVertex *gWin = FX_DRIVER_DATA(VB)->verts; + GLfloat *v = gWin[start].f; + GLfloat *vend = gWin[end].f; + VARS; + + (void) gWin; + (void) fxMesa; + (void) snapper; + + if (VB->ClipOrMask) { + GLubyte *clipmask = &VB->ClipMask[start]; + for (; v != vend; v += 16, clipmask++ INCR) { + if (*clipmask == 0) { + DO_SETUP; + } + } + } + else { + for (; v != vend; v += 16 INCR) { + DO_SETUP; + } + } + + if (ctx->FogMode == FOG_FRAGMENT + && ctx->ProjectionMatrix.m[15] != 0.0F) { + /* need to compute W values for fogging purposes */ + const GLfloat m10 = ctx->ProjectionMatrix.m[10]; + const GLfloat m14 = ctx->ProjectionMatrix.m[14]; + const GLfloat v10 = ctx->Viewport.WindowMap.m[10]; + const GLfloat v14 = ctx->Viewport.WindowMap.m[14]; + GLfloat *v = gWin[start].f; + GLfloat *win = VB->Win.data[start]; + if (VB->ClipOrMask) { + GLubyte *clipmask = &VB->ClipMask[start]; + for (; v != vend; v += 16, clipmask++, win += 4) { + if (*clipmask == 0) { + GLfloat zNDC = (win[2] - v14) / v10; + GLfloat zEye = (zNDC - m14) / m10; + v[OOWCOORD] = -1.0F / zEye; + } + } + } + else { + for (; v != vend; v += 16, win += 4) { + GLfloat zNDC = (win[2] - v14) / v10; + GLfloat zEye = (zNDC - m14) / m10; + v[OOWCOORD] = -1.0F / zEye; + } + } + } + + /* rare - I hope */ + FIXUP; + } +} + + +#undef V1 +#undef V2 +#undef V3 +#undef V4 +#undef V5 +#undef V6 +#undef VARS + +#undef S1 +#undef S2 +#undef S3 +#undef S4 +#undef S5 +#undef S6 +#undef DO_SETUP + +#undef I1 +#undef I4 +#undef I5 +#undef I6 +#undef INCR + +#undef F5 +#undef F6 +#undef F7 +#undef FIXUP + + +#undef IND +#undef NAME diff --git a/xc/lib/GL/mesa/src/drv/tdfx/fxvsetup.c b/xc/lib/GL/mesa/src/drv/tdfx/fxvsetup.c new file mode 100644 index 000000000..8102ea09c --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/tdfx/fxvsetup.c @@ -0,0 +1,578 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/fxvsetup.c,v 1.1 2000/09/24 13:51:20 alanh Exp $ */ +/* + * Mesa 3-D graphics library + * Version: 3.3 + * + * 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. + * + * + * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the + * terms stated above. + * + * Thank you for your contribution, David! + * + * Please make note of the above copyright/license statement. If you + * contributed code or bug fixes to this code under the previous (GNU + * Library) license and object to the new license, your code will be + * removed at your request. Please see the Mesa docs/COPYRIGHT file + * for more information. + * + * Additional Mesa/3Dfx driver developers: + * Daryll Strauss <daryll@precisioninsight.com> + * Keith Whitwell <keith@precisioninsight.com> + * + * See fxapi.h for more revision/author details. + */ + + +/* fxvsetup.c - 3Dfx VooDoo vertices setup functions */ + + +#include "fxdrv.h" +#include "fxtexman.h" +#include "fxsetup.h" +#include "mmath.h" +#include "pipeline.h" +#include "fxvsetup.h" + + +void +fxPrintSetupFlags(const char *msg, GLuint flags) +{ + fprintf(stderr, "%s: %d %s%s%s%s%s%s\n", + msg, + flags, + (flags & SETUP_XY) ? " xy," : "", + (flags & SETUP_Z) ? " z," : "", + (flags & SETUP_W) ? " w," : "", + (flags & SETUP_RGBA) ? " rgba," : "", + (flags & SETUP_TMU0) ? " tmu0," : "", + (flags & SETUP_TMU1) ? " tmu1," : ""); +} + +static void +project_texcoords(struct vertex_buffer *VB, + GLuint tmu_nr, GLuint tc_nr, GLuint start, GLuint count) +{ + fxVertex *v = FX_DRIVER_DATA(VB)->verts + start; + GrTmuVertex *tmu = &(((GrVertex *) v->f)->tmuvtx[tmu_nr]); + GLvector4f *vec = VB->TexCoordPtr[tc_nr]; + + GLuint i; + GLuint stride = vec->stride; + GLfloat *data = VEC_ELT(vec, GLfloat, start); + + for (i = start; i < count; i++, STRIDE_F(data, stride), v++) { + tmu->oow = v->f[OOWCOORD] * data[3]; + tmu = (GrTmuVertex *) ((char *) tmu + sizeof(fxVertex)); + } +} + + +static void +copy_w(struct vertex_buffer *VB, GLuint tmu_nr, GLuint start, GLuint count) +{ + fxVertex *v = FX_DRIVER_DATA(VB)->verts + start; + GrTmuVertex *tmu = &(((GrVertex *) v->f)->tmuvtx[tmu_nr]); + GLuint i; + + for (i = start; i < count; i++, v++) { + tmu->oow = v->f[OOWCOORD]; + tmu = (GrTmuVertex *) ((char *) tmu + sizeof(fxVertex)); + } +} + + +static tfxSetupFunc setupfuncs[0x40]; + + + + +#define IND SETUP_XY +#define NAME fxsetupXY +#include "fxvs_tmp.h" + +#define IND (SETUP_XY|SETUP_Z) +#define NAME fxsetupXYZ +#include "fxvs_tmp.h" + +#define IND (SETUP_XY|SETUP_W) +#define NAME fxsetupXYW +#include "fxvs_tmp.h" + +#define IND (SETUP_XY|SETUP_Z|SETUP_W) +#define NAME fxsetupXYZW +#include "fxvs_tmp.h" + +#define IND (SETUP_RGBA|SETUP_XY) +#define NAME fxsetupXYRGBA +#include "fxvs_tmp.h" + +#define IND (SETUP_RGBA|SETUP_XY|SETUP_Z) +#define NAME fxsetupXYZRGBA +#include "fxvs_tmp.h" + +#define IND (SETUP_RGBA|SETUP_XY|SETUP_W) +#define NAME fxsetupXYWRGBA +#include "fxvs_tmp.h" + +#define IND (SETUP_RGBA|SETUP_XY|SETUP_Z|SETUP_W) +#define NAME fxsetupXYZWRGBA +#include "fxvs_tmp.h" + +#define IND (SETUP_TMU0|SETUP_XY|SETUP_W) +#define NAME fxsetupXYWT0 +#include "fxvs_tmp.h" + +#define IND (SETUP_TMU0|SETUP_XY|SETUP_Z|SETUP_W) +#define NAME fxsetupXYZWT0 +#include "fxvs_tmp.h" + +#define IND (SETUP_TMU1|SETUP_TMU0|SETUP_XY|SETUP_W) +#define NAME fxsetupXYWT0T1 +#include "fxvs_tmp.h" + +#define IND (SETUP_TMU1|SETUP_TMU0|SETUP_XY|SETUP_Z|SETUP_W) +#define NAME fxsetupXYZWT0T1 +#include "fxvs_tmp.h" + +#define IND (SETUP_TMU0|SETUP_RGBA|SETUP_XY|SETUP_W) +#define NAME fxsetupXYWRGBAT0 +#include "fxvs_tmp.h" + +#define IND (SETUP_TMU0|SETUP_RGBA|SETUP_XY|SETUP_Z|SETUP_W) +#define NAME fxsetupXYZWRGBAT0 +#include "fxvs_tmp.h" + +#define IND (SETUP_TMU1|SETUP_TMU0|SETUP_RGBA|SETUP_XY|SETUP_W) +#define NAME fxsetupXYWRGBAT0T1 +#include "fxvs_tmp.h" + +#define IND (SETUP_TMU1|SETUP_TMU0|SETUP_RGBA|SETUP_XY|SETUP_Z|SETUP_W) +#define NAME fxsetupXYZWRGBAT0T1 +#include "fxvs_tmp.h" + +#define IND (SETUP_RGBA) +#define NAME fxsetupRGBA +#include "fxvs_tmp.h" + +#define IND (SETUP_TMU0) +#define NAME fxsetupT0 +#include "fxvs_tmp.h" + +#define IND (SETUP_TMU1) +#define NAME fxsetupT1 +#include "fxvs_tmp.h" + +#define IND (SETUP_TMU1|SETUP_TMU0) +#define NAME fxsetupT0T1 +#include "fxvs_tmp.h" + +#define IND (SETUP_TMU0|SETUP_RGBA) +#define NAME fxsetupRGBAT0 +#include "fxvs_tmp.h" + +#define IND (SETUP_TMU1|SETUP_RGBA) +#define NAME fxsetupRGBAT1 +#include "fxvs_tmp.h" + +#define IND (SETUP_TMU1|SETUP_TMU0|SETUP_RGBA) +#define NAME fxsetupRGBAT0T1 +#include "fxvs_tmp.h" + +#define IND (SETUP_W|SETUP_RGBA) +#define NAME fxsetupWRGBA +#include "fxvs_tmp.h" + +#define IND (SETUP_W|SETUP_TMU0) +#define NAME fxsetupWT0 +#include "fxvs_tmp.h" + +#define IND (SETUP_W|SETUP_TMU1) +#define NAME fxsetupWT1 +#include "fxvs_tmp.h" + +#define IND (SETUP_W|SETUP_TMU1|SETUP_TMU0) +#define NAME fxsetupWT0T1 +#include "fxvs_tmp.h" + +#define IND (SETUP_W|SETUP_TMU0|SETUP_RGBA) +#define NAME fxsetupWRGBAT0 +#include "fxvs_tmp.h" + +#define IND (SETUP_W|SETUP_TMU1|SETUP_RGBA) +#define NAME fxsetupWRGBAT1 +#include "fxvs_tmp.h" + +#define IND (SETUP_W|SETUP_TMU1|SETUP_TMU0|SETUP_RGBA) +#define NAME fxsetupWRGBAT0T1 +#include "fxvs_tmp.h" + + + +void +fxDDSetupInit(void) +{ + setupfuncs[SETUP_XY] = fxsetupXY; + setupfuncs[SETUP_XY | SETUP_Z] = fxsetupXYZ; + setupfuncs[SETUP_XY | SETUP_W] = fxsetupXYW; + setupfuncs[SETUP_XY | SETUP_Z | SETUP_W] = fxsetupXYZW; + + setupfuncs[SETUP_RGBA | SETUP_XY] = fxsetupXYRGBA; + setupfuncs[SETUP_RGBA | SETUP_XY | SETUP_Z] = fxsetupXYZRGBA; + setupfuncs[SETUP_RGBA | SETUP_XY | SETUP_W] = fxsetupXYWRGBA; + setupfuncs[SETUP_RGBA | SETUP_XY | SETUP_Z | SETUP_W] = fxsetupXYZWRGBA; + + /* If we have texture and xy then we must have w. + * If we have texture1 and w then we must have texture 0. + */ + setupfuncs[SETUP_TMU0 | SETUP_XY | SETUP_W] = fxsetupXYWT0; + setupfuncs[SETUP_TMU0 | SETUP_XY | SETUP_Z | SETUP_W] = fxsetupXYZWT0; + + setupfuncs[SETUP_TMU1 | SETUP_TMU0 | SETUP_XY | SETUP_W] = fxsetupXYWT0T1; + setupfuncs[SETUP_TMU1 | SETUP_TMU0 | SETUP_XY | SETUP_Z | SETUP_W] = + fxsetupXYZWT0T1; + + setupfuncs[SETUP_TMU0 | SETUP_RGBA | SETUP_XY | SETUP_W] = + fxsetupXYWRGBAT0; + setupfuncs[SETUP_TMU0 | SETUP_RGBA | SETUP_XY | SETUP_Z | SETUP_W] = + fxsetupXYZWRGBAT0; + + setupfuncs[SETUP_TMU1 | SETUP_TMU0 | SETUP_RGBA | SETUP_XY | SETUP_W] = + fxsetupXYWRGBAT0T1; + setupfuncs[SETUP_TMU1 | SETUP_TMU0 | SETUP_RGBA | SETUP_XY | SETUP_Z | + SETUP_W] = fxsetupXYZWRGBAT0T1; + + /* If we don't have xy then we can't have z... w is still a possibility. + */ + setupfuncs[SETUP_RGBA] = fxsetupRGBA; + setupfuncs[SETUP_TMU0] = fxsetupT0; + setupfuncs[SETUP_TMU1] = fxsetupT1; + setupfuncs[SETUP_TMU1 | SETUP_TMU0] = fxsetupT0T1; + setupfuncs[SETUP_TMU0 | SETUP_RGBA] = fxsetupRGBAT0; + setupfuncs[SETUP_TMU1 | SETUP_RGBA] = fxsetupRGBAT1; + setupfuncs[SETUP_TMU1 | SETUP_TMU0 | SETUP_RGBA] = fxsetupRGBAT0T1; + + setupfuncs[SETUP_W | SETUP_RGBA] = fxsetupWRGBA; + setupfuncs[SETUP_W | SETUP_TMU0] = fxsetupWT0; + setupfuncs[SETUP_W | SETUP_TMU1] = fxsetupWT1; + setupfuncs[SETUP_W | SETUP_TMU1 | SETUP_TMU0] = fxsetupWT0T1; + setupfuncs[SETUP_W | SETUP_TMU0 | SETUP_RGBA] = fxsetupWRGBAT0; + setupfuncs[SETUP_W | SETUP_TMU1 | SETUP_RGBA] = fxsetupWRGBAT1; + setupfuncs[SETUP_W | SETUP_TMU1 | SETUP_TMU0 | SETUP_RGBA] = + fxsetupWRGBAT0T1; + +} + + + +tfxSetupFunc +fxDDChooseSetupFunction(GLcontext * ctx) +{ + GLuint setupindex = SETUP_XY | SETUP_Z; + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + + fxMesa->setupindex = 0; + + if (ctx->RenderMode != GL_RENDER) + return 0; + + fxMesa->tmu_source[0] = 0; + fxMesa->tmu_source[1] = 1; + + fxMesa->tex_dest[0] = SETUP_TMU0; + fxMesa->tex_dest[1] = SETUP_TMU1; + + if (ctx->Light.ShadeModel == GL_SMOOTH && !ctx->Light.Model.TwoSide) + setupindex |= SETUP_RGBA; + + if (ctx->Fog.Enabled && ctx->FogMode == FOG_FRAGMENT) + setupindex |= SETUP_RGBA | SETUP_W; + + if ((ctx->Texture.ReallyEnabled & (TEXTURE0_2D | TEXTURE0_3D)) == + TEXTURE0_2D) { + /* This doesn't work for non-RGBA textures + if (ctx->Texture.Unit[0].EnvMode == GL_REPLACE) + setupindex &= ~SETUP_RGBA; + */ + setupindex |= SETUP_TMU0 | SETUP_W; + } + + if ((ctx->Texture.ReallyEnabled & (TEXTURE1_2D | TEXTURE1_3D)) == + TEXTURE1_2D) { + setupindex |= SETUP_TMU1 | SETUP_W; + if (setupindex & SETUP_TMU0) { /* both TMUs in use */ + struct gl_texture_object *tObj = ctx->Texture.Unit[0].CurrentD[2]; + tfxTexInfo *ti = fxTMGetTexInfo(tObj); + + if (ti->whichTMU != FX_TMU0) { /* TMU0 and TMU1 are swapped */ + fxMesa->tmu_source[0] = 1; + fxMesa->tex_dest[1] = SETUP_TMU0; + fxMesa->tmu_source[1] = 0; + fxMesa->tex_dest[0] = SETUP_TMU1; + } + } + } + + if (ctx->Color.BlendEnabled) + setupindex |= SETUP_RGBA; + + if (MESA_VERBOSE & (VERBOSE_DRIVER | VERBOSE_PIPELINE | VERBOSE_STATE)) + fxPrintSetupFlags("fxmesa: vertex setup function", setupindex); + + fxMesa->setupindex = setupindex; + fxMesa->view_clip_tri = fxTriViewClipTab[setupindex & 0x7]; + fxMesa->clip_tri_stride = fxTriClipStrideTab[setupindex & 0x7]; + return setupfuncs[setupindex]; +} + +void +fxDDDoRasterSetup(struct vertex_buffer *VB) +{ + GLcontext *ctx = VB->ctx; + FX_DRIVER_DATA(VB)->last_vert = FX_DRIVER_DATA(VB)->verts + VB->Count; + +#if 0 /* leaving this out fixes the Heretic2 stray polygon bug */ + if ((ctx->IndirectTriangles & DD_SW_RASTERIZE) == DD_SW_RASTERIZE) { + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + fxMesa->setupdone = 0; + return; + } +#endif + + if (VB->Type == VB_CVA_PRECALC) + fxDDPartialRasterSetup(VB); + else if (ctx->Driver.RasterSetup) /* NULL if in feedback/selection mode */ + ctx->Driver.RasterSetup(VB, VB->CopyStart, VB->Count); + +} + + +/* + * Need to check that merge&render will work before allowing this to + * happen here. Therefore - need to know that this will be fired when + * we get a forbidden input in the elt pipeline - and therefore need to check + * whether we have one *now*. Similarly need to know if state changes cause + * size4 texcoords to be introduced. + */ +void +fxDDCheckPartialRasterSetup(GLcontext * ctx, struct gl_pipeline_stage *d) +{ + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + GLuint tmp = fxMesa->setupdone; + + d->type = 0; + d->pre_forbidden_inputs = 0; + fxMesa->setupdone = 0; /* cleared if we return */ + + /* Indirect triangles must be rendered via the immediate pipeline. + * If all rasterization is software, no need to set up. + */ + if ((ctx->Array.Summary & VERT_OBJ_ANY) == 0) + return; + + if ((ctx->IndirectTriangles & DD_SW_SETUP) || + (ctx->IndirectTriangles & DD_SW_RASTERIZE) == DD_SW_RASTERIZE) + return; + + if ((ctx->Texture.ReallyEnabled & 0xf) && + !(ctx->Array.Flags & VERT_TEX0_ANY)) { + if (ctx->TextureMatrix[0].type == MATRIX_GENERAL || + ctx->TextureMatrix[0].type == MATRIX_PERSPECTIVE || + (ctx->Texture.Unit[0].TexGenEnabled & Q_BIT)) + return; + + d->pre_forbidden_inputs |= VERT_TEX0_4; + } + + if ((ctx->Texture.ReallyEnabled & 0xf0) && + !(ctx->Array.Flags & VERT_TEX1_ANY)) { + if (ctx->TextureMatrix[1].type == MATRIX_GENERAL || + ctx->TextureMatrix[1].type == MATRIX_PERSPECTIVE || + (ctx->Texture.Unit[1].TexGenEnabled & Q_BIT)) + return; + + d->pre_forbidden_inputs |= VERT_TEX1_4; + } + + + fxMesa->setupdone = tmp; + d->inputs = 0; + d->outputs = VERT_SETUP_PART; + d->type = PIPE_PRECALC; +} + + +/* Will be different every time - no point in trying to precalc the + * function to call. + */ +void +fxDDPartialRasterSetup(struct vertex_buffer *VB) +{ + GLuint new = VB->pipeline->new_outputs; + fxMesaContext fxMesa = (fxMesaContext) VB->ctx->DriverCtx; + GLuint ind = 0; + + FX_DRIVER_DATA(VB)->last_vert = FX_DRIVER_DATA(VB)->verts + VB->Count; + + if (new & VERT_WIN) { + new = VB->pipeline->outputs; + ind |= SETUP_XY | SETUP_W | SETUP_Z; + } + + if (new & VERT_TEX0_ANY) + ind |= SETUP_W | fxMesa->tex_dest[0]; + + if (new & VERT_TEX1_ANY) + ind |= SETUP_W | fxMesa->tex_dest[1]; + + if (new & VERT_RGBA) + ind |= SETUP_W | SETUP_RGBA; + + if ((new & VERT_WIN) == 0) + ind &= ~(fxMesa->setupdone & SETUP_W); + + fxMesa->setupdone &= ~ind; + ind &= fxMesa->setupindex; + fxMesa->setupdone |= ind; + + if (MESA_VERBOSE & (VERBOSE_DRIVER | VERBOSE_PIPELINE)) { + gl_print_vert_flags("new outputs", VB->pipeline->new_outputs); + fxPrintSetupFlags("fxmesa: partial setup function", ind); + } + + if (ind) + setupfuncs[ind] (VB, VB->Start, VB->Count); +} + +/* Almost certainly never called. + */ +void +fxDDResizeVB(struct vertex_buffer *VB, GLuint size) +{ + struct tfxMesaVertexBuffer *fvb = FX_DRIVER_DATA(VB); + + while (fvb->size < size) + fvb->size *= 2; + + ALIGN_FREE(VB->ClipMask); + VB->ClipMask = (GLubyte *) ALIGN_MALLOC(sizeof(GLubyte) * fvb->size, 4); + + FREE(fvb->vert_store); + fvb->vert_store = MALLOC(sizeof(fxVertex) * fvb->size + 31); + if (!fvb->vert_store || !VB->ClipMask) { + fprintf(stderr, "fx Driver: out of memory !\n"); + return; + } + fvb->verts = (fxVertex *) (((unsigned long) fvb->vert_store + 31) & ~31); + + gl_vector1ui_free(&fvb->clipped_elements); + gl_vector1ui_alloc(&fvb->clipped_elements, VEC_WRITABLE, fvb->size, 32); + + if (!fvb->clipped_elements.start) + goto memerror; + + return; + memerror: + fprintf(stderr, "fx Driver: out of memory !\n"); +} + + +void +fxDDRegisterVB(struct vertex_buffer *VB) +{ + struct tfxMesaVertexBuffer *fvb; + + fvb = (struct tfxMesaVertexBuffer *) calloc(1, sizeof(*fvb)); + + /* This looks like it allocates a lot of memory, but it basically + * just sets an upper limit on how much can be used - nothing like + * this amount will ever be turned into 'real' memory. + */ + if (VB->Type == VB_CVA_PRECALC) { + fvb->size = VB->Size * 5; + fvb->vert_store = MALLOC(sizeof(fxVertex) * fvb->size + 31); + if (!fvb->vert_store) + goto memerror; +#if defined(FX_GLIDE3) + fvb->triangle_b = MALLOC(sizeof(GrVertex *) * 4 * fvb->size + 31); + if (!fvb->triangle_b) + goto memerror; + fvb->strips_b = MALLOC(sizeof(GrVertex *) * 4 * fvb->size + 31); + if (!fvb->strips_b) + goto memerror; +#endif + fvb->verts = + (fxVertex *) (((unsigned long) fvb->vert_store + 31) & ~31); + gl_vector1ui_alloc(&fvb->clipped_elements, VEC_WRITABLE, fvb->size, + 32); + if (!fvb->clipped_elements.start) + goto memerror; + + ALIGN_FREE(VB->ClipMask); + VB->ClipMask = (GLubyte *) ALIGN_MALLOC(sizeof(GLubyte) * fvb->size, 4); + if (!VB->ClipMask) + goto memerror; + + } + else { + fvb->vert_store = MALLOC(sizeof(fxVertex) * (VB->Size + 12) + 31); + if (!fvb->vert_store) + goto memerror; +#if defined(FX_GLIDE3) + fvb->triangle_b = MALLOC(sizeof(GrVertex *) * 4 * fvb->size + 31); + if (!fvb->triangle_b) + goto memerror; + fvb->strips_b = MALLOC(sizeof(GrVertex *) * 4 * fvb->size + 31); + if (!fvb->strips_b) + goto memerror; +#endif + fvb->verts = + (fxVertex *) (((unsigned long) fvb->vert_store + 31) & ~31); + fvb->size = VB->Size + 12; + } + + + VB->driver_data = fvb; + return; + memerror: + fprintf(stderr, "fx Driver: out of memory !\n"); +} + + +void +fxDDUnregisterVB(struct vertex_buffer *VB) +{ + struct tfxMesaVertexBuffer *fvb = FX_DRIVER_DATA(VB); + + if (fvb) { + if (fvb->vert_store) + FREE(fvb->vert_store); + gl_vector1ui_free(&fvb->clipped_elements); + FREE(fvb); +#if defined(FX_GLIDE3) + if (fvb->strips_b) + FREE(fvb->strips_b); + if (fvb->triangle_b) + FREE(fvb->triangle_b); +#endif + VB->driver_data = 0; + } +} diff --git a/xc/lib/GL/mesa/src/drv/tdfx/fxvsetup.h b/xc/lib/GL/mesa/src/drv/tdfx/fxvsetup.h new file mode 100644 index 000000000..85a5f1f66 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/tdfx/fxvsetup.h @@ -0,0 +1,198 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/fxvsetup.h,v 1.1 2000/09/24 13:51:20 alanh Exp $ */ +/* + * Mesa 3-D graphics library + * Version: 3.3 + * + * 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. + * + * + * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the + * terms stated above. + * + * Thank you for your contribution, David! + * + * Please make note of the above copyright/license statement. If you + * contributed code or bug fixes to this code under the previous (GNU + * Library) license and object to the new license, your code will be + * removed at your request. Please see the Mesa docs/COPYRIGHT file + * for more information. + * + * Additional Mesa/3Dfx driver developers: + * Daryll Strauss <daryll@precisioninsight.com> + * Keith Whitwell <keith@precisioninsight.com> + * + * See fxapi.h for more revision/author details. + */ + + +#ifndef _FXVSETUP_H_ +#define _FXVSETUP_H_ + + +#define VARS_W + +#define VARS_Z + +#define VARS_TMU0 \ + GLuint tmu0_source = fxMesa->tmu_source[0]; \ + GLfloat *tmu0_data = VEC_ELT(VB->TexCoordPtr[tmu0_source], \ + GLfloat, start); \ + GLuint tmu0_stride = VB->TexCoordPtr[tmu0_source]->stride; \ + GLuint tmu0_sz = VB->TexCoordPtr[tmu0_source]->size; \ + struct gl_texture_unit *t0 = &ctx->Texture.Unit[tmu0_source]; \ + GLfloat sscale0 = FX_TEXTURE_DATA(t0)->sScale; \ + GLfloat tscale0 = FX_TEXTURE_DATA(t0)->tScale; + +#define VARS_TMU1 \ + GLuint tmu1_source = fxMesa->tmu_source[1]; \ + GLfloat *tmu1_data = VEC_ELT(VB->TexCoordPtr[tmu1_source], \ + GLfloat, start); \ + GLuint tmu1_stride = VB->TexCoordPtr[tmu1_source]->stride; \ + GLuint tmu1_sz = VB->TexCoordPtr[tmu1_source]->size; \ + struct gl_texture_unit *t1 = &ctx->Texture.Unit[tmu1_source]; \ + GLfloat sscale1 = FX_TEXTURE_DATA(t1)->sScale; \ + GLfloat tscale1 = FX_TEXTURE_DATA(t1)->tScale; + +#define VARS_RGBA \ + GLubyte *color = VEC_ELT(VB->ColorPtr, GLubyte, start); \ + GLuint col_stride = VB->ColorPtr->stride; + +#define VARS_XY GLfloat *win = VB->Win.data[start]; + +#define INCR_XY win += 4 + + +#ifdef FX_V2 +# define DO_SETUP_XY \ + v[XCOORD]=win[0]; \ + v[YCOORD]=win[1]; +#else +#ifdef DRIVERTS +# define DO_SETUP_XY \ + v[XCOORD]=win[0]+fxMesa->x_offset; \ + v[YCOORD]=win[1]+fxMesa->y_delta; +#else +# if (defined(__linux__) && defined(__i386__)) || defined(macintosh) +# define DO_SETUP_XY { \ + GLfloat t1 = win[0] + snapper; \ + GLfloat t2 = win[1] + snapper; \ + v[XCOORD] = t1 - snapper; \ + v[YCOORD] = t2 - snapper; \ + } +# else +# define DO_SETUP_XY { \ + /* trunc (x,y) to multiple of 1/16 */ \ + v[XCOORD]=((int)(win[0]*16.0f))*(1.0f/16.0f); \ + v[YCOORD]=((int)(win[1]*16.0f))*(1.0f/16.0f); \ + } +# endif +#endif +#endif + + +#define DO_SETUP_W { \ + v[OOWCOORD]=win[3]; \ +} + +#define DO_SETUP_Z v[ZCOORD]=win[2]; + +#define DO_SETUP_TMU0 \ +{ \ + v[S0COORD]=sscale0*tmu0_data[0]*v[OOWCOORD]; \ + v[T0COORD]=tscale0*tmu0_data[1]*v[OOWCOORD]; \ +} + +#define INCR_TMU0 STRIDE_F(tmu0_data, tmu0_stride) + +#define DO_SETUP_TMU1 \ +{ \ + v[S1COORD]=sscale1*tmu1_data[0]*v[OOWCOORD]; \ + v[T1COORD]=tscale1*tmu1_data[1]*v[OOWCOORD]; \ +} + +#define INCR_TMU1 STRIDE_F(tmu1_data, tmu1_stride) + +#if FX_USE_PARGB +#define DO_SETUP_RGBA \ + { GET_PARGB(v) = color[ACOMP] << 24 | color[RCOMP] << 16 | color[GCOMP] << 8 | color[BCOMP];} + +#else +#define DO_SETUP_RGBA \ +{ \ + UBYTE_COLOR_TO_FLOAT_255_COLOR2(v[RCOORD], color[0]); \ + UBYTE_COLOR_TO_FLOAT_255_COLOR2(v[GCOORD], color[1]); \ + UBYTE_COLOR_TO_FLOAT_255_COLOR2(v[BCOORD], color[2]); \ + UBYTE_COLOR_TO_FLOAT_255_COLOR2(v[ACOORD], color[3]); \ +} +#endif + +#define INCR_RGBA color += col_stride + + +#define _FIXUP_PRE \ + GLuint hs = fxMesa->stw_hint_state & ~(GR_STWHINT_W_DIFF_TMU0 | \ + GR_STWHINT_W_DIFF_TMU1); + +#define _FIXUP_TMU0 \ + if (tmu0_sz == 4) { \ + project_texcoords( VB, 0, tmu0_source, start, end ); \ + hs |= GR_STWHINT_W_DIFF_TMU0; \ + } + + +#define _FIXUP_TMU1 \ + if (tmu1_sz == 4) { \ + project_texcoords( VB, 1, tmu1_source, start, end ); \ + hs |= GR_STWHINT_W_DIFF_TMU1; \ + } + + +#define _FIXUP_TMU01 \ + if (tmu0_sz == 4) { \ + project_texcoords( VB, 0, tmu0_source, start, end ); \ + if (tmu1_sz == 4) \ + project_texcoords( VB, 1, tmu1_source, start, end ); \ + else \ + copy_w( VB, 1, start, end ); \ + hs |= (GR_STWHINT_W_DIFF_TMU0|GR_STWHINT_W_DIFF_TMU1); \ + } else if (tmu1_sz == 4) { \ + project_texcoords( VB, 1, tmu1_source, start, end ); \ + hs |= GR_STWHINT_W_DIFF_TMU1; \ + } + +#define _FIXUP_POST \ + if (hs != fxMesa->stw_hint_state) { \ + fxMesa->stw_hint_state = hs; \ + FX_grHints(fxMesa, GR_HINT_STWHINT, hs); \ + } + + +#define FIXUP_TMU0 { _FIXUP_PRE _FIXUP_TMU0 _FIXUP_POST } +#define FIXUP_TMU1 { _FIXUP_PRE _FIXUP_TMU1 _FIXUP_POST } +#define FIXUP_TMU01 { _FIXUP_PRE _FIXUP_TMU01 _FIXUP_POST } + + +/* v - pointer to destination GrVertex + * VB - source of data + * i - index into vb for data + */ + + +#endif diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_init.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_init.c index 70e7bbbb8..0c0ae8b0c 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_init.c +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_init.c @@ -24,6 +24,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_init.c,v 1.5 2000/09/26 15:56:50 tsi Exp $ */ /* * Authors: @@ -36,74 +37,60 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include <X11/Xlibint.h> #include "xf86dri.h" #include "tdfx_dri.h" -#include "tdfx_init.h" +#include "fxdrv.h" + #ifdef DEBUG_LOCKING -char *prevLockFile=0; -int prevLockLine=0; +char *prevLockFile = 0; +int prevLockLine = 0; #endif -static void performMagic(__DRIscreenPrivate *driScrnPriv) +static void +performMagic(__DRIscreenPrivate * driScrnPriv) { - tdfxScreenPrivate *gPriv = (tdfxScreenPrivate *)driScrnPriv->private; - TDFXDRIPtr gDRIPriv = (TDFXDRIPtr)driScrnPriv->pDevPriv; - - gPriv->regs.handle=gDRIPriv->regs; - gPriv->regs.size=gDRIPriv->regsSize; - gPriv->deviceID=gDRIPriv->deviceID; - gPriv->width=gDRIPriv->width; - gPriv->height=gDRIPriv->height; - gPriv->mem=gDRIPriv->mem; - gPriv->cpp=gDRIPriv->cpp; - gPriv->stride=gDRIPriv->stride; - gPriv->fifoOffset=gDRIPriv->fifoOffset; - gPriv->fifoSize=gDRIPriv->fifoSize; - gPriv->fbOffset=gDRIPriv->fbOffset; - gPriv->backOffset=gDRIPriv->backOffset; - gPriv->depthOffset=gDRIPriv->depthOffset; - gPriv->textureOffset=gDRIPriv->textureOffset; - gPriv->textureSize=gDRIPriv->textureSize; + tdfxScreenPrivate *gPriv = (tdfxScreenPrivate *) driScrnPriv->private; + TDFXDRIPtr gDRIPriv = (TDFXDRIPtr) driScrnPriv->pDevPriv; + + gPriv->regs.handle = gDRIPriv->regs; + gPriv->regs.size = gDRIPriv->regsSize; + gPriv->deviceID = gDRIPriv->deviceID; + gPriv->width = gDRIPriv->width; + gPriv->height = gDRIPriv->height; + gPriv->mem = gDRIPriv->mem; + gPriv->cpp = gDRIPriv->cpp; + gPriv->stride = gDRIPriv->stride; + gPriv->fifoOffset = gDRIPriv->fifoOffset; + gPriv->fifoSize = gDRIPriv->fifoSize; + gPriv->fbOffset = gDRIPriv->fbOffset; + gPriv->backOffset = gDRIPriv->backOffset; + gPriv->depthOffset = gDRIPriv->depthOffset; + gPriv->textureOffset = gDRIPriv->textureOffset; + gPriv->textureSize = gDRIPriv->textureSize; } -GLboolean tdfxMapAllRegions(__DRIscreenPrivate *driScrnPriv) +GLboolean +tdfxMapAllRegions(__DRIscreenPrivate * driScrnPriv) { - tdfxScreenPrivate *gPriv = (tdfxScreenPrivate *)driScrnPriv->private; - + tdfxScreenPrivate *gPriv = (tdfxScreenPrivate *) driScrnPriv->private; + /* First, pick apart pDevPriv & friends */ performMagic(driScrnPriv); - if (drmMap(driScrnPriv->fd, gPriv->regs.handle, gPriv->regs.size, - &gPriv->regs.map)) { - return GL_FALSE; + if (drmMap(driScrnPriv->fd, gPriv->regs.handle, gPriv->regs.size, + &gPriv->regs.map)) { + return GL_FALSE; } return GL_TRUE; } -void tdfxUnmapAllRegions(__DRIscreenPrivate *driScrnPriv) +void +tdfxUnmapAllRegions(__DRIscreenPrivate * driScrnPriv) { - tdfxScreenPrivate *gPriv = (tdfxScreenPrivate *)driScrnPriv->private; + tdfxScreenPrivate *gPriv = (tdfxScreenPrivate *) driScrnPriv->private; drmUnmap(gPriv->regs.map, gPriv->regs.size); } -/* - * Shutdown Glide library - */ -void fxCloseHardware(void) -{ - if (getenv("MESA_FX_INFO")) { - GrSstPerfStats_t st; - - FX_grSstPerfStats(&st); - fprintf(stderr,"Pixels Stats:\n"); - fprintf(stderr," # pixels processed (minus buffer clears): %u\n",(unsigned)st.pixelsIn); - fprintf(stderr," # pixels not drawn due to chroma key test failure: %u\n",(unsigned)st.chromaFail); - fprintf(stderr," # pixels not drawn due to depth test failure: %u\n",(unsigned)st.zFuncFail); - fprintf(stderr," # pixels not drawn due to alpha test failure: %u\n",(unsigned)st.aFuncFail); - fprintf(stderr," # pixels drawn (including buffer clears and LFB writes): %u\n",(unsigned)st.pixelsOut); - } - FX_grGlideShutdown(); -} #endif diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_inithw.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_inithw.c index 0bafa3190..1dcc6a0e8 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_inithw.c +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_inithw.c @@ -24,6 +24,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_inithw.c,v 1.6 2000/09/26 15:56:50 tsi Exp $ */ /* * Authors: @@ -33,67 +34,63 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifdef GLX_DIRECT_RENDERING -#include "tdfx_init.h" #include <glide.h> +#include "fxdrv.h" -GLboolean tdfxInitHW(__DRIdrawablePrivate *driDrawPriv, - tdfxContextPrivate *fxMesa) + +GLboolean +tdfxInitHW(__DRIdrawablePrivate * driDrawPriv, fxMesaContext fxMesa) { - /* KW: Would be nice to make one of these a member of the other. - */ - __DRIscreenPrivate *driScrnPriv = driDrawPriv->driScreenPriv; - tdfxScreenPrivate *sPriv = (tdfxScreenPrivate*)driScrnPriv->private; + /* KW: Would be nice to make one of these a member of the other. + */ + __DRIscreenPrivate *driScrnPriv = driDrawPriv->driScreenPriv; + tdfxScreenPrivate *sPriv = (tdfxScreenPrivate *) driScrnPriv->private; #ifdef DEBUG_LOCKING - fprintf(stderr, "Debug locking enabled\n"); + fprintf(stderr, "Debug locking enabled\n"); #endif - - if (fxMesa->initDone) return GL_TRUE; - fxMesa->width=driDrawPriv->w; - fxMesa->height=driDrawPriv->h; + if (fxMesa->initDone) + return GL_TRUE; - /* We have to use a light lock here, because we can't do any glide - operations yet. No use of FX_* functions in this function. */ - DRM_LIGHT_LOCK(driScrnPriv->fd, &driScrnPriv->pSAREA->lock, - driDrawPriv->driContextPriv->hHWContext); - FX_grGlideInit_NoLock(); + fxMesa->width = driDrawPriv->w; + fxMesa->height = driDrawPriv->h; - fxMesa->board = 0; - FX_grSstSelect_NoLock(fxMesa->board); + /* We have to use a light lock here, because we can't do any glide + operations yet. No use of FX_* functions in this function. */ + DRM_LIGHT_LOCK(driScrnPriv->fd, &driScrnPriv->pSAREA->lock, + driDrawPriv->driContextPriv->hHWContext); + FX_grGlideInit_NoLock(); - if (sPriv->deviceID==0x3) - fxMesa->haveTwoTMUs=GL_FALSE; - else - fxMesa->haveTwoTMUs=GL_TRUE; + fxMesa->board = 0; + FX_grSstSelect_NoLock(fxMesa->board); - /* !!! We are forcing these !!! */ - fxMesa->haveAlphaBuffer=GL_FALSE; - fxMesa->haveGlobalPaletteTexture=GL_FALSE; + if (sPriv->deviceID == 0x3) + fxMesa->haveTwoTMUs = GL_FALSE; + else + fxMesa->haveTwoTMUs = GL_TRUE; - fxMesa->glideContext = FX_grSstWinOpen_NoLock((FxU32)-1, GR_RESOLUTION_NONE, - GR_REFRESH_NONE, - GR_COLORFORMAT_ABGR, - GR_ORIGIN_LOWER_LEFT, 2, 1); + /* !!! We are forcing these !!! */ + fxMesa->haveAlphaBuffer = GL_FALSE; + fxMesa->haveGlobalPaletteTexture = GL_FALSE; - grDRIResetSAREA(); - DRM_UNLOCK(driScrnPriv->fd, &driScrnPriv->pSAREA->lock, - driDrawPriv->driContextPriv->hHWContext); + fxMesa->glideContext = + FX_grSstWinOpen_NoLock((FxU32) - 1, GR_RESOLUTION_NONE, + GR_REFRESH_NONE, GR_COLORFORMAT_ABGR, + GR_ORIGIN_LOWER_LEFT, 2, 1); - fxMesa->needClip=1; + grDRIResetSAREA(); + DRM_UNLOCK(driScrnPriv->fd, &driScrnPriv->pSAREA->lock, + driDrawPriv->driContextPriv->hHWContext); - if (!fxMesa->glideContext || !fxDDInitFxMesaContext( fxMesa )) - return GL_FALSE; + fxMesa->needClip = 1; - fxInitPixelTables(fxMesa, GL_FALSE); /* Load tables of pixel colors */ + if (!fxMesa->glideContext || !fxDDInitFxMesaContext(fxMesa)) + return GL_FALSE; - fxMesa->initDone=GL_TRUE; - return GL_TRUE; + fxMesa->initDone = GL_TRUE; + return GL_TRUE; } #endif - - - - 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 b40f0f054..228a59758 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_xmesa.c +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_xmesa.c @@ -24,98 +24,110 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_xmesa.c,v 1.8 2000/09/26 15:56:50 tsi Exp $ */ /* * Authors: - * Daryll Strauss <daryll@precisioninsight.com> - * Brian E. Paul <brian@precisioninsight.com> + * Daryll Strauss <daryll@valinux.com> + * Brian E. Paul <brianp@valinux.com> */ #ifdef GLX_DIRECT_RENDERING #include <X11/Xlibint.h> #include <glide.h> -#include "tdfx_init.h" +#include "fxdrv.h" #include "context.h" #include "matrix.h" #include "mmath.h" #include "vbxform.h" +#include "fxtexman.h" -__DRIcontextPrivate *gCC = 0; +/* including xf86PciInfo.h causes a bunch of errors */ +#ifndef PCI_CHIP_VOODOO5 +#define PCI_CHIP_VOODOO5 0x0009 +#endif -GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv) +GLboolean +XMesaInitDriver(__DRIscreenPrivate * sPriv) { - tdfxScreenPrivate *gsp; - - /* Check the DRI version */ - { - int major, minor, patch; - if (XF86DRIQueryVersion(sPriv->display, &major, &minor, &patch)) { - if (major != 3 || minor != 0 || patch < 0) { - char msg[1000]; - sprintf(msg, "3dfx DRI driver expected DRI version 3.0.x but got version %d.%d.%d", major, minor, patch); - __driMesaMessage(msg); - return GL_FALSE; - } - } - } - - /* Check that the DDX driver version is compatible */ - if (sPriv->ddxMajor != 1 || - sPriv->ddxMinor != 0 || - sPriv->ddxPatch < 0) { - char msg[1000]; - sprintf(msg, "3dfx DRI driver expected DDX driver version 1.0.x but got version %d.%d.%d", sPriv->ddxMajor, sPriv->ddxMinor, sPriv->ddxPatch); - __driMesaMessage(msg); - return GL_FALSE; - } - - /* Check that the DRM driver version is compatible */ - if (sPriv->drmMajor != 1 || - sPriv->drmMinor != 0 || - sPriv->drmPatch < 0) { - char msg[1000]; - sprintf(msg, "3dfx DRI driver expected DRM driver version 1.0.x but got version %d.%d.%d", sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch); - __driMesaMessage(msg); - return GL_FALSE; - } - - /* Allocate the private area */ - gsp = (tdfxScreenPrivate *)Xmalloc(sizeof(tdfxScreenPrivate)); - if (!gsp) - return GL_FALSE; - - gsp->driScrnPriv = sPriv; - - sPriv->private = (void *) gsp; - - if (!tdfxMapAllRegions(sPriv)) { - Xfree(gsp); - sPriv->private = NULL; - return GL_FALSE; - } - - return GL_TRUE; + tdfxScreenPrivate *gsp; + + /* Check the DRI version */ + { + int major, minor, patch; + if (XF86DRIQueryVersion(sPriv->display, &major, &minor, &patch)) { + if (major != 3 || minor != 0 || patch < 0) { + char msg[1000]; + sprintf(msg, + "3dfx DRI driver expected DRI version 3.0.x but got version %d.%d.%d", + major, minor, patch); + __driMesaMessage(msg); + return GL_FALSE; + } + } + } + + /* Check that the DDX driver version is compatible */ + if (sPriv->ddxMajor != 1 || sPriv->ddxMinor != 0 || sPriv->ddxPatch < 0) { + char msg[1000]; + sprintf(msg, + "3dfx DRI driver expected DDX driver version 1.0.x but got version %d.%d.%d", + sPriv->ddxMajor, sPriv->ddxMinor, sPriv->ddxPatch); + __driMesaMessage(msg); + return GL_FALSE; + } + + /* Check that the DRM driver version is compatible */ + if (sPriv->drmMajor != 1 || sPriv->drmMinor != 0 || sPriv->drmPatch < 0) { + char msg[1000]; + sprintf(msg, + "3dfx DRI driver expected DRM driver version 1.0.x but got version %d.%d.%d", + sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch); + __driMesaMessage(msg); + return GL_FALSE; + } + + /* Allocate the private area */ + gsp = (tdfxScreenPrivate *) Xmalloc(sizeof(tdfxScreenPrivate)); + if (!gsp) + return GL_FALSE; + + gsp->driScrnPriv = sPriv; + + sPriv->private = (void *) gsp; + + if (!tdfxMapAllRegions(sPriv)) { + Xfree(gsp); + sPriv->private = NULL; + return GL_FALSE; + } + + return GL_TRUE; } -void XMesaResetDriver(__DRIscreenPrivate *sPriv) + +void +XMesaResetDriver(__DRIscreenPrivate * sPriv) { - tdfxUnmapAllRegions(sPriv); - Xfree(sPriv->private); - sPriv->private = NULL; + tdfxUnmapAllRegions(sPriv); + Xfree(sPriv->private); + sPriv->private = NULL; } -GLvisual *XMesaCreateVisual(Display *dpy, - __DRIscreenPrivate *driScrnPriv, - const XVisualInfo *visinfo, - const __GLXvisualConfig *config) + +GLvisual * +XMesaCreateVisual(Display * dpy, + __DRIscreenPrivate * driScrnPriv, + const XVisualInfo * visinfo, + const __GLXvisualConfig * config) { - /* Drivers may change the args to _mesa_create_visual() in order to - * setup special visuals. - */ - return _mesa_create_visual( config->rgba, + /* Drivers may change the args to _mesa_create_visual() in order to + * setup special visuals. + */ + return _mesa_create_visual(config->rgba, config->doubleBuffer, config->stereo, _mesa_bitcount(visinfo->red_mask), @@ -129,276 +141,359 @@ GLvisual *XMesaCreateVisual(Display *dpy, config->accumGreenSize, config->accumBlueSize, config->accumAlphaSize, - 0 /* num samples */ ); + 0 /* num samples */ + ); } -GLboolean XMesaCreateContext(Display *dpy, GLvisual *mesaVis, - __DRIcontextPrivate *driContextPriv) +GLboolean +XMesaCreateContext(Display * dpy, GLvisual * mesaVis, + __DRIcontextPrivate * driContextPriv) { - tdfxContextPrivate *cPriv; - __DRIscreenPrivate *driScrnPriv = driContextPriv->driScreenPriv; - tdfxScreenPrivate *sPriv = (tdfxScreenPrivate *)driScrnPriv->private; - TDFXSAREAPriv *saPriv; - /*int **fifoPtr;*/ - - cPriv = (tdfxContextPrivate *)Xmalloc(sizeof(tdfxContextPrivate)); - if (!cPriv) { - return GL_FALSE; - } - - cPriv->hHWContext = driContextPriv->hHWContext; - cPriv->tdfxScrnPriv = sPriv; - /* deviceID = 0x05 = Voodoo3 */ - /* deviceID = 0x09 = Voodoo5 (and Voodoo5?) */ - cPriv->haveHwStencil = sPriv->deviceID == 0x9 && sPriv->cpp == 4; - - cPriv->glVis=mesaVis; - cPriv->glBuffer=gl_create_framebuffer(mesaVis, - GL_FALSE, /* software depth buffer? */ - mesaVis->StencilBits > 0 && !cPriv->haveHwStencil, - mesaVis->AccumRedBits > 0, - GL_FALSE /* software alpha channel */ - ); - - cPriv->screen_width=sPriv->width; - cPriv->screen_height=sPriv->height; - cPriv->new_state = ~0; - - cPriv->glCtx = driContextPriv->mesaContext; - cPriv->initDone=GL_FALSE; - - saPriv=(TDFXSAREAPriv*)((char*)driScrnPriv->pSAREA+sizeof(XF86DRISAREARec)); - grDRIOpen(driScrnPriv->pFB, sPriv->regs.map, sPriv->deviceID, - sPriv->width, sPriv->height, sPriv->mem, sPriv->cpp, sPriv->stride, - sPriv->fifoOffset, sPriv->fifoSize, sPriv->fbOffset, - sPriv->backOffset, sPriv->depthOffset, sPriv->textureOffset, - sPriv->textureSize, &saPriv->fifoPtr, &saPriv->fifoRead); - - driContextPriv->driverPrivate = (void *) cPriv; - - return GL_TRUE; + fxMesaContext fxMesa; + __DRIscreenPrivate *driScrnPriv = driContextPriv->driScreenPriv; + tdfxScreenPrivate *sPriv = (tdfxScreenPrivate *) driScrnPriv->private; + TDFXSAREAPriv *saPriv; + + fxMesa = (fxMesaContext) Xmalloc(sizeof(struct tfxMesaContext)); + if (!fxMesa) { + return GL_FALSE; + } + + fxMesa->hHWContext = driContextPriv->hHWContext; + fxMesa->tdfxScrnPriv = sPriv; + /* deviceID = 0x05 = Voodoo3 */ + /* deviceID = 0x09 = Voodoo5 (and Voodoo4?) */ + fxMesa->isNapalm = sPriv->deviceID == PCI_CHIP_VOODOO5; + fxMesa->haveHwStencil = fxMesa->isNapalm && sPriv->cpp == 4; + + + fxMesa->glVis = mesaVis; + fxMesa->screen_width = sPriv->width; + fxMesa->screen_height = sPriv->height; + fxMesa->new_state = ~0; + fxMesa->driContextPriv = driContextPriv; + fxMesa->glCtx = driContextPriv->mesaContext; + fxMesa->initDone = GL_FALSE; + + saPriv = + (TDFXSAREAPriv *) ((char *) driScrnPriv->pSAREA + + sizeof(XF86DRISAREARec)); + grDRIOpen(driScrnPriv->pFB, sPriv->regs.map, sPriv->deviceID, + sPriv->width, sPriv->height, sPriv->mem, sPriv->cpp, + sPriv->stride, sPriv->fifoOffset, sPriv->fifoSize, + sPriv->fbOffset, sPriv->backOffset, sPriv->depthOffset, + sPriv->textureOffset, sPriv->textureSize, &saPriv->fifoPtr, + &saPriv->fifoRead); + + driContextPriv->driverPrivate = (void *) fxMesa; + + return GL_TRUE; } -void XMesaDestroyContext(__DRIcontextPrivate *driContextPriv) + +void +XMesaDestroyContext(__DRIcontextPrivate * driContextPriv) { - tdfxContextPrivate *cPriv = (tdfxContextPrivate *) driContextPriv->driverPrivate; - if (cPriv) { - XFree(cPriv); - driContextPriv->driverPrivate = NULL; - } - - if (driContextPriv == gCC) { - gCC = 0; - } + fxMesaContext fxMesa = (fxMesaContext) driContextPriv->driverPrivate; + if (fxMesa) { + XFree(fxMesa); + driContextPriv->driverPrivate = NULL; + } } -GLframebuffer *XMesaCreateWindowBuffer( Display *dpy, - __DRIscreenPrivate *driScrnPriv, - __DRIdrawablePrivate *driDrawPriv, - GLvisual *mesaVis) +GLframebuffer * +XMesaCreateWindowBuffer(Display * dpy, + __DRIscreenPrivate * driScrnPriv, + __DRIdrawablePrivate * driDrawPriv, + GLvisual * mesaVis) { - return gl_create_framebuffer(mesaVis, - GL_FALSE, /* software depth buffer? */ - mesaVis->StencilBits > 0, - mesaVis->AccumRedBits > 0, - GL_FALSE /* software alpha channel? */ - ); + return gl_create_framebuffer(mesaVis, + GL_FALSE, /* software depth buffer? */ + mesaVis->StencilBits > 0, + mesaVis->AccumRedBits > 0, + GL_FALSE /* software alpha channel? */ + ); } -GLframebuffer *XMesaCreatePixmapBuffer( Display *dpy, - __DRIscreenPrivate *driScrnPriv, - __DRIdrawablePrivate *driDrawPriv, - GLvisual *mesaVis) +GLframebuffer * +XMesaCreatePixmapBuffer(Display * dpy, + __DRIscreenPrivate * driScrnPriv, + __DRIdrawablePrivate * driDrawPriv, + GLvisual * mesaVis) { #if 0 - /* Different drivers may have different combinations of hardware and - * software ancillary buffers. - */ - return gl_create_framebuffer(mesaVis, - GL_FALSE, /* software depth buffer? */ - mesaVis->StencilBits > 0, - mesaVis->AccumRedBits > 0, - mesaVis->AlphaBits > 0 - ); + /* Different drivers may have different combinations of hardware and + * software ancillary buffers. + */ + return gl_create_framebuffer(mesaVis, + GL_FALSE, /* software depth buffer? */ + mesaVis->StencilBits > 0, + mesaVis->AccumRedBits > 0, + mesaVis->AlphaBits > 0); #else - return NULL; /* not implemented yet */ + return NULL; /* not implemented yet */ #endif } -void XMesaSwapBuffers(__DRIdrawablePrivate *driDrawPriv) +void +XMesaSwapBuffers(__DRIdrawablePrivate * driDrawPriv) { - FxI32 result; + GET_CURRENT_CONTEXT(ctx); + fxMesaContext fxMesa = 0; + + if (!driDrawPriv->mesaBuffer->Visual->DBflag) + return; /* can't swap a single-buffered window */ + + /* If the current context's drawable matches the given drawable + * we have to do a glFinish (per the GLX spec). + */ + if (ctx) { + __DRIdrawablePrivate *curDrawPriv; + fxMesa = FX_CONTEXT(ctx); + curDrawPriv = fxMesa->driContextPriv->driDrawablePriv; + if (curDrawPriv == driDrawPriv) { + /* swapping window bound to current context, flush first */ + FLUSH_VB(ctx, "swap buffers"); + BEGIN_BOARD_LOCK(fxMesa); + } + else { + /* make fxMesa context current */ + grGlideGetState((GrState *) fxMesa->state); + fxMesa = (fxMesaContext) driDrawPriv->driContextPriv->driverPrivate; + BEGIN_BOARD_LOCK(fxMesa); + grSstSelect(fxMesa->board); + grGlideSetState((GrState *) fxMesa->state); + } + } + + #ifdef STATS - int stalls; - extern int texSwaps; - static int prevStalls=0; + { + int stalls; + static int prevStalls = 0; + stalls = grFifoGetStalls(); + if (stalls != prevStalls) { + fprintf(stderr, "%d stalls occurred\n", stalls - prevStalls); + prevStalls = stalls; + } + if (texSwaps) { + fprintf(stderr, "%d texture swaps occurred\n", texSwaps); + texSwaps = 0; + } + } #endif - tdfxContextPrivate *gCCPriv; - /* - ** NOT_DONE: This assumes buffer is currently bound to a context. - ** This needs to be able to swap buffers when not currently bound. - */ - if (gCC == NULL) - return; - gCCPriv = (tdfxContextPrivate *) gCC->driverPrivate; + /* XXX prototype grDRISwapClipRects() function may not be + * needed after all + */ +#if 0 + FX_grDRIBufferSwap(fxMesa, fxMesa->swapInterval); +#elif 1 + grDRIBufferSwap(fxMesa->swapInterval); +#else + grDRISwapClipRects(fxMesa->swapInterval, + driDrawPriv->numClipRects, + driDrawPriv->pClipRects); +#endif - FLUSH_VB( gCCPriv->glCtx, "swap buffers" ); - if (gCC->mesaContext->Visual->DBflag) { -#ifdef STATS - stalls=grFifoGetStalls(); - if (stalls!=prevStalls) { - fprintf(stderr, "%d stalls occurred\n", stalls-prevStalls); - prevStalls=stalls; - } - if (texSwaps) { - fprintf(stderr, "%d texture swaps occurred\n", texSwaps); - texSwaps=0; +#if 0 + { + FxI32 result; + do { + result = FX_grGetInteger(FX_PENDING_BUFFERSWAPS); + } while (result > fxMesa->maxPendingSwapBuffers); } #endif - FX_grDRIBufferSwap(gCCPriv->swapInterval); - do { - result = FX_grGetInteger(FX_PENDING_BUFFERSWAPS); - } while (result > gCCPriv->maxPendingSwapBuffers); - gCCPriv->stats.swapBuffer++; - } -} + fxMesa->stats.swapBuffer++; -GLboolean XMesaUnbindContext(__DRIcontextPrivate *driContextPriv) -{ - if (driContextPriv && driContextPriv == gCC) { - tdfxContextPrivate *gCCPriv; - gCCPriv = (tdfxContextPrivate *) gCC->driverPrivate; - FX_grGlideGetState((GrState*)gCCPriv->state); - } - return GL_TRUE; + + if (ctx) { + if (ctx->DriverCtx != fxMesa) { + /* restore original context */ + fxMesa = FX_CONTEXT(ctx); + grSstSelect(fxMesa->board); + grGlideSetState((GrState *) fxMesa->state); + } + END_BOARD_LOCK(fxMesa); + } } -GLboolean XMesaMakeCurrent(__DRIcontextPrivate *driContextPriv, - __DRIdrawablePrivate *driDrawPriv, - __DRIdrawablePrivate *driReadPriv) + +GLboolean +XMesaUnbindContext(__DRIcontextPrivate * driContextPriv) { - if (driContextPriv) { - tdfxContextPrivate *gCCPriv; + GET_CURRENT_CONTEXT(ctx); + if (driContextPriv && driContextPriv->mesaContext == ctx) { + fxMesaContext fxMesa = FX_CONTEXT(ctx); + FX_grGlideGetState(fxMesa, (GrState *) fxMesa->state); + } + return GL_TRUE; +} - gCC = driContextPriv; - gCCPriv = (tdfxContextPrivate *)driContextPriv->driverPrivate; - if (!gCCPriv->initDone) { - if (!tdfxInitHW(driDrawPriv, gCCPriv)) - return GL_FALSE; - gCCPriv->width=0; - XMesaWindowMoved(); - FX_grGlideGetState((GrState*)gCCPriv->state); +/* + * This function sends the window position and cliprect list to + * Glide for the given context. + */ +static void +XMesaWindowMoved(fxMesaContext fxMesa) +{ + __DRIdrawablePrivate *dPriv = fxMesa->driContextPriv->driDrawablePriv; + GLcontext *ctx = fxMesa->glCtx; + + grDRIPosition(dPriv->x, dPriv->y, dPriv->w, dPriv->h, + dPriv->numClipRects, dPriv->pClipRects); + fxMesa->numClipRects = dPriv->numClipRects; + fxMesa->pClipRects = dPriv->pClipRects; + if (dPriv->x != fxMesa->x_offset || dPriv->y != fxMesa->y_offset || + dPriv->w != fxMesa->width || dPriv->h != fxMesa->height) { + fxMesa->x_offset = dPriv->x; + fxMesa->y_offset = dPriv->y; + fxMesa->width = dPriv->w; + fxMesa->height = dPriv->h; + fxMesa->y_delta = + fxMesa->screen_height - fxMesa->y_offset - fxMesa->height; } - else { - FX_grSstSelect(gCCPriv->board); - FX_grGlideSetState((GrState*)gCCPriv->state); - XMesaWindowMoved(); + switch (dPriv->numClipRects) { + case 0: + fxMesa->clipMinX = dPriv->x; + fxMesa->clipMaxX = dPriv->x + dPriv->w; + fxMesa->clipMinY = dPriv->y; + fxMesa->clipMaxY = dPriv->y + dPriv->h; + fxSetScissorValues(ctx); + fxMesa->needClip = 0; + break; + case 1: + fxMesa->clipMinX = dPriv->pClipRects[0].x1; + fxMesa->clipMaxX = dPriv->pClipRects[0].x2; + fxMesa->clipMinY = dPriv->pClipRects[0].y1; + fxMesa->clipMaxY = dPriv->pClipRects[0].y2; + fxSetScissorValues(ctx); + fxMesa->needClip = 0; + break; + default: + fxMesa->needClip = 1; } - - gl_make_current2(gCCPriv->glCtx, driDrawPriv->mesaBuffer, driReadPriv->mesaBuffer); - - fxSetupDDPointers(gCCPriv->glCtx); - if (!gCCPriv->glCtx->Viewport.Width) - gl_Viewport(gCCPriv->glCtx, 0, 0, driDrawPriv->w, driDrawPriv->h); - } - else { - gl_make_current(0,0); - gCC = NULL; - } - return GL_TRUE; } -void XMesaWindowMoved(void) +GLboolean +XMesaMakeCurrent(__DRIcontextPrivate * driContextPriv, + __DRIdrawablePrivate * driDrawPriv, + __DRIdrawablePrivate * driReadPriv) { - __DRIdrawablePrivate *dPriv = gCC->driDrawablePriv; - tdfxContextPrivate *gCCPriv = (tdfxContextPrivate *) gCC->driverPrivate; - GLcontext *ctx = gCCPriv->glCtx; - - grDRIPosition(dPriv->x, dPriv->y, dPriv->w, dPriv->h, - dPriv->numClipRects, dPriv->pClipRects); - gCCPriv->numClipRects=dPriv->numClipRects; - gCCPriv->pClipRects=dPriv->pClipRects; - if (dPriv->x!=gCCPriv->x_offset || dPriv->y!=gCCPriv->y_offset || - dPriv->w!=gCCPriv->width || dPriv->h!=gCCPriv->height) { - gCCPriv->x_offset=dPriv->x; - gCCPriv->y_offset=dPriv->y; - gCCPriv->width=dPriv->w; - gCCPriv->height=dPriv->h; - gCCPriv->y_delta=gCCPriv->screen_height-gCCPriv->y_offset-gCCPriv->height; - } - gCCPriv->needClip=1; - switch (dPriv->numClipRects) { - case 0: - gCCPriv->clipMinX=dPriv->x; - gCCPriv->clipMaxX=dPriv->x+dPriv->w; - gCCPriv->clipMinY=dPriv->y; - gCCPriv->clipMaxY=dPriv->y+dPriv->h; - fxSetScissorValues(ctx); - gCCPriv->needClip=0; - break; - case 1: - gCCPriv->clipMinX=dPriv->pClipRects[0].x1; - gCCPriv->clipMaxX=dPriv->pClipRects[0].x2; - gCCPriv->clipMinY=dPriv->pClipRects[0].y1; - gCCPriv->clipMaxY=dPriv->pClipRects[0].y2; - fxSetScissorValues(ctx); - gCCPriv->needClip=0; - break; - default: - } + if (driContextPriv) { + fxMesaContext fxMesa; + + fxMesa = (fxMesaContext) driContextPriv->driverPrivate; + + if (!fxMesa->initDone) { + if (!tdfxInitHW(driDrawPriv, fxMesa)) + return GL_FALSE; + fxMesa->width = 0; + XMesaWindowMoved(fxMesa); + FX_grGlideGetState(fxMesa, (GrState *) fxMesa->state); + } + else { + FX_grSstSelect(fxMesa, fxMesa->board); + FX_grGlideSetState(fxMesa, (GrState *) fxMesa->state); + XMesaWindowMoved(fxMesa); + } + + assert(fxMesa->glCtx == driContextPriv->mesaContext); + + gl_make_current2(fxMesa->glCtx, driDrawPriv->mesaBuffer, + driReadPriv->mesaBuffer); + + if (!fxMesa->glCtx->Viewport.Width) + gl_Viewport(fxMesa->glCtx, 0, 0, driDrawPriv->w, driDrawPriv->h); + } + else { + gl_make_current(0, 0); + } + return GL_TRUE; } + /* This is called from within the LOCK_HARDWARE routine */ -void XMesaUpdateState(int windowMoved) +void +XMesaUpdateState(fxMesaContext fxMesa) { - __DRIdrawablePrivate *dPriv = gCC->driDrawablePriv; - __DRIscreenPrivate *sPriv = dPriv->driScreenPriv; - tdfxContextPrivate *gCCPriv = (tdfxContextPrivate *) gCC->driverPrivate; - TDFXSAREAPriv *saPriv=(TDFXSAREAPriv*)(((char*)sPriv->pSAREA)+sizeof(XF86DRISAREARec)); - - /* fprintf(stderr, "In FifoPtr=%d FifoRead=%d\n", saPriv->fifoPtr, saPriv->fifoRead); */ - if (saPriv->fifoOwner!=dPriv->driContextPriv->hHWContext) { - grDRIImportFifo(saPriv->fifoPtr, saPriv->fifoRead); - } - if (saPriv->ctxOwner!=dPriv->driContextPriv->hHWContext) { - /* This sequence looks a little odd. Glide mirrors the state, and - when you get the state you are forcing the mirror to be up to - date, and then getting a copy from the mirror. You can then force - that state onto the hardware when you set the state. */ - void *state; - state=malloc(FX_grGetInteger_NoLock(FX_GLIDE_STATE_SIZE)); - FX_grGlideGetState_NoLock(state); - FX_grGlideSetState_NoLock(state); - free(state); - } - if (saPriv->texOwner!=dPriv->driContextPriv->hHWContext) { - fxTMRestoreTextures_NoLock(gCCPriv); - } - if (windowMoved) - XMesaWindowMoved(); + __DRIcontextPrivate *cPriv = fxMesa->driContextPriv; + __DRIdrawablePrivate *dPriv = cPriv->driDrawablePriv; + __DRIscreenPrivate *sPriv = dPriv->driScreenPriv; + TDFXSAREAPriv *saPriv = (TDFXSAREAPriv *) (((char *) sPriv->pSAREA) + + sizeof(XF86DRISAREARec)); + int stamp; + char ret; + + DEBUG_CHECK_LOCK(); + DRM_CAS(&sPriv->pSAREA->lock, dPriv->driContextPriv->hHWContext, + DRM_LOCK_HELD | dPriv->driContextPriv->hHWContext, ret); + if (!ret) { + DEBUG_LOCK(); + return; + } + drmGetLock(sPriv->fd, dPriv->driContextPriv->hHWContext, 0); + stamp = dPriv->lastStamp; + /* This macro will update dPriv's cliprects if needed */ + XMESA_VALIDATE_DRAWABLE_INFO(cPriv->display, sPriv, dPriv); + /* fprintf(stderr, "In FifoPtr=%d FifoRead=%d\n", saPriv->fifoPtr, saPriv->fifoRead); */ + if (saPriv->fifoOwner != dPriv->driContextPriv->hHWContext) { + grDRIImportFifo(saPriv->fifoPtr, saPriv->fifoRead); + } + if (saPriv->ctxOwner != dPriv->driContextPriv->hHWContext) { + /* This sequence looks a little odd. Glide mirrors the state, and + when you get the state you are forcing the mirror to be up to + date, and then getting a copy from the mirror. You can then force + that state onto the hardware when you set the state. */ + void *state; + state = malloc(FX_grGetInteger_NoLock(FX_GLIDE_STATE_SIZE)); + FX_grGlideGetState_NoLock(state); + FX_grGlideSetState_NoLock(state); + free(state); + } + if (saPriv->texOwner != dPriv->driContextPriv->hHWContext) { + fxTMRestoreTextures_NoLock(fxMesa); + } +#if 0 + if (*dPriv->pStamp != stamp) +#else + if (*dPriv->pStamp != stamp || + saPriv->ctxOwner != dPriv->driContextPriv->hHWContext) +#endif + XMesaWindowMoved(fxMesa); + DEBUG_LOCK(); } -void XMesaSetSAREA(void) + +/* + * XXX is this used by anyone? + */ +#if 000 +static void +XMesaSetSAREA(void) { - __DRIdrawablePrivate *dPriv = gCC->driDrawablePriv; - __DRIscreenPrivate *sPriv = dPriv->driScreenPriv; - TDFXSAREAPriv *saPriv=(TDFXSAREAPriv*)(((char*)sPriv->pSAREA)+sizeof(XF86DRISAREARec)); - - saPriv->fifoOwner=dPriv->driContextPriv->hHWContext; - saPriv->ctxOwner=dPriv->driContextPriv->hHWContext; - saPriv->texOwner=dPriv->driContextPriv->hHWContext; - grDRIResetSAREA(); - /* fprintf(stderr, "Out FifoPtr=%d FifoRead=%d\n", saPriv->fifoPtr, saPriv->fifoRead); */ + __DRIdrawablePrivate *dPriv = gCC->driDrawablePriv; + __DRIscreenPrivate *sPriv = dPriv->driScreenPriv; + TDFXSAREAPriv *saPriv = + (TDFXSAREAPriv *) (((char *) sPriv->pSAREA) + + sizeof(XF86DRISAREARec)); + + saPriv->fifoOwner = dPriv->driContextPriv->hHWContext; + saPriv->ctxOwner = dPriv->driContextPriv->hHWContext; + saPriv->texOwner = dPriv->driContextPriv->hHWContext; + grDRIResetSAREA(); + /* fprintf(stderr, "Out FifoPtr=%d FifoRead=%d\n", saPriv->fifoPtr, saPriv->fifoRead); */ } +#endif + extern void __driRegisterExtensions(void); /* silence compiler warning */ @@ -406,17 +501,18 @@ extern void __driRegisterExtensions(void); /* silence compiler warning */ /* This function is called by libGL.so as soon as libGL.so is loaded. * This is where we'd register new extension functions with the dispatcher. */ -void __driRegisterExtensions(void) +void +__driRegisterExtensions(void) { #if 0 - /* Example. Also look in fxdd.c for more details. */ - { - const int _gloffset_FooBarEXT = 555; /* just an example number! */ - if (_glapi_add_entrypoint("glFooBarEXT", _gloffset_FooBarEXT)) { - void *f = glXGetProcAddressARB("glFooBarEXT"); - assert(f); - } - } + /* Example. Also look in fxdd.c for more details. */ + { + const int _gloffset_FooBarEXT = 555; /* just an example number! */ + if (_glapi_add_entrypoint("glFooBarEXT", _gloffset_FooBarEXT)) { + void *f = glXGetProcAddressARB("glFooBarEXT"); + assert(f); + } + } #endif } |