summaryrefslogtreecommitdiff
path: root/xc/extras/Mesa/src/FX
diff options
context:
space:
mode:
Diffstat (limited to 'xc/extras/Mesa/src/FX')
-rw-r--r--xc/extras/Mesa/src/FX/X86/fx_3dnow_fastpath.S82
-rw-r--r--xc/extras/Mesa/src/FX/X86/fx_3dnow_fasttmp.h325
-rw-r--r--xc/extras/Mesa/src/FX/fxapi.c1428
-rw-r--r--xc/extras/Mesa/src/FX/fxclip.c554
-rw-r--r--xc/extras/Mesa/src/FX/fxcliptmp.h346
-rw-r--r--xc/extras/Mesa/src/FX/fxcva.c513
-rw-r--r--xc/extras/Mesa/src/FX/fxcva.h70
-rw-r--r--xc/extras/Mesa/src/FX/fxcvatmp.h262
-rw-r--r--xc/extras/Mesa/src/FX/fxdd.c1189
-rw-r--r--xc/extras/Mesa/src/FX/fxddspan.c642
-rw-r--r--xc/extras/Mesa/src/FX/fxddtex.c1197
-rw-r--r--xc/extras/Mesa/src/FX/fxdrv.h686
-rw-r--r--xc/extras/Mesa/src/FX/fxfastpath.c425
-rw-r--r--xc/extras/Mesa/src/FX/fxfasttmp.h367
-rw-r--r--xc/extras/Mesa/src/FX/fxglidew.c451
-rw-r--r--xc/extras/Mesa/src/FX/fxglidew.h845
-rw-r--r--xc/extras/Mesa/src/FX/fxpipeline.c302
-rw-r--r--xc/extras/Mesa/src/FX/fxrender.c785
-rw-r--r--xc/extras/Mesa/src/FX/fxsanity.c124
-rw-r--r--xc/extras/Mesa/src/FX/fxsdettmp.h161
-rw-r--r--xc/extras/Mesa/src/FX/fxsetup.c1858
-rw-r--r--xc/extras/Mesa/src/FX/fxstripdet.c164
-rw-r--r--xc/extras/Mesa/src/FX/fxtexman.c747
-rw-r--r--xc/extras/Mesa/src/FX/fxtrifuncs.c372
-rw-r--r--xc/extras/Mesa/src/FX/fxtritmp.h475
-rw-r--r--xc/extras/Mesa/src/FX/fxvs_tmp.h215
-rw-r--r--xc/extras/Mesa/src/FX/fxvsetup.c576
-rw-r--r--xc/extras/Mesa/src/FX/fxvsetup.h199
-rw-r--r--xc/extras/Mesa/src/FX/fxwgl.c870
29 files changed, 16230 insertions, 0 deletions
diff --git a/xc/extras/Mesa/src/FX/X86/fx_3dnow_fastpath.S b/xc/extras/Mesa/src/FX/X86/fx_3dnow_fastpath.S
new file mode 100644
index 000000000..e032942be
--- /dev/null
+++ b/xc/extras/Mesa/src/FX/X86/fx_3dnow_fastpath.S
@@ -0,0 +1,82 @@
+#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) CONCAT(x,_RGBA)
+#include "fx_3dnow_fasttmp.h"
+
+#define SIZE 6
+#define TYPE (SETUP_TMU0)
+#define TAG(x) CONCAT(x,_TMU0)
+#include "fx_3dnow_fasttmp.h"
+
+#define SIZE 8
+#define TYPE (SETUP_TMU0|SETUP_TMU1)
+#define TAG(x) CONCAT(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) CONCAT(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) CONCAT(x,_RGBA_TMU0)
+#include "fx_3dnow_fasttmp.h"
+
+#define SIZE 12
+#define TYPE (SETUP_RGBA|SETUP_TMU0|SETUP_TMU1)
+#define TAG(x) CONCAT(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) CONCAT(x,_RGBA_TMU1)
+#include "fx_3dnow_fasttmp.h"
+
+
diff --git a/xc/extras/Mesa/src/FX/X86/fx_3dnow_fasttmp.h b/xc/extras/Mesa/src/FX/X86/fx_3dnow_fasttmp.h
new file mode 100644
index 000000000..fff802dd6
--- /dev/null
+++ b/xc/extras/Mesa/src/FX/X86/fx_3dnow_fasttmp.h
@@ -0,0 +1,325 @@
+
+ SEG_TEXT
+
+#if !defined(NASM_ASSEMBLER) && !defined(MASM_ASSEMBLER)
+#define _TAGLLBL(a) CONCAT(.L,a)
+#define TAGLLBL(a) _TAGLLBL(TAG(a))
+#else
+#define TAGLLBL(a) TAG(a)
+#endif
+
+#define TAG_GLNAME(x) TAG( GLNAME(x) )
+
+
+
+#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.
+ */
+
+ALIGNTEXT16
+GLOBL TAG_GLNAME( fx_3dnow_project_vertices )
+TAG_GLNAME( 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 )
+ *
+ */
+
+ALIGNTEXT16
+GLOBL TAG_GLNAME( fx_3dnow_project_clipped_vertices )
+TAG_GLNAME( 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
+#undef _TAGLLBL
+#undef TAGLLBL
+#undef TAG_GLNAME
+
diff --git a/xc/extras/Mesa/src/FX/fxapi.c b/xc/extras/Mesa/src/FX/fxapi.c
new file mode 100644
index 000000000..ec956958f
--- /dev/null
+++ b/xc/extras/Mesa/src/FX/fxapi.c
@@ -0,0 +1,1428 @@
+/* -*- mode: C; tab-width:8; -*- */
+
+/*
+ * 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.
+ */
+
+
+/* fxapi.c - 3Dfx VooDoo/Mesa interface */
+
+
+/********************************************************************
+ *
+ * Function names:
+ * fxMesa.... (The driver API)
+ * fxDD.... (Mesa device driver functions)
+ * fxTM.... (Texture manager functions)
+ * fxSetup.... (Voodoo units setup functions)
+ * fx.... (Internal driver functions)
+ *
+ * Data type names:
+ * fxMesa.... (Public driver data types)
+ * tfx.... (Private driver data types)
+ *
+ ********************************************************************
+ *
+ * V0.30 - David Bucciarelli (davibu@tin.it) Humanware s.r.l.
+ * - introduced a new MESA_GLX_FX related behavior
+ * - the Glide fog table was built in a wrong way (using
+ * gu* Glide function). Added the code for building the
+ * table following the OpenGL specs. Thanks to Steve Baker
+ * for highlighting the problem.
+ * - fixed few problems in my and Keith's fxDDClear code
+ * - merged my code with the Keith's one
+ * - used the new BlendFunc Mesa device driver function
+ * - used the new AlphaFunc Mesa device driver function
+ * - used the new Enable Mesa device driver function
+ * - fixed a bug related to fog in the Mesa core. Fog
+ * were applied two times: at vertex level and at fragment
+ * level (thanks to Steve Baker for reporting the problem)
+ * - glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE) now works
+ * (thanks to Jiri Pop for reporting the problem)
+ * - the driver works fine with OpenGL Unreal
+ * - fixed a bug in the Mesa core clipping code (related
+ * to the q texture coordinate)
+ * - introduced the support for the q texture coordinate
+ *
+ * Keith Whitwell (keithw@cableinet.co.uk)
+ * - optimized the driver and written all the new code
+ * required by the new Mesa-3.1 device driver API
+ * and by the new Mesa-3.1 core changes
+ * - written the cva support and many other stuff
+ *
+ * Brian Paul (brian_paul@avid.com) Avid Technology
+ * - fixed display list share bug for MESA_GLX_FX = window/fullscreen
+ * - fixed glClear/gl...Mask related problem
+ *
+ * Bert Schoenwaelder (bert@prinz-atm.CS.Uni-Magdeburg.De)
+ * - the driver is now able to sleep when waiting for the completation
+ * of multiple swapbuffer operations instead of wasting
+ * CPU time (NOTE: you must uncomment the lines in the
+ * fxMesaSwapBuffers function in order to enable this option)
+ *
+ * Eero Pajarre (epajarre@koti.tpo.fi)
+ * - enabled the macro FLOAT_COLOR_TO_UBYTE_COLOR under
+ * windows
+ * - written an asm x86 optimized float->integer conversions
+ * for windows
+ *
+ * Theodore Jump (tjump@cais.com)
+ * - fixed a small problem in the __wglMonitor function of the
+ * wgl emulator
+ * - written the in-window-rendering hack support for windows
+ * and Vooodoo1/2 cards
+ *
+ * V0.29 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
+ * - included in Mesa-3.0
+ * - now glGetString(GL_RENDERER) returns more information
+ * about the hardware configuration: "Mesa Glide <version>
+ * <Voodoo_Graphics|Voodoo_Rush|UNKNOWN> <num> CARD/<num> FB/
+ * <num> TM/<num> TMU/<NOSLI|SLI>"
+ * where: <num> CARD is the card used for the current context,
+ * <num> FB is the number of MB for the framebuffer,
+ * <num> TM is the number of MB for the texture memory,
+ * <num> TMU is the number of TMU. You can try to run
+ * Mesa/demos/glinfo in order to have an example of the
+ * output
+ * - fixed a problem of the WGL emulator with the
+ * OpenGL Optimizer 1.1 (thanks to Erwin Coumans for
+ * the bug report)
+ * - fixed some bug in the fxwgl.c code (thanks to
+ * Peter Pettersson for a patch and a bug report)
+ *
+ * Theodore Jump (tjump@cais.com)
+ * - written the SST_DUALHEAD support in the WGL emulator
+ *
+ * Daryll Strauss (daryll@harlot.rb.ca.us)
+ * - fixed the Voodoo Rush support for the in window rendering
+ *
+ * V0.28 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
+ * - the only supported multitexture functions are GL_MODULATE
+ * for texture set 0 and GL_MODULATE for texture set 1. In
+ * all other cases, the driver falls back to pure software
+ * rendering
+ * - written the support for the new GL_EXT_multitexture
+ * - written the DD_MAX_TEXTURE_COORD_SETS support in the
+ * fxDDGetParameteri() function
+ * - the driver falls back to pure software rendering when
+ * texture mapping function is GL_BLEND
+ *
+ * V0.27 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
+ * - inluded in the Mesa-3.0beta5
+ * - written a smal extension (GL_FXMESA_global_texture_lod_bias) in
+ * order to expose the LOD bias related Glide function
+ * - fixed a bug fxDDWriteMonoRGBAPixels()
+ * - the driver is now able to fallback to software rendering in
+ * any case not directly supported by the hardware
+ * - written the support for enabling/disabling dithering
+ * - the in-window-rendering hack now works with any X11 screen
+ * depth
+ * - fixed a problem related to color/depth/alpha buffer clears
+ * - fixed a problem when clearing buffer for a context with the
+ * alpha buffer
+ * - fixed a problem in the fxTMReloadSubMipMapLevel() function,
+ * I have forget a "break;" (thanks to Joe Waters for the bug report)
+ * - fixed a problem in the color format for the in window
+ * rendering hack
+ * - written the fxDDReadRGBAPixels function
+ * - written the fxDDDepthTestPixelsGeneric function
+ * - written the fxDDDepthTestSpanGeneric function
+ * - written the fxDDWriteMonoRGBAPixels function
+ * - written the fxDDWriteRGBAPixels function
+ * - removed the multitexture emulation code for Voodoo board
+ * with only one TMU
+ *
+ * Chris Prince <cprince@cs.washington.edu>
+ * - fixed a new bug in the wglUseFontBitmaps code
+ *
+ * Ralf Knoesel (rknoesel@Stormfront.com)
+ * - fixed a bug in the wglUseFontBitmaps code
+ *
+ * Rune Hasvold (runeh@ifi.uio.no)
+ * - fixed a problem related to the aux usage in the fxBestResolution
+ * function
+ * - fixed the order of pixel formats in the WGL emulator
+ *
+ * Fredrik Hubinette (hubbe@hubbe.net)
+ * - the driver shutdown the Glide for most common signals
+ *
+ * V0.26 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
+ * - included in the Mesa-3.0beta4
+ * - fixed a problem related to a my optimization for the Rune's
+ * pixel-span optimization
+ * - fixed a problem related to fxDDSetNearFar() and ctx->ProjectionMatrixType
+ * (thanks to Ben "Ctrl-Alt-Delete" and the Raul Alonso's ssystem)
+ * - fixed a small bug in the Rune's pixel-span optimization
+ * - fixed a problem with GL_CCW (thanks to Curt Olson for and example
+ * of the problem)
+ * - grVertex setup code is now ready for the internal thread support
+ * - fixed a no used optimization with clipped vertices in
+ * grVertex setup code
+ * - fixed a problem in the GL_LIGHT_MODEL_TWO_SIDE support (thanks
+ * to Patrick H. Madden for a complete example of the bug)
+ *
+ * Rune Hasvold (runeh@ifi.uio.no)
+ * - highly optimized the driver functions for writing pixel
+ * span (2-3 times faster !)
+ *
+ * Axel W. Volley (volley@acm.org) Krauss-Maffei Wehrtechnik
+ * - written the fxDDReadDepthSpanFloat() and fxDDReadDepthSpanInt()
+ * functions
+ *
+ * V0.25 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
+ * - fixed a problem with Voodoo boards with only one TMU
+ * - fixed a bug in the fxMesaCreateContext()
+ * - now the GL_FRONT_AND_BACK works fine also with
+ * the alpha buffer and/or antialiasing
+ * - written the support for GL_FRONT_AND_BACK drawing but
+ * it doesn't works with the alpha buffer and/or antialiasing
+ * - fixed some bug in the Mesa core for glCopyTexSubImage
+ * and glCopyTexImage functions (thanks to Mike Connell
+ * for an example of the problem)
+ * - make some small optimizations in the Mesa core in order
+ * to save same driver call and state change for not very
+ * well written applications
+ * - introduced the NEW_DRVSTATE and make other optimizations
+ * for minimizing state changes
+ * - made a lot of optimizations in order to minimize state
+ * changes
+ * - it isn't more possible to create a context with the
+ * depth buffer and the stancil buffer (it isn't yet supported)
+ * - now the partial support for the Multitexture extension
+ * works with Quake2 for windows
+ * - vertex snap is not longer used for the Voodoo2 (FX_V2
+ * must be defined)
+ * - done a lot of cleanup in the fxsetup.c file
+ * - now the partial support for the Multitexture extension
+ * works with GLQuake for windows
+ *
+ * Dieter Nuetzel (nuetzel@kogs.informatik.uni-hamburg.de) University of Hamburg
+ * - fixed a problem in the asm code for Linux of the fxvsetup.c file
+ * highlighted by the binutils-2.8.1.0.29. 'fildw' asm instruction
+ * changed in 'fild'
+ *
+ * Kevin Hester (kevinh@glassworks.net)
+ * - written the wglUseFontBitmaps() function in the WGL emulator
+ *
+ * V0.24 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
+ * - now the drive always uses per fragment fog
+ * - written a small optimization in the points drawing function
+ * - written the support for trilinear filtering with 2 TMUs
+ * - written the first partial support for the Multitexture extension.
+ * This task is quite hard because the color combine units work after
+ * the two texture combine units and not before as required by the
+ * Multitexture extension
+ * - written a workaround in fxBestResolution() in order to solve a
+ * problem with bzflag (it asks for 1x1 window !)
+ * - changed the fxBestResolution() behavior. It now returns the larger
+ * screen resolution supported by the hardware (instead of 640x480)
+ * when it is unable to find an appropriate resolution that is large
+ * enough for the requested size
+ * - the driver is now able to use also the texture memory attached to
+ * second TMU
+ * - the texture memory manager is now able to work with two TMUs and
+ * store texture maps in the memory attached to TMU0, TMU1 or to split
+ * the mimpmap levels across TMUs in order to support trilinear filtering
+ * - I have bought a Voodoo2 board !
+ * - the amount of frambuffer ram is now doubled when an SLI configuration
+ * is detected
+ * - solved a problem related to the fxDDTexParam() and fxTexInvalidate()
+ * functions (thanks to Rune Hasvold for highlighting the problem)
+ * - done some cleanup in the fxvsetup.c file, written
+ * the FXVSETUP_FUNC macro
+ * - done a lot of cleanup in data types and field names
+ *
+ * Rune Hasvold (runeh@ifi.uio.no)
+ * - written the support for a right management of the auxiliary buffer.
+ * You can now use an 800x600 screen without the depth and alpha
+ * buffer
+ * - written the support for a new pixel format (without the depth
+ * and alpha buffer) in the WGL emulator
+ * - fixed a bug in the window version of the GLUT (it was ever asking
+ * for depth buffer)
+ *
+ * V0.23 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
+ * - included in the Mesa-3.0beta2 release
+ * - written the support for the OpenGL 1.2 GL_TEXTURE_BASE_LEVEL
+ * and GL_TEXTURE_MAX_LEVEL
+ * - rewritten several functions for a more clean support of texture
+ * mapping and in order to solve some bug
+ * - the accumulation buffer works (it is bit slow beacuase it requires
+ * to read/write from/to the Voodoo frame buffer but it works)
+ * - fixed a bug in the fxDDReadRGBASpan driver function (the R and
+ * B channels were read in the wrong order). Thanks to Jason Heym
+ * for highlighting the problem
+ * - written the support for multiple contexts on multiple boards.
+ * you can now use the Mesa/Voodoo with multiple Voodoo Graphics
+ * boards (for example with multiple screens or an HMD)
+ * - the fxBestResolution() now check all available resolutions
+ * and it is able to check the amount of framebuffer memory
+ * before return a resolution
+ * - modified the GLX/X11 driver in order to support all the
+ * resolution available
+ * - changed all function names. They should be now a bit more
+ * readable
+ * - written the Glide grVertex setup code for two TMU or
+ * for Multitexture support with emulationa dn one TMU
+ * - written the support for the new Mesa driver
+ * function GetParametri
+ * - small optimization/clean up in the texbind() function
+ * - fixed a FPU precision problem for glOrtho and texture
+ * mapping (thanks to Antti Juhani Huovilainen for an example
+ * of the problem)
+ * - written some small SGI OpenGL emulation code for the wgl,
+ * the OpenGL Optimizer and Cosmo3D work fine under windows !
+ * - moved the point/line/triangle/quad support in the fxmesa7.c
+ * - fixed a bug in the clear_color_depth() (thanks to Henk Kok
+ * for an example of the problem)
+ * - written a small workaround for Linux GLQuake, it asks
+ * for the alpha buffer and the depth buffer at the some time
+ * (but it never uses the alpha buffer)
+ * - checked the antialiasing points, lines and polygons support.
+ * It works fine
+ * - written the support for standard OpenGL antialiasing using
+ * blending. Lines support works fine (tested with BZflag)
+ * while I have still to check the polygons and points support
+ * - written the support for the alpha buffer. The driver is now
+ * able to use the Voodoo auxiliary buffer as an alpha buffer
+ * instead of a depth buffer. Also all the OpenGL blending
+ * modes are now supported. But you can't request a context
+ * with an alpha buffer AND a depth buffer at the some time
+ * (this is an hardware limitation)
+ * - written the support for switching between the fullscreen
+ * rendering and the in-window-rendering hack on the fly
+ *
+ * Rune Hasvold (runeh@ifi.uio.no)
+ * - fixed a bug in the texparam() function
+ *
+ * Brian Paul (brianp@elastic.avid.com) Avid Technology
+ * - sources accomodated for the new Mesa 3.0beta1
+ *
+ * V0.22 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
+ * - included with some v0.23 bug fix in the final release
+ * of the Mesa-2.6
+ * - written the support for the MESA_WGL_FX env. var. but
+ * not tested because I have only Voodoo Graphics boards
+ * - fixed a bug in the backface culling code
+ * (thanks to David Farrell for an example of the problem)
+ * - fixed the "Quake2 elevator" bug
+ * - GL_POLYGONS with 3/4 vertices are now drawn as
+ * GL_TRIANLGES/GL_QUADS (a small optimization for GLQuake)
+ * - fixed a bug in fxmesa6.h for GL_LINE_LOOP
+ * - fixed a NearFarStack bug in the Mesa when applications
+ * directly call glLoadMatrix to load a projection matrix
+ * - done some cleanup in the fxmesa2.c file
+ * - the driver no longer translates the texture maps
+ * when the Mesa internal format and the Voodoo
+ * format are the some (usefull for 1 byte texture maps
+ * where the driver can directly use the Mesa texture
+ * map). Also the amount of used memory is halfed
+ * - fixed a bug for GL_DECAL and GL_RGBA
+ * - fixed a bug in the clear_color_depth()
+ * - tested the v0.22 with the Mesa-2.6beta2. Impressive
+ * performances improvement thanks to the new Josh's
+ * asm code (+10fps in the isosurf demo, +5fps in GLQuake
+ * TIMEREFRESH)
+ * - written a optimized version of the RenderVB Mesa driver
+ * function. The Voodoo driver is now able to upload polygons
+ * in the most common cases at a very good speed. Good
+ * performance improvement for large set of small polygons
+ * - optimized the asm code for setting up the color information
+ * in the Glide grVertex structure
+ * - fixed a bug in the fxmesa2.c asm code (the ClipMask[]
+ * wasn't working)
+ *
+ * Josh Vanderhoof (joshv@planet.net)
+ * - removed the flush() function because it isn't required
+ * - limited the maximum number of swapbuffers in the Voodoo
+ * commands FIFO (controlled by the env. var. MESA_FX_SWAP_PENDING)
+ *
+ * Holger Kleemiss (holger.kleemiss@metronet.de) STN Atlas Elektronik GmbH
+ * - applied some patch for the Voodoo Rush
+ *
+ * V0.21 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
+ * - the driver is now able to take advantage of the ClipMask[],
+ * ClipOrMask and ClipAndMask information also under Windows
+ * - introduced a new function in the Mesa driver interface
+ * ClearColorAndDepth(). Now the glClear() function is
+ * 2 times faster (!) when you have to clear the color buffer
+ * and the depth buffer at some time
+ * - written the first version of the fxRenderVB() driver
+ * function
+ * - optimized the glTexImage() path
+ * - removed the fxMesaTextureUsePalette() support
+ * - fixed a bug in the points support (thanks to David Farrell
+ * for an example of the problem)
+ * - written the optimized path for glSubTexImage(),
+ * introduced a new function in the Mesa driver interface
+ * TexSubImage(...)
+ * - fixed a bug for glColorMask and glDepthMask
+ * - the wbuffer is not more used. The Voodoo driver uses
+ * a standard 16bit zbuffer in all cases. It is more consistent
+ * and now GLQuake and GLQuake2test work also with a GL_ZTRICK 0
+ * - the driver is now able to take advantage of the ClipMask[],
+ * ClipOrMask and ClipAndMask information (under Linux);
+ * - rewritten the setup_fx_units() function, now the texture
+ * mapping support is compliant to the OpenGL specs (GL_BLEND
+ * support is still missing). The LinuxGLQuake console correctly
+ * fade in/out and transparent water of GLQuake2test works fine
+ * - written the support for the env. var. FX_GLIDE_SWAPINTERVAL
+ * - found a bug in the Mesa core. There is a roundup problem for
+ * color values out of the [0.0,1.0] range
+ *
+ * Wonko <matt@khm.de>
+ * - fixed a Voodoo Rush related problem in the fxwgl.c
+ *
+ * Daryll Strauss <daryll@harlot.rb.ca.us>
+ * - written the scissor test support
+ *
+ * V0.20 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
+ * - written the closetmmanger() function in order to free all the memory
+ * allocated by the Texture Memory Manager (it will be useful
+ * when the support for multiple contexts/boards will be ready)
+ * - now the Voodoo driver runs without printing any information,
+ * define the env. var. MESA_FX_INFO if you want to read some
+ * information about the hardware and some statistic
+ * - written a small workaround for the "GLQuake multiplayer white box bug"
+ * in the setup_fx_units() funxtions. I'm already rewriting
+ * this function because it is the source of nearly all the current
+ * Voodoo driver problems
+ * - fixed the GLQuake texture misalignment problem (the texture
+ * coordinates must be scaled between 0.0 and 256.0 and not
+ * between 0.0 and 255.0)
+ * - written the support for the GL_EXT_shared_texture_palette
+ * - some small change for supporting the automatic building of the
+ * OpenGL32.dll under the Windows platform
+ * - the redefinition of a mipmap level is now a LOT faster. This path
+ * is used by GLQuake for dynamic lighting with some call to glTexSubImage2D()
+ * - the texture memory is now managed a set of 2MB blocks so
+ * texture maps can't be allocated on a 2MB boundary. The new Pure3D
+ * needs this kind of support (and probably any other Voodoo Graphics
+ * board with more than 2MB of texture memory)
+ *
+ * Brian Paul (brianp@elastic.avid.com) Avid Technology
+ * - added write_monocolor_span(), fixed bug in write_color_span()
+ * - added test for stenciling in choosepoint/line/triangle functions
+ *
+ * Joe Waters (falc@attila.aegistech.com) Aegis
+ * - written the support for the env. var. SST_SCREENREFRESH
+ *
+ * V0.19 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
+ * - written the 3Dfx Global Palette extension for GLQuake
+ * - written the support for the GL_EXT_paletted_texture (it works only with GL_RGBA
+ * palettes and the alpha value is ignored ... this is a limitation of the
+ * the current Glide version and Voodoo hardware)
+ * - fixed the amount of memory allocated for 8bit textures
+ * - merged the under construction v0.19 driver with the Mesa 2.5
+ * - finally written the support for deleting textures
+ * - introduced a new powerful texture memory manager: the texture memory
+ * is used as a cache of the set of all defined texture maps. You can
+ * now define several MB of texture maps also with a 2MB of texture memory
+ * (the texture memory manager will do automatically all the swap out/swap in
+ * work). The new texture memory manager has also
+ * solved a lot of other bugs/no specs compliance/problems
+ * related to the texture memory usage. The texture
+ * manager code is inside the new fxmesa3.c file
+ * - broken the fxmesa.c file in two files (fxmesa1.c and fxmesa2.c)
+ * and done some code cleanup
+ * - now is possible to redefine texture mipmap levels already defined
+ * - fixed a problem with the amount of texture memory allocated for textures
+ * with not all mipmap levels defined
+ * - fixed a small problem with single buffer rendering
+ *
+ * Brian Paul (brianp@elastic.avid.com) Avid Technology
+ * - read/write_color_span() now use front/back buffer correctly
+ * - create GLvisual with 5,6,5 bits per pixel, not 8,8,8
+ * - removed a few ^M characters from fxmesa2.c file
+ *
+ * V0.18 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
+ * - the Mesa-2.4beta3 is finally using the driver quads support (the
+ * previous Mesa versions have never taken any advantage from the quads support !)
+ * - tested with the Glide 2.4 for Win
+ * - ported all asm code to Linux
+ * - ported the v0.18 to Linux (without asm code)
+ * - back to Linux !!!
+ * - optimized the SETUP macro (no more vertex snap for points and lines)
+ * - optimized the SETUP macro (added one argument)
+ * - the Mesa/Voodoo is now 20/30% for points, lines and small triangles !
+ * - performance improvement setting VBSIZE to 72
+ * - the GrVertex texture code is now written in asm
+ * - the GrVertex zbuffer code is now written in asm
+ * - the GrVertex wbuffer code is now written in asm
+ * - the GrVertex gouraud code is now written in asm
+ * - the GrVertex snap code is now written in asm
+ * - changed the 8bit compressed texture maps in 8bit palette texture maps
+ * support (it has the some advantage of compressed texture maps without the
+ * problem of a fixed NCC table for all mipmap levels)
+ * - written the support for 8bit compressed texture maps (but texture maps with
+ * more than one mipmap level aren't working fine)
+ * - finnaly everthing is working fine in MesaQuake !
+ * - fixed a bug in the computation of texture mapping coordinates (I have found
+ * the bug thanks to MesaQuake !)
+ * - written the GL_REPLACE support (mainly for MesaQuake)
+ * - written the support for textures with not all mipmap levels defined
+ * - rewritten all the Texture memory stuff
+ * - written the MesaQuake support (define MESAQUAKE)
+ * - working with a ZBuffer if glOrtho or not int the default glDepthRange,
+ * otherwise working with the WBuffer
+ * written the glDepthRange support
+ *
+ * Diego Picciani (d.picciani@novacomp.it) Nova Computer s.r.l.
+ * - written the fxCloseHardware() and the fxQuaryHardware() (mainly
+ * for the VoodooWGL emulator)
+ *
+ * Brian Paul (brianp@elastic.avid.com) Avid Technology
+ * - implemented read/write_color_span() so glRead/DrawPixels() works
+ * - now needs Glide 2.3 or later. Removed GLIDE_FULL_SCREEN and call to grSstOpen()
+ *
+ * V0.17 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
+ * - optimized the bitmap support (66% faster)
+ * - tested with the Mesa 2.3beta2
+ *
+ * Diego Picciani (d.picciani@novacomp.it) Nova Computer s.r.l.
+ * - solved a problem with the drawbitmap() and the Voodoo Rush
+ * (GR_ORIGIN_LOWER_LEFT did not work with the Stingray)
+ *
+ * Brian Paul (brianp@elastic.avid.com) Avid Technology
+ * - linux stuff
+ * - general code clean-up
+ * - added attribList parameter to fxMesaCreateContext()
+ * - single buffering works now
+ * - VB colors are now GLubytes, removed ColorShift stuff
+ *
+ * Paul Metzger
+ * - linux stuff
+ *
+ * V0.16 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
+ * - written the quadfunc support (no performance improvement)
+ * - written the support for the new Mesa 2.3beta1 driver interface (Wow ! It is faaaster)
+ * - rewritten the glBitmap support for the Glide 2.3 (~35% slower !)
+ * - written the glBitmap support for the most common case (fonts)
+ *
+ * Jack Palevich
+ * - Glide 2.3 porting
+ *
+ * Diego Picciani (d.picciani@novacomp.it) Nova Computer s.r.l.
+ * - extended the fxMesaCreateContext() and fxMesaCreateBestContext()
+ * functions in order to support also the Voodoo Rush
+ * - tested with the Hercules Stingray 128/3D (The rendering in a window works !)
+ *
+ * V0.15 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
+ * - written the GL_LUMINANCE_ALPHA support
+ * - written the GL_ALPHA support
+ * - written the GL_LUMINANCE support
+ * - now SETUP correctly set color for mono color sequences
+ * - written the 9x1,10x1,...,1x9,1x10,... texture map ratio support
+ * - written the no square texture map support
+ * - the fog table is no more rebuilt inside setup_fx_units() each time
+ *
+ * Henri Fousse (arnaud@pobox.oleane.com) Thomson Training & Simulation
+ * - written (not yet finished: no texture mapping) support for glOrtho
+ * - some change to setup functions
+ * - the fog support is now fully compatible with the standard OpenGL
+ * - rewritten several parts of the driver in order to take
+ * advantage of meshes (40% faster !!!)
+ *
+ * V0.14 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
+ * - now glAlphaFunc() works
+ * - now glDepthMask() works
+ * - solved a mipmap problem when using more than one texture
+ * - moved ti, texid and wscale inside the fxMesaContext (now we can
+ * easy support more ctx and more boards)
+ * - the management of the fxMesaContext was completly broken !
+ * - solved several problems about Alpha and texture Alpha
+ * - 4 (RGBA) texture channels supported
+ * - setting the default color to white
+ *
+ * Henri Fousse (arnaud@pobox.oleane.com) Thomson Training & Simulation
+ * - small change to fxMesaCreateContext() and fxMesaMakeCurrent()
+ * - written the fog support
+ * - setting the default clear color to black
+ * - written cleangraphics() for the onexit() function
+ * - written fxMesaCreateBestContext()
+ *
+ * V0.13 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
+ * - now glBlendFunc() works for all glBlendFunc without DST_ALPHA
+ * (because the alpha buffer is not yet implemented)
+ * - now fxMesaCreateContext() accept resolution and refresh rate
+ * - fixed a bug for texture mapping: the w (alias z) must be set
+ * also without depth buffer
+ * - fixed a bug for texture image with width!=256
+ * - written texparam()
+ * - written all point, line and triangle functions for all possible supported
+ * contexts and the driver is slight faster with points, lines and small triangles
+ * - fixed a small bug in fx/fxmesa.h (glOrtho)
+ *
+ * V0.12 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
+ * - glDepthFunc supported
+ * - introduced a trick to discover the far plane distance
+ * (see fxMesaSetFar and fx/fxmesa.h)
+ * - now the wbuffer works with homogeneous coordinate (and it
+ * doesn't work with a glOrtho projection :)
+ * - solved several problems with homogeneous coordinate and texture mapping
+ * - fixed a bug in all line functions
+ * - fixed a clear framebuffer bug
+ * - solved a display list/teximg problem (but use
+ * glBindTexture: it is several times faster)
+ *
+ * V0.11 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
+ * - introduced texture mapping support (not yet finished !)
+ * - tested with Mesa2.2b6
+ * - the driver is faster
+ * - written glFlush/glFinish
+ * - the driver print a lot of info about the Glide lib
+ *
+ * v0.1 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
+ * - Initial revision
+ *
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "conf.h"
+#endif
+
+#if defined(FX)
+#include "fxdrv.h"
+
+static fxMesaContext fxMesaCurrentCtx=NULL;
+
+/*
+ * Status of 3Dfx hardware initialization
+ */
+
+static int glbGlideInitialized=0;
+static int glb3DfxPresent=0;
+static int glbTotNumCtx=0;
+
+GrHwConfiguration glbHWConfig;
+int glbCurrentBoard=0;
+
+
+#if defined(__WIN32__)
+static int cleangraphics(void)
+{
+ glbTotNumCtx=1;
+ fxMesaDestroyContext(fxMesaCurrentCtx);
+
+ return 0;
+}
+#elif defined(__linux__)
+static void cleangraphics(void)
+{
+ glbTotNumCtx=1;
+ fxMesaDestroyContext(fxMesaCurrentCtx);
+}
+
+static void cleangraphics_handler(int s)
+{
+ fprintf(stderr,"fxmesa: Received a not handled signal %d\n",s);
+
+ cleangraphics();
+/* abort(); */
+ exit(1);
+}
+#endif
+
+
+/*
+ * Select the Voodoo board to use when creating
+ * a new context.
+ */
+GLboolean GLAPIENTRY fxMesaSelectCurrentBoard(int n)
+{
+ fxQueryHardware();
+
+ if((n<0) || (n>=glbHWConfig.num_sst))
+ return GL_FALSE;
+
+ glbCurrentBoard=n;
+
+ return GL_TRUE;
+}
+
+
+fxMesaContext GLAPIENTRY fxMesaGetCurrentContext(void)
+{
+ return fxMesaCurrentCtx;
+}
+
+
+void GLAPIENTRY fxMesaSetNearFar(GLfloat n, GLfloat f)
+{
+ if(fxMesaCurrentCtx)
+ fxDDSetNearFar(fxMesaCurrentCtx->glCtx,n,f);
+}
+
+
+/*
+ * The 3Dfx Global Palette extension for GLQuake.
+ * More a trick than a real extesion, use the shared global
+ * palette extension.
+ */
+extern void GLAPIENTRY gl3DfxSetPaletteEXT(GLuint *pal); /* silence warning */
+void GLAPIENTRY gl3DfxSetPaletteEXT(GLuint *pal)
+{
+ fxMesaContext fxMesa =fxMesaCurrentCtx;
+
+ if (MESA_VERBOSE&VERBOSE_DRIVER) {
+ int i;
+
+ fprintf(stderr,"fxmesa: gl3DfxSetPaletteEXT()\n");
+
+ for(i=0;i<256;i++)
+ fprintf(stderr,"%x\n",pal[i]);
+ }
+
+ if(fxMesa) {
+ fxMesa->haveGlobalPaletteTexture=1;
+
+ FX_grTexDownloadTable(GR_TMU0,GR_TEXTABLE_PALETTE,(GuTexPalette *)pal);
+ if (fxMesa->haveTwoTMUs)
+ FX_grTexDownloadTable(GR_TMU1,GR_TEXTABLE_PALETTE,(GuTexPalette *)pal);
+ }
+}
+
+
+static GrScreenResolution_t fxBestResolution(int width, int height, int aux)
+{
+ static int resolutions[][5]={
+ { 320, 200, GR_RESOLUTION_320x200, 2, 2 },
+ { 320, 240, GR_RESOLUTION_320x240, 2, 2 },
+ { 512, 384, GR_RESOLUTION_512x384, 2, 2 },
+ { 640, 400, GR_RESOLUTION_640x400, 2, 2 },
+ { 640, 480, GR_RESOLUTION_640x480, 2, 2 },
+ { 800, 600, GR_RESOLUTION_800x600, 4, 2 },
+ { 960, 720, GR_RESOLUTION_960x720, 6, 4 }
+#ifdef GR_RESOLUTION_1024x768
+ ,{ 1024, 768, GR_RESOLUTION_1024x768, 8, 4 }
+#endif
+#ifdef GR_RESOLUTION_1280x1024
+ ,{ 1280, 1024, GR_RESOLUTION_1280x1024, 8, 8 }
+#endif
+#ifdef GR_RESOLUTION_1600x1200
+ ,{ 1600, 1200, GR_RESOLUTION_1600x1200, 16, 8 }
+#endif
+ };
+ int NUM_RESOLUTIONS = sizeof(resolutions) / (sizeof(int)*5);
+ int i,fbmem;
+ GrScreenResolution_t lastvalidres=resolutions[4][2];
+
+ fxQueryHardware();
+
+ if(glbHWConfig.SSTs[glbCurrentBoard].type==GR_SSTTYPE_VOODOO) {
+ fbmem=glbHWConfig.SSTs[glbCurrentBoard].sstBoard.VoodooConfig.fbRam;
+
+ if(glbHWConfig.SSTs[glbCurrentBoard].sstBoard.VoodooConfig.sliDetect)
+ fbmem*=2;
+ } else if(glbHWConfig.SSTs[glbCurrentBoard].type==GR_SSTTYPE_SST96)
+ fbmem=glbHWConfig.SSTs[glbCurrentBoard].sstBoard.SST96Config.fbRam;
+ else
+ fbmem=2;
+
+ /* A work around for BZFlag */
+
+ if((width==1) && (height==1)) {
+ width=640;
+ height=480;
+ }
+
+ for(i=0;i<NUM_RESOLUTIONS;i++)
+ if(resolutions[i][4-aux]<=fbmem) {
+ if((width<=resolutions[i][0]) && (height<=resolutions[i][1]))
+ return resolutions[i][2];
+
+ lastvalidres=resolutions[i][2];
+ }
+
+ return lastvalidres;
+}
+
+
+fxMesaContext GLAPIENTRY fxMesaCreateBestContext(GLuint win,GLint width, GLint height,
+ const GLint attribList[])
+{
+ GrScreenRefresh_t refresh;
+ int i;
+ int res,aux;
+ refresh=GR_REFRESH_75Hz;
+
+ if(getenv("SST_SCREENREFRESH")) {
+ if(!strcmp(getenv("SST_SCREENREFRESH"),"60"))
+ refresh=GR_REFRESH_60Hz;
+ if(!strcmp(getenv("SST_SCREENREFRESH"),"70"))
+ refresh=GR_REFRESH_70Hz;
+ if(!strcmp(getenv("SST_SCREENREFRESH"),"72"))
+ refresh=GR_REFRESH_72Hz;
+ if(!strcmp(getenv("SST_SCREENREFRESH"),"75"))
+ refresh=GR_REFRESH_75Hz;
+ if(!strcmp(getenv("SST_SCREENREFRESH"),"80"))
+ refresh=GR_REFRESH_80Hz;
+ if(!strcmp(getenv("SST_SCREENREFRESH"),"85"))
+ refresh=GR_REFRESH_85Hz;
+ if(!strcmp(getenv("SST_SCREENREFRESH"),"90"))
+ refresh=GR_REFRESH_90Hz;
+ if(!strcmp(getenv("SST_SCREENREFRESH"),"100"))
+ refresh=GR_REFRESH_100Hz;
+ if(!strcmp(getenv("SST_SCREENREFRESH"),"120"))
+ refresh=GR_REFRESH_120Hz;
+ }
+
+ aux=0;
+ for(i=0;attribList[i]!=FXMESA_NONE;i++)
+ if((attribList[i]==FXMESA_ALPHA_SIZE) ||
+ (attribList[i]==FXMESA_DEPTH_SIZE)) {
+ if(attribList[++i]>0) {
+ aux=1;
+ break;
+ }
+ }
+
+ res=fxBestResolution(width,height,aux);
+
+ return fxMesaCreateContext(win,res,refresh,attribList);
+}
+
+
+#if 0
+void fxsignals()
+{
+ signal(SIGINT,SIG_IGN);
+ signal(SIGHUP,SIG_IGN);
+ signal(SIGPIPE,SIG_IGN);
+ signal(SIGFPE,SIG_IGN);
+ signal(SIGBUS,SIG_IGN);
+ signal(SIGILL,SIG_IGN);
+ signal(SIGSEGV,SIG_IGN);
+ signal(SIGTERM,SIG_IGN);
+}
+#endif
+
+/*
+ * Create a new FX/Mesa context and return a handle to it.
+ */
+fxMesaContext GLAPIENTRY fxMesaCreateContext(GLuint win,
+ GrScreenResolution_t res,
+ GrScreenRefresh_t ref,
+ const GLint attribList[])
+{
+ fxMesaContext fxMesa = NULL;
+ int i,type;
+ int aux;
+ GLboolean doubleBuffer=GL_FALSE;
+ GLboolean alphaBuffer=GL_FALSE;
+ GLboolean verbose=GL_FALSE;
+ GLint depthSize=0;
+ GLint stencilSize=0;
+ GLint accumSize=0;
+ GLcontext *shareCtx = NULL;
+ GLcontext *ctx = 0;
+ /*FX_GrContext_t glideContext = 0;*/
+ char *errorstr;
+ GLboolean useBGR;
+ char *system = NULL;
+
+ if (MESA_VERBOSE&VERBOSE_DRIVER) {
+ fprintf(stderr,"fxmesa: fxMesaCreateContext() Start\n");
+ }
+
+ if(getenv("MESA_FX_INFO"))
+ verbose=GL_TRUE;
+
+ aux=0;
+ i=0;
+ while(attribList[i]!=FXMESA_NONE) {
+ switch (attribList[i]) {
+ case FXMESA_DOUBLEBUFFER:
+ doubleBuffer=GL_TRUE;
+ break;
+ case FXMESA_ALPHA_SIZE:
+ i++;
+ alphaBuffer=attribList[i]>0;
+ if(alphaBuffer)
+ aux=1;
+ break;
+ case FXMESA_DEPTH_SIZE:
+ i++;
+ depthSize=attribList[i];
+ if(depthSize) {
+ aux=1;
+ depthSize = 16;
+ }
+ break;
+ case FXMESA_STENCIL_SIZE:
+ i++;
+ stencilSize=attribList[i];
+ break;
+ case FXMESA_ACCUM_SIZE:
+ i++;
+ accumSize=attribList[i];
+ break;
+ /* XXX ugly hack here for sharing display lists */
+#define FXMESA_SHARE_CONTEXT 990099 /* keep in sync with xmesa1.c! */
+ case FXMESA_SHARE_CONTEXT:
+ i++;
+ {
+ const void *vPtr = &attribList[i];
+ GLcontext **ctx = (GLcontext **) vPtr;
+ shareCtx = *ctx;
+ }
+ break;
+ default:
+ if (MESA_VERBOSE&VERBOSE_DRIVER) {
+ fprintf(stderr,"fxmesa: fxMesaCreateContext() End (defualt)\n");
+ }
+ return NULL;
+ }
+ i++;
+ }
+
+ /* A workaround for Linux GLQuake */
+ if(depthSize && alphaBuffer)
+ alphaBuffer=0;
+
+ if ((type=fxQueryHardware()) < 0) {
+ fprintf(stderr,"fx Driver: ERROR no Voodoo1/2 Graphics or Voodoo Rush !\n");
+ return NULL;
+ }
+
+ if(type==GR_SSTTYPE_VOODOO)
+ win=0;
+
+ grSstSelect(glbCurrentBoard);
+
+ fxMesa=(fxMesaContext)calloc(1,sizeof(struct tfxMesaContext));
+ if(!fxMesa) {
+ errorstr = "malloc";
+ goto errorhandler;
+ }
+
+ if(glbHWConfig.SSTs[glbCurrentBoard].type==GR_SSTTYPE_VOODOO)
+ fxMesa->haveTwoTMUs=(glbHWConfig.SSTs[glbCurrentBoard].sstBoard.VoodooConfig.nTexelfx > 1);
+ else if(glbHWConfig.SSTs[glbCurrentBoard].type==GR_SSTTYPE_SST96)
+ fxMesa->haveTwoTMUs=(glbHWConfig.SSTs[glbCurrentBoard].sstBoard.SST96Config.nTexelfx > 1);
+ else
+ fxMesa->haveTwoTMUs=GL_FALSE;
+
+ fxMesa->haveDoubleBuffer=doubleBuffer;
+ fxMesa->haveAlphaBuffer=alphaBuffer;
+ fxMesa->haveGlobalPaletteTexture=GL_FALSE;
+ fxMesa->haveZBuffer=depthSize ? 16 : 0;
+ fxMesa->verbose=verbose;
+ fxMesa->board=glbCurrentBoard;
+
+
+ fxMesa->glideContext = FX_grSstWinOpen((FxU32)win,res,ref,
+#if FXMESA_USE_ARGB
+ GR_COLORFORMAT_ARGB,
+#else
+ GR_COLORFORMAT_ABGR,
+#endif
+ GR_ORIGIN_LOWER_LEFT,
+ 2,aux);
+ if (!fxMesa->glideContext){
+ errorstr = "grSstWinOpen";
+ goto errorhandler;
+ }
+
+ /*
+ * Pixel tables are use during pixel read-back
+ * Either initialize them for RGB or BGR order.
+ */
+#if FXMESA_USE_ARGB
+ useBGR = GL_FALSE; /* Force RGB pixel order */
+ system = "FXMESA_USE_ARGB";
+#else
+ if (glbHWConfig.SSTs[glbCurrentBoard].type == GR_SSTTYPE_VOODOO) {
+ /* jk991130 - Voodoo 3s don't use BGR. Query the # of TMUs
+ * as Voodoo3s have 2 TMUs on board, Banshee has only 1
+ * bk000413 - another suggestion from Joseph Kain is using
+ * VendorID 0x121a for all 3dfx boards
+ * DeviceID VG 1/V2 2/VB 3/V3 5
+ * For now we cehck for known BGR devices, and presume
+ * everything else to be a V3/RGB.
+ */
+ GrVoodooConfig_t *voodoo;
+ voodoo = &glbHWConfig.SSTs[glbCurrentBoard].sstBoard.VoodooConfig;
+
+ if (voodoo->nTexelfx == 1) {
+ /* Voodoo1 or Banshee */
+ useBGR = GL_TRUE;
+ system = "Voodoo1";
+ }
+ else if (voodoo->nTexelfx == 2 &&
+ voodoo->fbiRev == 260 &&
+ voodoo->tmuConfig[0].tmuRev == 4 &&
+ (voodoo->tmuConfig[0].tmuRam == 2 ||
+ voodoo->tmuConfig[0].tmuRam == 4)) {
+ /* Voodoo 2 */
+ useBGR = GL_TRUE;
+ system = "Voodoo2";
+ }
+ else if (voodoo->nTexelfx == 2 &&
+ voodoo->fbiRev == 2 &&
+ voodoo->tmuConfig[0].tmuRev == 1 &&
+ voodoo->tmuConfig[0].tmuRam == 4) {
+ /* Quantum3D Obsidian 50/100 */
+ useBGR = GL_TRUE;
+ system = "Quantum3D Obsidian";
+ }
+ else
+ /* Brian
+ * (voodoo->nTexelfx == 2 &&
+ * voodoo->fbiRev == 0 &&
+ * voodoo->tmuConfig[0].tmuRev == 148441048 &&
+ * voodoo->tmuConfig[0].tmuRam == 3)
+ * Bernd
+ * (voodoo->nTexelfx == 2 &&
+ * voodoo->fbiRev == 69634 &&
+ * voodoo->tmuConfig[0].tmuRev == 69634 &&
+ * voodoo->tmuConfig[0].tmuRam == 2 )
+ */
+ {
+ /* Presumed Voodoo3 */
+ useBGR = GL_FALSE;
+ system = "Voodoo3";
+ }
+ if (getenv("MESA_FX_INFO")) {
+ printf("Voodoo: Texelfx: %d / FBI Rev.: %d / TMU Rev.: %d / TMU RAM: %d\n",
+ voodoo->nTexelfx,
+ voodoo->fbiRev,
+ voodoo->tmuConfig[0].tmuRev,
+ voodoo->tmuConfig[0].tmuRam );
+ }
+ }
+ else {
+ useBGR = GL_FALSE; /* use RGB pixel order otherwise */
+ system = "non-voodoo";
+ }
+#endif /*FXMESA_USE_ARGB*/
+
+ if (getenv("MESA_FX_INFO"))
+ printf("Voodoo pixel order: %s (%s)\n", useBGR ? "BGR" : "RGB", system);
+
+ fxInitPixelTables(fxMesa, useBGR);
+
+ fxMesa->width=FX_grSstScreenWidth();
+ fxMesa->height=FX_grSstScreenHeight();
+
+ fxMesa->clipMinX = 0;
+ fxMesa->clipMaxX = fxMesa->width;
+ fxMesa->clipMinY = 0;
+ fxMesa->clipMaxY = fxMesa->height;
+
+ fxMesa->screen_width = fxMesa->width;
+ fxMesa->screen_height = fxMesa->height;
+ fxMesa->x_offset = 0;
+ fxMesa->y_offset = 0;
+ fxMesa->y_delta = 0;
+
+ fxMesa->needClip = 0;
+
+ if(verbose)
+ fprintf(stderr,"Voodoo Glide screen size: %dx%d\n",
+ (int)FX_grSstScreenWidth(),(int)FX_grSstScreenHeight());
+
+ fxMesa->glVis=gl_create_visual(GL_TRUE, /* RGB mode */
+ alphaBuffer,
+ doubleBuffer,
+ GL_FALSE, /* stereo */
+ depthSize, /* depth_size */
+ stencilSize, /* stencil_size */
+ accumSize, /* accum_size */
+ 0, /* index bits */
+ 5,6,5,0); /* RGBA bits */
+ if (!fxMesa->glVis) {
+ errorstr = "gl_create_visual";
+ goto errorhandler;
+ }
+
+ ctx = fxMesa->glCtx=gl_create_context(fxMesa->glVis,
+ shareCtx, /* share list context */
+ (void *) fxMesa, GL_TRUE);
+ if (!ctx) {
+ errorstr = "gl_create_context";
+ goto errorhandler;
+ }
+
+
+ if (!fxDDInitFxMesaContext( fxMesa )) {
+ errorstr = "fxDDInitFxMesaContext failed";
+ goto errorhandler;
+ }
+
+
+ fxMesa->glBuffer=gl_create_framebuffer(fxMesa->glVis,
+ GL_FALSE, /* no software depth */
+ fxMesa->glVis->StencilBits > 0,
+ fxMesa->glVis->AccumRedBits > 0,
+ fxMesa->glVis->AlphaBits > 0 );
+ if (!fxMesa->glBuffer) {
+ errorstr = "gl_create_framebuffer";
+ goto errorhandler;
+ }
+
+ glbTotNumCtx++;
+
+ /* install signal handlers */
+#if defined(__linux__)
+ /* Only install if environment var. is not set. */
+ if (fxMesa->glCtx->CatchSignals && !getenv("MESA_FX_NO_SIGNALS")) {
+ signal(SIGINT,cleangraphics_handler);
+ signal(SIGHUP,cleangraphics_handler);
+ signal(SIGPIPE,cleangraphics_handler);
+ signal(SIGFPE,cleangraphics_handler);
+ signal(SIGBUS,cleangraphics_handler);
+ signal(SIGILL,cleangraphics_handler);
+ signal(SIGSEGV,cleangraphics_handler);
+ signal(SIGTERM,cleangraphics_handler);
+ }
+#endif
+
+ if (MESA_VERBOSE&VERBOSE_DRIVER) {
+ fprintf(stderr,"fxmesa: fxMesaCreateContext() End\n");
+ }
+
+ return fxMesa;
+
+ errorhandler:
+ if (fxMesa) {
+ if (fxMesa->glideContext)
+ FX_grSstWinClose(fxMesa->glideContext);
+ fxMesa->glideContext = 0;
+
+ if (fxMesa->state)
+ free(fxMesa->state);
+ if (fxMesa->fogTable)
+ free(fxMesa->fogTable);
+ if (fxMesa->glBuffer)
+ gl_destroy_framebuffer(fxMesa->glBuffer);
+ if (fxMesa->glVis)
+ gl_destroy_visual(fxMesa->glVis);
+ if (fxMesa->glCtx)
+ gl_destroy_context(fxMesa->glCtx);
+ free(fxMesa);
+ }
+
+ if (MESA_VERBOSE&VERBOSE_DRIVER) {
+ fprintf(stderr,"fxmesa: fxMesaCreateContext() End (%s)\n",errorstr);
+ }
+ return NULL;
+}
+
+
+/*
+ * Function to set the new window size in the context (mainly for the Voodoo Rush)
+ */
+void GLAPIENTRY fxMesaUpdateScreenSize(fxMesaContext fxMesa)
+{
+ fxMesa->width=FX_grSstScreenWidth();
+ fxMesa->height=FX_grSstScreenHeight();
+}
+
+
+/*
+ * Destroy the given FX/Mesa context.
+ */
+void GLAPIENTRY fxMesaDestroyContext(fxMesaContext fxMesa)
+{
+ if (MESA_VERBOSE&VERBOSE_DRIVER) {
+ fprintf(stderr,"fxmesa: fxMesaDestroyContext()\n");
+ }
+
+ if(fxMesa) {
+ gl_destroy_visual(fxMesa->glVis);
+ gl_destroy_context(fxMesa->glCtx);
+ gl_destroy_framebuffer(fxMesa->glBuffer);
+
+ glbTotNumCtx--;
+
+ fxCloseHardware();
+ FX_grSstWinClose(fxMesa->glideContext);
+
+ if(fxMesa->verbose) {
+ fprintf(stderr,"Misc Stats:\n");
+ fprintf(stderr," # swap buffer: %u\n",fxMesa->stats.swapBuffer);
+
+ if(!fxMesa->stats.swapBuffer)
+ fxMesa->stats.swapBuffer=1;
+
+ fprintf(stderr,"Textures Stats:\n");
+ fprintf(stderr," Free texture memory on TMU0: %d:\n",fxMesa->freeTexMem[FX_TMU0]);
+ if(fxMesa->haveTwoTMUs)
+ fprintf(stderr," Free texture memory on TMU1: %d:\n",fxMesa->freeTexMem[FX_TMU1]);
+ fprintf(stderr," # request to TMM to upload a texture objects: %u\n",
+ fxMesa->stats.reqTexUpload);
+ fprintf(stderr," # request to TMM to upload a texture objects per swapbuffer: %.2f\n",
+ fxMesa->stats.reqTexUpload/(float)fxMesa->stats.swapBuffer);
+ fprintf(stderr," # texture objects uploaded: %u\n",
+ fxMesa->stats.texUpload);
+ fprintf(stderr," # texture objects uploaded per swapbuffer: %.2f\n",
+ fxMesa->stats.texUpload/(float)fxMesa->stats.swapBuffer);
+ fprintf(stderr," # MBs uploaded to texture memory: %.2f\n",
+ fxMesa->stats.memTexUpload/(float)(1<<20));
+ fprintf(stderr," # MBs uploaded to texture memory per swapbuffer: %.2f\n",
+ (fxMesa->stats.memTexUpload/(float)fxMesa->stats.swapBuffer)/(float)(1<<20));
+ }
+ if (fxMesa->state)
+ free(fxMesa->state);
+ if (fxMesa->fogTable)
+ free(fxMesa->fogTable);
+ fxTMClose(fxMesa);
+
+ free(fxMesa);
+ }
+
+ if(fxMesa==fxMesaCurrentCtx)
+ fxMesaCurrentCtx=NULL;
+}
+
+
+/*
+ * Make the specified FX/Mesa context the current one.
+ */
+void GLAPIENTRY fxMesaMakeCurrent(fxMesaContext fxMesa)
+{
+ if (MESA_VERBOSE&VERBOSE_DRIVER) {
+ fprintf(stderr,"fxmesa: fxMesaMakeCurrent(...) Start\n");
+ }
+
+ if(!fxMesa) {
+ gl_make_current(NULL,NULL);
+ fxMesaCurrentCtx=NULL;
+
+ if (MESA_VERBOSE&VERBOSE_DRIVER) {
+ fprintf(stderr,"fxmesa: fxMesaMakeCurrent(NULL) End\n");
+ }
+
+ return;
+ }
+
+ /* if this context is already the current one, we can return early */
+ if (fxMesaCurrentCtx == fxMesa
+ && fxMesaCurrentCtx->glCtx == gl_get_current_context()) {
+ if (MESA_VERBOSE&VERBOSE_DRIVER) {
+ fprintf(stderr,"fxmesa: fxMesaMakeCurrent(fxMesaCurrentCtx==fxMesa) End\n");
+ }
+
+ return;
+ }
+
+ if(fxMesaCurrentCtx)
+ grGlideGetState((GrState*)fxMesaCurrentCtx->state);
+
+ fxMesaCurrentCtx=fxMesa;
+
+ grSstSelect(fxMesa->board);
+ grGlideSetState((GrState*)fxMesa->state);
+
+ gl_make_current(fxMesa->glCtx,fxMesa->glBuffer);
+
+ fxSetupDDPointers(fxMesa->glCtx);
+
+ /* The first time we call MakeCurrent we set the initial viewport size */
+ if(fxMesa->glCtx->Viewport.Width==0)
+ gl_Viewport(fxMesa->glCtx,0,0,fxMesa->width,fxMesa->height);
+
+ if (MESA_VERBOSE&VERBOSE_DRIVER) {
+ fprintf(stderr,"fxmesa: fxMesaMakeCurrent(...) End\n");
+ }
+}
+
+
+#if 0
+static void QueryCounters(void)
+{
+ static GLuint prevPassed = 0;
+ static GLuint prevFailed = 0;
+ GLuint failed, passed;
+ GrSstPerfStats_t st;
+
+ FX_grSstPerfStats(&st);
+ failed = st.zFuncFail - st.aFuncFail - st.chromaFail;
+ passed = st.pixelsIn - failed;
+ printf("failed: %d passed: %d\n", failed - prevFailed, passed - prevPassed);
+
+ prevPassed = passed;
+ prevFailed = failed;
+}
+#endif
+
+
+/*
+ * Swap front/back buffers for current context if double buffered.
+ */
+void GLAPIENTRY fxMesaSwapBuffers(void)
+{
+ if (MESA_VERBOSE&VERBOSE_DRIVER) {
+ fprintf(stderr,"fxmesa: ------------------------------- fxMesaSwapBuffers() -------------------------------\n");
+ }
+
+ if(fxMesaCurrentCtx) {
+ FLUSH_VB( fxMesaCurrentCtx->glCtx, "swap buffers" );
+
+ if(fxMesaCurrentCtx->haveDoubleBuffer) {
+
+ grBufferSwap(fxMesaCurrentCtx->swapInterval);
+
+ /*
+ * Don't allow swap buffer commands to build up!
+ */
+ while(FX_grGetInteger(FX_PENDING_BUFFERSWAPS)>fxMesaCurrentCtx->maxPendingSwapBuffers)
+ /* The driver is able to sleep when waiting for the completation
+ of multiple swapbuffer operations instead of wasting
+ CPU time (NOTE: you must uncomment the following line in the
+ in order to enable this option) */
+ /* usleep(10000); */
+ ;
+
+ fxMesaCurrentCtx->stats.swapBuffer++;
+ }
+ }
+}
+
+
+/*
+ * Query 3Dfx hardware presence/kind
+ */
+int GLAPIENTRY fxQueryHardware(void)
+{
+ if (MESA_VERBOSE&VERBOSE_DRIVER) {
+ fprintf(stderr,"fxmesa: fxQueryHardware() Start\n");
+ }
+
+ if (!glbGlideInitialized) {
+ grGlideInit();
+ if (FX_grSstQueryHardware(&glbHWConfig)) {
+ grSstSelect(glbCurrentBoard);
+ glb3DfxPresent = 1;
+
+ if (getenv("MESA_FX_INFO")) {
+ char buf[80];
+
+ FX_grGlideGetVersion(buf);
+ fprintf(stderr, "Voodoo Using Glide V%s\n", buf);
+ fprintf(stderr, "Voodoo Number of boards: %d\n", glbHWConfig.num_sst);
+
+ if (glbHWConfig.SSTs[glbCurrentBoard].type == GR_SSTTYPE_VOODOO) {
+ GrVoodooConfig_t *voodoo;
+ voodoo = &glbHWConfig.SSTs[glbCurrentBoard].sstBoard.VoodooConfig;
+
+ fprintf(stderr, "Voodoo Framebuffer RAM: %d\n",
+ voodoo->sliDetect ? (voodoo->fbRam*2) : voodoo->fbRam);
+ fprintf(stderr, "Voodoo Number of TMUs: %d\n", voodoo->nTexelfx);
+ fprintf(stderr, "Voodoo fbRam: %d\n", voodoo->fbRam);
+ fprintf(stderr, "Voodoo fbiRev: %d\n", voodoo->fbiRev);
+
+ fprintf(stderr,"Voodoo SLI detected: %d\n", voodoo->sliDetect);
+ }
+ else if (glbHWConfig.SSTs[glbCurrentBoard].type == GR_SSTTYPE_SST96) {
+ GrSst96Config_t *sst96;
+ sst96 = &glbHWConfig.SSTs[glbCurrentBoard].sstBoard.SST96Config;
+ fprintf(stderr, "Voodoo Framebuffer RAM: %d\n", sst96->fbRam);
+ fprintf(stderr, "Voodoo Number of TMUs: %d\n", sst96->nTexelfx);
+ }
+
+ }
+ }
+ else {
+ glb3DfxPresent = 0;
+ }
+
+ glbGlideInitialized = 1;
+
+#if defined(__WIN32__)
+ onexit((_onexit_t)cleangraphics);
+#elif defined(__linux__)
+ /* Only register handler if environment variable is not defined. */
+ if (!getenv("MESA_FX_NO_SIGNALS")) {
+ atexit(cleangraphics);
+ }
+#endif
+ }
+
+ if (MESA_VERBOSE&VERBOSE_DRIVER) {
+ fprintf(stderr,"fxmesa: fxQueryHardware() End (voodooo)\n");
+ }
+
+ return glbHWConfig.SSTs[glbCurrentBoard].type;
+}
+
+
+/*
+ * Shutdown Glide library
+ */
+void GLAPIENTRY fxCloseHardware(void)
+{
+ if (glbGlideInitialized) {
+ 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);
+ }
+
+ if (glbTotNumCtx == 0) {
+ grGlideShutdown();
+ glbGlideInitialized = 0;
+ }
+ }
+}
+
+
+#else
+
+
+/*
+ * Need this to provide at least one external definition.
+ */
+extern int gl_fx_dummy_function_api(void);
+int gl_fx_dummy_function_api(void)
+{
+ return 0;
+}
+
+#endif /* FX */
diff --git a/xc/extras/Mesa/src/FX/fxclip.c b/xc/extras/Mesa/src/FX/fxclip.c
new file mode 100644
index 000000000..7067516be
--- /dev/null
+++ b/xc/extras/Mesa/src/FX/fxclip.c
@@ -0,0 +1,554 @@
+/* -*- mode: C; tab-width:8; c-basic-offset:2 -*- */
+
+/*
+ * 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.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "conf.h"
+#endif
+
+#if defined(FX)
+
+#include "fxdrv.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;
+}
+
+#else
+
+/*
+ * Need this to provide at least one external definition.
+ */
+int gl_fxclip_dummy(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/xc/extras/Mesa/src/FX/fxcliptmp.h b/xc/extras/Mesa/src/FX/fxcliptmp.h
new file mode 100644
index 000000000..82beeda6a
--- /dev/null
+++ b/xc/extras/Mesa/src/FX/fxcliptmp.h
@@ -0,0 +1,346 @@
+/* -*- mode: C; tab-width:8; c-basic-offset:2 -*- */
+
+/*
+ * 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(tmp0, tmp1, width) \
+ do { \
+ 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(4, verts); \
+ } while (0)
+
+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(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(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(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/extras/Mesa/src/FX/fxcva.c b/xc/extras/Mesa/src/FX/fxcva.c
new file mode 100644
index 000000000..188210add
--- /dev/null
+++ b/xc/extras/Mesa/src/FX/fxcva.c
@@ -0,0 +1,513 @@
+/* -*- mode: C; tab-width:8; c-basic-offset:2 -*- */
+
+/*
+ * 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 */
+
+
+#ifdef HAVE_CONFIG_H
+#include "conf.h"
+#endif
+
+#if defined(FX)
+
+#include "fxdrv.h"
+#include "mmath.h"
+#include "vbindirect.h"
+#include "pb.h"
+#include "fxvsetup.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];
+
+ if (!mask) {
+ FX_grDrawTriangle((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((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( (GrVertex *)v )
+#define DRAW_LINE FX_grDrawLine( (GrVertex *)v, (GrVertex *)prev_v )
+#define DRAW_TRI FX_grDrawTriangle( (GrVertex *)gWin[l[0]].f, (GrVertex *)gWin[l[1]].f, (GrVertex *)v )
+#define DRAW_TRI2 FX_grDrawTriangle( 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;
+}
+
+
+
+#else
+
+
+/*
+ * Need this to provide at least one external definition.
+ */
+
+int gl_fx_dummy_function_cva(void)
+{
+ return 0;
+}
+
+
+#endif /* FX */
diff --git a/xc/extras/Mesa/src/FX/fxcva.h b/xc/extras/Mesa/src/FX/fxcva.h
new file mode 100644
index 000000000..f809ec010
--- /dev/null
+++ b/xc/extras/Mesa/src/FX/fxcva.h
@@ -0,0 +1,70 @@
+/* -*- mode: C; tab-width:8; c-basic-offset:2 -*- */
+
+/*
+ * 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 );
+
+
+
+#endif
+
diff --git a/xc/extras/Mesa/src/FX/fxcvatmp.h b/xc/extras/Mesa/src/FX/fxcvatmp.h
new file mode 100644
index 000000000..801dc0edd
--- /dev/null
+++ b/xc/extras/Mesa/src/FX/fxcvatmp.h
@@ -0,0 +1,262 @@
+/* -*- mode: C; tab-width:8; c-basic-offset:2 -*- */
+
+/*
+ * 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/extras/Mesa/src/FX/fxdd.c b/xc/extras/Mesa/src/FX/fxdd.c
new file mode 100644
index 000000000..fc8bbb824
--- /dev/null
+++ b/xc/extras/Mesa/src/FX/fxdd.c
@@ -0,0 +1,1189 @@
+/* -*- mode: C; tab-width:8; c-basic-offset:2 -*- */
+
+/*
+ * 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 device driver functions */
+
+
+#ifdef HAVE_CONFIG_H
+#include "conf.h"
+#endif
+
+#if defined(FX)
+
+#include "image.h"
+#include "types.h"
+#include "fxdrv.h"
+#include "enums.h"
+#include "extensions.h"
+#include "pb.h"
+
+/* These lookup table are used to extract RGB values in [0,255] from
+ * 16-bit pixel values.
+ */
+GLubyte FX_PixelToR[0x10000];
+GLubyte FX_PixelToG[0x10000];
+GLubyte FX_PixelToB[0x10000];
+
+
+/*
+ * Initialize the FX_PixelTo{RGB} arrays.
+ * Input: bgrOrder - if TRUE, pixels are in BGR order, else RGB order.
+ */
+void fxInitPixelTables(fxMesaContext fxMesa, GLboolean bgrOrder)
+{
+ GLuint pixel;
+
+ fxMesa->bgrOrder=bgrOrder;
+ 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_PixelToR[pixel] = r;
+ FX_PixelToG[pixel] = g;
+ FX_PixelToB[pixel] = b;
+ }
+}
+
+
+/**********************************************************************/
+/***** Miscellaneous functions *****/
+/**********************************************************************/
+
+/* Enalbe/Disable dithering */
+static void fxDDDither(GLcontext *ctx, GLboolean enable)
+{
+ if (MESA_VERBOSE&VERBOSE_DRIVER) {
+ fprintf(stderr,"fxmesa: fxDDDither()\n");
+ }
+
+ if (enable) {
+ FX_grDitherMode(GR_DITHER_4x4);
+ } else {
+ FX_grDitherMode(GR_DITHER_DISABLE);
+ }
+}
+
+
+/* Return buffer size information */
+static void fxDDBufferSize(GLcontext *ctx, GLuint *width, GLuint *height)
+{
+ fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+
+ 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=(fxMesaContext)ctx->DriverCtx;
+ 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=(fxMesaContext)ctx->DriverCtx;
+ 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 FxU16 clearD = (FxU16) (ctx->Depth.Clear * 0xffff);
+ GLbitfield softwareMask = mask & (DD_STENCIL_BIT | DD_ACCUM_BIT);
+
+ /* we can't clear stencil or accum buffers */
+ mask &= ~(DD_STENCIL_BIT | DD_ACCUM_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);
+ }
+
+ /*
+ * This could probably be done fancier but doing each possible case
+ * explicitly is less error prone.
+ */
+ switch (mask) {
+ case DD_BACK_LEFT_BIT | DD_DEPTH_BIT:
+ /* back buffer & depth */
+ FX_grDepthMask(FXTRUE);
+ FX_grRenderBuffer(GR_BUFFER_BACKBUFFER);
+ FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD);
+ if (!ctx->Depth.Mask) {
+ FX_grDepthMask(FXFALSE);
+ }
+ break;
+ case DD_FRONT_LEFT_BIT | DD_DEPTH_BIT:
+ /* XXX it appears that the depth buffer isn't cleared when
+ * glRenderBuffer(GR_BUFFER_FRONTBUFFER) is set.
+ * This is a work-around/
+ */
+ /* clear depth */
+ FX_grDepthMask(FXTRUE);
+ FX_grRenderBuffer(GR_BUFFER_BACKBUFFER);
+ FX_grColorMask(FXFALSE,FXFALSE);
+ FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD);
+ /* clear front */
+ FX_grColorMask(FXTRUE, ctx->Color.ColorMask[ACOMP] && fxMesa->haveAlphaBuffer);
+ FX_grRenderBuffer(GR_BUFFER_FRONTBUFFER);
+ FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD);
+ break;
+ case DD_BACK_LEFT_BIT:
+ /* back buffer only */
+ FX_grDepthMask(FXFALSE);
+ FX_grRenderBuffer(GR_BUFFER_BACKBUFFER);
+ FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD);
+ if (ctx->Depth.Mask) {
+ FX_grDepthMask(FXTRUE);
+ }
+ break;
+ case DD_FRONT_LEFT_BIT:
+ /* front buffer only */
+ FX_grDepthMask(FXFALSE);
+ FX_grRenderBuffer(GR_BUFFER_FRONTBUFFER);
+ FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD);
+ if (ctx->Depth.Mask) {
+ FX_grDepthMask(FXTRUE);
+ }
+ break;
+ case DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT:
+ /* front and back */
+ FX_grDepthMask(FXFALSE);
+ FX_grRenderBuffer(GR_BUFFER_BACKBUFFER);
+ FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD);
+ FX_grRenderBuffer(GR_BUFFER_FRONTBUFFER);
+ FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD);
+ if (ctx->Depth.Mask) {
+ FX_grDepthMask(FXTRUE);
+ }
+ break;
+ case DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT | DD_DEPTH_BIT:
+ /* clear front */
+ FX_grDepthMask(FXFALSE);
+ FX_grRenderBuffer(GR_BUFFER_FRONTBUFFER);
+ FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD);
+ /* clear back and depth */
+ FX_grDepthMask(FXTRUE);
+ FX_grRenderBuffer(GR_BUFFER_BACKBUFFER);
+ FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD);
+ if (!ctx->Depth.Mask) {
+ FX_grDepthMask(FXFALSE);
+ }
+ break;
+ case DD_DEPTH_BIT:
+ /* just the depth buffer */
+ FX_grRenderBuffer(GR_BUFFER_BACKBUFFER);
+ FX_grColorMask(FXFALSE,FXFALSE);
+ FX_grDepthMask(FXTRUE);
+ FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD);
+ FX_grColorMask(FXTRUE, ctx->Color.ColorMask[ACOMP] && fxMesa->haveAlphaBuffer);
+ if (ctx->Color.DrawDestMask & FRONT_LEFT_BIT)
+ FX_grRenderBuffer(GR_BUFFER_FRONTBUFFER);
+ if (!ctx->Depth.Test || !ctx->Depth.Mask)
+ FX_grDepthMask(FXFALSE);
+ break;
+ default:
+ /* error */
+ ;
+ }
+
+ 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->currentFB);
+ return GL_TRUE;
+ }
+ else if (mode == GL_BACK_LEFT) {
+ fxMesa->currentFB = GR_BUFFER_BACKBUFFER;
+ FX_grRenderBuffer(fxMesa->currentFB);
+ return GL_TRUE;
+ }
+ else if (mode == GL_NONE) {
+ FX_grColorMask(FXFALSE,FXFALSE);
+ 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->currentFB);
+ }
+ else if (mode == GL_BACK_LEFT) {
+ fxMesa->currentFB = GR_BUFFER_BACKBUFFER;
+ FX_grRenderBuffer(fxMesa->currentFB);
+ }
+}
+
+
+#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 fxDDDrawBitmap(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(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(GR_LFB_WRITE_ONLY,fxMesa->currentFB);
+ return GL_TRUE;
+}
+
+
+static GLboolean fxDDReadPixels( 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();
+ 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[pixel0];
+ *d++ = FX_PixelToG[pixel0];
+ *d++ = FX_PixelToB[pixel0];
+ *d++ = FX_PixelToR[pixel1];
+ *d++ = FX_PixelToG[pixel1];
+ *d++ = FX_PixelToB[pixel1];
+ }
+ if (extraPixel) {
+ GLushort pixel = src[width-1];
+ *d++ = FX_PixelToR[pixel];
+ *d++ = FX_PixelToG[pixel];
+ *d++ = FX_PixelToB[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[pixel0];
+ *d++ = FX_PixelToG[pixel0];
+ *d++ = FX_PixelToB[pixel0];
+ *d++ = 255;
+ *d++ = FX_PixelToR[pixel1];
+ *d++ = FX_PixelToG[pixel1];
+ *d++ = FX_PixelToB[pixel1];
+ *d++ = 255;
+ }
+ if (extraPixel) {
+ const GLushort pixel = src[width-1];
+ *d++ = FX_PixelToR[pixel];
+ *d++ = FX_PixelToG[pixel];
+ *d++ = FX_PixelToB[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();
+ return result;
+ }
+}
+
+
+
+static void fxDDFinish(GLcontext *ctx)
+{
+ FX_grFlush();
+}
+
+
+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);
+ fxCloseHardware();
+ exit(-1);
+ return 0;
+ }
+}
+
+
+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)
+{
+#if defined(GLX_DIRECT_RENDERING)
+ /* Building for DRI driver */
+ switch (name) {
+ case GL_RENDERER:
+ {
+ static char buffer[100];
+ char hardware[100];
+ strcpy(hardware, grGetString(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 20000510", hardware);
+ return buffer;
+ }
+ case GL_VENDOR:
+ return "Precision Insight, Inc.";
+ default:
+ return NULL;
+ }
+
+#else
+
+ /* Building for Voodoo1/2 stand-alone Mesa */
+ switch (name) {
+ case GL_RENDERER:
+ {
+ static char buf[80];
+
+ if (glbHWConfig.SSTs[glbCurrentBoard].type==GR_SSTTYPE_VOODOO) {
+ GrVoodooConfig_t *vc =
+ &glbHWConfig.SSTs[glbCurrentBoard].sstBoard.VoodooConfig;
+
+ sprintf(buf,
+ "Mesa Glide v0.30 Voodoo_Graphics %d "
+ "CARD/%d FB/%d TM/%d TMU/%s",
+ glbCurrentBoard,
+ (vc->sliDetect ? (vc->fbRam*2) : vc->fbRam),
+ (vc->tmuConfig[GR_TMU0].tmuRam +
+ ((vc->nTexelfx>1) ? vc->tmuConfig[GR_TMU1].tmuRam : 0)),
+ vc->nTexelfx,
+ (vc->sliDetect ? "SLI" : "NOSLI"));
+ }
+ else if (glbHWConfig.SSTs[glbCurrentBoard].type==GR_SSTTYPE_SST96) {
+ GrSst96Config_t *sc =
+ &glbHWConfig.SSTs[glbCurrentBoard].sstBoard.SST96Config;
+
+ sprintf(buf,
+ "Glide v0.30 Voodoo_Rush %d "
+ "CARD/%d FB/%d TM/%d TMU/NOSLI",
+ glbCurrentBoard,
+ sc->fbRam,
+ sc->tmuConfig.tmuRam,
+ sc->nTexelfx);
+ }
+ else {
+ strcpy(buf, "Glide v0.30 UNKNOWN");
+ }
+ return (GLubyte *) buf;
+ }
+ default:
+ return NULL;
+ }
+#endif
+}
+
+
+int fxDDInitFxMesaContext( fxMesaContext fxMesa )
+{
+
+ FX_setupGrVertexLayout();
+
+ 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;
+
+ 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;
+ fxMesa->lastUnitsMode=FX_UM_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_grColorMask(FXTRUE, fxMesa->haveAlphaBuffer ? FXTRUE : FXFALSE);
+ if(fxMesa->haveDoubleBuffer) {
+ fxMesa->currentFB=GR_BUFFER_BACKBUFFER;
+ FX_grRenderBuffer(GR_BUFFER_BACKBUFFER);
+ } else {
+ fxMesa->currentFB=GR_BUFFER_FRONTBUFFER;
+ FX_grRenderBuffer(GR_BUFFER_FRONTBUFFER);
+ }
+
+ fxMesa->state = NULL;
+ fxMesa->fogTable = NULL;
+
+ fxMesa->state = malloc(FX_grGetInteger(FX_GLIDE_STATE_SIZE));
+ fxMesa->fogTable = malloc(FX_grGetInteger(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->haveZBuffer)
+ FX_grDepthBufferMode(GR_DEPTHBUFFER_ZBUFFER);
+
+#if (!FXMESA_USE_ARGB)
+ FX_grLfbWriteColorFormat(GR_COLORFORMAT_ABGR); /* Not every Glide has this */
+#endif
+
+ fxMesa->textureAlign=FX_grGetInteger(FX_TEXTURE_ALIGN);
+ fxMesa->glCtx->Const.MaxTextureLevels=9;
+ fxMesa->glCtx->Const.MaxTextureSize=256;
+ 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((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);
+
+ /* Run the config file */
+ gl_context_initialize( fxMesa->glCtx );
+
+ return 1;
+}
+
+
+#if 0
+/* Example extension function */
+static void fxFooBarEXT(GLint i)
+{
+ printf("You called glFooBarEXT(%d)\n", i);
+}
+#endif
+
+
+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_add(ctx, DEFAULT_ON, "3DFX_set_global_palette", 0);
+
+ if (!fxMesa->haveTwoTMUs)
+ gl_extensions_disable(ctx, "GL_EXT_texture_env_add");
+
+ if (!fxMesa->emulateTwoTMUs)
+ gl_extensions_disable(ctx, "GL_ARB_multitexture");
+
+
+ /* 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
+}
+
+
+/************************************************************************/
+/************************************************************************/
+/************************************************************************/
+
+/* 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->RasterMask & (STENCIL_BIT | MULTI_DRAW_BIT)) ||
+ ((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 (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;
+ }
+ }
+
+ 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 */
+ FX_grCullMode(GR_CULL_DISABLE);
+ FX_CONTEXT(ctx)->cullMode=GR_CULL_DISABLE;
+ }
+ }
+}
+
+void fxSetupDDPointers(GLcontext *ctx)
+{
+ if (MESA_VERBOSE&VERBOSE_DRIVER) {
+ fprintf(stderr,"fxmesa: fxSetupDDPointers()\n");
+ }
+
+ ctx->Driver.UpdateState=fxDDUpdateDDPointers;
+
+ ctx->Driver.WriteDepthSpan=fxDDWriteDepthSpan;
+ ctx->Driver.WriteDepthPixels=fxDDWriteDepthPixels;
+ ctx->Driver.ReadDepthSpan=fxDDReadDepthSpan;
+ ctx->Driver.ReadDepthPixels=fxDDReadDepthPixels;
+
+ ctx->Driver.GetString=fxDDGetString;
+
+ ctx->Driver.Dither=fxDDDither;
+
+ ctx->Driver.NearFar=fxDDSetNearFar;
+
+ ctx->Driver.GetParameteri=fxDDGetParameteri;
+
+ 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.Bitmap=fxDDDrawBitmap;
+ ctx->Driver.DrawPixels=NULL;
+ ctx->Driver.ReadPixels=fxDDReadPixels;
+
+ ctx->Driver.Finish=fxDDFinish;
+ ctx->Driver.Flush=NULL;
+
+ ctx->Driver.RenderStart=NULL;
+ ctx->Driver.RenderFinish=NULL;
+
+ ctx->Driver.TexImage2D = fxDDTexImage2D;
+ ctx->Driver.TexSubImage2D = fxDDTexSubImage2D;
+ ctx->Driver.GetTexImage = fxDDGetTexImage;
+ ctx->Driver.TexEnv=fxDDTexEnv;
+ ctx->Driver.TexParameter=fxDDTexParam;
+ ctx->Driver.BindTexture=fxDDTexBind;
+ ctx->Driver.DeleteTexture=fxDDTexDel;
+ ctx->Driver.UpdateTexturePalette=fxDDTexPalette;
+
+ ctx->Driver.RectFunc=NULL;
+
+ ctx->Driver.AlphaFunc=fxDDAlphaFunc;
+ ctx->Driver.BlendFunc=fxDDBlendFunc;
+ 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);
+}
+
+
+#else
+
+
+/*
+ * Need this to provide at least one external definition.
+ */
+
+int gl_fx_dummy_function_dd(void)
+{
+ return 0;
+}
+
+#endif /* FX */
+
diff --git a/xc/extras/Mesa/src/FX/fxddspan.c b/xc/extras/Mesa/src/FX/fxddspan.c
new file mode 100644
index 000000000..c620cc3c6
--- /dev/null
+++ b/xc/extras/Mesa/src/FX/fxddspan.c
@@ -0,0 +1,642 @@
+/* -*- mode: C; tab-width:8; c-basic-offset:2 -*- */
+
+/*
+ * 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 */
+
+
+#ifdef HAVE_CONFIG_H
+#include "conf.h"
+#endif
+
+#if defined(FX)
+
+#include "fxdrv.h"
+
+#ifdef _MSC_VER
+#ifdef _WIN32
+#pragma warning( disable : 4090 4022 )
+/* 4101 : "different 'const' qualifier"
+ * 4022 : "pointer mistmatch for actual parameter 'n'
+ */
+#endif
+#endif
+
+
+#if !defined(FXMESA_USE_ARGB)
+
+
+#if defined(FX_GLIDE3) && defined(XF86DRI)
+
+static FxBool writeRegionClipped(fxMesaContext fxMesa, GrBuffer_t dst_buffer,
+ FxU32 dst_x, FxU32 dst_y, GrLfbSrcFmt_t src_format,
+ FxU32 src_width, FxU32 src_height, FxI32 src_stride,
+ void *src_data)
+{
+ int i, x, w, srcElt;
+ void *data;
+
+ if (src_width==1 && src_height==1) { /* Easy case writing a point */
+ for (i=0; i<fxMesa->numClipRects; i++) {
+ if ((dst_x>=fxMesa->pClipRects[i].x1) &&
+ (dst_x<fxMesa->pClipRects[i].x2) &&
+ (dst_y>=fxMesa->pClipRects[i].y1) &&
+ (dst_y<fxMesa->pClipRects[i].y2)) {
+ FX_grLfbWriteRegion(dst_buffer, dst_x, dst_y, src_format,
+ 1, 1, src_stride, src_data);
+ return GL_TRUE;
+ }
+ }
+ } else if (src_height==1) { /* Writing a span */
+ if (src_format==GR_LFB_SRC_FMT_8888) srcElt=4;
+ else if (src_format==GR_LFB_SRC_FMT_ZA16) srcElt=2;
+ else {
+ fprintf(stderr, "Unknown src_format passed to writeRegionClipped\n");
+ return GL_FALSE;
+ }
+ for (i=0; i<fxMesa->numClipRects; i++) {
+ if (dst_y>=fxMesa->pClipRects[i].y1 && dst_y<fxMesa->pClipRects[i].y2) {
+ if (dst_x<fxMesa->pClipRects[i].x1) {
+ x=fxMesa->pClipRects[i].x1;
+ data=((char*)src_data)+srcElt*(x - dst_x);
+ w=src_width-(x-dst_x);
+ } else {
+ x=dst_x;
+ data=src_data;
+ w=src_width;
+ }
+ if (x+w>fxMesa->pClipRects[i].x2) {
+ w=fxMesa->pClipRects[i].x2-x;
+ }
+ FX_grLfbWriteRegion(dst_buffer, x, dst_y, src_format, w, 1,
+ src_stride, data);
+ }
+ }
+ } else { /* Punt on the case of arbitrary rectangles */
+ return GL_FALSE;
+ }
+ return GL_TRUE;
+}
+
+#else
+
+#define writeRegionClipped(fxm,dst_buffer,dst_x,dst_y,src_format,src_width,src_height,src_stride,src_data) \
+ FX_grLfbWriteRegion(dst_buffer,dst_x,dst_y,src_format,src_width,src_height,src_stride,src_data)
+
+#endif
+
+
+/* KW: Rearranged the args in the call to grLfbWriteRegion().
+ */
+#define LFB_WRITE_SPAN_MESA(dst_buffer, \
+ dst_x, \
+ dst_y, \
+ src_width, \
+ src_stride, \
+ src_data) \
+ writeRegionClipped(fxMesa, dst_buffer, \
+ dst_x, \
+ dst_y, \
+ GR_LFB_SRC_FMT_8888, \
+ src_width, \
+ 1, \
+ src_stride, \
+ src_data) \
+
+
+#else /* !defined(FXMESA_USE_RGBA) */
+
+#define writeRegionClipped(fxm,dst_buffer,dst_x,dst_y,src_format,src_width,src_height,src_stride,src_data) \
+ FX_grLfbWriteRegion(dst_buffer,dst_x,dst_y,src_format,src_width,src_height,src_stride,src_data)
+
+
+#define MESACOLOR_TO_ARGB(c) ( \
+ ( ((unsigned int)(c[ACOMP]))<<24 ) | \
+ ( ((unsigned int)(c[RCOMP]))<<16 ) | \
+ ( ((unsigned int)(c[GCOMP]))<<8 ) | \
+ ( (unsigned int)(c[BCOMP])) )
+
+inline void LFB_WRITE_SPAN_MESA(GrBuffer_t dst_buffer,
+ FxU32 dst_x,
+ FxU32 dst_y,
+ FxU32 src_width,
+ FxI32 src_stride,
+ void *src_data )
+{
+ /* Covert to ARGB */
+ GLubyte (*rgba)[4] = src_data;
+ GLuint argb[MAX_WIDTH];
+ int i;
+
+ for (i = 0; i < src_width; i++)
+ {
+ argb[i] = MESACOLOR_TO_ARGB(rgba[i]);
+ }
+ writeRegionClipped( /*fxMesa,*/ NULL, dst_buffer,
+ dst_x,
+ dst_y,
+ GR_LFB_SRC_FMT_8888,
+ src_width,
+ 1,
+ src_stride,
+ (void*)argb);
+}
+
+#endif /* !defined(FXMESA_USE_RGBA) */
+
+
+/************************************************************************/
+/***** Span functions *****/
+/************************************************************************/
+
+
+static void fxDDWriteRGBASpan(const GLcontext *ctx,
+ GLuint n, GLint x, GLint y,
+ const GLubyte rgba[][4], const GLubyte mask[])
+{
+ fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+ GLuint i;
+ GLint bottom=fxMesa->height+fxMesa->y_offset-1;
+
+ if (MESA_VERBOSE&VERBOSE_DRIVER) {
+ fprintf(stderr,"fxmesa: fxDDWriteRGBASpan(...)\n");
+ }
+
+ x+=fxMesa->x_offset;
+ if (mask) {
+ int span=0;
+
+ for (i=0;i<n;i++) {
+ if (mask[i]) {
+ ++span;
+ } else {
+ if (span > 0) {
+ LFB_WRITE_SPAN_MESA( fxMesa->currentFB, x+i-span, bottom-y,
+ /* GR_LFB_SRC_FMT_8888,*/ span, /*1,*/ 0, (void *) rgba[i-span] );
+ span = 0;
+ }
+ }
+ }
+
+ if (span > 0)
+ LFB_WRITE_SPAN_MESA( fxMesa->currentFB, x+n-span, bottom-y,
+ /* GR_LFB_SRC_FMT_8888, */ span, /*1,*/ 0, (void *) rgba[n-span] );
+ } else
+ LFB_WRITE_SPAN_MESA( fxMesa->currentFB, x, bottom-y,/* GR_LFB_SRC_FMT_8888,*/
+ n,/* 1,*/ 0, (void *) rgba );
+}
+
+
+static void fxDDWriteRGBSpan(const GLcontext *ctx,
+ GLuint n, GLint x, GLint y,
+ const GLubyte rgb[][3], const GLubyte mask[])
+{
+ fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+ GLuint i;
+ GLint bottom=fxMesa->height+fxMesa->y_offset-1;
+ GLubyte rgba[MAX_WIDTH][4];
+
+ if (MESA_VERBOSE&VERBOSE_DRIVER) {
+ fprintf(stderr,"fxmesa: fxDDWriteRGBSpan()\n");
+ }
+
+ x+=fxMesa->x_offset;
+ if (mask) {
+ int span=0;
+
+ for (i=0;i<n;i++) {
+ if (mask[i]) {
+ rgba[span][RCOMP] = rgb[i][0];
+ rgba[span][GCOMP] = rgb[i][1];
+ rgba[span][BCOMP] = rgb[i][2];
+ rgba[span][ACOMP] = 255;
+ ++span;
+ } else {
+ if (span > 0) {
+ LFB_WRITE_SPAN_MESA( fxMesa->currentFB, x+i-span, bottom-y,
+ /*GR_LFB_SRC_FMT_8888,*/ span,/* 1,*/ 0, (void *) rgba );
+ span = 0;
+ }
+ }
+ }
+
+ if (span > 0)
+ LFB_WRITE_SPAN_MESA( fxMesa->currentFB, x+n-span, bottom-y,
+ /*GR_LFB_SRC_FMT_8888,*/ span,/* 1,*/ 0, (void *) rgba );
+ } else {
+ for (i=0;i<n;i++) {
+ rgba[i][RCOMP]=rgb[i][0];
+ rgba[i][GCOMP]=rgb[i][1];
+ rgba[i][BCOMP]=rgb[i][2];
+ rgba[i][ACOMP]=255;
+ }
+
+ LFB_WRITE_SPAN_MESA( fxMesa->currentFB, x, bottom-y,/* GR_LFB_SRC_FMT_8888,*/
+ n,/* 1,*/ 0, (void *) rgba );
+ }
+}
+
+
+static void fxDDWriteMonoRGBASpan(const GLcontext *ctx,
+ GLuint n, GLint x, GLint y,
+ const GLubyte mask[])
+{
+ fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+ GLuint i;
+ GLint bottom=fxMesa->height+fxMesa->y_offset-1;
+ GLuint data[MAX_WIDTH];
+
+ if (MESA_VERBOSE&VERBOSE_DRIVER) {
+ fprintf(stderr,"fxmesa: fxDDWriteMonoRGBASpan(...)\n");
+ }
+
+ x+=fxMesa->x_offset;
+ if (mask) {
+ int span=0;
+
+ for (i=0;i<n;i++) {
+ if (mask[i]) {
+ data[span] = (GLuint) fxMesa->color;
+ ++span;
+ } else {
+ if (span > 0) {
+ writeRegionClipped(fxMesa, fxMesa->currentFB, x+i-span, bottom-y,
+ GR_LFB_SRC_FMT_8888, span, 1, 0,
+ (void *) data );
+ span = 0;
+ }
+ }
+ }
+
+ if (span > 0)
+ writeRegionClipped(fxMesa, fxMesa->currentFB, x+n-span, bottom-y,
+ GR_LFB_SRC_FMT_8888, span, 1, 0,
+ (void *) data );
+ } else {
+ for (i=0;i<n;i++) {
+ data[i]=(GLuint) fxMesa->color;
+ }
+
+ writeRegionClipped(fxMesa, fxMesa->currentFB, x, bottom-y, GR_LFB_SRC_FMT_8888,
+ n, 1, 0, (void *) data );
+ }
+}
+
+
+#if 0
+static void fxDDReadRGBASpan(const GLcontext *ctx,
+ GLuint n, GLint x, GLint y, GLubyte rgba[][4])
+{
+ fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+ GLushort data[MAX_WIDTH];
+ GLuint i;
+ GLint bottom=fxMesa->height+fxMesa->y_offset-1;
+
+ printf("read span %d, %d, %d\n", x,y,n);
+ if (MESA_VERBOSE&VERBOSE_DRIVER) {
+ fprintf(stderr,"fxmesa: fxDDReadRGBASpan(...)\n");
+ }
+
+ assert(n < MAX_WIDTH);
+
+ x+=fxMesa->x_offset;
+ FX_grLfbReadRegion( fxMesa->currentFB, x, bottom-y, n, 1, 0, data);
+
+ for (i=0;i<n;i++) {
+ GLushort pixel = data[i];
+ rgba[i][RCOMP] = FX_PixelToR[pixel];
+ rgba[i][GCOMP] = FX_PixelToG[pixel];
+ rgba[i][BCOMP] = FX_PixelToB[pixel];
+ rgba[i][ACOMP] = 255;
+ }
+}
+#endif
+
+
+/*
+ * 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=(fxMesaContext)ctx->DriverCtx;
+ GrLfbInfo_t info;
+ BEGIN_BOARD_LOCK();
+ 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 *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[pixel0];
+ rgba[i][GCOMP] = FX_PixelToG[pixel0];
+ rgba[i][BCOMP] = FX_PixelToB[pixel0];
+ rgba[i][ACOMP] = 255;
+ rgba[i+1][RCOMP] = FX_PixelToR[pixel1];
+ rgba[i+1][GCOMP] = FX_PixelToG[pixel1];
+ rgba[i+1][BCOMP] = FX_PixelToB[pixel1];
+ rgba[i+1][ACOMP] = 255;
+ }
+ if (extraPixel) {
+ GLushort pixel = data16[n];
+ rgba[n][RCOMP] = FX_PixelToR[pixel];
+ rgba[n][GCOMP] = FX_PixelToG[pixel];
+ rgba[n][BCOMP] = FX_PixelToB[pixel];
+ rgba[n][ACOMP] = 255;
+ }
+
+ grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB);
+ }
+ END_BOARD_LOCK();
+}
+
+
+/************************************************************************/
+/***** Pixel functions *****/
+/************************************************************************/
+
+static void fxDDWriteRGBAPixels(const GLcontext *ctx,
+ GLuint n, const GLint x[], const GLint y[],
+ CONST GLubyte rgba[][4], const GLubyte mask[])
+{
+ fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+ GLuint i;
+ GLint bottom=fxMesa->height+fxMesa->y_offset-1;
+
+ if (MESA_VERBOSE&VERBOSE_DRIVER) {
+ fprintf(stderr,"fxmesa: fxDDWriteRGBAPixels(...)\n");
+ }
+
+ for(i=0;i<n;i++)
+ if(mask[i])
+ LFB_WRITE_SPAN_MESA(fxMesa->currentFB, x[i]+fxMesa->x_offset, bottom-y[i],
+ 1, 1, (void *)rgba[i]);
+}
+
+static void fxDDWriteMonoRGBAPixels(const GLcontext *ctx,
+ GLuint n, const GLint x[], const GLint y[],
+ const GLubyte mask[])
+{
+ fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+ GLuint i;
+ GLint bottom=fxMesa->height+fxMesa->y_offset-1;
+
+ if (MESA_VERBOSE&VERBOSE_DRIVER) {
+ fprintf(stderr,"fxmesa: fxDDWriteMonoRGBAPixels(...)\n");
+ }
+
+ for(i=0;i<n;i++)
+ if(mask[i])
+ writeRegionClipped(fxMesa, fxMesa->currentFB,x[i]+fxMesa->x_offset,bottom-y[i],
+ GR_LFB_SRC_FMT_8888,1,1,0,(void *) &fxMesa->color);
+}
+
+
+static void read_R5G6B5_pixels(const GLcontext *ctx,
+ GLuint n, const GLint x[], const GLint y[],
+ GLubyte rgba[][4], const GLubyte mask[])
+{
+ fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
+ GrLfbInfo_t info;
+ BEGIN_BOARD_LOCK();
+ 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 / 2);
+#else
+ const GLint srcStride = info.strideInBytes / 2; /* stride in GLushorts */
+#endif
+ const GLint winX = fxMesa->x_offset;
+ const GLint winY = fxMesa->y_offset + fxMesa->height - 1;
+ 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]);
+ const GLushort pixel = *data16;
+ rgba[i][RCOMP] = FX_PixelToR[pixel];
+ rgba[i][GCOMP] = FX_PixelToG[pixel];
+ rgba[i][BCOMP] = FX_PixelToB[pixel];
+ rgba[i][ACOMP] = 255;
+ }
+ }
+ grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB);
+ }
+ END_BOARD_LOCK();
+}
+
+
+
+/************************************************************************/
+/***** Depth functions *****/
+/************************************************************************/
+
+void fxDDWriteDepthSpan(GLcontext *ctx,
+ GLuint n, GLint x, GLint y, const GLdepth depth[],
+ const GLubyte mask[])
+{
+ fxMesaContext fxMesa = (fxMesaContext)ctx->DriverCtx;
+ GLint bottom = fxMesa->height + fxMesa->y_offset - 1;
+
+ if (MESA_VERBOSE & VERBOSE_DRIVER) {
+ fprintf(stderr, "fxmesa: fxDDWriteDepthSpan(...)\n");
+ }
+
+ x += fxMesa->x_offset;
+
+ if (mask) {
+ GLint i;
+ for (i = 0; i < n; i++) {
+ if (mask[i]) {
+ GLshort d = depth[i];
+ writeRegionClipped(fxMesa, GR_BUFFER_AUXBUFFER, x + i, bottom - y,
+ GR_LFB_SRC_FMT_ZA16, 1, 1, 0, (void *) &d);
+ }
+ }
+ }
+ else {
+ GLushort depth16[MAX_WIDTH];
+ GLint i;
+ for (i = 0; i < n; i++) {
+ depth16[i] = depth[i];
+ }
+ writeRegionClipped(fxMesa, GR_BUFFER_AUXBUFFER, x, bottom - y,
+ GR_LFB_SRC_FMT_ZA16, n, 1, 0, (void *) depth16);
+ }
+}
+
+
+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;
+
+ if (MESA_VERBOSE & VERBOSE_DRIVER) {
+ fprintf(stderr, "fxmesa: fxDDReadDepthSpan(...)\n");
+ }
+
+ x += fxMesa->x_offset;
+ FX_grLfbReadRegion(GR_BUFFER_AUXBUFFER, x, bottom - y, n, 1, 0, depth16);
+ for (i = 0; i < n; i++) {
+ depth[i] = depth16[i];
+ }
+}
+
+
+
+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;
+
+ if (MESA_VERBOSE & VERBOSE_DRIVER) {
+ fprintf(stderr, "fxmesa: fxDDWriteDepthPixels(...)\n");
+ }
+
+ for (i = 0; i < n; i++) {
+ if (mask[i]) {
+ int xpos = x[i] + fxMesa->x_offset;
+ int ypos = bottom - y[i];
+ GLushort d = depth[i];
+ writeRegionClipped(fxMesa, GR_BUFFER_AUXBUFFER, xpos, ypos,
+ GR_LFB_SRC_FMT_ZA16, 1, 1, 0, (void *) &d);
+ }
+ }
+}
+
+
+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;
+
+ if (MESA_VERBOSE & VERBOSE_DRIVER) {
+ fprintf(stderr, "fxmesa: fxDDReadDepthPixels(...)\n");
+ }
+
+ for (i = 0; i < n; i++) {
+ int xpos = x[i] + fxMesa->x_offset;
+ int ypos = bottom - y[i];
+ GLushort d;
+ FX_grLfbReadRegion(GR_BUFFER_AUXBUFFER, xpos, ypos, 1, 1, 0, &d);
+ depth[i] = d;
+ }
+}
+
+
+
+
+/************************************************************************/
+
+
+void fxSetupDDSpanPointers(GLcontext *ctx)
+{
+ ctx->Driver.WriteRGBASpan =fxDDWriteRGBASpan;
+ ctx->Driver.WriteRGBSpan =fxDDWriteRGBSpan;
+ ctx->Driver.WriteMonoRGBASpan =fxDDWriteMonoRGBASpan;
+ ctx->Driver.WriteRGBAPixels =fxDDWriteRGBAPixels;
+ ctx->Driver.WriteMonoRGBAPixels =fxDDWriteMonoRGBAPixels;
+
+ ctx->Driver.WriteCI8Span =NULL;
+ ctx->Driver.WriteCI32Span =NULL;
+ ctx->Driver.WriteMonoCISpan =NULL;
+ ctx->Driver.WriteCI32Pixels =NULL;
+ ctx->Driver.WriteMonoCIPixels =NULL;
+
+ /* ctx->Driver.ReadRGBASpan =fxDDReadRGBASpan;*/
+ ctx->Driver.ReadRGBASpan = read_R5G6B5_span;
+ ctx->Driver.ReadRGBAPixels = read_R5G6B5_pixels;
+
+ ctx->Driver.ReadCI32Span =NULL;
+ ctx->Driver.ReadCI32Pixels =NULL;
+}
+
+
+#else
+
+
+/*
+ * Need this to provide at least one external definition.
+ */
+
+int gl_fx_dummy_function_span(void)
+{
+ return 0;
+}
+
+#endif /* FX */
diff --git a/xc/extras/Mesa/src/FX/fxddtex.c b/xc/extras/Mesa/src/FX/fxddtex.c
new file mode 100644
index 000000000..dd2bf4456
--- /dev/null
+++ b/xc/extras/Mesa/src/FX/fxddtex.c
@@ -0,0 +1,1197 @@
+/* -*- mode: C; tab-width:8; c-basic-offset:2 -*- */
+
+/*
+ * 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.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "conf.h"
+#endif
+
+#if defined(FX)
+
+#include "fxdrv.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)))) {
+ fprintf(stderr,"fx Driver: out of memory !\n");
+ fxCloseHardware();
+ exit(-1);
+ }
+
+ 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;
+}
+
+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);
+ }
+
+ }
+
+ 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;
+ }
+}
+
+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;
+}
+
+
+
+/*
+ * 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(GR_TMU0,GR_TEXTABLE_PALETTE, &(fxMesa->glbPalette));
+ if (fxMesa->haveTwoTMUs)
+ FX_grTexDownloadTable(GR_TMU1, GR_TEXTABLE_PALETTE, &(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(l2) (0x800000 * l2)
+
+
+int fxTexGetInfo(int w, int h, GrLOD_t *lodlevel, GrAspectRatio_t *ar,
+ float *sscale, float *tscale,
+ int *i_sscale, int *i_tscale,
+ int *wscale, int *hscale)
+{
+
+ static GrLOD_t lod[9]={GR_LOD_256,GR_LOD_128,GR_LOD_64,GR_LOD_32,
+ GR_LOD_16,GR_LOD_8,GR_LOD_4,GR_LOD_2,GR_LOD_1};
+
+ int logw,logh,ws,hs;
+ GrLOD_t l;
+ GrAspectRatio_t aspectratio;
+ float s,t;
+ int is,it;
+
+ logw=logbase2(w);
+ logh=logbase2(h);
+
+ switch(logw-logh) {
+ case 0:
+ aspectratio=GR_ASPECT_1x1;
+ l=lod[8-logw];
+ s=t=256.0f;
+ is=it=INT_TRICK(8);
+ ws=hs=1;
+ break;
+ case 1:
+ aspectratio=GR_ASPECT_2x1;
+ l=lod[8-logw];
+ s=256.0f;
+ t=128.0f;
+ is=INT_TRICK(8);it=INT_TRICK(7);
+ ws=1;
+ hs=1;
+ break;
+ case 2:
+ aspectratio=GR_ASPECT_4x1;
+ l=lod[8-logw];
+ s=256.0f;
+ t=64.0f;
+ is=INT_TRICK(8);it=INT_TRICK(6);
+ ws=1;
+ hs=1;
+ break;
+ case 3:
+ aspectratio=GR_ASPECT_8x1;
+ l=lod[8-logw];
+ s=256.0f;
+ t=32.0f;
+ is=INT_TRICK(8);it=INT_TRICK(5);
+ ws=1;
+ hs=1;
+ break;
+ case 4:
+ aspectratio=GR_ASPECT_8x1;
+ l=lod[8-logw];
+ s=256.0f;
+ t=32.0f;
+ is=INT_TRICK(8);it=INT_TRICK(5);
+ ws=1;
+ hs=2;
+ break;
+ case 5:
+ aspectratio=GR_ASPECT_8x1;
+ l=lod[8-logw];
+ s=256.0f;
+ t=32.0f;
+ is=INT_TRICK(8);it=INT_TRICK(5);
+ ws=1;
+ hs=4;
+ break;
+ case 6:
+ aspectratio=GR_ASPECT_8x1;
+ l=lod[8-logw];
+ s=256.0f;
+ t=32.0f;
+ is=INT_TRICK(8);it=INT_TRICK(5);
+ ws=1;
+ hs=8;
+ break;
+ case 7:
+ aspectratio=GR_ASPECT_8x1;
+ l=lod[8-logw];
+ s=256.0f;
+ t=32.0f;
+ is=INT_TRICK(8);it=INT_TRICK(5);
+ ws=1;
+ hs=16;
+ break;
+ case 8:
+ aspectratio=GR_ASPECT_8x1;
+ l=lod[8-logw];
+ s=256.0f;
+ t=32.0f;
+ is=INT_TRICK(8);it=INT_TRICK(5);
+ ws=1;
+ hs=32;
+ break;
+ case -1:
+ aspectratio=GR_ASPECT_1x2;
+ l=lod[8-logh];
+ s=128.0f;
+ t=256.0f;
+ is=INT_TRICK(7);it=INT_TRICK(8);
+ ws=1;
+ hs=1;
+ break;
+ case -2:
+ aspectratio=GR_ASPECT_1x4;
+ l=lod[8-logh];
+ s=64.0f;
+ t=256.0f;
+ is=INT_TRICK(6);it=INT_TRICK(8);
+ ws=1;
+ hs=1;
+ break;
+ case -3:
+ aspectratio=GR_ASPECT_1x8;
+ l=lod[8-logh];
+ s=32.0f;
+ t=256.0f;
+ is=INT_TRICK(5);it=INT_TRICK(8);
+ ws=1;
+ hs=1;
+ break;
+ case -4:
+ aspectratio=GR_ASPECT_1x8;
+ l=lod[8-logh];
+ s=32.0f;
+ t=256.0f;
+ is=INT_TRICK(5);it=INT_TRICK(8);
+ ws=2;
+ hs=1;
+ break;
+ case -5:
+ aspectratio=GR_ASPECT_1x8;
+ l=lod[8-logh];
+ s=32.0f;
+ t=256.0f;
+ is=INT_TRICK(5);it=INT_TRICK(8);
+ ws=4;
+ hs=1;
+ break;
+ case -6:
+ aspectratio=GR_ASPECT_1x8;
+ l=lod[8-logh];
+ s=32.0f;
+ t=256.0f;
+ is=INT_TRICK(5);it=INT_TRICK(8);
+ ws=8;
+ hs=1;
+ break;
+ case -7:
+ aspectratio=GR_ASPECT_1x8;
+ l=lod[8-logh];
+ s=32.0f;
+ t=256.0f;
+ is=INT_TRICK(5);it=INT_TRICK(8);
+ ws=16;
+ hs=1;
+ break;
+ case -8:
+ aspectratio=GR_ASPECT_1x8;
+ l=lod[8-logh];
+ s=32.0f;
+ t=256.0f;
+ is=INT_TRICK(5);it=INT_TRICK(8);
+ ws=32;
+ hs=1;
+ break;
+ default:
+ return 0;
+ break;
+ }
+
+ if(lodlevel)
+ (*lodlevel)=l;
+
+ if(ar)
+ (*ar)=aspectratio;
+
+ 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;
+
+
+ return 1;
+}
+
+/*
+ * Given an OpenGL internal texture format, return the corresponding
+ * Glide internal texture format and base texture format.
+ */
+void fxTexGetFormat(GLenum glformat, GrTextureFormat_t *tfmt, GLint *ifmt)
+{
+ switch(glformat) {
+ case 1:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE4:
+ case GL_LUMINANCE8:
+ case GL_LUMINANCE12:
+ case GL_LUMINANCE16:
+ if(tfmt)
+ (*tfmt)=GR_TEXFMT_INTENSITY_8;
+ if(ifmt)
+ (*ifmt)=GL_LUMINANCE;
+ 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(tfmt)
+ (*tfmt)=GR_TEXFMT_ALPHA_INTENSITY_88;
+ if(ifmt)
+ (*ifmt)=GL_LUMINANCE_ALPHA;
+ break;
+ case GL_INTENSITY:
+ case GL_INTENSITY4:
+ case GL_INTENSITY8:
+ case GL_INTENSITY12:
+ case GL_INTENSITY16:
+ if(tfmt)
+ (*tfmt)=GR_TEXFMT_ALPHA_8;
+ if(ifmt)
+ (*ifmt)=GL_INTENSITY;
+ break;
+ case GL_ALPHA:
+ case GL_ALPHA4:
+ case GL_ALPHA8:
+ case GL_ALPHA12:
+ case GL_ALPHA16:
+ if(tfmt)
+ (*tfmt)=GR_TEXFMT_ALPHA_8;
+ if(ifmt)
+ (*ifmt)=GL_ALPHA;
+ break;
+ case 3:
+ case GL_RGB:
+ case GL_R3_G3_B2:
+ case GL_RGB4:
+ case GL_RGB5:
+ case GL_RGB8:
+ case GL_RGB10:
+ case GL_RGB12:
+ case GL_RGB16:
+ if(tfmt)
+ (*tfmt)=GR_TEXFMT_RGB_565;
+ if(ifmt)
+ (*ifmt)=GL_RGB;
+ break;
+ case 4:
+ case GL_RGBA:
+ case GL_RGBA2:
+ case GL_RGBA4:
+ case GL_RGBA8:
+ case GL_RGB10_A2:
+ case GL_RGBA12:
+ case GL_RGBA16:
+ if(tfmt)
+ (*tfmt)=GR_TEXFMT_ARGB_4444;
+ if(ifmt)
+ (*ifmt)=GL_RGBA;
+ break;
+ case GL_RGB5_A1:
+ if(tfmt)
+ (*tfmt)=GR_TEXFMT_ARGB_1555;
+ if(ifmt)
+ (*ifmt)=GL_RGBA;
+ 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(tfmt)
+ (*tfmt)=GR_TEXFMT_P_8;
+ if(ifmt)
+ (*ifmt)=GL_RGBA; /* XXX why is this RGBA? */
+ break;
+ default:
+ fprintf(stderr,
+ "fx Driver: unsupported internalFormat in fxTexGetFormat()\n");
+ fxCloseHardware();
+ exit(-1);
+ break;
+ }
+}
+
+static GLboolean fxIsTexSupported(GLenum target, GLint internalFormat,
+ const struct gl_texture_image *image)
+{
+ if(target != GL_TEXTURE_2D)
+ return GL_FALSE;
+
+ if(!fxTexGetInfo(image->Width,image->Height,NULL,NULL,NULL,NULL,NULL,NULL,
+ NULL,NULL))
+ return GL_FALSE;
+
+ if (image->Border > 0)
+ return GL_FALSE;
+
+ return GL_TRUE;
+}
+
+
+/**********************************************************************/
+/**** NEW TEXTURE IMAGE FUNCTIONS ****/
+/**********************************************************************/
+
+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 = (fxMesaContext)ctx->DriverCtx;
+
+ if (target != GL_TEXTURE_2D)
+ return GL_FALSE;
+
+ if (!texObj->DriverData)
+ texObj->DriverData = fxAllocTexObjData(fxMesa);
+
+ if (fxIsTexSupported(target, texImage->IntFormat, texImage)) {
+ GrTextureFormat_t gldformat;
+ tfxTexInfo *ti = fxTMGetTexInfo(texObj);
+ tfxMipMapLevel *mml = &ti->mipmapLevel[level];
+ GLint dstWidth, dstHeight, wScale, hScale, texelSize, dstStride;
+ MesaIntTexFormat intFormat;
+
+ fxTexGetFormat(texImage->IntFormat, &gldformat, NULL);
+
+ fxTexGetInfo(texImage->Width, texImage->Height, NULL,NULL,NULL,NULL,
+ NULL,NULL, &wScale, &hScale);
+
+ dstWidth = texImage->Width * wScale;
+ dstHeight = texImage->Height * hScale;
+
+ switch (texImage->IntFormat) {
+ case GL_INTENSITY:
+ case GL_INTENSITY4:
+ case GL_INTENSITY8:
+ case GL_INTENSITY12:
+ case GL_INTENSITY16:
+ texelSize = 1;
+ intFormat = MESA_I8;
+ break;
+ case 1:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE4:
+ case GL_LUMINANCE8:
+ case GL_LUMINANCE12:
+ case GL_LUMINANCE16:
+ texelSize = 1;
+ intFormat = MESA_L8;
+ break;
+ case GL_ALPHA:
+ case GL_ALPHA4:
+ case GL_ALPHA8:
+ case GL_ALPHA12:
+ case GL_ALPHA16:
+ texelSize = 1;
+ intFormat = MESA_A8;
+ 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:
+ texelSize = 1;
+ intFormat = MESA_C8;
+ 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:
+ texelSize = 2;
+ intFormat = MESA_A8_L8;
+ break;
+ case 3:
+ case GL_RGB:
+ case GL_R3_G3_B2:
+ case GL_RGB4:
+ case GL_RGB5:
+ case GL_RGB8:
+ case GL_RGB10:
+ case GL_RGB12:
+ case GL_RGB16:
+ texelSize = 2;
+ intFormat = MESA_R5_G6_B5;
+ break;
+ case 4:
+ case GL_RGBA:
+ case GL_RGBA2:
+ case GL_RGBA4:
+ case GL_RGBA8:
+ case GL_RGB10_A2:
+ case GL_RGBA12:
+ case GL_RGBA16:
+ texelSize = 2;
+ intFormat = MESA_A4_R4_G4_B4;
+ break;
+ case GL_RGB5_A1:
+ texelSize = 2;
+ intFormat = MESA_A1_R5_G5_B5;
+ break;
+ default:
+ gl_problem(NULL, "tdfx driver: texbuildimagemap() bad format");
+ return GL_FALSE;
+ }
+
+ _mesa_set_teximage_component_sizes(intFormat, texImage);
+
+ /*printf("teximage:\n");*/
+ /* allocate new storage for texture image, if needed */
+ if (!mml->data || mml->glideFormat != gldformat ||
+ mml->width != dstWidth || mml->height != dstHeight) {
+ if (mml->data)
+ FREE(mml->data);
+ mml->data = MALLOC(dstWidth * dstHeight * texelSize);
+ if (!mml->data)
+ return GL_FALSE;
+ mml->glideFormat = gldformat;
+ mml->width = dstWidth;
+ mml->height = dstHeight;
+ fxTexInvalidate(ctx, texObj);
+ }
+
+ dstStride = dstWidth * texelSize;
+
+ /* store the texture image */
+ if (!_mesa_convert_teximage(intFormat, dstWidth, dstHeight, mml->data,
+ dstStride,
+ texImage->Width, texImage->Height,
+ format, type, pixels, packing)) {
+ return GL_FALSE;
+ }
+
+ if (ti->validated && ti->isInTM) {
+ /*printf("reloadmipmaplevels\n");*/
+ fxTMReloadMipMapLevel(fxMesa, texObj, level);
+ }
+ else {
+ /*printf("invalidate2\n");*/
+ fxTexInvalidate(ctx,texObj);
+ }
+
+ *retainInternalCopy = GL_FALSE;
+ return GL_TRUE;
+ }
+ else {
+ gl_problem(NULL, "fx Driver: unsupported texture in fxDDTexImg()\n");
+ return GL_FALSE;
+ }
+}
+
+
+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)
+{
+ fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
+ tfxTexInfo *ti;
+ GLint wscale, hscale, dstStride;
+ tfxMipMapLevel *mml;
+ GLboolean result;
+
+ if (target != GL_TEXTURE_2D)
+ return GL_FALSE;
+
+ if (!texObj->DriverData)
+ return GL_FALSE;
+
+ ti = fxTMGetTexInfo(texObj);
+ mml = &ti->mipmapLevel[level];
+
+ fxTexGetInfo( texImage->Width, texImage->Height, NULL,NULL,NULL,NULL,
+ NULL,NULL, &wscale, &hscale);
+
+ assert(mml->data); /* must have an existing texture image! */
+
+ 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_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)
+ fxTMReloadMipMapLevel(fxMesa, texObj, level);
+ else
+ fxTexInvalidate(ctx, texObj);
+
+ return GL_TRUE;
+}
+
+
+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");
+ }
+}
+
+
+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;
+
+ GLubyte *data = (GLubyte *) MALLOC(texImage->Width * texImage->Height * 4);
+ if (!data)
+ return NULL;
+
+ 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:
+ 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_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;
+ default:
+ gl_problem(NULL, "Bad glideFormat in fxDDGetTexImage");
+ return NULL;
+ }
+ _mesa_unconvert_teximage(mesaFormat, mml->width, mml->height, mml->data,
+ srcStride, texImage->Width, texImage->Height,
+ glFormat, data);
+ *formatOut = glFormat;
+ *typeOut = GL_UNSIGNED_BYTE;
+ *freeImageOut = GL_TRUE;
+ return data;
+ }
+ else {
+ return NULL;
+ }
+}
+
+
+#else
+
+
+/*
+ * Need this to provide at least one external definition.
+ */
+
+int gl_fx_dummy_function_ddtex(void)
+{
+ return 0;
+}
+
+#endif /* FX */
diff --git a/xc/extras/Mesa/src/FX/fxdrv.h b/xc/extras/Mesa/src/FX/fxdrv.h
new file mode 100644
index 000000000..c85c73d8e
--- /dev/null
+++ b/xc/extras/Mesa/src/FX/fxdrv.h
@@ -0,0 +1,686 @@
+/* -*- mode: C; tab-width:8; c-basic-offset:2 -*- */
+
+/*
+ * 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 FXDRV_H
+#define FXDRV_H
+
+/* If you comment out this define, a variable takes its place, letting
+ * you turn debugging on/off from the debugger.
+ */
+
+#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"
+
+#ifdef XF86DRI
+typedef struct tfxMesaContext *fxMesaContext;
+#else
+#include "GL/fxmesa.h"
+#endif
+#include "fxglidew.h"
+/* use gl/gl.h GLAPI/GLAPIENTRY/GLCALLBACK in place of WINGDIAPI/APIENTRY/CALLBACK, */
+/* these are defined in mesa gl/gl.h - tjump@spgs.com */
+
+
+
+extern void fx_sanity_triangle( 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
+
+
+#if FX_USE_PARGB
+
+#define CLIP_XCOORD 0 /* normal place */
+#define CLIP_YCOROD 1 /* normal place */
+#define CLIP_ZCOORD 2 /* normal place */
+#define CLIP_WCOORD 3 /* normal place */
+#define CLIP_GCOORD 4 /* GR_VERTEX_PARGB_OFFSET */
+#define CLIP_BCOORD 5 /* GR_VERTEX_SOW_TMU0_OFFSET */
+#define CLIP_RCOORD 6 /* GR_VERTEX_TOW_TMU0_OFFSET */
+#define CLIP_ACOORD 7 /* GR_VERTEX_OOW_TMU0_OFFSET */
+
+#else
+
+#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 */
+
+
+#endif
+
+/* Should have size == 16 * sizeof(float).
+ */
+typedef struct {
+ GLfloat f[15]; /* Same layout as GrVertex */
+ GLubyte mask; /* Unsued */
+ GLubyte usermask; /* Unused */
+} fxVertex;
+
+
+
+
+#if defined(FXMESA_USE_ARGB)
+#define FXCOLOR4( c ) ( \
+ ( ((unsigned int)(c[3]))<<24 ) | \
+ ( ((unsigned int)(c[0]))<<16 ) | \
+ ( ((unsigned int)(c[1]))<<8 ) | \
+ ( (unsigned int)(c[2])) )
+
+#else
+#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
+#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(FXCOLOR4(color)); \
+ } \
+ } else { \
+ FX_grConstantColorValue(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]); \
+}
+
+#if FX_USE_PARGB
+#define GOURAUD2(v, c) { \
+ GLubyte *col = c; \
+ v->argb=MESACOLOR2PARGB(col); \
+}
+#else
+#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]); \
+}
+#endif
+
+
+/* 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
+
+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 */
+ GrTextureFormat_t glideFormat; /* Glide image format */
+ unsigned short *data; /* Glide-formated texture image */
+} tfxMipMapLevel;
+
+typedef struct tfxTexInfo_t {
+ struct tfxTexInfo *next;
+ struct gl_texture_object *tObj;
+
+ GLuint lastTimeUsed;
+ FxU32 whichTMU;
+ GLboolean isInTM;
+
+ 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;
+
+ /* Depth test */
+
+ GLboolean depthTestEnabled;
+ GLboolean depthMask;
+ GrCmpFnc_t depthTestFunc;
+} 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
+
+/* 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(XFree86Server) || defined(GLX_DIRECT_RENDERING)
+#include "tdfx_init.h"
+#else
+#define DRI_FX_CONTEXT
+#define BEGIN_BOARD_LOCK()
+#define END_BOARD_LOCK()
+#define BEGIN_CLIP_LOOP()
+#define END_CLIP_LOOP()
+#endif
+
+
+/* These lookup table are used to extract RGB values in [0,255] from
+ * 16-bit pixel values.
+ */
+extern GLubyte FX_PixelToR[0x10000];
+extern GLubyte FX_PixelToG[0x10000];
+extern GLubyte FX_PixelToB[0x10000];
+
+
+struct tfxMesaContext {
+ GuTexPalette glbPalette;
+
+ GLcontext *glCtx; /* the core Mesa context */
+#if !defined(XFree86Server) && !defined(GLX_DIRECT_RENDERING)
+ GLvisual *glVis; /* describes the color buffer */
+ GLframebuffer *glBuffer; /* the ancillary buffers */
+#endif
+
+ GLint board; /* the board used for this context */
+ GLint width, height; /* size of color buffer */
+
+ GrBuffer_t currentFB;
+
+ GLboolean bgrOrder;
+ GrColor_t color;
+ GrColor_t clearC;
+ GrAlpha_t clearA;
+ GLuint constColor;
+ GrCullMode_t cullMode;
+
+ tfxUnitsState unitsState;
+ tfxUnitsState restoreUnitsState; /* saved during multipass */
+
+ 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 */
+
+ GLuint texBindNumber;
+ GLint tmuSrc;
+ GLuint lastUnitsMode;
+ 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 haveZBuffer;
+ GLboolean haveDoubleBuffer;
+ GLboolean haveGlobalPaletteTexture;
+ 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;
+
+ DRI_FX_CONTEXT
+};
+
+typedef void (*tfxSetupFunc)(struct vertex_buffer *, GLuint, GLuint);
+
+extern GrHwConfiguration glbHWConfig;
+extern int glbCurrentBoard;
+
+extern void fxPrintSetupFlags( const char *msg, GLuint flags );
+extern void fxSetupFXUnits(GLcontext *);
+extern void fxSetupDDPointers(GLcontext *);
+extern void fxDDSetNearFar(GLcontext *, GLfloat, GLfloat);
+
+extern void fxDDSetupInit(void);
+extern void fxDDCvaInit(void);
+extern void fxDDTrifuncInit(void);
+extern void fxDDFastPathInit(void);
+
+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 fxUpdateDDSpanPointers(GLcontext *);
+extern void fxSetupDDSpanPointers(GLcontext *);
+
+extern void fxPrintTextureData(tfxTexInfo *ti);
+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 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 void fxDDTexPalette(GLcontext *, struct gl_texture_object *);
+extern void fxDDTexUseGlbPalette(GLcontext *, GLboolean);
+
+extern void fxDDEnable(GLcontext *, GLenum, GLboolean);
+extern void fxDDAlphaFunc(GLcontext *, GLenum, GLclampf);
+extern void fxDDBlendFunc(GLcontext *, GLenum, GLenum);
+extern void fxDDDepthMask(GLcontext *, GLboolean);
+extern void fxDDDepthFunc(GLcontext *, GLenum);
+
+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 fxDDCheckMergeAndRender( GLcontext *ctx,
+ struct gl_pipeline_stage *d );
+
+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 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 );
+
+extern void fxDDRenderElementsDirect( struct vertex_buffer *VB );
+extern void fxDDRenderVBIndirectDirect( struct vertex_buffer *VB );
+
+extern void fxDDInitExtensions( GLcontext *ctx );
+
+#define fxTMGetTexInfo(o) ((tfxTexInfo*)((o)->DriverData))
+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 *);
+#define fxTMMoveOutTM_NoLock fxTMMoveOutTM
+extern void fxTMFreeTexture(fxMesaContext, struct gl_texture_object *);
+extern void fxTMReloadMipMapLevel(fxMesaContext, struct gl_texture_object *, GLint);
+extern void fxTMReloadSubMipMapLevel(fxMesaContext, struct gl_texture_object *,
+ GLint, GLint, GLint);
+
+extern void fxTexGetFormat(GLenum, GrTextureFormat_t *, GLint *);
+extern int fxTexGetInfo(int, int, GrLOD_t *, GrAspectRatio_t *,
+ float *, float *, int *, int *, int *, int *);
+
+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 fxDDWriteDepthSpan(GLcontext *ctx, GLuint n, GLint x, GLint y,
+ const GLdepth depth[], const GLubyte mask[]);
+
+extern void fxDDReadDepthSpan(GLcontext *ctx, GLuint n, GLint x, GLint y,
+ GLdepth depth[]);
+
+extern void fxDDWriteDepthPixels(GLcontext *ctx, GLuint n,
+ const GLint x[], const GLint y[],
+ const GLdepth depth[], const GLubyte mask[]);
+
+extern void fxDDReadDepthPixels(GLcontext *ctx, GLuint n,
+ const GLint x[], const GLint y[],
+ GLdepth depth[]);
+
+extern void fxDDFastPath( struct vertex_buffer *VB );
+
+extern void fxDDShadeModel(GLcontext *ctx, GLenum mode);
+
+extern void fxDDCullFace(GLcontext *ctx, GLenum mode);
+extern void fxDDFrontFace(GLcontext *ctx, GLenum mode);
+
+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);
+
+#endif
diff --git a/xc/extras/Mesa/src/FX/fxfastpath.c b/xc/extras/Mesa/src/FX/fxfastpath.c
new file mode 100644
index 000000000..8a327e72a
--- /dev/null
+++ b/xc/extras/Mesa/src/FX/fxfastpath.c
@@ -0,0 +1,425 @@
+/* -*- mode: C; tab-width:8; c-basic-offset:2 -*- */
+
+/*
+ * 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.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "conf.h"
+#endif
+
+
+#if defined(FX)
+
+#include "types.h"
+#include "cva.h"
+#include "mmath.h"
+#include "fxdrv.h"
+#include "vertices.h"
+#include "X86/common_x86_asm.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,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;
+}
+
+
+#else
+
+/*
+ * Need this to provide at least one external definition.
+ */
+int gl_fxfastpath_dummy(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/xc/extras/Mesa/src/FX/fxfasttmp.h b/xc/extras/Mesa/src/FX/fxfasttmp.h
new file mode 100644
index 000000000..f97b8108f
--- /dev/null
+++ b/xc/extras/Mesa/src/FX/fxfasttmp.h
@@ -0,0 +1,367 @@
+/* -*- mode: C; tab-width:8; c-basic-offset:2 -*- */
+
+/*
+ * 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/extras/Mesa/src/FX/fxglidew.c b/xc/extras/Mesa/src/FX/fxglidew.c
new file mode 100644
index 000000000..5155c825a
--- /dev/null
+++ b/xc/extras/Mesa/src/FX/fxglidew.c
@@ -0,0 +1,451 @@
+/* -*- mode: C; tab-width:8; c-basic-offset:2 -*- */
+
+/*
+ * 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.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "conf.h"
+#endif
+
+#if defined(FX)
+#include "glide.h"
+#include "fxglidew.h"
+#include "fxdrv.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+FxI32 FX_grGetInteger_NoLock(FxU32 pname)
+{
+#if !defined(FX_GLIDE3)
+ switch (pname)
+ {
+ case FX_FOG_TABLE_ENTRIES:
+ return GR_FOG_TABLE_SIZE;
+ case FX_GLIDE_STATE_SIZE:
+ return sizeof(GrState);
+ case FX_LFB_PIXEL_PIPE:
+ return FXFALSE;
+ case FX_PENDING_BUFFERSWAPS:
+ return grBufferNumPending();
+ case FX_TEXTURE_ALIGN:
+ /* This is a guess from reading the glide3 docs */
+ return 8;
+ default:
+ if (MESA_VERBOSE&VERBOSE_DRIVER) {
+ fprintf(stderr,"Wrong parameter in FX_grGetInteger!\n");
+ }
+ return -1;
+ }
+#else
+ FxU32 grname;
+ FxI32 result;
+
+ 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:
+ grname = pname;
+ break;
+ default:
+ if (MESA_VERBOSE&VERBOSE_DRIVER) {
+ fprintf(stderr,"Wrong parameter in FX_grGetInteger!\n");
+ }
+ return -1;
+ }
+
+ grGet(grname,4,&result);
+ return result;
+#endif
+}
+
+FxI32 FX_grGetInteger(FxU32 pname)
+{
+ int result;
+
+ BEGIN_BOARD_LOCK();
+ result=FX_grGetInteger_NoLock(pname);
+ END_BOARD_LOCK();
+ return result;
+}
+
+
+FxBool FX_grLfbLock(GrLock_t type, GrBuffer_t buffer,
+ GrLfbWriteMode_t writeMode, GrOriginLocation_t origin,
+ FxBool pixelPipeline, GrLfbInfo_t *info ) {
+ FxBool result;
+
+ BEGIN_BOARD_LOCK();
+ result=grLfbLock(type, buffer, writeMode, origin, pixelPipeline, info);
+ END_BOARD_LOCK();
+ return result;
+}
+
+FxU32 FX_grTexTextureMemRequired(FxU32 evenOdd, GrTexInfo *info) {
+ FxU32 result;
+
+ BEGIN_BOARD_LOCK();
+ result=grTexTextureMemRequired(evenOdd, info);
+ END_BOARD_LOCK();
+ return result;
+}
+
+FxU32 FX_grTexMinAddress(GrChipID_t tmu) {
+ FxU32 result;
+
+ BEGIN_BOARD_LOCK();
+ result=grTexMinAddress(tmu);
+ END_BOARD_LOCK();
+ return result;
+}
+
+extern FxU32 FX_grTexMaxAddress(GrChipID_t tmu) {
+ FxU32 result;
+
+ BEGIN_BOARD_LOCK();
+ result=grTexMaxAddress(tmu);
+ END_BOARD_LOCK();
+ return result;
+}
+
+FxBool FX_grSstControl(FxU32 code)
+{
+#if defined(FX_GLIDE3)
+ /* The glide 3 sources call for grEnable/grDisable to be called in exchange
+ * for grSstControl. */
+ switch(code) {
+ case GR_CONTROL_ACTIVATE:
+ grEnable(GR_PASSTHRU);
+ break;
+ case GR_CONTROL_DEACTIVATE:
+ grDisable(GR_PASSTHRU);
+ break;
+ }
+ /* Appearently GR_CONTROL_RESIZE can be ignored. */
+ return 1; /* OK? */
+#else
+ FxU32 result;
+ BEGIN_BOARD_LOCK();
+ result = grSstControl(code);
+ END_BOARD_LOCK();
+ return result;
+#endif
+}
+
+
+#if defined(FX_GLIDE3)
+
+void FX_grGammaCorrectionValue(float val)
+{
+ (void)val;
+/* ToDo */
+}
+
+int FX_getFogTableSize(void)
+{
+ int result;
+ BEGIN_BOARD_LOCK();
+ grGet(GR_FOG_TABLE_ENTRIES,sizeof(int),(void*)&result);
+ END_BOARD_LOCK();
+ return result;
+}
+
+int FX_getGrStateSize(void)
+{
+ int result;
+ BEGIN_BOARD_LOCK();
+ grGet(GR_GLIDE_STATE_SIZE,sizeof(int),(void*)&result);
+ END_BOARD_LOCK();
+
+ return result;
+
+}
+
+int FX_grSstScreenWidth()
+{
+ FxI32 result[4];
+
+ BEGIN_BOARD_LOCK();
+ grGet(GR_VIEWPORT,sizeof(FxI32)*4,result);
+ END_BOARD_LOCK();
+
+ return result[2];
+}
+
+int FX_grSstScreenHeight()
+{
+ FxI32 result[4];
+
+ BEGIN_BOARD_LOCK();
+ grGet(GR_VIEWPORT,sizeof(FxI32)*4,result);
+ END_BOARD_LOCK();
+
+ return result[3];
+}
+
+void FX_grGlideGetVersion(char *buf)
+{
+ BEGIN_BOARD_LOCK();
+ strcpy(buf,grGetString(GR_VERSION));
+ END_BOARD_LOCK();
+}
+
+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(GrVertex *a,GrVertex *b)
+{
+ /* ToDo */
+ BEGIN_CLIP_LOOP();
+ grDrawLine(a,b);
+ END_CLIP_LOOP();
+}
+
+void FX_grAADrawPoint(GrVertex *a)
+{
+ BEGIN_CLIP_LOOP();
+ grDrawPoint(a);
+ END_CLIP_LOOP();
+}
+
+void FX_grDrawPolygonVertexList(int n, GrVertex *verts)
+{
+ BEGIN_CLIP_LOOP();
+ grDrawVertexArrayContiguous(GR_POLYGON, n, verts, sizeof(GrVertex));
+ END_CLIP_LOOP();
+}
+
+#if FX_USE_PARGB
+void FX_setupGrVertexLayout(void)
+{
+ BEGIN_BOARD_LOCK();
+ 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();
+}
+#else /* FX_USE_PARGB */
+void FX_setupGrVertexLayout(void)
+{
+ BEGIN_BOARD_LOCK();
+ 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();
+}
+#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(GrHint_t hintType, FxU32 hintMask) {
+ BEGIN_BOARD_LOCK();
+ FX_grHints_NoLock(hintType, hintMask);
+ END_BOARD_LOCK();
+}
+
+int FX_grSstQueryHardware(GrHwConfiguration *config)
+{
+ int i,j;
+ int numFB;
+
+ BEGIN_BOARD_LOCK();
+ 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();
+ return 1;
+}
+
+#else
+
+int FX_grSstScreenWidth()
+{
+ int i;
+ BEGIN_BOARD_LOCK();
+ i = grSstScreenWidth();
+ END_BOARD_LOCK();
+ return i;
+}
+
+int FX_grSstScreenHeight()
+{
+ int i;
+ BEGIN_BOARD_LOCK();
+ i = grSstScreenHeight();
+ END_BOARD_LOCK();
+ return i;
+}
+
+int FX_grSstQueryHardware(GrHwConfiguration *c)
+{
+ int i;
+ BEGIN_BOARD_LOCK();
+ i = grSstQueryHardware(c);
+ END_BOARD_LOCK();
+ return i;
+}
+
+
+#endif /* FX_GLIDE3 */
+
+/* It appears to me that this function is needed either way. */
+FX_GrContext_t FX_grSstWinOpen( 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();
+ 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();
+ return i;
+}
+
+
+
+#else
+
+/*
+ * Need this to provide at least one external definition.
+ */
+
+int gl_fx_dummy_function_glidew(void)
+{
+ return 0;
+}
+
+#endif /* FX */
diff --git a/xc/extras/Mesa/src/FX/fxglidew.h b/xc/extras/Mesa/src/FX/fxglidew.h
new file mode 100644
index 000000000..6da1ea5f3
--- /dev/null
+++ b/xc/extras/Mesa/src/FX/fxglidew.h
@@ -0,0 +1,845 @@
+/* -*- mode: C; tab-width:8; c-basic-offset:2 -*- */
+
+/*
+ * 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>
+
+/*
+ * 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
+
+/*
+ * Genral warper functions for Glide2/Glide3:
+ */
+extern FxI32 FX_grGetInteger(FxU32 pname);
+extern FxI32 FX_grGetInteger_NoLock(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(TMU,type,data) \
+ do { \
+ BEGIN_BOARD_LOCK(); \
+ grTexDownloadTable(type,data); \
+ END_BOARD_LOCK(); \
+ } 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() \
+ do { \
+ BEGIN_BOARD_LOCK(); \
+ grFlush(); \
+ END_BOARD_LOCK(); \
+ } while (0)
+#else
+#define FX_grFlush() \
+ do { \
+ BEGIN_BOARD_LOCK(); \
+ grSstIdle(); \
+ END_BOARD_LOCK(); \
+ } while (0)
+#endif
+
+#define FX_grFinish() \
+ do { \
+ BEGIN_BOARD_LOCK(); \
+ grFinish(); \
+ END_BOARD_LOCK(); \
+ } while (0)
+
+/*
+ * Write region: ToDo possible exploit the PixelPipe parameter.
+ */
+#if defined(FX_GLIDE3)
+#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,FXFALSE,src_stride,src_data); \
+ END_BOARD_LOCK(); \
+ } 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(src_buffer,src_x,src_y,src_width,src_height,dst_stride,dst_data) \
+ do { \
+ BEGIN_BOARD_LOCK(); \
+ grLfbReadRegion(src_buffer,src_x,src_y,src_width,src_height,dst_stride,dst_data); \
+ END_BOARD_LOCK(); \
+ } while (0);
+
+/*
+ * Draw triangle
+ */
+#define FX_grDrawTriangle(a,b,c) \
+ do { \
+ BEGIN_CLIP_LOOP(); \
+ grDrawTriangle(a,b,c); \
+ END_CLIP_LOOP(); \
+ } 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
+
+/*
+ * ScreenWidth/Height stuff.
+ */
+ extern int FX_grSstScreenWidth(void);
+ extern int FX_grSstScreenHeight(void);
+
+
+
+/*
+ * Version string.
+ */
+#if defined(FX_GLIDE3)
+ extern void FX_grGlideGetVersion(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(GrHwConfiguration *config);
+
+/*
+ * GrHints
+ */
+#if defined(FX_GLIDE3)
+ extern void FX_grHints_NoLock(GrHint_t hintType, FxU32 hintMask);
+ extern void FX_grHints(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(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(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(void);
+#else
+ #define FX_setupGrVertexLayout() do {} while (0)
+#endif
+/*
+ * grSstControl stuff
+ */
+extern FxBool FX_grSstControl(FxU32 code);
+
+/*
+ * 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(w) \
+ do { \
+ BEGIN_BOARD_LOCK(); \
+ grSstWinClose(w); \
+ END_BOARD_LOCK(); \
+ } while (0)
+#else
+#define FX_grSstWinClose(w) \
+ do { \
+ BEGIN_BOARD_LOCK(); \
+ grSstWinClose(); \
+ END_BOARD_LOCK(); \
+ } while (0)
+#endif
+
+
+extern FX_GrContext_t FX_grSstWinOpen( 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(v1, v2) \
+ do { \
+ BEGIN_CLIP_LOOP(); \
+ grDrawLine(v1, v2); \
+ END_CLIP_LOOP(); \
+ } while (0)
+
+#define FX_grDrawPoint(p) \
+ do { \
+ BEGIN_CLIP_LOOP(); \
+ grDrawPoint(p); \
+ END_CLIP_LOOP(); \
+ } while (0)
+
+#if defined(FX_GLIDE3)
+extern void FX_grDrawPolygonVertexList(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(m) \
+ do { \
+ BEGIN_BOARD_LOCK(); \
+ grDitherMode(m); \
+ END_BOARD_LOCK(); \
+ } while (0)
+
+#define FX_grRenderBuffer(b) \
+ do { \
+ BEGIN_BOARD_LOCK(); \
+ grRenderBuffer(b); \
+ END_BOARD_LOCK(); \
+ } while (0)
+
+#define FX_grBufferClear(c, a, d) \
+ do { \
+ BEGIN_CLIP_LOOP(); \
+ grBufferClear(c, a, d); \
+ END_CLIP_LOOP(); \
+ } while (0)
+
+#define FX_grDepthMask(m) \
+ do { \
+ BEGIN_BOARD_LOCK(); \
+ grDepthMask(m); \
+ END_BOARD_LOCK(); \
+ } while (0)
+
+#define FX_grColorMask(c, a) \
+ do { \
+ BEGIN_BOARD_LOCK(); \
+ grColorMask(c, a); \
+ END_BOARD_LOCK(); \
+ } while (0)
+
+extern FxBool FX_grLfbLock(GrLock_t type, GrBuffer_t buffer,
+ GrLfbWriteMode_t writeMode,
+ GrOriginLocation_t origin, FxBool pixelPipeline,
+ GrLfbInfo_t *info );
+
+#define FX_grLfbUnlock(t, b) \
+ do { \
+ BEGIN_BOARD_LOCK(); \
+ grLfbUnlock(t, b); \
+ END_BOARD_LOCK(); \
+ } while (0)
+
+#define FX_grConstantColorValue(v) \
+ do { \
+ BEGIN_BOARD_LOCK(); \
+ grConstantColorValue(v); \
+ END_BOARD_LOCK(); \
+ } while (0)
+
+#define FX_grConstantColorValue_NoLock grConstantColorValue
+
+#define FX_grAADrawTriangle(a, b, c, ab, bc, ca) \
+ do { \
+ BEGIN_CLIP_LOOP(); \
+ grAADrawTriangle(a, b, c, ab, bc, ca); \
+ END_CLIP_LOOP(); \
+ } while (0)
+
+#define FX_grAlphaBlendFunction(rs, rd, as, ad) \
+ do { \
+ BEGIN_BOARD_LOCK(); \
+ grAlphaBlendFunction(rs, rd, as, ad); \
+ END_BOARD_LOCK(); \
+ } while (0)
+
+#define FX_grAlphaCombine(func, fact, loc, oth, inv) \
+ do { \
+ BEGIN_BOARD_LOCK(); \
+ grAlphaCombine(func, fact, loc, oth, inv); \
+ END_BOARD_LOCK(); \
+ } while (0)
+
+#define FX_grAlphaCombine_NoLock grAlphaCombine
+
+#define FX_grAlphaTestFunction(f) \
+ do { \
+ BEGIN_BOARD_LOCK(); \
+ grAlphaTestFunction(f); \
+ END_BOARD_LOCK(); \
+ } while (0)
+
+#define FX_grAlphaTestReferenceValue(v) \
+ do { \
+ BEGIN_BOARD_LOCK(); \
+ grAlphaTestReferenceValue(v); \
+ END_BOARD_LOCK(); \
+ } while (0)
+
+#define FX_grClipWindow(minx, miny, maxx, maxy) \
+ do { \
+ BEGIN_BOARD_LOCK(); \
+ grClipWindow(minx, miny, maxx, maxy); \
+ END_BOARD_LOCK(); \
+ } while (0)
+
+#define FX_grClipWindow_NoLock grClipWindow
+
+#define FX_grColorCombine(func, fact, loc, oth, inv) \
+ do { \
+ BEGIN_BOARD_LOCK(); \
+ grColorCombine(func, fact, loc, oth, inv); \
+ END_BOARD_LOCK(); \
+ } while (0)
+
+#define FX_grColorCombine_NoLock grColorCombine
+
+#define FX_grCullMode(m) \
+ do { \
+ BEGIN_BOARD_LOCK(); \
+ grCullMode(m); \
+ END_BOARD_LOCK(); \
+ } while (0)
+
+#define FX_grDepthBiasLevel(lev) \
+ do { \
+ BEGIN_BOARD_LOCK(); \
+ grDepthBiasLevel(lev); \
+ END_BOARD_LOCK(); \
+ } while (0)
+
+#define FX_grDepthBufferFunction(func) \
+ do { \
+ BEGIN_BOARD_LOCK(); \
+ grDepthBufferFunction(func); \
+ END_BOARD_LOCK(); \
+ } while (0)
+
+#define FX_grFogColorValue(c) \
+ do { \
+ BEGIN_BOARD_LOCK(); \
+ grFogColorValue(c); \
+ END_BOARD_LOCK(); \
+ } while (0)
+
+#define FX_grFogMode(m) \
+ do { \
+ BEGIN_BOARD_LOCK(); \
+ grFogMode(m); \
+ END_BOARD_LOCK(); \
+ } while (0)
+
+#define FX_grFogTable(t) \
+ do { \
+ BEGIN_BOARD_LOCK(); \
+ grFogTable(t); \
+ END_BOARD_LOCK(); \
+ } while (0)
+
+#define FX_grTexClampMode(t, sc, tc) \
+ do { \
+ BEGIN_BOARD_LOCK(); \
+ grTexClampMode(t, sc, tc); \
+ END_BOARD_LOCK(); \
+ } while (0)
+
+#define FX_grTexClampMode_NoLock grTexClampMode
+
+#define FX_grTexCombine(t, rfunc, rfact, afunc, afact, rinv, ainv) \
+ do { \
+ BEGIN_BOARD_LOCK(); \
+ grTexCombine(t, rfunc, rfact, afunc, afact, rinv, ainv); \
+ END_BOARD_LOCK(); \
+ } while (0)
+
+#define FX_grTexCombine_NoLock grTexCombine
+
+#define FX_grTexDownloadMipMapLevel(t, sa, tlod, llod, ar, f, eo, d) \
+ do { \
+ BEGIN_BOARD_LOCK(); \
+ grTexDownloadMipMapLevel(t, sa, tlod, llod, ar, f, eo, d); \
+ END_BOARD_LOCK(); \
+ } while (0)
+
+#define FX_grTexDownloadMipMapLevel_NoLock grTexDownloadMipMapLevel
+
+#define FX_grTexDownloadMipMapLevelPartial(t, sa, tlod, llod, ar, f, eo, d, s, e); \
+ do { \
+ BEGIN_BOARD_LOCK(); \
+ grTexDownloadMipMapLevelPartial(t, sa, tlod, llod, ar, f, eo, d, s, e); \
+ END_BOARD_LOCK(); \
+ } while (0)
+
+#define FX_grTexFilterMode(t, minf, magf) \
+ do { \
+ BEGIN_BOARD_LOCK(); \
+ grTexFilterMode(t, minf, magf); \
+ END_BOARD_LOCK(); \
+ } while (0)
+
+#define FX_grTexFilterMode_NoLock grTexFilterMode
+
+extern FxU32 FX_grTexMinAddress(GrChipID_t tmu);
+extern FxU32 FX_grTexMaxAddress(GrChipID_t tmu);
+
+#define FX_grTexMipMapMode(t, m, lod) \
+ do { \
+ BEGIN_BOARD_LOCK(); \
+ grTexMipMapMode(t, m, lod); \
+ END_BOARD_LOCK(); \
+ } while (0)
+
+#define FX_grTexMipMapMode_NoLock grTexMipMapMode
+
+#define FX_grTexSource(t, sa, eo, i) \
+ do { \
+ BEGIN_BOARD_LOCK(); \
+ grTexSource(t, sa, eo, i); \
+ END_BOARD_LOCK(); \
+ } while (0)
+
+#define FX_grTexSource_NoLock grTexSource
+
+extern FxU32 FX_grTexTextureMemRequired(FxU32 evenOdd, GrTexInfo *info);
+#define FX_grTexTextureMemRequired_NoLock grTexTextureMemRequired
+
+#define FX_grGlideGetState(s) \
+ do { \
+ BEGIN_BOARD_LOCK(); \
+ grGlideGetState(s); \
+ END_BOARD_LOCK(); \
+ } while (0)
+#define FX_grGlideGetState_NoLock(s) grGlideGetState(s);
+
+#define FX_grDRIBufferSwap(i) \
+ do { \
+ BEGIN_BOARD_LOCK(); \
+ grDRIBufferSwap(i); \
+ END_BOARD_LOCK(); \
+ } while (0)
+
+#define FX_grSstSelect(b) \
+ do { \
+ BEGIN_BOARD_LOCK(); \
+ grSstSelect(b); \
+ END_BOARD_LOCK(); \
+ } while (0)
+
+#define FX_grSstSelect_NoLock grSstSelect
+
+#define FX_grGlideSetState(s) \
+ do { \
+ BEGIN_BOARD_LOCK(); \
+ grGlideSetState(s); \
+ END_BOARD_LOCK(); \
+ } while (0)
+#define FX_grGlideSetState_NoLock(s) grGlideSetState(s);
+
+#define FX_grDepthBufferMode(m) \
+ do { \
+ BEGIN_BOARD_LOCK(); \
+ grDepthBufferMode(m); \
+ END_BOARD_LOCK(); \
+ } while (0)
+
+#define FX_grLfbWriteColorFormat(f) \
+ do { \
+ BEGIN_BOARD_LOCK(); \
+ grLfbWriteColorFormat(f); \
+ END_BOARD_LOCK(); \
+ } while (0)
+
+#define FX_grDrawVertexArray(m, c, p) \
+ do { \
+ BEGIN_CLIP_LOOP(); \
+ grDrawVertexArray(m, c, p); \
+ END_CLIP_LOOP(); \
+ } while (0)
+
+#define FX_grGlideShutdown() \
+ do { \
+ BEGIN_BOARD_LOCK(); \
+ grGlideShutdown(); \
+ END_BOARD_LOCK(); \
+ } while (0)
+
+#define FX_grTexLodBiasValue_NoLock(t, v) grTexLodBiasValue(t, v)
+
+#define FX_grTexLodBiasValue(t, v) \
+ do { \
+ BEGIN_BOARD_LOCK(); \
+ grTexLodBiasValue(t, v); \
+ END_BOARD_LOCK(); \
+ } while (0)
+
+#define FX_grGlideInit_NoLock grGlideInit
+#define FX_grSstWinOpen_NoLock grSstWinOpen
+
+extern int FX_getFogTableSize(void);
+extern int FX_getGrStateSize(void);
+
+#endif /* __FX_GLIDE_WARPER__ */
+
diff --git a/xc/extras/Mesa/src/FX/fxpipeline.c b/xc/extras/Mesa/src/FX/fxpipeline.c
new file mode 100644
index 000000000..cf4c9ebbc
--- /dev/null
+++ b/xc/extras/Mesa/src/FX/fxpipeline.c
@@ -0,0 +1,302 @@
+/* -*- mode: C; tab-width:8; c-basic-offset:2 -*- */
+
+/*
+ * 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.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "conf.h"
+#endif
+
+
+#if defined(FX)
+
+#include "fxdrv.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;
+}
+*/
+
+#else
+
+/*
+ * Need this to provide at least one external definition.
+ */
+int gl_fxpipeline_dummy(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/xc/extras/Mesa/src/FX/fxrender.c b/xc/extras/Mesa/src/FX/fxrender.c
new file mode 100644
index 000000000..5935998f8
--- /dev/null
+++ b/xc/extras/Mesa/src/FX/fxrender.c
@@ -0,0 +1,785 @@
+/* -*- mode: C; tab-width:8; c-basic-offset:2 -*- */
+
+/*
+ * 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 */
+
+
+#ifdef HAVE_CONFIG_H
+#include "conf.h"
+#endif
+
+#if defined(FX)
+
+#include "fxdrv.h"
+#include "vbcull.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 )
+{
+ 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((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[] )
+{
+ 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(i0,i1,i2);
+ }
+ }
+}
+
+
+
+
+
+static INLINE void fxSafeClippedLine( struct vertex_buffer *VB,
+ GLuint v1, GLuint v2 )
+{
+ GLubyte mask = VB->ClipMask[v1] | VB->ClipMask[v2];
+
+ if (!mask) {
+ fxVertex *gWin = FX_DRIVER_DATA(VB)->verts;
+ FX_grDrawLine((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];
+
+ if (!mask) {
+ FX_grDrawTriangle((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 )
+{
+ GLubyte *clipmask = VB->ClipMask;
+ GLubyte mask = clipmask[v2] | clipmask[v1] | clipmask[v];
+
+ if (!mask) {
+ FX_grDrawTriangle((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((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((GrVertex *)gWin[i1].f, \
+ (GrVertex *)gWin[i2].f, \
+ (GrVertex *)gWin[i].f); \
+ } else { \
+ FX_grDrawTriangle((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((GrVertex *)gWin[i3].f, \
+ (GrVertex *)gWin[i2].f, \
+ (GrVertex *)gWin[i].f); \
+ FX_grDrawTriangle((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( (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((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((GrVertex *)gWin[i3].f, \
+ (GrVertex *)gWin[i2].f, \
+ (GrVertex *)gWin[i].f); \
+ FX_grDrawTriangle((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( (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((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((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((GrVertex *)gWin[elt[e]].f); \
+ } \
+ } while (0)
+
+#define RENDER_LINE( i1, i ) \
+ do { \
+ GLuint e1 = elt[i1], e = elt[i]; \
+ FX_grDrawLine((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((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((GrVertex *)gWin[e3].f, \
+ (GrVertex *)gWin[e2].f, \
+ (GrVertex *)gWin[e].f); \
+ FX_grDrawTriangle((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;
+
+#define INIT(x)
+
+#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 ));
+}
+
+
+#else
+
+
+/*
+ * Need this to provide at least one external definition.
+ */
+
+int gl_fx_dummy_function_render(void)
+{
+ return 0;
+}
+
+#endif /* FX */
diff --git a/xc/extras/Mesa/src/FX/fxsanity.c b/xc/extras/Mesa/src/FX/fxsanity.c
new file mode 100644
index 000000000..9f815012e
--- /dev/null
+++ b/xc/extras/Mesa/src/FX/fxsanity.c
@@ -0,0 +1,124 @@
+/* -*- mode: C; tab-width:8; c-basic-offset:2 -*- */
+
+/*
+ * 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.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "conf.h"
+#endif
+
+
+
+#if defined(FX)
+#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( 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(v1,v2,v3);
+ else
+ fprintf(stderr, "\n\n\n");
+}
+
+#else
+
+void gl_fxsanity_dummy()
+{
+}
+
+#endif
diff --git a/xc/extras/Mesa/src/FX/fxsdettmp.h b/xc/extras/Mesa/src/FX/fxsdettmp.h
new file mode 100644
index 000000000..7b77b36c2
--- /dev/null
+++ b/xc/extras/Mesa/src/FX/fxsdettmp.h
@@ -0,0 +1,161 @@
+/* -*- mode: C; tab-width:8; c-basic-offset:2 -*- */
+
+/*
+ * 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/extras/Mesa/src/FX/fxsetup.c b/xc/extras/Mesa/src/FX/fxsetup.c
new file mode 100644
index 000000000..f1a56650b
--- /dev/null
+++ b/xc/extras/Mesa/src/FX/fxsetup.c
@@ -0,0 +1,1858 @@
+/* -*- mode: C; tab-width:8; c-basic-offset:2 -*- */
+
+/*
+ * 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 */
+
+
+#ifdef HAVE_CONFIG_H
+#include "conf.h"
+#endif
+
+#if defined(FX)
+
+#include "fxdrv.h"
+#include "enums.h"
+
+static GLuint fxGetTexSetConfiguration(GLcontext *ctx,
+ struct gl_texture_object *tObj0,
+ struct gl_texture_object *tObj1);
+static void fxSetupTextureSingleTMU_NoLock(GLcontext *ctx, GLuint textureset);
+static void fxSetupDoubleTMU_NoLock(fxMesaContext fxMesa,
+ struct gl_texture_object *tObj0,
+ struct gl_texture_object *tObj1);
+static void fxSetupTexture_NoLock(GLcontext *ctx);
+static void fxSetupTexture(GLcontext *ctx);
+static void fxSetupBlend(GLcontext *ctx);
+static void fxSetupDepthTest(GLcontext *ctx);
+static void fxSetupScissor(GLcontext *ctx);
+static void fxSetupCull(GLcontext *ctx);
+static void gl_print_fx_state_flags( const char *msg, GLuint flags);
+/*static GLboolean fxMultipassBlend(struct vertex_buffer *, GLuint);*/
+static GLboolean fxMultipassTexture( struct vertex_buffer *, GLuint );
+
+static void fxTexValidate(GLcontext *ctx, struct gl_texture_object *tObj)
+{
+ 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(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(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));
+
+ switch (tObj->WrapS) {
+ case GL_CLAMP_TO_EDGE:
+ /* What's this really mean compared to GL_CLAMP? */
+ 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:
+ /* What's this really mean compared to GL_CLAMP? */
+ 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,&(ti->palette));
+ FX_grTexDownloadTable_NoLock(GR_TMU1,GR_TEXTABLE_PALETTE,&(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, &(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);
+
+ 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);
+
+/* if(fxMesa->lastUnitsMode==unitsmode) */
+/* return; */
+
+ fxMesa->lastUnitsMode=unitsmode;
+
+ 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;
+ 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) {
+ BEGIN_BOARD_LOCK();
+ fxSetupTextureSingleTMU_NoLock(ctx, textureset);
+ END_BOARD_LOCK();
+}
+
+/************************* 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, &(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, &(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);
+
+/* if(fxMesa->lastUnitsMode==unitsmode) */
+/* return; */
+
+ fxMesa->lastUnitsMode=unitsmode;
+
+ 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);
+
+ fxMesa->lastUnitsMode=FX_UM_NONE;
+}
+
+/************************************************************************/
+/************************** 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) {
+ BEGIN_BOARD_LOCK();
+ fxSetupTexture_NoLock(ctx);
+ END_BOARD_LOCK();
+}
+
+/************************************************************************/
+/**************************** Blend SetUp *******************************/
+/************************************************************************/
+
+/* XXX consider supporting GL_INGR_blend_func_separate */
+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;
+ }
+}
+
+static void fxSetupBlend(GLcontext *ctx)
+{
+ fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+ 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=(fxMesaContext)ctx->DriverCtx;
+ 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:
+ fprintf(stderr,"fx Driver: internal error in fxDDAlphaFunc()\n");
+ fxCloseHardware();
+ exit(-1);
+ break;
+ }
+
+ 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(us->alphaTestFunc);
+ FX_grAlphaTestReferenceValue(us->alphaTestRefValue);
+ } else
+ FX_grAlphaTestFunction(GR_CMP_ALWAYS);
+}
+
+/************************************************************************/
+/************************** Depth Test SetUp ****************************/
+/************************************************************************/
+
+void fxDDDepthFunc(GLcontext *ctx, GLenum func)
+{
+ fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+ tfxUnitsState *us=&fxMesa->unitsState;
+ GrCmpFnc_t dfunc;
+
+ switch(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:
+ fprintf(stderr,"fx Driver: internal error in fxDDDepthFunc()\n");
+ fxCloseHardware();
+ exit(-1);
+ break;
+ }
+
+ if(dfunc!=us->depthTestFunc) {
+ us->depthTestFunc=dfunc;
+ fxMesa->new_state |= FX_NEW_DEPTH;
+ ctx->Driver.RenderStart = fxSetupFXUnits;
+ }
+
+}
+
+void fxDDDepthMask(GLcontext *ctx, GLboolean flag)
+{
+ fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+ tfxUnitsState *us=&fxMesa->unitsState;
+
+ if(flag!=us->depthMask) {
+ us->depthMask=flag;
+ fxMesa->new_state |= FX_NEW_DEPTH;
+ ctx->Driver.RenderStart = fxSetupFXUnits;
+ }
+}
+
+static void fxSetupDepthTest(GLcontext *ctx)
+{
+ fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+ tfxUnitsState *us=&fxMesa->unitsState;
+
+ if (us->depthTestEnabled) {
+ FX_grDepthBufferFunction(us->depthTestFunc);
+ FX_grDepthMask(us->depthMask);
+ }
+ else {
+ FX_grDepthBufferFunction(GR_CMP_ALWAYS);
+ FX_grDepthMask(FXFALSE);
+ }
+}
+
+/************************************************************************/
+/**************************** 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)
+{
+ fxMesaContext fxMesa = FX_CONTEXT(ctx);
+
+ if (ctx->Color.DrawBuffer == GL_NONE) {
+ FX_grColorMask(FXFALSE, FXFALSE);
+ }
+ else {
+ FX_grColorMask(ctx->Color.ColorMask[RCOMP] ||
+ ctx->Color.ColorMask[GCOMP] ||
+ ctx->Color.ColorMask[BCOMP],
+ ctx->Color.ColorMask[ACOMP] && fxMesa->haveAlphaBuffer);
+ }
+}
+
+
+
+
+/************************************************************************/
+/**************************** Fog Mode SetUp ****************************/
+/************************************************************************/
+
+/*
+ * This is called during state update in order to update the Glide fog state.
+ */
+static void fxSetupFog(GLcontext *ctx)
+{
+ if (ctx->Fog.Enabled && ctx->FogMode==FOG_FRAGMENT) {
+ fxMesaContext fxMesa = FX_CONTEXT(ctx);
+
+ /* 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(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->fogTable);
+ FX_grFogMode(GR_FOG_WITH_TABLE);
+ }
+ else {
+ FX_grFogMode(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;
+ int ymin, ymax, check;
+
+ 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;
+ check=1;
+ } else {
+ xmin=0;
+ ymin=0;
+ xmax=fxMesa->width;
+ ymax=fxMesa->height;
+ check=0;
+ }
+ xmin+=fxMesa->x_offset;
+ xmax+=fxMesa->x_offset;
+ ymin+=fxMesa->y_delta;
+ ymax+=fxMesa->y_delta;
+ if (xmin<fxMesa->clipMinX) xmin=fxMesa->clipMinX;
+ if (xmax>fxMesa->clipMaxX) xmax=fxMesa->clipMaxX;
+ if (ymin<fxMesa->screen_height-fxMesa->clipMaxY)
+ ymin=fxMesa->screen_height-fxMesa->clipMaxY;
+ if (ymax>fxMesa->screen_height-fxMesa->clipMinY)
+ ymax=fxMesa->screen_height-fxMesa->clipMinY;
+ FX_grClipWindow_NoLock(xmin, ymin, xmax, ymax);
+}
+
+static void fxSetupScissor(GLcontext *ctx)
+{
+ fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+ if (!fxMesa->needClip) {
+ BEGIN_BOARD_LOCK();
+ fxSetScissorValues(ctx);
+ END_BOARD_LOCK();
+ }
+}
+
+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)
+{
+ 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(FX_CONTEXT(ctx)->cullMode);
+}
+
+
+/************************************************************************/
+/****************************** DD Enable ******************************/
+/************************************************************************/
+
+void fxDDEnable(GLcontext *ctx, GLenum cap, GLboolean state)
+{
+ fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+ 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:
+ if(state!=us->depthTestEnabled) {
+ us->depthTestEnabled=state;
+ fxMesa->new_state |= FX_NEW_DEPTH;
+ ctx->Driver.RenderStart = fxSetupFXUnits;
+ }
+ 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;
+ default:
+ ; /* XXX 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);
+ }
+ /* 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);
+ 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 );
+ break;
+ }
+
+ fxDDDepthMask( 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 );
+ 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_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; */
+ }
+}
+
+
+
+#else
+
+
+/*
+ * Need this to provide at least one external definition.
+ */
+
+int gl_fx_dummy_function_setup(void)
+{
+ return 0;
+}
+
+#endif /* FX */
diff --git a/xc/extras/Mesa/src/FX/fxstripdet.c b/xc/extras/Mesa/src/FX/fxstripdet.c
new file mode 100644
index 000000000..bc21234b6
--- /dev/null
+++ b/xc/extras/Mesa/src/FX/fxstripdet.c
@@ -0,0 +1,164 @@
+/* -*- mode: C; tab-width:8; c-basic-offset:2 -*- */
+
+/*
+ * 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.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "conf.h"
+#endif
+#if defined(FX) && defined(FX_GLIDE3)
+
+#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;
+
+#define STRIPSLOCAL_VAR int sc = 0;
+
+#define INIT(a)
+
+#define SENDTRI(u0,u1,u2) FX_grDrawTriangle((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(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((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(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((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(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
+}
+
+
+#endif /* defined(FX) && FX_GLIDE3 */
diff --git a/xc/extras/Mesa/src/FX/fxtexman.c b/xc/extras/Mesa/src/FX/fxtexman.c
new file mode 100644
index 000000000..2ffaeadd7
--- /dev/null
+++ b/xc/extras/Mesa/src/FX/fxtexman.c
@@ -0,0 +1,747 @@
+/* -*- mode: C; tab-width:8; c-basic-offset:2 -*- */
+
+/*
+ * 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 */
+
+
+#ifdef HAVE_CONFIG_H
+#include "conf.h"
+#endif
+
+#if defined(FX)
+
+#include "fxdrv.h"
+
+int texSwaps=0;
+
+#define FX_2MB_SPLIT 0x200000
+
+static struct gl_texture_object *fxTMFindOldestObject(fxMesaContext fxMesa,
+ int tmu);
+
+
+#ifdef TEXSANITY
+static void fubar()
+{
+}
+
+ /* 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
+
+static MemRange *fxTMNewRangeNode(fxMesaContext fxMesa, FxU32 start, FxU32 end) {
+ MemRange *result=0;
+
+ if (fxMesa->tmPool) {
+ result=fxMesa->tmPool;
+ fxMesa->tmPool=fxMesa->tmPool->next;
+ } else {
+ if (!(result=MALLOC(sizeof(MemRange)))) {
+ fprintf(stderr, "fxDriver: out of memory!\n");
+ fxCloseHardware();
+ exit(-1);
+ }
+ }
+ result->startAddr=start;
+ result->endAddr=end;
+ return result;
+}
+
+static void fxTMDeleteRangeNode(fxMesaContext fxMesa, MemRange *range)
+{
+ range->next=fxMesa->tmPool;
+ fxMesa->tmPool=range;
+}
+
+static void fxTMUInit(fxMesaContext fxMesa, int tmu)
+{
+ MemRange *tmn, *last;
+ FxU32 start,end,blockstart,blockend;
+
+ start=FX_grTexMinAddress(tmu);
+ end=FX_grTexMaxAddress(tmu);
+
+ if(fxMesa->verbose) {
+ fprintf(stderr,"Voodoo %s configuration:",(tmu==FX_TMU0) ? "TMU0" : "TMU1");
+ fprintf(stderr,"Voodoo Lower texture memory address (%u)\n",(unsigned int)start);
+ fprintf(stderr,"Voodoo Higher texture memory address (%u)\n",(unsigned int)end);
+ fprintf(stderr,"Voodoo Splitting Texture memory in 2b blocks:\n");
+ }
+
+ fxMesa->freeTexMem[tmu]=end-start;
+ fxMesa->tmFree[tmu]=NULL;
+
+ last=0;
+ blockstart=start;
+ while (blockstart<end) {
+ if (blockstart+FX_2MB_SPLIT>end) blockend=end;
+ else blockend=blockstart+FX_2MB_SPLIT;
+
+ if(fxMesa->verbose)
+ fprintf(stderr,"Voodoo %07u-%07u\n",
+ (unsigned int)blockstart,(unsigned int)blockend);
+
+ tmn=fxTMNewRangeNode(fxMesa, blockstart, blockend);
+ tmn->next=0;
+
+ if (last) last->next=tmn;
+ else fxMesa->tmFree[tmu]=tmn;
+ last=tmn;
+
+ blockstart+=FX_2MB_SPLIT;
+ }
+}
+
+static int fxTMFindStartAddr(fxMesaContext fxMesa, GLint tmu, int size)
+{
+ MemRange *prev, *tmp;
+ int result;
+ struct gl_texture_object *obj;
+
+ while (1) {
+ prev=0;
+ tmp=fxMesa->tmFree[tmu];
+ while (tmp) {
+ if (tmp->endAddr-tmp->startAddr>=size) { /* Fits here */
+ result=tmp->startAddr;
+ tmp->startAddr+=size;
+ if (tmp->startAddr==tmp->endAddr) { /* Empty */
+ if (prev) {
+ prev->next=tmp->next;
+ } else {
+ fxMesa->tmFree[tmu]=tmp->next;
+ }
+ fxTMDeleteRangeNode(fxMesa, tmp);
+ }
+ fxMesa->freeTexMem[tmu]-=size;
+ return result;
+ }
+ prev=tmp;
+ tmp=tmp->next;
+ }
+ /* No free space. Discard oldest */
+ obj=fxTMFindOldestObject(fxMesa, tmu);
+ if (!obj) {
+ fprintf(stderr, "fx Driver: No space for texture\n");
+ return -1;
+ }
+ fxTMMoveOutTM(fxMesa, obj);
+ texSwaps++;
+ }
+}
+
+static void fxTMRemoveRange(fxMesaContext fxMesa, GLint tmu, MemRange *range)
+{
+ MemRange *tmp, *prev;
+
+ if (range->startAddr==range->endAddr) {
+ fxTMDeleteRangeNode(fxMesa, range);
+ return;
+ }
+ fxMesa->freeTexMem[tmu]+=range->endAddr-range->startAddr;
+ prev=0;
+ tmp=fxMesa->tmFree[tmu];
+ while (tmp) {
+ if (range->startAddr>tmp->startAddr) {
+ prev=tmp;
+ tmp=tmp->next;
+ } else break;
+ }
+ /* When we create the regions, we make a split at the 2MB boundary.
+ Now we have to make sure we don't join those 2MB boundary regions
+ back together again. */
+ range->next=tmp;
+ if (tmp) {
+ if (range->endAddr==tmp->startAddr && tmp->startAddr&(FX_2MB_SPLIT-1)) {
+ /* Combine */
+ tmp->startAddr=range->startAddr;
+ fxTMDeleteRangeNode(fxMesa, range);
+ range=tmp;
+ }
+ }
+ if (prev) {
+ if (prev->endAddr==range->startAddr && range->startAddr&(FX_2MB_SPLIT-1)) {
+ /* Combine */
+ prev->endAddr=range->endAddr;
+ prev->next=range->next;
+ fxTMDeleteRangeNode(fxMesa, range);
+ } else prev->next=range;
+ } else {
+ fxMesa->tmFree[tmu]=range;
+ }
+}
+
+static struct gl_texture_object *fxTMFindOldestObject(fxMesaContext fxMesa,
+ int tmu)
+{
+ GLuint age, old, lasttime, bindnumber;
+ tfxTexInfo *info;
+ struct gl_texture_object *obj, *tmp;
+
+ tmp=fxMesa->glCtx->Shared->TexObjectList;
+ if (!tmp) return 0;
+ obj=0;
+ old=0;
+
+ bindnumber=fxMesa->texBindNumber;
+ while (tmp) {
+ info=fxTMGetTexInfo(tmp);
+
+ if (info && info->isInTM &&
+ ((info->whichTMU==tmu) || (info->whichTMU==FX_TMU_BOTH) ||
+ (info->whichTMU==FX_TMU_SPLIT))) {
+ lasttime=info->lastTimeUsed;
+
+ if (lasttime>bindnumber)
+ age=bindnumber+(UINT_MAX-lasttime+1); /* TO DO: check wrap around */
+ else
+ age=bindnumber-lasttime;
+
+ if (age>=old) {
+ old=age;
+ obj=tmp;
+ }
+ }
+ tmp=tmp->Next;
+ }
+ return obj;
+}
+
+static MemRange *fxTMAddObj(fxMesaContext fxMesa,
+ struct gl_texture_object *tObj,
+ GLint tmu, int texmemsize)
+{
+ FxU32 startAddr;
+ MemRange *range;
+
+ startAddr=fxTMFindStartAddr(fxMesa, tmu, texmemsize);
+ if (startAddr<0) return 0;
+ range=fxTMNewRangeNode(fxMesa, startAddr, startAddr+texmemsize);
+ return range;
+}
+
+/* External Functions */
+
+void fxTMMoveInTM_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj, GLint where)
+{
+ tfxTexInfo *ti=fxTMGetTexInfo(tObj);
+ int i,l;
+ int texmemsize;
+
+ if (MESA_VERBOSE&VERBOSE_DRIVER) {
+ fprintf(stderr,"fxmesa: fxTMMoveInTM(%d)\n",tObj->Name);
+ }
+
+ fxMesa->stats.reqTexUpload++;
+
+ if (!ti->validated) {
+ fprintf(stderr,"fx Driver: internal error in fxTMMoveInTM() -> not validated\n");
+ fxCloseHardware();
+ exit(-1);
+ }
+
+ 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=(int)FX_grTexTextureMemRequired_NoLock(GR_MIPMAPLEVELMASK_BOTH,
+ &(ti->info));
+ ti->tm[where]=fxTMAddObj(fxMesa, tObj, where, texmemsize);
+ 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=(int)FX_grTexTextureMemRequired_NoLock(GR_MIPMAPLEVELMASK_ODD,
+ &(ti->info));
+ ti->tm[FX_TMU0]=fxTMAddObj(fxMesa, tObj, FX_TMU0, texmemsize);
+ fxMesa->stats.memTexUpload+=texmemsize;
+
+ texmemsize=(int)FX_grTexTextureMemRequired_NoLock(GR_MIPMAPLEVELMASK_EVEN,
+ &(ti->info));
+ ti->tm[FX_TMU1]=fxTMAddObj(fxMesa, tObj, FX_TMU1, texmemsize);
+ 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=(int)FX_grTexTextureMemRequired_NoLock(GR_MIPMAPLEVELMASK_BOTH,
+ &(ti->info));
+ ti->tm[FX_TMU0]=fxTMAddObj(fxMesa, tObj, FX_TMU0, texmemsize);
+ fxMesa->stats.memTexUpload+=texmemsize;
+
+ texmemsize=(int)FX_grTexTextureMemRequired_NoLock(GR_MIPMAPLEVELMASK_BOTH,
+ &(ti->info));
+ ti->tm[FX_TMU1]=fxTMAddObj(fxMesa, tObj, FX_TMU1, texmemsize);
+ 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);
+ fxCloseHardware();
+ exit(-1);
+ }
+
+ fxMesa->stats.texUpload++;
+
+ ti->isInTM=GL_TRUE;
+}
+
+void fxTMMoveInTM(fxMesaContext fxMesa, struct gl_texture_object *tObj, GLint where) {
+ BEGIN_BOARD_LOCK();
+ fxTMMoveInTM_NoLock(fxMesa, tObj, where);
+ END_BOARD_LOCK();
+}
+
+void fxTMReloadMipMapLevel(fxMesaContext fxMesa, struct gl_texture_object *tObj, GLint level)
+{
+ tfxTexInfo *ti=fxTMGetTexInfo(tObj);
+ GrLOD_t lodlevel;
+ GLint tmu;
+
+ if (!ti->validated) {
+ fprintf(stderr,"fx Driver: internal error in fxTMReloadMipMapLevel() -> not validated\n");
+ fxCloseHardware();
+ exit(-1);
+ }
+
+ tmu=(int)ti->whichTMU;
+ fxTMMoveInTM(fxMesa, tObj, tmu);
+
+ fxTexGetInfo(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(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(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(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(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(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);
+ fxCloseHardware();
+ exit(-1);
+ }
+}
+
+void fxTMReloadSubMipMapLevel(fxMesaContext fxMesa,
+ struct gl_texture_object *tObj,
+ GLint level, GLint yoffset, GLint height)
+{
+ tfxTexInfo *ti=fxTMGetTexInfo(tObj);
+ GrLOD_t lodlevel;
+ unsigned short *data;
+ GLint tmu;
+
+ if(!ti->validated) {
+ fprintf(stderr,"fx Driver: internal error in fxTMReloadSubMipMapLevel() -> not validated\n");
+ fxCloseHardware();
+ exit(-1);
+ }
+
+ tmu=(int)ti->whichTMU;
+ fxTMMoveInTM(fxMesa, tObj, tmu);
+
+ fxTexGetInfo(ti->mipmapLevel[0].width, ti->mipmapLevel[0].height,
+ &lodlevel, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+
+ if((ti->info.format==GR_TEXFMT_INTENSITY_8) ||
+ (ti->info.format==GR_TEXFMT_P_8) ||
+ (ti->info.format==GR_TEXFMT_ALPHA_8))
+ data=ti->mipmapLevel[level].data+((yoffset*ti->mipmapLevel[level].width)>>1);
+ else
+ data=ti->mipmapLevel[level].data+yoffset*ti->mipmapLevel[level].width;
+
+ switch(tmu) {
+ case FX_TMU0:
+ case FX_TMU1:
+ FX_grTexDownloadMipMapLevelPartial(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(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(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(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(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);
+ fxCloseHardware();
+ exit(-1);
+ }
+}
+
+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");
+ fxCloseHardware();
+ exit(-1);
+ }
+
+ ti->isInTM=GL_FALSE;
+ ti->whichTMU=FX_TMU_NONE;
+}
+
+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;
+ }
+}
+
+void fxTMInit(fxMesaContext fxMesa)
+{
+ fxMesa->texBindNumber=0;
+ fxMesa->tmPool=0;
+
+ fxTMUInit(fxMesa,FX_TMU0);
+
+ if(fxMesa->haveTwoTMUs)
+ fxTMUInit(fxMesa,FX_TMU1);
+}
+
+void fxTMClose(fxMesaContext fxMesa)
+{
+ MemRange *tmp, *next;
+
+ tmp=fxMesa->tmPool;
+ while (tmp) {
+ next=tmp->next;
+ FREE(tmp);
+ tmp=next;
+ }
+ tmp=fxMesa->tmFree[FX_TMU0];
+ while (tmp) {
+ next=tmp->next;
+ FREE(tmp);
+ tmp=next;
+ }
+ if (fxMesa->haveTwoTMUs) {
+ tmp=fxMesa->tmFree[FX_TMU1];
+ while (tmp) {
+ next=tmp->next;
+ FREE(tmp);
+ tmp=next;
+ }
+ }
+}
+
+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;
+ }
+}
+
+#else
+
+
+/*
+ * Need this to provide at least one external definition.
+ */
+
+int gl_fx_dummy_function_texman(void)
+{
+ return 0;
+}
+
+#endif /* FX */
diff --git a/xc/extras/Mesa/src/FX/fxtrifuncs.c b/xc/extras/Mesa/src/FX/fxtrifuncs.c
new file mode 100644
index 000000000..4b349b31b
--- /dev/null
+++ b/xc/extras/Mesa/src/FX/fxtrifuncs.c
@@ -0,0 +1,372 @@
+/* -*- mode: C; tab-width:8; c-basic-offset:2 -*- */
+
+/*
+ * 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 */
+
+
+#ifdef HAVE_CONFIG_H
+#include "conf.h"
+#endif
+
+#if defined(FX)
+
+#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(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 (flags & DD_MULTIDRAW) ind |= FX_FRONT_BACK;
+ 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(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);
+}
+
+#else
+
+
+/*
+ * Need this to provide at least one external definition.
+ */
+
+extern int gl_fx_dummy_function_tris(void);
+int gl_fx_dummy_function_tris(void)
+{
+ return 0;
+}
+
+#endif /* FX */
diff --git a/xc/extras/Mesa/src/FX/fxtritmp.h b/xc/extras/Mesa/src/FX/fxtritmp.h
new file mode 100644
index 000000000..9e59b4fc7
--- /dev/null
+++ b/xc/extras/Mesa/src/FX/fxtritmp.h
@@ -0,0 +1,475 @@
+/* -*- mode: C; tab-width:8; c-basic-offset:2 -*- */
+
+/*
+ * 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((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_grColorMask(ctx->Color.ColorMask[RCOMP] ||
+ ctx->Color.ColorMask[GCOMP] ||
+ ctx->Color.ColorMask[BCOMP],
+ FXFALSE);
+
+ FX_grDepthMask(FXFALSE);
+ FX_grRenderBuffer(GR_BUFFER_BACKBUFFER);
+ }
+
+ if (IND & FX_ANTIALIAS)
+ FX_grAADrawTriangle(v1, v2, v3, FXTRUE, FXTRUE, FXTRUE);
+ else
+ FX_grDrawTriangle(v1, v2, v3);
+
+ /* Might be quicker to do two passes, one for each buffer?
+ */
+ if (IND & FX_FRONT_BACK) {
+ FX_grColorMask(ctx->Color.ColorMask[RCOMP] ||
+ ctx->Color.ColorMask[GCOMP] ||
+ ctx->Color.ColorMask[BCOMP],
+ ctx->Color.ColorMask[ACOMP] && fxMesa->haveAlphaBuffer);
+
+ if(ctx->Depth.Mask) FX_grDepthMask(FXTRUE);
+
+ FX_grRenderBuffer(GR_BUFFER_FRONTBUFFER);
+
+ if (IND & FX_ANTIALIAS)
+ FX_grAADrawTriangle(v1,v2,v3, FXTRUE,FXTRUE,FXTRUE);
+ else
+ FX_grDrawTriangle(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((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_grColorMask(ctx->Color.ColorMask[RCOMP] ||
+ ctx->Color.ColorMask[GCOMP] ||
+ ctx->Color.ColorMask[BCOMP],
+ FXFALSE);
+
+ FX_grDepthMask(FXFALSE);
+ FX_grRenderBuffer(GR_BUFFER_BACKBUFFER);
+ }
+
+ if (IND & FX_ANTIALIAS) {
+ FX_grAADrawTriangle(v1, v2, v4, FXTRUE, FXTRUE, FXTRUE);
+ FX_grAADrawTriangle(v2, v3, v4, FXTRUE, FXTRUE, FXTRUE);
+ } else {
+ FX_grDrawTriangle(v1, v2, v4);
+ FX_grDrawTriangle(v2, v3, v4);
+ }
+
+ /* Might be quicker to do two passes, one for each buffer?
+ */
+ if (IND & FX_FRONT_BACK) {
+ FX_grColorMask(ctx->Color.ColorMask[RCOMP] ||
+ ctx->Color.ColorMask[GCOMP] ||
+ ctx->Color.ColorMask[BCOMP],
+ ctx->Color.ColorMask[ACOMP] && fxMesa->haveAlphaBuffer);
+
+ if(ctx->Depth.Mask) FX_grDepthMask(FXTRUE);
+
+ FX_grRenderBuffer(GR_BUFFER_FRONTBUFFER);
+
+ if (IND & FX_ANTIALIAS) {
+ FX_grAADrawTriangle(v1, v2, v4, FXTRUE, FXTRUE, FXTRUE);
+ FX_grAADrawTriangle(v2, v3, v4, FXTRUE, FXTRUE, FXTRUE);
+ } else {
+ FX_grDrawTriangle(v1, v2, v4);
+ FX_grDrawTriangle(v2, v3, v4);
+ }
+ }
+}
+
+#define DRAW_LINE(tmp0, tmp1, width) \
+ do { \
+ const float xoff = 0.125, yoff = 0.125; \
+ GrVertex verts[4]; \
+ float dx, dy, wx, wy; \
+ \
+ dx = tmp0->x - tmp1->x; \
+ dy = tmp0->y - tmp1->y; \
+ \
+ if (dx * dx > dy * dy) { \
+ wx = 0; \
+ wy = width; \
+ } else { \
+ wx = width; \
+ wy = 0; \
+ } \
+ \
+ verts[0] = *tmp0; \
+ verts[1] = *tmp0; \
+ verts[2] = *tmp1; \
+ verts[3] = *tmp1; \
+ \
+ verts[0].x = tmp0->x - wx + xoff; \
+ verts[0].y = tmp0->y - wy + yoff; \
+ \
+ verts[1].x = tmp0->x + wx + xoff; \
+ verts[1].y = tmp0->y + wy + yoff; \
+ \
+ verts[2].x = tmp1->x + wx + xoff; \
+ verts[2].y = tmp1->y + wy + yoff; \
+ \
+ verts[3].x = tmp1->x - wx + xoff; \
+ verts[3].y = tmp1->y - wy + yoff; \
+ \
+ FX_grDrawPolygonVertexList(4, verts); \
+ } while (0)
+
+#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)
+ {
+ /* Flat shading seems broke. Explicitly set vertex colors to same color */
+ GOURAUD2(v1,color[pv]);
+ GOURAUD2(v2,color[pv]);
+ }
+ 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_grColorMask(ctx->Color.ColorMask[RCOMP] ||
+ ctx->Color.ColorMask[GCOMP] ||
+ ctx->Color.ColorMask[BCOMP],
+ FXFALSE);
+ FX_grDepthMask(FXFALSE);
+ FX_grRenderBuffer(GR_BUFFER_BACKBUFFER);
+ }
+
+ if (IND & FX_ANTIALIAS)
+ FX_grAADrawLine(v1,v2);
+ else
+ DRAW_LINE(v1,v2,w);
+
+ if (IND & FX_FRONT_BACK)
+ {
+ FX_grColorMask(ctx->Color.ColorMask[RCOMP] ||
+ ctx->Color.ColorMask[GCOMP] ||
+ ctx->Color.ColorMask[BCOMP],
+ ctx->Color.ColorMask[ACOMP] && fxMesa->haveAlphaBuffer);
+
+ if(ctx->Depth.Mask)
+ FX_grDepthMask(FXTRUE);
+
+ FX_grRenderBuffer(GR_BUFFER_FRONTBUFFER);
+
+ if (IND & FX_ANTIALIAS)
+ FX_grAADrawLine(v1,v2);
+ else
+ DRAW_LINE(v1,v2,w);
+ }
+}
+#endif
+
+
+#if (IND & FX_OFFSET) == 0
+
+#if IND & FX_FLAT
+# if IND & FX_ANTIALIAS
+#if FX_USE_PARGB
+# define FLAT_COLOR(x,y) GET_PA(gWin[i].f) = y[3];
+#else
+# define FLAT_COLOR(x,y) gWin[i].f[ACOORD] = y[3]; \
+ FX_VB_COLOR(x, y)
+#endif
+# else
+# define FLAT_COLOR(x,y) FX_VB_COLOR(x, y)
+# endif
+#else
+#define FLAT_COLOR(x,y)
+#endif
+
+
+#define DRAW_POINT(i, sz) \
+ do { \
+ GrVertex verts[4], *tmp; \
+ \
+ tmp = (GrVertex*)gWin[i].f; \
+ verts[0] = *tmp; \
+ verts[1] = *tmp; \
+ verts[2] = *tmp; \
+ verts[3] = *tmp; \
+ verts[0].x = verts[3].x = tmp->x + sz; \
+ verts[0].y = verts[1].y = tmp->y + sz; \
+ verts[2].x = verts[1].x = tmp->x - sz; \
+ verts[2].y = verts[3].y = tmp->y - sz; \
+ \
+ FX_grDrawPolygonVertexList(4, verts); \
+ } while (0)
+
+static void TAG(fx_points)(GLcontext *ctx, GLuint first, GLuint last)
+{
+ fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+ struct vertex_buffer *VB = ctx->VB;
+ fxVertex *gWin = FX_DRIVER_DATA(VB)->verts;
+ GLubyte (*color)[4] = VB->ColorPtr->data;
+ GLuint i;
+ GLfloat sz = ctx->Point.Size * .5;
+
+ (void) color; (void) fxMesa;
+
+ if (IND & FX_FRONT_BACK) {
+ FX_grColorMask(ctx->Color.ColorMask[RCOMP] ||
+ ctx->Color.ColorMask[GCOMP] ||
+ ctx->Color.ColorMask[BCOMP],
+ FXFALSE);
+
+ FX_grDepthMask(FXFALSE);
+ FX_grRenderBuffer(GR_BUFFER_BACKBUFFER);
+ }
+
+ if(!VB->ClipOrMask) {
+ for(i=first;i<=last;i++) {
+ FLAT_COLOR(fxMesa, color[i]);
+ DRAW_POINT(i, sz);
+ }
+ } else {
+ for(i=first;i<=last;i++) {
+ if(VB->ClipMask[i]==0) {
+ FLAT_COLOR(fxMesa, color[i]);
+ DRAW_POINT(i, sz);
+ }
+ }
+ }
+
+ if (IND & FX_FRONT_BACK) {
+ FX_grColorMask(ctx->Color.ColorMask[RCOMP] ||
+ ctx->Color.ColorMask[GCOMP] ||
+ ctx->Color.ColorMask[BCOMP],
+ ctx->Color.ColorMask[ACOMP] && fxMesa->haveAlphaBuffer);
+ if(ctx->Depth.Mask)
+ FX_grDepthMask(FXTRUE);
+ FX_grRenderBuffer(GR_BUFFER_FRONTBUFFER);
+
+
+ if(!VB->ClipOrMask) {
+ for(i=first;i<=last;i++) {
+ FLAT_COLOR(fxMesa, color[i]);
+ DRAW_POINT(i, sz);
+ }
+ } else {
+ for(i=first;i<=last;i++) {
+ if(VB->ClipMask[i]==0) {
+ FLAT_COLOR(fxMesa, color[i]);
+ DRAW_POINT(i, sz);
+ }
+ }
+ }
+ }
+}
+
+#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/extras/Mesa/src/FX/fxvs_tmp.h b/xc/extras/Mesa/src/FX/fxvs_tmp.h
new file mode 100644
index 000000000..d9001db5e
--- /dev/null
+++ b/xc/extras/Mesa/src/FX/fxvs_tmp.h
@@ -0,0 +1,215 @@
+/* -*- mode: C; tab-width:8; c-basic-offset:2 -*- */
+
+/*
+ * 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/extras/Mesa/src/FX/fxvsetup.c b/xc/extras/Mesa/src/FX/fxvsetup.c
new file mode 100644
index 000000000..5b075f404
--- /dev/null
+++ b/xc/extras/Mesa/src/FX/fxvsetup.c
@@ -0,0 +1,576 @@
+/* -*- mode: C; tab-width:8; c-basic-offset:2 -*- */
+
+/*
+ * 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 */
+
+
+#ifdef HAVE_CONFIG_H
+#include "conf.h"
+#endif
+
+#if defined(FX)
+
+#include "fxdrv.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 only works for GL_RGBA texture format.
+ 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 != NULL) && (ctx->Driver.RasterSetup != NULL))
+ 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[1].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");
+ fxCloseHardware();
+ exit(-1);
+ }
+ 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");
+ fxCloseHardware();
+ exit(-1);
+}
+
+
+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");
+ fxCloseHardware();
+ exit(-1);
+}
+
+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;
+ }
+}
+
+
+
+#else
+
+
+/*
+ * Need this to provide at least one external definition.
+ */
+
+int gl_fx_dummy_function_vsetup(void)
+{
+ return 0;
+}
+
+#endif /* FX */
diff --git a/xc/extras/Mesa/src/FX/fxvsetup.h b/xc/extras/Mesa/src/FX/fxvsetup.h
new file mode 100644
index 000000000..48123c46b
--- /dev/null
+++ b/xc/extras/Mesa/src/FX/fxvsetup.h
@@ -0,0 +1,199 @@
+/* -*- mode: C; tab-width:8; c-basic-offset:2 -*- */
+
+/*
+ * 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(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/extras/Mesa/src/FX/fxwgl.c b/xc/extras/Mesa/src/FX/fxwgl.c
new file mode 100644
index 000000000..1f0e16a95
--- /dev/null
+++ b/xc/extras/Mesa/src/FX/fxwgl.c
@@ -0,0 +1,870 @@
+/* -*- mode: C; tab-width:8; c-basic-offset:2 -*- */
+
+/*
+ * 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.
+ */
+
+
+
+/* fxwgl.c - Microsoft wgl functions emulation for
+ * 3Dfx VooDoo/Mesa interface
+ */
+
+
+#ifdef __WIN32__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <windows.h>
+#include "GL/gl.h"
+
+#ifdef __cplusplus
+ }
+#endif
+
+#include <stdio.h>
+#include "GL/fxmesa.h"
+#include "fxdrv.h"
+
+#define MAX_MESA_ATTRS 20
+
+struct __extensions__
+{
+ PROC proc;
+ char *name;
+};
+
+struct __pixelformat__
+{
+ PIXELFORMATDESCRIPTOR pfd;
+ GLint mesaAttr[MAX_MESA_ATTRS];
+};
+
+WINGDIAPI void GLAPIENTRY gl3DfxSetPaletteEXT(GLuint *);
+
+static struct __extensions__ ext[] = {
+
+#ifdef GL_EXT_polygon_offset
+ { (PROC)glPolygonOffsetEXT, "glPolygonOffsetEXT" },
+#endif
+ { (PROC)glBlendEquationEXT, "glBlendEquationEXT" },
+ { (PROC)glBlendColorEXT, "glBlendColorExt" },
+ { (PROC)glVertexPointerEXT, "glVertexPointerEXT" },
+ { (PROC)glNormalPointerEXT, "glNormalPointerEXT" },
+ { (PROC)glColorPointerEXT, "glColorPointerEXT" },
+ { (PROC)glIndexPointerEXT, "glIndexPointerEXT" },
+ { (PROC)glTexCoordPointerEXT, "glTexCoordPointer" },
+ { (PROC)glEdgeFlagPointerEXT, "glEdgeFlagPointerEXT" },
+ { (PROC)glGetPointervEXT, "glGetPointervEXT" },
+ { (PROC)glArrayElementEXT, "glArrayElementEXT" },
+ { (PROC)glDrawArraysEXT, "glDrawArrayEXT" },
+ { (PROC)glAreTexturesResidentEXT, "glAreTexturesResidentEXT" },
+ { (PROC)glBindTextureEXT, "glBindTextureEXT" },
+ { (PROC)glDeleteTexturesEXT, "glDeleteTexturesEXT" },
+ { (PROC)glGenTexturesEXT, "glGenTexturesEXT" },
+ { (PROC)glIsTextureEXT, "glIsTextureEXT" },
+ { (PROC)glPrioritizeTexturesEXT, "glPrioritizeTexturesEXT" },
+ { (PROC)glCopyTexSubImage3DEXT, "glCopyTexSubImage3DEXT" },
+ { (PROC)glTexImage3DEXT, "glTexImage3DEXT" },
+ { (PROC)glTexSubImage3DEXT, "glTexSubImage3DEXT" },
+ { (PROC)gl3DfxSetPaletteEXT, "3DFX_set_global_palette" },
+ { (PROC)glColorTableEXT, "glColorTableEXT" },
+ { (PROC)glColorSubTableEXT, "glColorSubTableEXT" },
+ { (PROC)glGetColorTableEXT, "glGetColorTableEXT" },
+ { (PROC)glGetColorTableParameterfvEXT, "glGetColorTableParameterfvEXT" },
+ { (PROC)glGetColorTableParameterivEXT, "glGetColorTableParameterivEXT" },
+ { (PROC)glPointParameterfEXT, "glPointParameterfEXT" },
+ { (PROC)glPointParameterfvEXT, "glPointParameterfvEXT" },
+ { (PROC)glBlendFuncSeparateINGR, "glBlendFuncSeparateINGR" },
+ { (PROC)glActiveTextureARB, "glActiveTextureARB" },
+ { (PROC)glClientActiveTextureARB, "glClientActiveTextureARB" },
+ { (PROC)glMultiTexCoord1dARB, "glMultiTexCoord1dARB" },
+ { (PROC)glMultiTexCoord1dvARB, "glMultiTexCoord1dvARB" },
+ { (PROC)glMultiTexCoord1fARB, "glMultiTexCoord1fARB" },
+ { (PROC)glMultiTexCoord1fvARB, "glMultiTexCoord1fvARB" },
+ { (PROC)glMultiTexCoord1iARB, "glMultiTexCoord1iARB" },
+ { (PROC)glMultiTexCoord1ivARB, "glMultiTexCoord1ivARB" },
+ { (PROC)glMultiTexCoord1sARB, "glMultiTexCoord1sARB" },
+ { (PROC)glMultiTexCoord1svARB, "glMultiTexCoord1svARB" },
+ { (PROC)glMultiTexCoord2dARB, "glMultiTexCoord2dARB" },
+ { (PROC)glMultiTexCoord2dvARB, "glMultiTexCoord2dvARB" },
+ { (PROC)glMultiTexCoord2fARB, "glMultiTexCoord2fARB" },
+ { (PROC)glMultiTexCoord2fvARB, "glMultiTexCoord2fvARB" },
+ { (PROC)glMultiTexCoord2iARB, "glMultiTexCoord2iARB" },
+ { (PROC)glMultiTexCoord2ivARB, "glMultiTexCoord2ivARB" },
+ { (PROC)glMultiTexCoord2sARB, "glMultiTexCoord2sARB" },
+ { (PROC)glMultiTexCoord2svARB, "glMultiTexCoord2svARB" },
+ { (PROC)glMultiTexCoord3dARB, "glMultiTexCoord3dARB" },
+ { (PROC)glMultiTexCoord3dvARB, "glMultiTexCoord3dvARB" },
+ { (PROC)glMultiTexCoord3fARB, "glMultiTexCoord3fARB" },
+ { (PROC)glMultiTexCoord3fvARB, "glMultiTexCoord3fvARB" },
+ { (PROC)glMultiTexCoord3iARB, "glMultiTexCoord3iARB" },
+ { (PROC)glMultiTexCoord3ivARB, "glMultiTexCoord3ivARB" },
+ { (PROC)glMultiTexCoord3sARB, "glMultiTexCoord3sARB" },
+ { (PROC)glMultiTexCoord3svARB, "glMultiTexCoord3svARB" },
+ { (PROC)glMultiTexCoord4dARB, "glMultiTexCoord4dARB" },
+ { (PROC)glMultiTexCoord4dvARB, "glMultiTexCoord4dvARB" },
+ { (PROC)glMultiTexCoord4fARB, "glMultiTexCoord4fARB" },
+ { (PROC)glMultiTexCoord4fvARB, "glMultiTexCoord4fvARB" },
+ { (PROC)glMultiTexCoord4iARB, "glMultiTexCoord4iARB" },
+ { (PROC)glMultiTexCoord4ivARB, "glMultiTexCoord4ivARB" },
+ { (PROC)glMultiTexCoord4sARB, "glMultiTexCoord4sARB" },
+ { (PROC)glMultiTexCoord4svARB, "glMultiTexCoord4svARB" },
+ { (PROC)glLockArraysEXT, "glLockArraysEXT" },
+ { (PROC)glUnlockArraysEXT, "glUnlockArraysEXT" }
+};
+
+static int qt_ext = sizeof(ext) / sizeof(ext[0]);
+
+struct __pixelformat__ pix[] =
+{
+ /* None */
+ {
+ {
+ sizeof(PIXELFORMATDESCRIPTOR), 1,
+ PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|
+ PFD_DOUBLEBUFFER|PFD_SWAP_COPY,
+ PFD_TYPE_RGBA,
+ 32,
+ 8,0,8,8,8,16,0,24,
+ 0,0,0,0,0,
+ 0,
+ 0,
+ 0,
+ PFD_MAIN_PLANE,
+ 0,0,0,0
+ },
+ {
+ FXMESA_DOUBLEBUFFER,
+ FXMESA_ALPHA_SIZE, 0,
+ FXMESA_DEPTH_SIZE, 0,
+ FXMESA_STENCIL_SIZE, 0,
+ FXMESA_ACCUM_SIZE, 0,
+ FXMESA_NONE
+ }
+ },
+
+ /* Alpha */
+ {
+ {
+ sizeof(PIXELFORMATDESCRIPTOR), 1,
+ PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|
+ PFD_DOUBLEBUFFER|PFD_SWAP_COPY,
+ PFD_TYPE_RGBA,
+ 32,
+ 8,0,8,8,8,16,8,24,
+ 0,0,0,0,0,
+ 0,
+ 0,
+ 0,
+ PFD_MAIN_PLANE,
+ 0,0,0,0
+ },
+ {
+ FXMESA_DOUBLEBUFFER,
+ FXMESA_ALPHA_SIZE, 8,
+ FXMESA_DEPTH_SIZE, 0,
+ FXMESA_STENCIL_SIZE, 0,
+ FXMESA_ACCUM_SIZE, 0,
+ FXMESA_NONE
+ }
+ },
+
+ /* Depth */
+ {
+ {
+ sizeof(PIXELFORMATDESCRIPTOR), 1,
+ PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|
+ PFD_DOUBLEBUFFER|PFD_SWAP_COPY,
+ PFD_TYPE_RGBA,
+ 32,
+ 8,0,8,8,8,16,0,24,
+ 0,0,0,0,0,
+ 16,
+ 0,
+ 0,
+ PFD_MAIN_PLANE,
+ 0,0,0,0
+ },
+ {
+ FXMESA_DOUBLEBUFFER,
+ FXMESA_ALPHA_SIZE, 0,
+ FXMESA_DEPTH_SIZE, 16,
+ FXMESA_STENCIL_SIZE, 0,
+ FXMESA_ACCUM_SIZE, 0,
+ FXMESA_NONE
+ }
+ }
+};
+static int qt_pix = sizeof(pix) / sizeof(pix[0]);
+
+static fxMesaContext ctx = NULL;
+static WNDPROC hWNDOldProc;
+static int curPFD = 0;
+static HDC hDC;
+static HWND hWND;
+
+static GLboolean haveDualHead;
+
+/* For the in-window-rendering hack */
+
+static GLboolean gdiWindowHack;
+static GLboolean gdiWindowHackEna;
+static void *dibSurfacePtr;
+static BITMAPINFO *dibBMI;
+static HBITMAP dibHBM;
+static HWND dibWnd;
+
+LONG GLAPIENTRY __wglMonitor(HWND hwnd,UINT message,UINT wParam,LONG lParam)
+
+{
+ long ret; /* Now gives the resized window at the end to hWNDOldProc */
+
+ if(ctx && hwnd == hWND) {
+ switch(message) {
+ case WM_PAINT:
+ case WM_MOVE:
+ break;
+ case WM_DISPLAYCHANGE:
+ case WM_SIZE:
+ if (wParam != SIZE_MINIMIZED) {
+ static int moving = 0;
+ if (!moving) {
+ if(fxQueryHardware()!=GR_SSTTYPE_VOODOO) {
+ if(!FX_grSstControl(GR_CONTROL_RESIZE)) {
+ moving = 1;
+ SetWindowPos(hwnd, 0, 0, 0, 300, 300, SWP_NOMOVE|SWP_NOZORDER);
+ moving = 0;
+ if(!FX_grSstControl(GR_CONTROL_RESIZE)) {
+ /*MessageBox(0,_T("Error changing windowsize"),_T("fxMESA"),MB_OK);*/
+ PostMessage(hWND,WM_CLOSE,0,0);
+ }
+ }
+ }
+
+ /* Do the clipping in the glide library */
+ FX_grClipWindow(0,0,FX_grSstScreenWidth(),FX_grSstScreenHeight());
+ /* And let the new size set in the context */
+ fxMesaUpdateScreenSize(ctx);
+ }
+ }
+ break;
+ case WM_ACTIVATE:
+ if((fxQueryHardware()==GR_SSTTYPE_VOODOO) &&
+ (!gdiWindowHack) &&
+ (!haveDualHead)) {
+ WORD fActive = LOWORD(wParam);
+ BOOL fMinimized = (BOOL) HIWORD(wParam);
+
+ if((fActive == WA_INACTIVE) || fMinimized)
+ FX_grSstControl(GR_CONTROL_DEACTIVATE);
+ else
+ FX_grSstControl(GR_CONTROL_ACTIVATE);
+ }
+ break;
+ case WM_SHOWWINDOW:
+ break;
+ case WM_SYSKEYDOWN:
+ case WM_SYSCHAR:
+ if(gdiWindowHackEna && (VK_RETURN == wParam)) {
+ if(gdiWindowHack) {
+ gdiWindowHack = GL_FALSE;
+ FX_grSstControl(GR_CONTROL_ACTIVATE);
+ } else {
+ gdiWindowHack = GL_TRUE;
+ FX_grSstControl(GR_CONTROL_DEACTIVATE);
+ }
+ }
+ break;
+ }
+ }
+
+ /* Finaly call the hWNDOldProc, which handles the resize witch the
+ now changed window sizes */
+ ret = CallWindowProc( hWNDOldProc, hwnd, message, wParam, lParam );
+
+ return(ret);
+}
+
+BOOL GLAPIENTRY wglCopyContext(HGLRC hglrcSrc,HGLRC hglrcDst,UINT mask)
+{
+ return(FALSE);
+}
+
+HGLRC GLAPIENTRY wglCreateContext(HDC hdc)
+{
+ HWND hWnd;
+ WNDPROC oldProc;
+ int error;
+
+ if(ctx) {
+ SetLastError(0);
+ return(NULL);
+ }
+
+ if(!(hWnd = WindowFromDC(hdc))) {
+ SetLastError(0);
+ return(NULL);
+ }
+
+ if(curPFD == 0) {
+ SetLastError(0);
+ return(NULL);
+ }
+
+ if((oldProc = (WNDPROC)GetWindowLong(hWnd,GWL_WNDPROC)) != __wglMonitor) {
+ hWNDOldProc = oldProc;
+ SetWindowLong(hWnd,GWL_WNDPROC,(LONG)__wglMonitor);
+ }
+
+#ifndef FX_SILENT
+ freopen("MESA.LOG","w",stderr);
+#endif
+
+ ShowWindow(hWnd, SW_SHOWNORMAL);
+ SetForegroundWindow(hWnd);
+ Sleep(100); /* an hack for win95 */
+
+ if(fxQueryHardware() == GR_SSTTYPE_VOODOO) {
+ RECT cliRect;
+
+ GetClientRect(hWnd,&cliRect);
+ error = !(ctx = fxMesaCreateBestContext((GLuint)hWnd,cliRect.right,cliRect.bottom,
+ pix[curPFD - 1].mesaAttr));
+
+ if(!error) {
+ /* create the DIB section for windowed rendering */
+ DWORD *p;
+
+ dibWnd = hWnd;
+
+ hDC = GetDC(dibWnd);
+
+ dibBMI = (BITMAPINFO*) MALLOC( sizeof(BITMAPINFO) + (256*sizeof(RGBQUAD)));
+
+ memset(dibBMI,0,sizeof(BITMAPINFO) + (256*sizeof(RGBQUAD)));
+
+ dibBMI->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ dibBMI->bmiHeader.biWidth = ctx->width;
+ dibBMI->bmiHeader.biHeight = -ctx->height;
+ dibBMI->bmiHeader.biPlanes = (short)1;
+ dibBMI->bmiHeader.biBitCount = (short)16;
+ dibBMI->bmiHeader.biCompression = BI_BITFIELDS;
+ dibBMI->bmiHeader.biSizeImage = 0;
+ dibBMI->bmiHeader.biXPelsPerMeter = 0;
+ dibBMI->bmiHeader.biYPelsPerMeter = 0;
+ dibBMI->bmiHeader.biClrUsed = 3;
+ dibBMI->bmiHeader.biClrImportant = 3;
+
+ p = (DWORD*)dibBMI->bmiColors;
+ p[0] = 0xF800;
+ p[1] = 0x07E0;
+ p[2] = 0x001F;
+
+ dibHBM = CreateDIBSection(hDC, dibBMI, DIB_RGB_COLORS, &dibSurfacePtr, NULL, 0);
+
+ ReleaseDC(dibWnd, hDC);
+
+ gdiWindowHackEna = (dibHBM != NULL ? GL_TRUE : GL_FALSE);
+
+ if (!getenv("MESA_WGL_FX") || !strcmp(getenv("MESA_WGL_FX"),"fullscreen"))
+ gdiWindowHack = GL_FALSE;
+ else {
+ gdiWindowHack = GL_TRUE;
+ FX_grSstControl(GR_CONTROL_DEACTIVATE);
+ }
+ }
+ } else {
+ /* For the Voodoo Rush */
+
+ if(getenv("MESA_WGL_FX") && !strcmp(getenv("MESA_WGL_FX"),"fullscreen")) {
+ RECT cliRect;
+
+ GetClientRect(hWnd,&cliRect);
+ error = !(ctx = fxMesaCreateBestContext((GLuint)hWnd,cliRect.right,cliRect.bottom,
+ pix[curPFD - 1].mesaAttr));
+ } else
+ error = !(ctx = fxMesaCreateContext((GLuint)hWnd,GR_RESOLUTION_NONE,GR_REFRESH_75Hz,
+ pix[curPFD - 1].mesaAttr));
+ }
+
+ if(getenv("SST_DUALHEAD"))
+ haveDualHead=((atoi(getenv("SST_DUALHEAD"))==1) ? GL_TRUE:GL_FALSE);
+ else
+ haveDualHead=GL_FALSE;
+
+ if(error) {
+ SetLastError(0);
+ return(NULL);
+ }
+
+ hDC = hdc;
+ hWND = hWnd;
+
+ /* Required by the OpenGL Optimizer 1.1 (is it a Optimizer bug ?) */
+ wglMakeCurrent(hdc,(HGLRC)1);
+
+ return((HGLRC)1);
+}
+
+HGLRC GLAPIENTRY wglCreateLayerContext(HDC hdc,int iLayerPlane)
+{
+ SetLastError(0);
+ return(NULL);
+}
+
+BOOL GLAPIENTRY wglDeleteContext(HGLRC hglrc)
+{
+ if(ctx && hglrc == (HGLRC)1) {
+ if (gdiWindowHackEna) {
+ DeleteObject(dibHBM);
+ FREE(dibBMI);
+
+ dibSurfacePtr = NULL;
+ dibBMI = NULL;
+ dibHBM = NULL;
+ dibWnd = NULL;
+ }
+
+ fxMesaDestroyContext(ctx);
+
+ SetWindowLong(WindowFromDC(hDC),GWL_WNDPROC,(LONG)hWNDOldProc);
+
+ ctx = NULL;
+ hDC = 0;
+ return(TRUE);
+ }
+
+ SetLastError(0);
+
+ return(FALSE);
+}
+
+HGLRC GLAPIENTRY wglGetCurrentContext(VOID)
+{
+ if(ctx)
+ return((HGLRC)1);
+
+ SetLastError(0);
+ return(NULL);
+}
+
+HDC GLAPIENTRY wglGetCurrentDC(VOID)
+{
+ if(ctx)
+ return(hDC);
+
+ SetLastError(0);
+ return(NULL);
+}
+
+PROC GLAPIENTRY wglGetProcAddress(LPCSTR lpszProc)
+{
+ int i;
+
+ /*fprintf(stderr,"fxMesa: looking for extension %s\n",lpszProc);
+ fflush(stderr);*/
+
+ for(i = 0;i < qt_ext;i++)
+ if(!strcmp(lpszProc,ext[i].name)) {
+ /*fprintf(stderr,"fxMesa: found extension %s\n",lpszProc);
+ fflush(stderr);*/
+
+ return(ext[i].proc);
+ }
+ SetLastError(0);
+ return(NULL);
+}
+
+BOOL GLAPIENTRY wglMakeCurrent(HDC hdc,HGLRC hglrc)
+{
+ if((hdc==NULL) && (hglrc==NULL))
+ return(TRUE);
+
+ if(!ctx || hglrc != (HGLRC)1 || WindowFromDC(hdc) != hWND) {
+ SetLastError(0);
+ return(FALSE);
+ }
+
+ hDC = hdc;
+
+ fxMesaMakeCurrent(ctx);
+
+ return(TRUE);
+}
+
+BOOL GLAPIENTRY wglShareLists(HGLRC hglrc1,HGLRC hglrc2)
+{
+ if(!ctx || hglrc1 != (HGLRC)1 || hglrc1 != hglrc2) {
+ SetLastError(0);
+ return(FALSE);
+ }
+
+ return(TRUE);
+}
+
+BOOL GLAPIENTRY wglUseFontBitmaps(HDC fontDevice, DWORD firstChar, DWORD numChars, DWORD listBase)
+{
+#define VERIFY(a) a
+
+ TEXTMETRIC metric;
+ BITMAPINFO *dibInfo;
+ HDC bitDevice;
+ COLORREF tempColor;
+ int i;
+
+ VERIFY(GetTextMetrics(fontDevice, &metric));
+
+ dibInfo = (BITMAPINFO *) calloc(sizeof(BITMAPINFO) + sizeof(RGBQUAD), 1);
+ dibInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ dibInfo->bmiHeader.biPlanes = 1;
+ dibInfo->bmiHeader.biBitCount = 1;
+ dibInfo->bmiHeader.biCompression = BI_RGB;
+
+ bitDevice = CreateCompatibleDC(fontDevice);
+ // HDC bitDevice = CreateDC("DISPLAY", NULL, NULL, NULL);
+ // VERIFY(bitDevice);
+
+ // Swap fore and back colors so the bitmap has the right polarity
+ tempColor = GetBkColor(bitDevice);
+ SetBkColor(bitDevice, GetTextColor(bitDevice));
+ SetTextColor(bitDevice, tempColor);
+
+ // Place chars based on base line
+ VERIFY(SetTextAlign(bitDevice, TA_BASELINE) >= 0 ? 1 : 0);
+
+ for(i = 0; i < numChars; i++) {
+ SIZE size;
+ char curChar;
+ int charWidth,charHeight,bmapWidth,bmapHeight,numBytes,res;
+ HBITMAP bitObject;
+ HGDIOBJ origBmap;
+ unsigned char *bmap;
+
+ curChar = i + firstChar;
+
+ // Find how high/wide this character is
+ VERIFY(GetTextExtentPoint32(bitDevice, &curChar, 1, &size));
+
+ // Create the output bitmap
+ charWidth = size.cx;
+ charHeight = size.cy;
+ bmapWidth = ((charWidth + 31) / 32) * 32; // Round up to the next multiple of 32 bits
+ bmapHeight = charHeight;
+ bitObject = CreateCompatibleBitmap(bitDevice,
+ bmapWidth,
+ bmapHeight);
+ //VERIFY(bitObject);
+
+ // Assign the output bitmap to the device
+ origBmap = SelectObject(bitDevice, bitObject);
+ VERIFY(origBmap);
+
+ VERIFY( PatBlt( bitDevice, 0, 0, bmapWidth, bmapHeight,BLACKNESS ) );
+
+ // Use our source font on the device
+ VERIFY(SelectObject(bitDevice, GetCurrentObject(fontDevice,OBJ_FONT)));
+
+ // Draw the character
+ VERIFY(TextOut(bitDevice, 0, metric.tmAscent, &curChar, 1));
+
+ // Unselect our bmap object
+ VERIFY(SelectObject(bitDevice, origBmap));
+
+ // Convert the display dependant representation to a 1 bit deep DIB
+ numBytes = (bmapWidth * bmapHeight) / 8;
+ bmap = MALLOC(numBytes);
+ dibInfo->bmiHeader.biWidth = bmapWidth;
+ dibInfo->bmiHeader.biHeight = bmapHeight;
+ res = GetDIBits(bitDevice, bitObject, 0, bmapHeight, bmap,
+ dibInfo,
+ DIB_RGB_COLORS);
+ //VERIFY(res);
+
+ // Create the GL object
+ glNewList(i + listBase, GL_COMPILE);
+ glBitmap(bmapWidth, bmapHeight, 0.0, metric.tmDescent,
+ charWidth, 0.0,
+ bmap);
+ glEndList();
+ // CheckGL();
+
+ // Destroy the bmap object
+ DeleteObject(bitObject);
+
+ // Deallocate the bitmap data
+ FREE(bmap);
+ }
+
+ // Destroy the DC
+ VERIFY(DeleteDC(bitDevice));
+
+ FREE(dibInfo);
+
+ return TRUE;
+#undef VERIFY
+}
+
+BOOL GLAPIENTRY wglUseFontBitmapsW(HDC hdc,DWORD first,DWORD count,DWORD listBase)
+{
+ return(FALSE);
+}
+
+BOOL GLAPIENTRY wglUseFontOutlinesA(HDC hdc,DWORD first,DWORD count,
+ DWORD listBase,FLOAT deviation,
+ FLOAT extrusion,int format,
+ LPGLYPHMETRICSFLOAT lpgmf)
+{
+ SetLastError(0);
+ return(FALSE);
+}
+
+BOOL GLAPIENTRY wglUseFontOutlinesW(HDC hdc,DWORD first,DWORD count,
+ DWORD listBase,FLOAT deviation,
+ FLOAT extrusion,int format,
+ LPGLYPHMETRICSFLOAT lpgmf)
+{
+ SetLastError(0);
+ return(FALSE);
+}
+
+
+BOOL GLAPIENTRY wglSwapLayerBuffers(HDC hdc,UINT fuPlanes)
+{
+ if(ctx && WindowFromDC(hdc) == hWND) {
+ fxMesaSwapBuffers();
+
+ return(TRUE);
+ }
+
+ SetLastError(0);
+ return(FALSE);
+}
+
+int GLAPIENTRY wglChoosePixelFormat(HDC hdc,
+ CONST PIXELFORMATDESCRIPTOR *ppfd)
+{
+ int i,best=-1,qt_valid_pix;
+
+ qt_valid_pix = qt_pix;
+
+ if(ppfd->nSize != sizeof(PIXELFORMATDESCRIPTOR) || ppfd->nVersion != 1) {
+ SetLastError(0);
+ return(0);
+ }
+
+ for(i = 0;i < qt_valid_pix;i++) {
+ if((ppfd->dwFlags & PFD_DRAW_TO_WINDOW) && !(pix[i].pfd.dwFlags & PFD_DRAW_TO_WINDOW))
+ continue;
+ if((ppfd->dwFlags & PFD_DRAW_TO_BITMAP) && !(pix[i].pfd.dwFlags & PFD_DRAW_TO_BITMAP))
+ continue;
+ if((ppfd->dwFlags & PFD_SUPPORT_GDI) && !(pix[i].pfd.dwFlags & PFD_SUPPORT_GDI))
+ continue;
+ if((ppfd->dwFlags & PFD_SUPPORT_OPENGL) && !(pix[i].pfd.dwFlags & PFD_SUPPORT_OPENGL))
+ continue;
+ if(!(ppfd->dwFlags & PFD_DOUBLEBUFFER_DONTCARE) &&
+ ((ppfd->dwFlags & PFD_DOUBLEBUFFER) != (pix[i].pfd.dwFlags & PFD_DOUBLEBUFFER)))
+ continue;
+ if(!(ppfd->dwFlags & PFD_STEREO_DONTCARE) &&
+ ((ppfd->dwFlags & PFD_STEREO) != (pix[i].pfd.dwFlags & PFD_STEREO)))
+ continue;
+
+ if (ppfd->cDepthBits > 0 && pix[i].pfd.cDepthBits == 0)
+ continue; /* need depth buffer */
+
+ if (ppfd->cAlphaBits > 0 && pix[i].pfd.cAlphaBits == 0)
+ continue; /* need alpha buffer */
+
+ if(ppfd->iPixelType == pix[i].pfd.iPixelType) {
+ best = i + 1;
+ break;
+ }
+ }
+
+ if(best == -1) {
+ SetLastError(0);
+ return(0);
+ }
+
+ return(best);
+}
+
+int GLAPIENTRY ChoosePixelFormat(HDC hdc,
+ CONST PIXELFORMATDESCRIPTOR *ppfd)
+{
+ return wglChoosePixelFormat(hdc,ppfd);
+}
+
+int GLAPIENTRY wglDescribePixelFormat(HDC hdc,int iPixelFormat,UINT nBytes,
+ LPPIXELFORMATDESCRIPTOR ppfd)
+{
+ int qt_valid_pix;
+
+ qt_valid_pix = qt_pix;
+
+ if(iPixelFormat < 1 || iPixelFormat > qt_valid_pix ||
+ ((nBytes != sizeof(PIXELFORMATDESCRIPTOR)) && (nBytes != 0))) {
+ SetLastError(0);
+ return(0);
+ }
+
+ if(nBytes != 0)
+ *ppfd = pix[iPixelFormat - 1].pfd;
+
+ return(qt_valid_pix);
+}
+
+int GLAPIENTRY DescribePixelFormat(HDC hdc,int iPixelFormat,UINT nBytes,
+ LPPIXELFORMATDESCRIPTOR ppfd)
+{
+ return wglDescribePixelFormat(hdc,iPixelFormat,nBytes,ppfd);
+}
+
+int GLAPIENTRY wglGetPixelFormat(HDC hdc)
+{
+ if(curPFD == 0) {
+ SetLastError(0);
+ return(0);
+ }
+
+ return(curPFD);
+}
+
+int GLAPIENTRY GetPixelFormat(HDC hdc)
+{
+ return wglGetPixelFormat(hdc);
+}
+
+BOOL GLAPIENTRY wglSetPixelFormat(HDC hdc,int iPixelFormat,
+ CONST PIXELFORMATDESCRIPTOR *ppfd)
+{
+ int qt_valid_pix;
+
+ qt_valid_pix = qt_pix;
+
+ if(iPixelFormat < 1 || iPixelFormat > qt_valid_pix || ppfd->nSize != sizeof(PIXELFORMATDESCRIPTOR)) {
+ SetLastError(0);
+ return(FALSE);
+ }
+ curPFD = iPixelFormat;
+
+ return(TRUE);
+}
+
+BOOL GLAPIENTRY wglSwapBuffers(HDC hdc)
+{
+ if(!ctx) {
+ SetLastError(0);
+ return(FALSE);
+ }
+
+ fxMesaSwapBuffers();
+
+ if(gdiWindowHack) {
+ GLuint width=ctx->width;
+ GLuint height=ctx->height;
+
+ HDC hdcScreen = GetDC(dibWnd);
+ HDC hdcDIBSection = CreateCompatibleDC(hdcScreen);
+ HBITMAP holdBitmap = (HBITMAP) SelectObject(hdcDIBSection, dibHBM);
+
+ FX_grLfbReadRegion(GR_BUFFER_FRONTBUFFER, 0, 0,
+ width, height,
+ width * 2,
+ dibSurfacePtr);
+
+ /* Since the hardware is configured for GR_COLORFORMAT_ABGR the pixel data is
+ * going to come out as BGR 565, which is reverse of what we need for blitting
+ * to screen, so we need to convert it here pixel-by-pixel (ick). This loop would NOT
+ * be required if the color format was changed to GR_COLORFORMAT_ARGB, but I do
+ * not know the ramifications of that, so this will work until that is resolved.
+ *
+ * This routine CRIES out for MMX implementation, however since that's not
+ * guaranteed to be running on MMX enabled hardware so I'm not going to do
+ * that. I'm just going to try to make a reasonably efficient C
+ * version. -TAJ
+ *
+ * This routine drops frame rate by <1 fps on a 200Mhz MMX processor with a 640x480
+ * display. Obviously, it's performance hit will be higher on larger displays and
+ * less on smaller displays. To support the window-hack display this is probably fine.
+ */
+#if FXMESA_USE_ARGB
+ {
+ unsigned long *pixel = dibSurfacePtr;
+ unsigned long count = (width * height) / 2;
+
+ while (count--)
+ {
+ *pixel++ = (*pixel & 0x07e007e0) /* greens */
+ | ((*pixel & 0xf800f800) >> 11) /* swap blues */
+ | ((*pixel & 0x001f001f) << 11) /* swap reds */
+ ;
+ }
+ }
+#endif
+
+ BitBlt(hdcScreen, 0, 0,
+ width, height,
+ hdcDIBSection,
+ 0, 0, SRCCOPY);
+
+ ReleaseDC(dibWnd, hdcScreen);
+ SelectObject(hdcDIBSection, holdBitmap);
+ DeleteDC(hdcDIBSection);
+ }
+
+ return(TRUE);
+}
+
+BOOL GLAPIENTRY SetPixelFormat(HDC hdc, int iPixelFormat,
+ CONST PIXELFORMATDESCRIPTOR *ppfd)
+{
+ return wglSetPixelFormat(hdc,iPixelFormat,ppfd);
+}
+
+BOOL GLAPIENTRY SwapBuffers(HDC hdc)
+{
+ return wglSwapBuffers(hdc);
+}
+
+#endif /* FX */