diff options
author | Keith Whitwell <[email protected]> | 2001-07-12 22:09:21 +0000 |
---|---|---|
committer | Keith Whitwell <[email protected]> | 2001-07-12 22:09:21 +0000 |
commit | 1182ffeec39bf419928ba862c225e80a439fee7a (patch) | |
tree | af9e3f9019e3c59cb73d770eb60e94c5c77bdd25 /src/mesa/drivers/glide/fxtris.c | |
parent | fae7b778b81b686ef419f971064b5fe12fb4ead3 (diff) |
Rename some of the tnl->Driver.* functions to tnl->Driver.Render.*, to make it
clear that these are owned by t_vb_render.c.
Make swrast_setup opaque - it now hooks itself directly into
tnl->Driver.Render.*. Add a _swsetup_Wakeup() call that does this.
Update X11 (tested), osmesa and FX drivers for this change.
FX compiles but is probably broken as the changes there are large. It was the
only remaining driver that used the internal _swsetup_ functions for
interp and copy_pv. This usage has been replaced with code from the DRI
tdfx driver.
Diffstat (limited to 'src/mesa/drivers/glide/fxtris.c')
-rw-r--r-- | src/mesa/drivers/glide/fxtris.c | 1119 |
1 files changed, 651 insertions, 468 deletions
diff --git a/src/mesa/drivers/glide/fxtris.c b/src/mesa/drivers/glide/fxtris.c index 829aabe7492..5129a94476b 100644 --- a/src/mesa/drivers/glide/fxtris.c +++ b/src/mesa/drivers/glide/fxtris.c @@ -1,641 +1,824 @@ +/* -*- mode: c; c-basic-offset: 3 -*- + * + * Copyright 2000 VA Linux Systems Inc., Fremont, California. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * VA LINUX SYSTEMS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +/* $XFree86: xc/lib/GL/mesa/src/drv/fx/fxtris.c,v 1.5 2000/09/24 13:51:04 alanh Exp $ */ +/* Authors: + * Keith Whitwell <[email protected]> + */ -#ifdef HAVE_CONFIG_H -#include "conf.h" -#endif +#include <stdio.h> +#include <math.h> -#if defined(FX) +#include "glheader.h" +#include "mtypes.h" +#include "macros.h" +#include "colormac.h" -#include "mmath.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" - #include "tnl/t_context.h" #include "tnl/t_pipeline.h" #include "fxdrv.h" -#include "fxglidew.h" - - - - - - -static void -fx_draw_point(GLcontext * ctx, const fxVertex * v) +/* + * Subpixel offsets to adjust Mesa's (true) window coordinates to + * Glide coordinates. We need these to ensure precise rasterization. + * Otherwise, we'll fail a bunch of conformance tests. + */ +#define TRI_X_OFFSET ( 0.0F) +#define TRI_Y_OFFSET ( 0.0F) +#define LINE_X_OFFSET ( 0.0F) +#define LINE_Y_OFFSET ( 0.125F) +#define PNT_X_OFFSET ( 0.375F) +#define PNT_Y_OFFSET ( 0.375F) + +static void fxRasterPrimitive( GLcontext *ctx, GLenum prim ); +static void fxRenderPrimitive( GLcontext *ctx, GLenum prim ); + +/*********************************************************************** + * Macros for t_dd_tritmp.h to draw basic primitives * + ***********************************************************************/ + +#define TRI( a, b, c ) \ +do { \ + if (DO_FALLBACK) \ + fxMesa->draw_tri( fxMesa, a, b, c ); \ + else \ + grDrawTriangle( a, b, c ); \ +} while (0) \ + +#define QUAD( a, b, c, d ) \ +do { \ + if (DO_FALLBACK) { \ + fxMesa->draw_tri( fxMesa, a, b, d ); \ + fxMesa->draw_tri( fxMesa, b, c, d ); \ + } else { \ + grDrawTriangle( a, b, d ); \ + grDrawTriangle( b, c, d ); \ + } \ +} while (0) + +#define LINE( v0, v1 ) \ +do { \ + if (DO_FALLBACK) \ + fxMesa->draw_line( fxMesa, v0, v1 ); \ + else { \ + v0->x += LINE_X_OFFSET - TRI_X_OFFSET; \ + v0->y += LINE_Y_OFFSET - TRI_Y_OFFSET; \ + v1->x += LINE_X_OFFSET - TRI_X_OFFSET; \ + v1->y += LINE_Y_OFFSET - TRI_Y_OFFSET; \ + grDrawLine( v0, v1 ); \ + v0->x -= LINE_X_OFFSET - TRI_X_OFFSET; \ + v0->y -= LINE_Y_OFFSET - TRI_Y_OFFSET; \ + v1->x -= LINE_X_OFFSET - TRI_X_OFFSET; \ + v1->y -= LINE_Y_OFFSET - TRI_Y_OFFSET; \ + } \ +} while (0) + +#define POINT( v0 ) \ +do { \ + if (DO_FALLBACK) \ + fxMesa->draw_point( fxMesa, v0 ); \ + else { \ + v0->x += PNT_X_OFFSET - TRI_X_OFFSET; \ + v0->y += PNT_Y_OFFSET - TRI_Y_OFFSET; \ + grDrawPoint( v0 ); \ + v0->x -= PNT_X_OFFSET - TRI_X_OFFSET; \ + v0->y -= PNT_Y_OFFSET - TRI_Y_OFFSET; \ + } \ +} while (0) + + +/*********************************************************************** + * Fallback to swrast for basic primitives * + ***********************************************************************/ + +/* Build an SWvertex from a hardware vertex. + * + * This code is hit only when a mix of accelerated and unaccelerated + * primitives are being drawn, and only for the unaccelerated + * primitives. + */ +static void +fx_translate_vertex( GLcontext *ctx, const GrVertex *src, SWvertex *dst) { - GLfloat sz = ctx->Point._Size; - - if (sz <= 1.0) { - grDrawPoint(&(v->v)); - } - else { - GrVertex verts[4]; - - sz *= .5; + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GLuint ts0 = fxMesa->tmu_source[0]; + GLuint ts1 = fxMesa->tmu_source[1]; + GLfloat w = 1.0 / src->oow; - verts[0] = v->v; - verts[1] = v->v; - verts[2] = v->v; - verts[3] = v->v; + dst->win[0] = src->x; + dst->win[1] = src->y; + dst->win[2] = src->ooz; + dst->win[3] = src->oow; - verts[0].x = v->v.x - sz; - verts[0].y = v->v.y - sz; + dst->color[0] = (GLubyte) src->r; + dst->color[1] = (GLubyte) src->g; + dst->color[2] = (GLubyte) src->b; + dst->color[3] = (GLubyte) src->a; - verts[1].x = v->v.x + sz; - verts[1].y = v->v.y - sz; + dst->texcoord[ts0][0] = fxMesa->inv_s0scale * src->tmuvtx[0].sow * w; + dst->texcoord[ts0][1] = fxMesa->inv_t0scale * src->tmuvtx[0].tow * w; - verts[2].x = v->v.x + sz; - verts[2].y = v->v.y + sz; + if (fxMesa->stw_hint_state & GR_STWHINT_W_DIFF_TMU0) + dst->texcoord[ts0][3] = src->tmuvtx[0].oow * w; + else + dst->texcoord[ts0][3] = 1.0; - verts[3].x = v->v.x - sz; - verts[3].y = v->v.y + sz; + if (fxMesa->SetupIndex & SETUP_TMU1) { + dst->texcoord[ts1][0] = fxMesa->inv_s1scale * src->tmuvtx[1].sow * w; + dst->texcoord[ts1][1] = fxMesa->inv_t1scale * src->tmuvtx[1].tow * w; - grDrawTriangle(&verts[0], &verts[1], &verts[3]); - grDrawTriangle(&verts[1], &verts[2], &verts[3]); + if (fxMesa->stw_hint_state & GR_STWHINT_W_DIFF_TMU1) + dst->texcoord[ts1][3] = src->tmuvtx[1].oow * w; + else + dst->texcoord[ts1][3] = 1.0; } + + dst->pointSize = ctx->Point._Size; } -static void -fx_draw_line(GLcontext * ctx, const fxVertex * v0, const fxVertex * v1) +static void +fx_fallback_tri( fxMesaContext fxMesa, + GrVertex *v0, + GrVertex *v1, + GrVertex *v2 ) { - float width = ctx->Line.Width; - - if (width <= 1.0) { - grDrawLine(&(v0->v), &(v1->v)); - } - else { - GrVertex verts[4]; - float dx, dy, ix, iy; - - dx = v0->v.x - v1->v.x; - dy = v0->v.y - v1->v.y; - - if (dx * dx > dy * dy) { - iy = width * .5; - ix = 0; - } - else { - iy = 0; - ix = width * .5; - } - - - verts[0] = v0->v; - verts[0].x -= ix; - verts[0].y -= iy; + GLcontext *ctx = fxMesa->glCtx; + SWvertex v[3]; + fx_translate_vertex( ctx, v0, &v[0] ); + fx_translate_vertex( ctx, v1, &v[1] ); + fx_translate_vertex( ctx, v2, &v[2] ); + _swrast_Triangle( ctx, &v[0], &v[1], &v[2] ); +} - verts[1] = v0->v; - verts[1].x += ix; - verts[1].y += iy; - verts[2] = v1->v; - verts[2].x += ix; - verts[2].y += iy; +static void +fx_fallback_line( fxMesaContext fxMesa, + GrVertex *v0, + GrVertex *v1 ) +{ + GLcontext *ctx = fxMesa->glCtx; + SWvertex v[2]; + fx_translate_vertex( ctx, v0, &v[0] ); + fx_translate_vertex( ctx, v1, &v[1] ); + _swrast_Line( ctx, &v[0], &v[1] ); +} - verts[3] = v1->v; - verts[3].x -= ix; - verts[3].y -= iy; - grDrawTriangle(&verts[0], &verts[1], &verts[3]); - grDrawTriangle(&verts[1], &verts[2], &verts[3]); - } +static void +fx_fallback_point( fxMesaContext fxMesa, + GrVertex *v0 ) +{ + GLcontext *ctx = fxMesa->glCtx; + SWvertex v[1]; + fx_translate_vertex( ctx, v0, &v[0] ); + _swrast_Point( ctx, &v[0] ); } -static void -fx_draw_tri(GLcontext * ctx, const fxVertex * v0, const fxVertex * v1, - const fxVertex * v2) +/*********************************************************************** + * Functions to draw basic primitives * + ***********************************************************************/ + +static void fx_print_vertex( GLcontext *ctx, const GrVertex *v ) { - grDrawTriangle(&(v0->v), &(v1->v), &(v2->v)); + fprintf(stderr, "vertex at %p\n", v); + + fprintf(stderr, "x %f y %f z %f oow %f\n", + v->x, v->y, v->ooz, v->oow); + fprintf(stderr, "r %f g %f b %f a %f\n", + v->r, + v->g, + v->b, + v->a); + + fprintf(stderr, "\n"); } +#define DO_FALLBACK 0 - -#define FX_COLOR(vert, c) { \ - GLfloat *col = c; \ - UNCLAMPED_FLOAT_TO_UBYTE(vert->v.r, col[0]); \ - UNCLAMPED_FLOAT_TO_UBYTE(vert->v.g, col[1]); \ - UNCLAMPED_FLOAT_TO_UBYTE(vert->v.b, col[2]); \ - UNCLAMPED_FLOAT_TO_UBYTE(vert->v.a, col[3]); \ +/* Need to do clip loop at each triangle when mixing swrast and hw + * rendering. These functions are only used when mixed-mode rendering + * is occurring. + */ +static void fx_draw_quad( fxMesaContext fxMesa, + GrVertex *v0, + GrVertex *v1, + GrVertex *v2, + GrVertex *v3 ) +{ + QUAD( v0, v1, v2, v3 ); } -#define FX_COPY_COLOR( dst, src ) { \ - dst->v.r = src->v.r; \ - dst->v.g = src->v.g; \ - dst->v.b = src->v.b; \ - dst->v.a = src->v.a; \ +static void fx_draw_triangle( fxMesaContext fxMesa, + GrVertex *v0, + GrVertex *v1, + GrVertex *v2 ) +{ + TRI( v0, v1, v2 ); } +static void fx_draw_line( fxMesaContext fxMesa, + GrVertex *v0, + GrVertex *v1 ) +{ + /* No support for wide lines (avoid wide/aa line fallback). + */ + LINE(v0, v1); +} - -#define FX_FLAT_BIT 0x01 -#define FX_OFFSET_BIT 0x02 -#define FX_TWOSIDE_BIT 0x04 -#define FX_UNFILLED_BIT 0x10 -#define FX_FALLBACK_BIT 0x20 -#define FX_MAX_TRIFUNC 0x40 - -static struct +static void fx_draw_point( fxMesaContext fxMesa, + GrVertex *v0 ) { - points_func points; - line_func line; - triangle_func triangle; - quad_func quad; + /* No support for wide points. + */ + POINT( v0 ); } -rast_tab[FX_MAX_TRIFUNC]; +#undef DO_FALLBACK + + +#define FX_UNFILLED_BIT 0x1 +#define FX_OFFSET_BIT 0x2 +#define FX_TWOSIDE_BIT 0x4 +#define FX_FLAT_BIT 0x8 +#define FX_FALLBACK_BIT 0x10 +#define FX_MAX_TRIFUNC 0x20 + +static struct { + points_func points; + line_func line; + triangle_func triangle; + quad_func quad; +} rast_tab[FX_MAX_TRIFUNC]; + +#define DO_FALLBACK (IND & FX_FALLBACK_BIT) +#define DO_OFFSET (IND & FX_OFFSET_BIT) +#define DO_UNFILLED (IND & FX_UNFILLED_BIT) +#define DO_TWOSIDE (IND & FX_TWOSIDE_BIT) +#define DO_FLAT (IND & FX_FLAT_BIT) +#define DO_TRI 1 +#define DO_QUAD 1 +#define DO_LINE 1 +#define DO_POINTS 1 +#define DO_FULL_QUAD 1 + +#define HAVE_RGBA 1 +#define HAVE_SPEC 0 +#define HAVE_HW_FLATSHADE 0 +#define HAVE_BACK_COLORS 0 +#define VERTEX GrVertex +#define TAB rast_tab + +#define DEPTH_SCALE 1.0 +#define UNFILLED_TRI unfilled_tri +#define UNFILLED_QUAD unfilled_quad +#define VERT_X(_v) _v->x +#define VERT_Y(_v) _v->y +#define VERT_Z(_v) _v->ooz +#define AREA_IS_CCW( a ) (a < 0) +#define GET_VERTEX(e) (fxMesa->verts + e) + +#define VERT_SET_RGBA( dst, f ) \ +do { \ + dst->r = CLAMP( f[0], 0, 1 ) * 255.0; \ + dst->g = CLAMP( f[1], 0, 1 ) * 255.0; \ + dst->b = CLAMP( f[2], 0, 1 ) * 255.0; \ + dst->a = CLAMP( f[3], 0, 1 ) * 255.0; \ +} while (0) + +#define VERT_COPY_RGBA( v0, v1 ) \ +do { \ + v0->r = v1->r; \ + v0->g = v1->g; \ + v0->b = v1->b; \ + v0->a = v1->a; \ +} while (0) + +#define VERT_SAVE_RGBA( idx ) \ +do { \ + color[idx][0] = v[idx]->r; \ + color[idx][1] = v[idx]->g; \ + color[idx][1] = v[idx]->b; \ + color[idx][3] = v[idx]->a; \ +} while (0) + + +#define VERT_RESTORE_RGBA( idx ) \ +do { \ + v[idx]->r = color[idx][0]; \ + v[idx]->g = color[idx][1]; \ + v[idx]->b = color[idx][2]; \ + v[idx]->a = color[idx][3]; \ +} while (0) + + +#define LOCAL_VARS(n) \ + fxMesaContext fxMesa = FX_CONTEXT(ctx); \ + GLfloat color[n][4]; \ + (void) color; + + + +/*********************************************************************** + * Functions to draw basic unfilled primitives * + ***********************************************************************/ + +#define RASTERIZE(x) if (fxMesa->raster_primitive != x) \ + fxRasterPrimitive( ctx, x ) +#define RENDER_PRIMITIVE fxMesa->render_primitive +#define IND FX_FALLBACK_BIT +#define TAG(x) x +#include "tnl_dd/t_dd_unfilled.h" +#undef IND + +/*********************************************************************** + * Functions to draw GL primitives * + ***********************************************************************/ #define IND (0) #define TAG(x) x -#include "fxtritmp.h" - -#define IND (FX_FLAT_BIT) -#define TAG(x) x##_flat -#include "fxtritmp.h" +#include "tnl_dd/t_dd_tritmp.h" #define IND (FX_OFFSET_BIT) #define TAG(x) x##_offset -#include "fxtritmp.h" - -#define IND (FX_OFFSET_BIT | FX_FLAT_BIT) -#define TAG(x) x##_offset_flat -#include "fxtritmp.h" +#include "tnl_dd/t_dd_tritmp.h" #define IND (FX_TWOSIDE_BIT) #define TAG(x) x##_twoside -#include "fxtritmp.h" - -#define IND (FX_TWOSIDE_BIT | FX_FLAT_BIT) -#define TAG(x) x##_twoside_flat -#include "fxtritmp.h" +#include "tnl_dd/t_dd_tritmp.h" -#define IND (FX_TWOSIDE_BIT | FX_OFFSET_BIT) +#define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT) #define TAG(x) x##_twoside_offset -#include "fxtritmp.h" +#include "tnl_dd/t_dd_tritmp.h" -#define IND (FX_TWOSIDE_BIT | FX_OFFSET_BIT | FX_FLAT_BIT) -#define TAG(x) x##_twoside_offset_flat -#include "fxtritmp.h" +#define IND (FX_UNFILLED_BIT) +#define TAG(x) x##_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_OFFSET_BIT|FX_UNFILLED_BIT) +#define TAG(x) x##_offset_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_UNFILLED_BIT) +#define TAG(x) x##_twoside_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_UNFILLED_BIT) +#define TAG(x) x##_twoside_offset_unfilled +#include "tnl_dd/t_dd_tritmp.h" #define IND (FX_FALLBACK_BIT) #define TAG(x) x##_fallback -#include "fxtritmp.h" - -#define IND (FX_FLAT_BIT | FX_FALLBACK_BIT) -#define TAG(x) x##_flat_fallback -#include "fxtritmp.h" +#include "tnl_dd/t_dd_tritmp.h" -#define IND (FX_OFFSET_BIT | FX_FALLBACK_BIT) +#define IND (FX_OFFSET_BIT|FX_FALLBACK_BIT) #define TAG(x) x##_offset_fallback -#include "fxtritmp.h" +#include "tnl_dd/t_dd_tritmp.h" -#define IND (FX_OFFSET_BIT | FX_FLAT_BIT | FX_FALLBACK_BIT) -#define TAG(x) x##_offset_flat_fallback -#include "fxtritmp.h" - -#define IND (FX_TWOSIDE_BIT | FX_FALLBACK_BIT) +#define IND (FX_TWOSIDE_BIT|FX_FALLBACK_BIT) #define TAG(x) x##_twoside_fallback -#include "fxtritmp.h" - -#define IND (FX_TWOSIDE_BIT | FX_FLAT_BIT | FX_FALLBACK_BIT) -#define TAG(x) x##_twoside_flat_fallback -#include "fxtritmp.h" +#include "tnl_dd/t_dd_tritmp.h" -#define IND (FX_TWOSIDE_BIT | FX_OFFSET_BIT | FX_FALLBACK_BIT) +#define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_FALLBACK_BIT) #define TAG(x) x##_twoside_offset_fallback -#include "fxtritmp.h" +#include "tnl_dd/t_dd_tritmp.h" -#define IND (FX_TWOSIDE_BIT | FX_OFFSET_BIT | FX_FLAT_BIT | FX_FALLBACK_BIT) -#define TAG(x) x##_twoside_offset_flat_fallback -#include "fxtritmp.h" +#define IND (FX_UNFILLED_BIT|FX_FALLBACK_BIT) +#define TAG(x) x##_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" -#define IND (FX_UNFILLED_BIT) -#define TAG(x) x##_unfilled -#include "fxtritmp.h" +#define IND (FX_OFFSET_BIT|FX_UNFILLED_BIT|FX_FALLBACK_BIT) +#define TAG(x) x##_offset_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" -#define IND (FX_FLAT_BIT | FX_UNFILLED_BIT) -#define TAG(x) x##_flat_unfilled -#include "fxtritmp.h" +#define IND (FX_TWOSIDE_BIT|FX_UNFILLED_BIT|FX_FALLBACK_BIT) +#define TAG(x) x##_twoside_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" -#define IND (FX_OFFSET_BIT | FX_UNFILLED_BIT) -#define TAG(x) x##_offset_unfilled -#include "fxtritmp.h" +#define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_UNFILLED_BIT| \ + FX_FALLBACK_BIT) +#define TAG(x) x##_twoside_offset_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" -#define IND (FX_OFFSET_BIT | FX_FLAT_BIT | FX_UNFILLED_BIT) -#define TAG(x) x##_offset_flat_unfilled -#include "fxtritmp.h" -#define IND (FX_TWOSIDE_BIT | FX_UNFILLED_BIT) -#define TAG(x) x##_twoside_unfilled -#include "fxtritmp.h" +/* Fx doesn't support provoking-vertex flat-shading? + */ +#define IND (FX_FLAT_BIT) +#define TAG(x) x##_flat +#include "tnl_dd/t_dd_tritmp.h" -#define IND (FX_TWOSIDE_BIT | FX_FLAT_BIT | FX_UNFILLED_BIT) -#define TAG(x) x##_twoside_flat_unfilled -#include "fxtritmp.h" +#define IND (FX_OFFSET_BIT|FX_FLAT_BIT) +#define TAG(x) x##_offset_flat +#include "tnl_dd/t_dd_tritmp.h" -#define IND (FX_TWOSIDE_BIT | FX_OFFSET_BIT | FX_UNFILLED_BIT) -#define TAG(x) x##_twoside_offset_unfilled -#include "fxtritmp.h" +#define IND (FX_TWOSIDE_BIT|FX_FLAT_BIT) +#define TAG(x) x##_twoside_flat +#include "tnl_dd/t_dd_tritmp.h" -#define IND (FX_TWOSIDE_BIT | FX_OFFSET_BIT | FX_FLAT_BIT | FX_UNFILLED_BIT) -#define TAG(x) x##_twoside_offset_flat_unfilled -#include "fxtritmp.h" +#define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_FLAT_BIT) +#define TAG(x) x##_twoside_offset_flat +#include "tnl_dd/t_dd_tritmp.h" -#define IND (FX_FALLBACK_BIT | FX_UNFILLED_BIT) -#define TAG(x) x##_fallback_unfilled -#include "fxtritmp.h" +#define IND (FX_UNFILLED_BIT|FX_FLAT_BIT) +#define TAG(x) x##_unfilled_flat +#include "tnl_dd/t_dd_tritmp.h" -#define IND (FX_FLAT_BIT | FX_FALLBACK_BIT | FX_UNFILLED_BIT) -#define TAG(x) x##_flat_fallback_unfilled -#include "fxtritmp.h" +#define IND (FX_OFFSET_BIT|FX_UNFILLED_BIT|FX_FLAT_BIT) +#define TAG(x) x##_offset_unfilled_flat +#include "tnl_dd/t_dd_tritmp.h" -#define IND (FX_OFFSET_BIT | FX_FALLBACK_BIT | FX_UNFILLED_BIT) -#define TAG(x) x##_offset_fallback_unfilled -#include "fxtritmp.h" +#define IND (FX_TWOSIDE_BIT|FX_UNFILLED_BIT|FX_FLAT_BIT) +#define TAG(x) x##_twoside_unfilled_flat +#include "tnl_dd/t_dd_tritmp.h" -#define IND (FX_OFFSET_BIT | FX_FLAT_BIT | FX_FALLBACK_BIT | FX_UNFILLED_BIT) -#define TAG(x) x##_offset_flat_fallback_unfilled -#include "fxtritmp.h" +#define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_UNFILLED_BIT|FX_FLAT_BIT) +#define TAG(x) x##_twoside_offset_unfilled_flat +#include "tnl_dd/t_dd_tritmp.h" -#define IND (FX_TWOSIDE_BIT | FX_FALLBACK_BIT | FX_UNFILLED_BIT) -#define TAG(x) x##_twoside_fallback_unfilled -#include "fxtritmp.h" +#define IND (FX_FALLBACK_BIT|FX_FLAT_BIT) +#define TAG(x) x##_fallback_flat +#include "tnl_dd/t_dd_tritmp.h" -#define IND (FX_TWOSIDE_BIT | FX_FLAT_BIT | FX_FALLBACK_BIT | FX_UNFILLED_BIT) -#define TAG(x) x##_twoside_flat_fallback_unfilled -#include "fxtritmp.h" +#define IND (FX_OFFSET_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT) +#define TAG(x) x##_offset_fallback_flat +#include "tnl_dd/t_dd_tritmp.h" -#define IND (FX_TWOSIDE_BIT | FX_OFFSET_BIT | FX_FALLBACK_BIT | FX_UNFILLED_BIT) -#define TAG(x) x##_twoside_offset_fallback_unfilled -#include "fxtritmp.h" +#define IND (FX_TWOSIDE_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT) +#define TAG(x) x##_twoside_fallback_flat +#include "tnl_dd/t_dd_tritmp.h" -#define IND (FX_TWOSIDE_BIT | FX_OFFSET_BIT | FX_FLAT_BIT | FX_FALLBACK_BIT | FX_UNFILLED_BIT) -#define TAG(x) x##_twoside_offset_flat_fallback_unfilled -#include "fxtritmp.h" +#define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT) +#define TAG(x) x##_twoside_offset_fallback_flat +#include "tnl_dd/t_dd_tritmp.h" +#define IND (FX_UNFILLED_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT) +#define TAG(x) x##_unfilled_fallback_flat +#include "tnl_dd/t_dd_tritmp.h" +#define IND (FX_OFFSET_BIT|FX_UNFILLED_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT) +#define TAG(x) x##_offset_unfilled_fallback_flat +#include "tnl_dd/t_dd_tritmp.h" +#define IND (FX_TWOSIDE_BIT|FX_UNFILLED_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT) +#define TAG(x) x##_twoside_unfilled_fallback_flat +#include "tnl_dd/t_dd_tritmp.h" +#define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_UNFILLED_BIT| \ + FX_FALLBACK_BIT|FX_FLAT_BIT) +#define TAG(x) x##_twoside_offset_unfilled_fallback_flat +#include "tnl_dd/t_dd_tritmp.h" -void -fxDDTrifuncInit(void) +static void init_rast_tab( void ) { init(); - init_flat(); init_offset(); - init_offset_flat(); init_twoside(); - init_twoside_flat(); init_twoside_offset(); - init_twoside_offset_flat(); + init_unfilled(); + init_offset_unfilled(); + init_twoside_unfilled(); + init_twoside_offset_unfilled(); init_fallback(); - init_flat_fallback(); init_offset_fallback(); - init_offset_flat_fallback(); init_twoside_fallback(); - init_twoside_flat_fallback(); init_twoside_offset_fallback(); - init_twoside_offset_flat_fallback(); + init_unfilled_fallback(); + init_offset_unfilled_fallback(); + init_twoside_unfilled_fallback(); + init_twoside_offset_unfilled_fallback(); - init_unfilled(); - init_flat_unfilled(); - init_offset_unfilled(); - init_offset_flat_unfilled(); - init_twoside_unfilled(); - init_twoside_flat_unfilled(); - init_twoside_offset_unfilled(); - init_twoside_offset_flat_unfilled(); - init_fallback_unfilled(); - init_flat_fallback_unfilled(); - init_offset_fallback_unfilled(); - init_offset_flat_fallback_unfilled(); - init_twoside_fallback_unfilled(); - init_twoside_flat_fallback_unfilled(); - init_twoside_offset_fallback_unfilled(); - init_twoside_offset_flat_fallback_unfilled(); + init_flat(); + init_offset_flat(); + init_twoside_flat(); + init_twoside_offset_flat(); + init_unfilled_flat(); + init_offset_unfilled_flat(); + init_twoside_unfilled_flat(); + init_twoside_offset_unfilled_flat(); + init_fallback_flat(); + init_offset_fallback_flat(); + init_twoside_fallback_flat(); + init_twoside_offset_fallback_flat(); + init_unfilled_fallback_flat(); + init_offset_unfilled_fallback_flat(); + init_twoside_unfilled_fallback_flat(); + init_twoside_offset_unfilled_fallback_flat(); } -/* Build an SWvertex from a GrVertex. This is workable because in - * states where the GrVertex is insufficent (eg separate-specular), - * the driver initiates a total fallback, and builds SWvertices - * directly -- it recognizes that it will never have use for the - * GrVertex. - * - * This code is hit only when a mix of accelerated and unaccelerated - * primitives are being drawn, and only for the unaccelerated - * primitives. - */ -static void -fx_translate_vertex(GLcontext * ctx, const fxVertex * src, SWvertex * dst) -{ - fxMesaContext fxMesa = FX_CONTEXT(ctx); - GLuint ts0 = fxMesa->tmu_source[0]; - GLuint ts1 = fxMesa->tmu_source[1]; - GLfloat w = 1.0 / src->v.oow; - - dst->win[0] = src->v.x; - dst->win[1] = src->v.y; - dst->win[2] = src->v.ooz; - dst->win[3] = src->v.oow; - - dst->color[0] = (GLubyte) src->v.r; - dst->color[1] = (GLubyte) src->v.g; - dst->color[2] = (GLubyte) src->v.b; - dst->color[3] = (GLubyte) src->v.a; - - dst->texcoord[ts0][0] = fxMesa->inv_s0scale * src->v.tmuvtx[0].sow * w; - dst->texcoord[ts0][1] = fxMesa->inv_t0scale * src->v.tmuvtx[0].tow * w; - if (fxMesa->stw_hint_state & GR_STWHINT_W_DIFF_TMU0) - dst->texcoord[ts0][3] = src->v.tmuvtx[0].oow * w; - else - dst->texcoord[ts0][3] = 1.0; +/**********************************************************************/ +/* Render whole (indexed) begin/end objects */ +/**********************************************************************/ - dst->texcoord[ts1][0] = fxMesa->inv_s1scale * src->v.tmuvtx[1].sow * w; - dst->texcoord[ts1][1] = fxMesa->inv_t1scale * src->v.tmuvtx[1].tow * w; - if (fxMesa->stw_hint_state & GR_STWHINT_W_DIFF_TMU1) - dst->texcoord[ts1][3] = src->v.tmuvtx[1].oow * w; - else - dst->texcoord[ts1][3] = 1.0; -} +#define VERT(x) (vertptr + x) +#define RENDER_POINTS( start, count ) \ + for ( ; start < count ; start++) \ + grDrawPoint( VERT(ELT(start)) ); -static void -fx_fallback_tri(GLcontext * ctx, - const fxVertex * v0, const fxVertex * v1, const fxVertex * v2) -{ - SWvertex v[3]; - fx_translate_vertex(ctx, v0, &v[0]); - fx_translate_vertex(ctx, v1, &v[1]); - fx_translate_vertex(ctx, v2, &v[2]); - _swrast_Triangle(ctx, &v[0], &v[1], &v[2]); -} +#define RENDER_LINE( v0, v1 ) \ + grDrawLine( VERT(v0), VERT(v1) ) +#define RENDER_TRI( v0, v1, v2 ) \ + grDrawTriangle( VERT(v0), VERT(v1), VERT(v2) ) -static void -fx_fallback_line(GLcontext * ctx, const fxVertex * v0, const fxVertex * v1) -{ - SWvertex v[2]; - fx_translate_vertex(ctx, v0, &v[0]); - fx_translate_vertex(ctx, v1, &v[1]); - _swrast_Line(ctx, &v[0], &v[1]); -} +#define RENDER_QUAD( v0, v1, v2, v3 ) \ + fx_draw_quad( fxMesa, VERT(v0), VERT(v1), VERT(v2), VERT(v3) ) +#define INIT(x) fxRenderPrimitive( ctx, x ) -static void -fx_fallback_point(GLcontext * ctx, const fxVertex * v0) -{ - SWvertex v[1]; - fx_translate_vertex(ctx, v0, &v[0]); - _swrast_Point(ctx, &v[0]); -} +#undef LOCAL_VARS +#define LOCAL_VARS \ + fxMesaContext fxMesa = FX_CONTEXT(ctx); \ + GrVertex *vertptr = fxMesa->verts; \ + const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \ + (void) elt; +#define RESET_STIPPLE +#define RESET_OCCLUSION +#define PRESERVE_VB_DEFS -/* System to turn culling off for rasterized lines and points, and - * back on for rasterized triangles. +/* Elts, no clipping. */ -static void -fx_cull_draw_tri(GLcontext * ctx, - const fxVertex * v0, const fxVertex * v1, - const fxVertex * v2) -{ - fxMesaContext fxMesa = FX_CONTEXT(ctx); - - FX_grCullMode(fxMesa->cullMode); - - fxMesa->draw_line = fxMesa->initial_line; - fxMesa->draw_point = fxMesa->initial_point; - fxMesa->draw_tri = fxMesa->subsequent_tri; - - fxMesa->draw_tri(ctx, v0, v1, v2); -} +#undef ELT +#undef TAG +#define TAG(x) fx_##x##_elts +#define ELT(x) elt[x] +#include "tnl_dd/t_dd_rendertmp.h" +/* Verts, no clipping. + */ +#undef ELT +#undef TAG +#define TAG(x) fx_##x##_verts +#define ELT(x) x +#include "tnl_dd/t_dd_rendertmp.h" -static void -fx_cull_draw_line(GLcontext * ctx, const fxVertex * v0, const fxVertex * v1) -{ - fxMesaContext fxMesa = FX_CONTEXT(ctx); - FX_grCullMode(GR_CULL_DISABLE); - fxMesa->draw_point = fxMesa->initial_point; - fxMesa->draw_tri = fxMesa->initial_tri; - fxMesa->draw_line = fxMesa->subsequent_line; +/**********************************************************************/ +/* Render clipped primitives */ +/**********************************************************************/ - fxMesa->draw_line(ctx, v0, v1); -} -static void -fx_cull_draw_point(GLcontext * ctx, const fxVertex * v0) +static void fxRenderClippedPoly( GLcontext *ctx, const GLuint *elts, + GLuint n ) { fxMesaContext fxMesa = FX_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + GLuint prim = fxMesa->render_primitive; + + /* Render the new vertices as an unclipped polygon. + */ + { + GLuint *tmp = VB->Elts; + VB->Elts = (GLuint *)elts; + tnl->Driver.Render.PrimTabElts[GL_POLYGON]( ctx, 0, n, + PRIM_BEGIN|PRIM_END ); + VB->Elts = tmp; + } - FX_grCullMode(GR_CULL_DISABLE); - - fxMesa->draw_line = fxMesa->initial_line; - fxMesa->draw_tri = fxMesa->initial_tri; - fxMesa->draw_point = fxMesa->subsequent_point; - - fxMesa->draw_point(ctx, v0); + /* Restore the render primitive + */ + if (prim != GL_POLYGON) + tnl->Driver.Render.PrimitiveNotify( ctx, prim ); } -static void -fx_null_tri(GLcontext * ctx, - const fxVertex * v0, const fxVertex * v1, const fxVertex * v2) +static void fxFastRenderClippedPoly( GLcontext *ctx, const GLuint *elts, + GLuint n ) { - (void) v0; - (void) v1; - (void) v2; + fxMesaContext fxMesa = FX_CONTEXT( ctx ); + GrVertex *vertptr = fxMesa->verts; + const GrVertex *start = VERT(elts[0]); + int i; + + for (i = 2 ; i < n ; i++) { + grDrawTriangle( start, VERT(elts[i-1]), VERT(elts[i]) ); + } } +/**********************************************************************/ +/* Choose render functions */ +/**********************************************************************/ +#define POINT_FALLBACK (DD_POINT_SMOOTH) +#define LINE_FALLBACK (DD_LINE_STIPPLE) +#define TRI_FALLBACK (DD_TRI_SMOOTH) +#define ANY_FALLBACK_FLAGS (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK|DD_TRI_STIPPLE) +#define ANY_RASTER_FLAGS (DD_FLATSHADE|DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET| \ + DD_TRI_UNFILLED) -/**********************************************************************/ -/* Render whole begin/end objects */ -/**********************************************************************/ -/* Vertices, no clipping. - */ -#define RENDER_POINTS( start, count ) \ - for ( ; start < count ; start++) \ - grDrawPoint( &v[ELT(start)].v ); +static void fxChooseRenderState(GLcontext *ctx) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GLuint flags = ctx->_TriangleCaps; + GLuint index = 0; -#define RENDER_LINE( i1, i ) \ - grDrawLine( &v[i1].v, &v[i].v ) +/* fprintf(stderr, "%s\n", __FUNCTION__); */ -#define RENDER_TRI( i2, i1, i ) \ - grDrawTriangle( &v[i2].v, &v[i1].v, &v[i].v ) + if (flags & (ANY_FALLBACK_FLAGS|ANY_RASTER_FLAGS)) { + if (flags & ANY_RASTER_FLAGS) { + if (flags & DD_TRI_LIGHT_TWOSIDE) index |= FX_TWOSIDE_BIT; + if (flags & DD_TRI_OFFSET) index |= FX_OFFSET_BIT; + if (flags & DD_TRI_UNFILLED) index |= FX_UNFILLED_BIT; + if (flags & DD_FLATSHADE) index |= FX_FLAT_BIT; + } -#define RENDER_QUAD( i3, i2, i1, i ) \ - grDrawTriangle( &v[i3].v, &v[i2].v, &v[i].v ); \ - grDrawTriangle( &v[i2].v, &v[i1].v, &v[i].v ) + fxMesa->draw_point = fx_draw_point; + fxMesa->draw_line = fx_draw_line; + fxMesa->draw_tri = fx_draw_triangle; -#define TAG(x) fx_##x##_verts -#define LOCAL_VARS \ - fxVertex *v = FX_CONTEXT(ctx)->verts; \ - const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \ - (void) elt; + /* Hook in fallbacks for specific primitives. + * + * + */ + if (flags & (POINT_FALLBACK| + LINE_FALLBACK| + TRI_FALLBACK)) + { + if (flags & POINT_FALLBACK) + fxMesa->draw_point = fx_fallback_point; -/* Verts, no clipping. - */ -#define ELT(x) x -#define RESET_STIPPLE -#define RESET_OCCLUSION -#define PRESERVE_VB_DEFS -#include "tnl/t_vb_rendertmp.h" + if (flags & LINE_FALLBACK) + fxMesa->draw_line = fx_fallback_line; + if (flags & TRI_FALLBACK) + fxMesa->draw_tri = fx_fallback_tri; -/* Elts, no clipping. - */ -#undef ELT -#undef TAG -#define TAG(x) fx_##x##_elts -#define ELT(x) elt[x] -#include "tnl/t_vb_rendertmp.h" + index |= FX_FALLBACK_BIT; + } + } + tnl->Driver.Render.Points = rast_tab[index].points; + tnl->Driver.Render.Line = rast_tab[index].line; + tnl->Driver.Render.ClippedLine = rast_tab[index].line; + tnl->Driver.Render.Triangle = rast_tab[index].triangle; + tnl->Driver.Render.Quad = rast_tab[index].quad; + + if (index == 0) { + tnl->Driver.Render.PrimTabVerts = fx_render_tab_verts; + tnl->Driver.Render.PrimTabElts = fx_render_tab_elts; + tnl->Driver.Render.ClippedPolygon = fxFastRenderClippedPoly; + } else { + tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts; + tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts; + tnl->Driver.Render.ClippedPolygon = fxRenderClippedPoly; + } +} /**********************************************************************/ -/* Choose render functions */ +/* Runtime render state and callbacks */ /**********************************************************************/ +static GLenum reduced_prim[GL_POLYGON+1] = { + GL_POINTS, + GL_LINES, + GL_LINES, + GL_LINES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES +}; -#define POINT_FALLBACK (DD_POINT_SMOOTH ) -#define LINE_FALLBACK (DD_LINE_STIPPLE) -#define TRI_FALLBACK (DD_TRI_SMOOTH | DD_TRI_STIPPLE ) -#define ANY_FALLBACK (POINT_FALLBACK | LINE_FALLBACK | TRI_FALLBACK) +/* Always called between RenderStart and RenderFinish --> We already + * hold the lock. + */ +static void fxRasterPrimitive( GLcontext *ctx, GLenum prim ) +{ + fxMesaContext fxMesa = FX_CONTEXT( ctx ); -#define ANY_RENDER_FLAGS (DD_FLATSHADE | \ - DD_TRI_LIGHT_TWOSIDE | \ - DD_TRI_OFFSET | \ - DD_TRI_UNFILLED) + fxMesa->raster_primitive = prim; + if (prim == GL_TRIANGLES) + grCullMode( fxMesa->cullMode ); + else + grCullMode( GR_CULL_DISABLE ); +} -/* Setup the Point, Line, Triangle and Quad functions based on the - * current rendering state. Wherever possible, use the hardware to - * render the primitive. Otherwise, fallback to software rendering. +/* Determine the rasterized primitive when not drawing unfilled + * polygons. */ -void -fxDDChooseRenderState(GLcontext * ctx) +static void fxRenderPrimitive( GLcontext *ctx, GLenum prim ) { - TNLcontext *tnl = TNL_CONTEXT(ctx); fxMesaContext fxMesa = FX_CONTEXT(ctx); - GLuint flags = ctx->_TriangleCaps; - GLuint index = 0; + GLuint rprim = reduced_prim[prim]; - if (!fxMesa->is_in_hardware) { - /* Build software vertices directly. No acceleration is - * possible. GrVertices may be insufficient for this mode. - */ - tnl->Driver.PointsFunc = _swsetup_Points; - tnl->Driver.LineFunc = _swsetup_Line; - tnl->Driver.TriangleFunc = _swsetup_Triangle; - tnl->Driver.QuadFunc = _swsetup_Quad; - tnl->Driver.RenderTabVerts = _tnl_render_tab_verts; - tnl->Driver.RenderTabElts = _tnl_render_tab_elts; - - fxMesa->render_index = FX_FALLBACK_BIT; - return; - } + fxMesa->render_primitive = prim; - if (flags & ANY_RENDER_FLAGS) { - if (flags & DD_FLATSHADE) - index |= FX_FLAT_BIT; - if (flags & DD_TRI_LIGHT_TWOSIDE) - index |= FX_TWOSIDE_BIT; - if (flags & DD_TRI_OFFSET) - index |= FX_OFFSET_BIT; - if (flags & DD_TRI_UNFILLED) - index |= FX_UNFILLED_BIT; + if (rprim == GL_TRIANGLES && (ctx->_TriangleCaps & DD_TRI_UNFILLED)) + return; + + if (fxMesa->raster_primitive != rprim) { + fxRasterPrimitive( ctx, rprim ); } +} - if (flags & (ANY_FALLBACK | - DD_LINE_WIDTH | DD_POINT_SIZE | DD_TRI_CULL_FRONT_BACK)) { - - /* Hook in fallbacks for specific primitives. - - * Set up a system to turn culling on/off for wide points and - * lines. Alternately: figure out what tris to send so that - * culling isn't a problem. - * - * This replaces the ReducedPrimitiveChange mechanism. - */ - index |= FX_FALLBACK_BIT; - fxMesa->initial_point = fx_cull_draw_point; - fxMesa->initial_line = fx_cull_draw_line; - fxMesa->initial_tri = fx_cull_draw_tri; - - fxMesa->subsequent_point = fx_draw_point; - fxMesa->subsequent_line = fx_draw_line; - fxMesa->subsequent_tri = fx_draw_tri; - - if (flags & POINT_FALLBACK) - fxMesa->initial_point = fx_fallback_point; - - if (flags & LINE_FALLBACK) - fxMesa->initial_line = fx_fallback_line; - if ((flags & DD_LINE_SMOOTH) && ctx->Line.Width != 1.0) - fxMesa->initial_line = fx_fallback_line; - if (flags & TRI_FALLBACK) - fxMesa->initial_tri = fx_fallback_tri; +/**********************************************************************/ +/* Manage total rasterization fallbacks */ +/**********************************************************************/ - if (flags & DD_TRI_CULL_FRONT_BACK) - fxMesa->initial_tri = fx_null_tri; - fxMesa->draw_point = fxMesa->initial_point; - fxMesa->draw_line = fxMesa->initial_line; - fxMesa->draw_tri = fxMesa->initial_tri; - } - else if (fxMesa->render_index & FX_FALLBACK_BIT) { - FX_grCullMode(fxMesa->cullMode); - } +void fxCheckIsInHardware( GLcontext *ctx ) +{ + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + TNLcontext *tnl = TNL_CONTEXT(ctx); + GLuint oldfallback = !fxMesa->is_in_hardware; + GLuint newfallback; - tnl->Driver.PointsFunc = rast_tab[index].points; - tnl->Driver.LineFunc = rast_tab[index].line; - tnl->Driver.TriangleFunc = rast_tab[index].triangle; - tnl->Driver.QuadFunc = rast_tab[index].quad; - fxMesa->render_index = index; + fxMesa->is_in_hardware = check_IsInHardware( ctx ); + newfallback = !fxMesa->is_in_hardware; - if (fxMesa->render_index == 0) { - tnl->Driver.RenderTabVerts = fx_render_tab_verts; - tnl->Driver.RenderTabElts = fx_render_tab_elts; + if (newfallback) { + if (oldfallback == 0) { + _swsetup_Wakeup( ctx ); + } } else { - tnl->Driver.RenderTabVerts = _tnl_render_tab_verts; - tnl->Driver.RenderTabElts = _tnl_render_tab_elts; + if (oldfallback) { + _swrast_flush( ctx ); + tnl->Driver.Render.Start = fxCheckTexSizes; + tnl->Driver.Render.Finish = _swrast_flush; + tnl->Driver.Render.PrimitiveNotify = fxRenderPrimitive; + tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon; + tnl->Driver.Render.ClippedLine = _tnl_RenderClippedLine; + tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts; + tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts; + tnl->Driver.Render.ResetLineStipple = _swrast_ResetLineStipple; + tnl->Driver.Render.BuildVertices = fxBuildVertices; + tnl->Driver.Render.Multipass = 0; + fxDDChooseSetupState(ctx); + fxDDChooseRenderState(ctx); + } } } +void fxDDInitTriFuncs( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + fxMesaContext fxMesa = FX_CONTEXT(ctx); + static int firsttime = 1; + if (firsttime) { + init_rast_tab(); + firsttime = 0; + } - -#else - - -/* - * Need this to provide at least one external definition. - */ - -extern int gl_fx_dummy_function_trifuncs(void); -int -gl_fx_dummy_function_trifuncs(void) -{ - return 0; + tnl->Driver.Render.Start = fxCheckTexSizes; + tnl->Driver.Render.Finish = _swrast_flush; + tnl->Driver.Render.PrimitiveNotify = fxRenderPrimitive; + tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon; + tnl->Driver.Render.ClippedLine = _tnl_RenderClippedLine; + tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts; + tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts; + tnl->Driver.Render.ResetLineStipple = _swrast_ResetLineStipple; + tnl->Driver.Render.BuildVertices = fxBuildVertices; + tnl->Driver.Render.Multipass = 0; + + (void) fx_print_vertex; } - -#endif /* FX */ |