diff options
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 */ |