summaryrefslogtreecommitdiff
path: root/xc/lib/GL/mesa/src
diff options
context:
space:
mode:
authordawes <dawes>2000-11-07 22:09:49 +0000
committerdawes <dawes>2000-11-07 22:09:49 +0000
commitf93d27aa9ffc3e26ebb937ccd8dfe3319315c70c (patch)
tree4c21a480eb5dcca70013481c2f9e0873fa09ce6b /xc/lib/GL/mesa/src
parent0aaf69d45917298d83ad7ddf346914232987aa70 (diff)
Import of XFree86 4.0.1dX_4_0_1d
Diffstat (limited to 'xc/lib/GL/mesa/src')
-rw-r--r--xc/lib/GL/mesa/src/Imakefile37
-rw-r--r--xc/lib/GL/mesa/src/X86/Imakefile38
-rw-r--r--xc/lib/GL/mesa/src/drv/common/stenciltmp.h134
-rw-r--r--xc/lib/GL/mesa/src/drv/ffb/Imakefile4
-rw-r--r--xc/lib/GL/mesa/src/drv/ffb/ffb_vb.c12
-rw-r--r--xc/lib/GL/mesa/src/drv/gamma/Imakefile4
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/Imakefile7
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810_xmesa.c5
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810dd.c23
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810ioctl.h6
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810tris.c4
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810tris.h4
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810vb.c16
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/Imakefile23
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c110
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mga_xmesa.h6
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgabuffers.c29
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgacontext.h316
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgadd.c34
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgaeltpath.c44
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgafastpath.c7
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgaioctl.c63
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgaioctl.h14
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgapipeline.c4
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgaspan.c90
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgastate.c331
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgatex.c1686
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgatex.h69
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgatexcnv.c257
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgatexmem.c492
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgatris.c39
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgatris.h166
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgavb.c69
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgavb.h11
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/Imakefile7
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_tex.c25
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_texobj.h4
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_vb.c18
-rw-r--r--xc/lib/GL/mesa/src/drv/sis/Imakefile9
-rw-r--r--xc/lib/GL/mesa/src/drv/sis/sis_alloc.c16
-rw-r--r--xc/lib/GL/mesa/src/drv/sis/sis_clear.c1
-rw-r--r--xc/lib/GL/mesa/src/drv/sis/sis_common.h1
-rw-r--r--xc/lib/GL/mesa/src/drv/sis/sis_ctx.c1
-rw-r--r--xc/lib/GL/mesa/src/drv/sis/sis_ctx.h1
-rw-r--r--xc/lib/GL/mesa/src/drv/sis/sis_debug.c1
-rw-r--r--xc/lib/GL/mesa/src/drv/sis/sis_debug.h1
-rw-r--r--xc/lib/GL/mesa/src/drv/sis/sis_fastpath.c1
-rw-r--r--xc/lib/GL/mesa/src/drv/sis/sis_fog.c1
-rw-r--r--xc/lib/GL/mesa/src/drv/sis/sis_init.h1
-rw-r--r--xc/lib/GL/mesa/src/drv/sis/sis_linefunc.h1
-rw-r--r--xc/lib/GL/mesa/src/drv/sis/sis_lock.h1
-rw-r--r--xc/lib/GL/mesa/src/drv/sis/sis_mesa.c5
-rw-r--r--xc/lib/GL/mesa/src/drv/sis/sis_mesa.h1
-rw-r--r--xc/lib/GL/mesa/src/drv/sis/sis_reg.h1
-rw-r--r--xc/lib/GL/mesa/src/drv/sis/sis_render.c1
-rw-r--r--xc/lib/GL/mesa/src/drv/sis/sis_span.c3
-rw-r--r--xc/lib/GL/mesa/src/drv/sis/sis_stencil.c1
-rw-r--r--xc/lib/GL/mesa/src/drv/sis/sis_swzfunc.h1
-rw-r--r--xc/lib/GL/mesa/src/drv/sis/sis_texture.c14
-rw-r--r--xc/lib/GL/mesa/src/drv/sis/sis_trifunc.h1
-rw-r--r--xc/lib/GL/mesa/src/drv/sis/sis_xmesa.c1
-rw-r--r--xc/lib/GL/mesa/src/drv/sis/sis_xmesaP.h2
-rw-r--r--xc/lib/GL/mesa/src/drv/sis/sis_xwin.c1
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/Imakefile80
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/X86/fx_3dnow_fastpath.S84
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/X86/fx_3dnow_fasttmp.h314
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/fxclip.c537
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/fxcliptmp.h353
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/fxcva.c492
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/fxcva.h64
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/fxcvatmp.h278
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/fxdd.c1939
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/fxddspan.c2054
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/fxddtex.c1647
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/fxddtex.h99
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/fxdrv.h800
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/fxfastpath.c405
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/fxfasttmp.h363
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/fxglidew.c483
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/fxglidew.h987
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/fxpipeline.c293
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/fxpipeline.h16
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/fxrender.c780
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/fxsanity.c110
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/fxsdettmp.h154
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/fxsetup.c2077
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/fxsetup.h35
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/fxstripdet.c161
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/fxtexman.c845
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/fxtexman.h29
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/fxtrifuncs.c365
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/fxtritmp.h446
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/fxvs_tmp.h215
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/fxvsetup.c578
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/fxvsetup.h198
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/tdfx_init.c83
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/tdfx_inithw.c83
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/tdfx_xmesa.c690
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
}