summaryrefslogtreecommitdiff
path: root/xc/extras/Mesa/src/FX/fxrender.c
diff options
context:
space:
mode:
authordawes <dawes>2000-11-30 18:49:38 +0000
committerdawes <dawes>2000-11-30 18:49:38 +0000
commit055ef92b0fcbf4afffd0a6b1e0593f3e9c44b623 (patch)
treec75c2f8883c8b6fff44f9c7b0aea55be7c4f3001 /xc/extras/Mesa/src/FX/fxrender.c
parentd129f7fd02961869422c111dd8c3cf824bc54243 (diff)
XFree86 4.0.1f mergeX_4_0_1f-20001130-merge
Diffstat (limited to 'xc/extras/Mesa/src/FX/fxrender.c')
-rw-r--r--xc/extras/Mesa/src/FX/fxrender.c785
1 files changed, 785 insertions, 0 deletions
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 */