summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/glide/fxtris.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers/glide/fxtris.c')
-rw-r--r--src/mesa/drivers/glide/fxtris.c568
1 files changed, 568 insertions, 0 deletions
diff --git a/src/mesa/drivers/glide/fxtris.c b/src/mesa/drivers/glide/fxtris.c
new file mode 100644
index 0000000000..7d887133b6
--- /dev/null
+++ b/src/mesa/drivers/glide/fxtris.c
@@ -0,0 +1,568 @@
+
+
+#ifdef HAVE_CONFIG_H
+#include "conf.h"
+#endif
+
+#if defined(FX)
+
+#include "mmath.h"
+#include "swrast/swrast.h"
+#include "swrast_setup/swrast_setup.h"
+
+#include "tnl/t_context.h"
+
+#include "fxdrv.h"
+#include "fxglidew.h"
+
+
+
+
+
+
+
+
+static void
+fx_draw_point( GLcontext *ctx, const fxVertex *v )
+{
+ GLfloat sz = ctx->Point._Size;
+
+ if ( sz <= 1.0 )
+ {
+ grDrawPoint( &(v->v) );
+ }
+ else
+ {
+ GrVertex verts[4];
+
+ sz *= .5;
+
+ verts[0] = v->v;
+ verts[1] = v->v;
+ verts[2] = v->v;
+ verts[3] = v->v;
+
+ verts[0].x = v->v.x - sz;
+ verts[0].y = v->v.y - sz;
+
+ verts[1].x = v->v.x + sz;
+ verts[1].y = v->v.y - sz;
+
+ verts[2].x = v->v.x + sz;
+ verts[2].y = v->v.y + sz;
+
+ verts[3].x = v->v.x - sz;
+ verts[3].y = v->v.y + sz;
+
+ grDrawTriangle( &verts[0], &verts[1], &verts[3] );
+ grDrawTriangle( &verts[1], &verts[2], &verts[3] );
+ }
+}
+
+
+static void
+fx_draw_line( GLcontext *ctx, const fxVertex *v0, const fxVertex *v1 )
+{
+ 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;
+
+ verts[1] = v0->v;
+ verts[1].x += ix;
+ verts[1].y += iy;
+
+ verts[2] = v1->v;
+ verts[2].x += ix;
+ verts[2].y += iy;
+
+ 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_draw_tri( GLcontext *ctx, const fxVertex *v0, const fxVertex *v1,
+ const fxVertex *v2 )
+{
+ grDrawTriangle( &(v0->v), &(v1->v), &(v2->v) );
+}
+
+
+
+#define FX_COLOR(vert, c) { \
+ GLubyte *col = c; \
+ vert->v.r=UBYTE_COLOR_TO_FLOAT_255_COLOR(col[0]); \
+ vert->v.g=UBYTE_COLOR_TO_FLOAT_255_COLOR(col[1]); \
+ vert->v.b=UBYTE_COLOR_TO_FLOAT_255_COLOR(col[2]); \
+ vert->v.a=UBYTE_COLOR_TO_FLOAT_255_COLOR(col[3]); \
+}
+
+#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; \
+}
+
+
+
+#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 {
+ points_func points;
+ line_func line;
+ triangle_func triangle;
+ quad_func quad;
+} rast_tab[FX_MAX_TRIFUNC];
+
+
+#define IND (0)
+#define TAG(x) x
+#include "fxtritmp.h"
+
+#define IND (FX_FLAT_BIT)
+#define TAG(x) x##_flat
+#include "fxtritmp.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"
+
+#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"
+
+#define IND (FX_TWOSIDE_BIT | FX_OFFSET_BIT)
+#define TAG(x) x##_twoside_offset
+#include "fxtritmp.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_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"
+
+#define IND (FX_OFFSET_BIT | FX_FALLBACK_BIT)
+#define TAG(x) x##_offset_fallback
+#include "fxtritmp.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 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"
+
+#define IND (FX_TWOSIDE_BIT | FX_OFFSET_BIT | FX_FALLBACK_BIT)
+#define TAG(x) x##_twoside_offset_fallback
+#include "fxtritmp.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)
+#define TAG(x) x##_unfilled
+#include "fxtritmp.h"
+
+#define IND (FX_FLAT_BIT | FX_UNFILLED_BIT)
+#define TAG(x) x##_flat_unfilled
+#include "fxtritmp.h"
+
+#define IND (FX_OFFSET_BIT | FX_UNFILLED_BIT)
+#define TAG(x) x##_offset_unfilled
+#include "fxtritmp.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"
+
+#define IND (FX_TWOSIDE_BIT | FX_FLAT_BIT | FX_UNFILLED_BIT)
+#define TAG(x) x##_twoside_flat_unfilled
+#include "fxtritmp.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_OFFSET_BIT | FX_FLAT_BIT | FX_UNFILLED_BIT)
+#define TAG(x) x##_twoside_offset_flat_unfilled
+#include "fxtritmp.h"
+
+#define IND (FX_FALLBACK_BIT | FX_UNFILLED_BIT)
+#define TAG(x) x##_fallback_unfilled
+#include "fxtritmp.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_FALLBACK_BIT | FX_UNFILLED_BIT)
+#define TAG(x) x##_offset_fallback_unfilled
+#include "fxtritmp.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_FALLBACK_BIT | FX_UNFILLED_BIT)
+#define TAG(x) x##_twoside_fallback_unfilled
+#include "fxtritmp.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_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_OFFSET_BIT | FX_FLAT_BIT | FX_FALLBACK_BIT | FX_UNFILLED_BIT)
+#define TAG(x) x##_twoside_offset_flat_fallback_unfilled
+#include "fxtritmp.h"
+
+
+
+
+
+
+void fxDDTrifuncInit( void )
+{
+ init();
+ init_flat();
+ init_offset();
+ init_offset_flat();
+ init_twoside();
+ init_twoside_flat();
+ init_twoside_offset();
+ init_twoside_offset_flat();
+ 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();
+ 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();
+}
+
+
+/* Build an SWvertex from a GrVertex. This is workable because in
+ * states where the GrVertex is insufficent (eg seperate-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;
+
+ 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;
+}
+
+
+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] );
+}
+
+
+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] );
+}
+
+
+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] );
+}
+
+
+/* System to turn culling off for rasterized lines and points, and
+ * back on for rasterized triangles.
+ */
+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 );
+}
+
+
+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;
+
+ fxMesa->draw_line( ctx, v0, v1 );
+}
+
+
+static void
+fx_cull_draw_point( GLcontext *ctx, const fxVertex *v0 )
+{
+ fxMesaContext fxMesa = FX_CONTEXT( ctx );
+
+ 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 );
+}
+
+
+static void
+fx_null_tri( GLcontext *ctx,
+ const fxVertex *v0, const fxVertex *v1, const fxVertex *v2 )
+{
+ (void) v0;
+ (void) v1;
+ (void) v2;
+}
+
+
+
+#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)
+
+
+#define ANY_RENDER_FLAGS (DD_FLATSHADE | \
+ DD_TRI_LIGHT_TWOSIDE | \
+ DD_TRI_OFFSET | \
+ DD_TRI_UNFILLED)
+
+
+
+/* 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.
+ */
+void fxDDChooseRenderState( GLcontext *ctx )
+{
+ fxMesaContext fxMesa = FX_CONTEXT( ctx );
+ GLuint flags = ctx->_TriangleCaps;
+ GLuint index = 0;
+
+ if ( !fxMesa->is_in_hardware ) {
+ /* Build software vertices directly. No acceleration is
+ * possible. GrVertices may be insufficient for this mode.
+ */
+ ctx->Driver.PointsFunc = _swsetup_Points;
+ ctx->Driver.LineFunc = _swsetup_Line;
+ ctx->Driver.TriangleFunc = _swsetup_Triangle;
+ ctx->Driver.QuadFunc = _swsetup_Quad;
+
+ fxMesa->render_index = FX_FALLBACK_BIT;
+ return;
+ }
+
+ 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 ( 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;
+
+ 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);
+ }
+
+ ctx->Driver.PointsFunc = rast_tab[index].points;
+ ctx->Driver.LineFunc = rast_tab[index].line;
+ ctx->Driver.TriangleFunc = rast_tab[index].triangle;
+ ctx->Driver.QuadFunc = rast_tab[index].quad;
+ fxMesa->render_index = index;
+}
+
+
+#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;
+}
+
+#endif /* FX */