aboutsummaryrefslogtreecommitdiff
path: root/nx-X11/extras/Mesa/src/mesa/drivers/dri/s3v/s3v_tris.c
diff options
context:
space:
mode:
Diffstat (limited to 'nx-X11/extras/Mesa/src/mesa/drivers/dri/s3v/s3v_tris.c')
-rw-r--r--nx-X11/extras/Mesa/src/mesa/drivers/dri/s3v/s3v_tris.c850
1 files changed, 850 insertions, 0 deletions
diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/dri/s3v/s3v_tris.c b/nx-X11/extras/Mesa/src/mesa/drivers/dri/s3v/s3v_tris.c
new file mode 100644
index 000000000..d6cceddd4
--- /dev/null
+++ b/nx-X11/extras/Mesa/src/mesa/drivers/dri/s3v/s3v_tris.c
@@ -0,0 +1,850 @@
+/*
+ * Author: Max Lingua <sunmax@libero.it>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <sys/ioctl.h>
+
+#include "s3v_context.h"
+#include "s3v_vb.h"
+#include "s3v_tris.h"
+
+#include "glheader.h"
+#include "mtypes.h"
+#include "macros.h"
+#include "colormac.h"
+
+#include "swrast/swrast.h"
+#include "swrast_setup/swrast_setup.h"
+#include "tnl/tnl.h"
+#include "tnl/t_context.h"
+#include "tnl/t_pipeline.h"
+
+
+/***********************************************************************
+ * Build hardware rasterization functions *
+ ***********************************************************************/
+
+#define DO_TRI 1
+#define HAVE_RGBA 1
+#define HAVE_SPEC 0
+#define HAVE_BACK_COLORS 0
+#define HAVE_HW_FLATSHADE 1
+#define VERTEX s3vVertex
+#define TAB rast_tab
+
+#define VERT_SET_RGBA( v, c ) \
+do { \
+ UNCLAMPED_FLOAT_TO_RGBA_CHAN( v->ub4[4], c); \
+/* *(v->ub4[4]) = c; \ */ \
+} while (0)
+#define VERT_COPY_RGBA( v0, v1 ) v0->ui[4] = v1->ui[4]
+/*
+#define VERT_COPY_RGBA1( v0, v1 ) v0->ui[4] = v1->ui[4]
+*/
+#define VERT_SAVE_RGBA( idx ) color[idx] = v[idx]->ui[4]
+#define VERT_RESTORE_RGBA( idx ) v[idx]->ui[4] = color[idx]
+
+#define S3V_OFFSET_BIT 0x01
+#define S3V_TWOSIDE_BIT 0x02
+#define S3V_UNFILLED_BIT 0x04
+#define S3V_FALLBACK_BIT 0x08
+#define S3V_MAX_TRIFUNC 0x10
+
+
+static struct {
+ tnl_points_func points;
+ tnl_line_func line;
+ tnl_triangle_func triangle;
+ tnl_quad_func quad;
+} rast_tab[S3V_MAX_TRIFUNC];
+
+#define S3V_RAST_CULL_BIT 0x01
+#define S3V_RAST_FLAT_BIT 0x02
+#define S3V_RAST_TEX_BIT 0x04
+
+static s3v_point_func s3v_point_tab[0x8];
+static s3v_line_func s3v_line_tab[0x8];
+static s3v_tri_func s3v_tri_tab[0x8];
+static s3v_quad_func s3v_quad_tab[0x8];
+
+#define IND (0)
+#define TAG(x) x
+#include "s3v_tritmp.h"
+
+#define IND (S3V_RAST_CULL_BIT)
+#define TAG(x) x##_cull
+#include "s3v_tritmp.h"
+
+#define IND (S3V_RAST_FLAT_BIT)
+#define TAG(x) x##_flat
+#include "s3v_tritmp.h"
+
+#define IND (S3V_RAST_CULL_BIT|S3V_RAST_FLAT_BIT)
+#define TAG(x) x##_cull_flat
+#include "s3v_tritmp.h"
+
+#define IND (S3V_RAST_TEX_BIT)
+#define TAG(x) x##_tex
+#include "s3v_tritmp.h"
+
+#define IND (S3V_RAST_CULL_BIT|S3V_RAST_TEX_BIT)
+#define TAG(x) x##_cull_tex
+#include "s3v_tritmp.h"
+
+#define IND (S3V_RAST_FLAT_BIT|S3V_RAST_TEX_BIT)
+#define TAG(x) x##_flat_tex
+#include "s3v_tritmp.h"
+
+#define IND (S3V_RAST_CULL_BIT|S3V_RAST_FLAT_BIT|S3V_RAST_TEX_BIT)
+#define TAG(x) x##_cull_flat_tex
+#include "s3v_tritmp.h"
+
+static void init_rast_tab( void )
+{
+ DEBUG(("*** init_rast_tab ***\n"));
+
+ s3v_init();
+ s3v_init_cull();
+ s3v_init_flat();
+ s3v_init_cull_flat();
+ s3v_init_tex();
+ s3v_init_cull_tex();
+ s3v_init_flat_tex();
+ s3v_init_cull_flat_tex();
+}
+
+/***********************************************************************
+ * Rasterization fallback helpers *
+ ***********************************************************************/
+
+
+/* This code is hit only when a mix of accelerated and unaccelerated
+ * primitives are being drawn, and only for the unaccelerated
+ * primitives.
+ */
+
+#if 0
+static void
+s3v_fallback_quad( s3vContextPtr vmesa,
+ const s3vVertex *v0,
+ const s3vVertex *v1,
+ const s3vVertex *v2,
+ const s3vVertex *v3 )
+{
+ GLcontext *ctx = vmesa->glCtx;
+ SWvertex v[4];
+ s3v_translate_vertex( ctx, v0, &v[0] );
+ s3v_translate_vertex( ctx, v1, &v[1] );
+ s3v_translate_vertex( ctx, v2, &v[2] );
+ s3v_translate_vertex( ctx, v3, &v[3] );
+ DEBUG(("s3v_fallback_quad\n"));
+/* _swrast_Quad( ctx, &v[0], &v[1], &v[2], &v[3] ); */
+}
+
+static void
+s3v_fallback_tri( s3vContextPtr vmesa,
+ const s3vVertex *v0,
+ const s3vVertex *v1,
+ const s3vVertex *v2 )
+{
+ GLcontext *ctx = vmesa->glCtx;
+ SWvertex v[3];
+ s3v_translate_vertex( ctx, v0, &v[0] );
+ s3v_translate_vertex( ctx, v1, &v[1] );
+ s3v_translate_vertex( ctx, v2, &v[2] );
+ DEBUG(("s3v_fallback_tri\n"));
+/* _swrast_Triangle( ctx, &v[0], &v[1], &v[2] ); */
+}
+
+static void
+s3v_fallback_line( s3vContextPtr vmesa,
+ const s3vVertex *v0,
+ const s3vVertex *v1 )
+{
+ GLcontext *ctx = vmesa->glCtx;
+ SWvertex v[2];
+ s3v_translate_vertex( ctx, v0, &v[0] );
+ s3v_translate_vertex( ctx, v1, &v[1] );
+ DEBUG(("s3v_fallback_line\n"));
+ _swrast_Line( ctx, &v[0], &v[1] );
+}
+
+/*
+static void
+s3v_fallback_point( s3vContextPtr vmesa,
+ const s3vVertex *v0 )
+{
+ GLcontext *ctx = vmesa->glCtx;
+ SWvertex v[1];
+ s3v_translate_vertex( ctx, v0, &v[0] );
+ _swrast_Point( ctx, &v[0] );
+}
+*/
+#endif
+
+/***********************************************************************
+ * Choose rasterization functions *
+ ***********************************************************************/
+
+#define _S3V_NEW_RASTER_STATE (_NEW_FOG | \
+ _NEW_TEXTURE | \
+ _DD_NEW_TRI_SMOOTH | \
+ _DD_NEW_LINE_SMOOTH | \
+ _DD_NEW_POINT_SMOOTH | \
+ _DD_NEW_TRI_STIPPLE | \
+ _DD_NEW_LINE_STIPPLE)
+
+#define LINE_FALLBACK (0)
+#define TRI_FALLBACK (0)
+
+static void s3v_nodraw_triangle(GLcontext *ctx, s3vVertex *v0,
+ s3vVertex *v1, s3vVertex *v2)
+{
+ (void) (ctx && v0 && v1 && v2);
+}
+
+static void s3v_nodraw_quad(GLcontext *ctx,
+ s3vVertex *v0, s3vVertex *v1,
+ s3vVertex *v2, s3vVertex *v3)
+{
+ (void) (ctx && v0 && v1 && v2 && v3);
+}
+
+void s3vChooseRasterState(GLcontext *ctx);
+
+void s3vChooseRasterState(GLcontext *ctx)
+{
+ s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+ GLuint flags = ctx->_TriangleCaps;
+ GLuint ind = 0;
+
+ DEBUG(("*** s3vChooseRasterState ***\n"));
+
+ if (ctx->Polygon.CullFlag) {
+ if (ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK) {
+ vmesa->draw_tri = (s3v_tri_func)s3v_nodraw_triangle;
+ vmesa->draw_quad = (s3v_quad_func)s3v_nodraw_quad;
+ return;
+ }
+ ind |= S3V_RAST_CULL_BIT;
+ /* s3v_update_cullsign(ctx); */
+ } /* else vmesa->backface_sign = 0; */
+
+ if ( flags & DD_FLATSHADE )
+ ind |= S3V_RAST_FLAT_BIT;
+
+ if ( ctx->Texture.Unit[0]._ReallyEnabled ) {
+ ind |= S3V_RAST_TEX_BIT;
+ }
+
+ DEBUG(("ind = %i\n", ind));
+
+ vmesa->draw_line = s3v_line_tab[ind];
+ vmesa->draw_tri = s3v_tri_tab[ind];
+ vmesa->draw_quad = s3v_quad_tab[ind];
+ vmesa->draw_point = s3v_point_tab[ind];
+
+#if 0
+ /* Hook in fallbacks for specific primitives. CURRENTLY DISABLED
+ */
+
+ if (flags & LINE_FALLBACK)
+ vmesa->draw_line = s3v_fallback_line;
+
+ if (flags & TRI_FALLBACK) {
+ DEBUG(("TRI_FALLBACK\n"));
+ vmesa->draw_tri = s3v_fallback_tri;
+ vmesa->draw_quad = s3v_fallback_quad;
+ }
+#endif
+}
+
+
+
+
+/***********************************************************************
+ * Macros for t_dd_tritmp.h to draw basic primitives *
+ ***********************************************************************/
+
+#define TRI( v0, v1, v2 ) \
+do { \
+ /*
+ if (DO_FALLBACK) \
+ vmesa->draw_tri( vmesa, v0, v1, v2 ); \
+ else */ \
+ DEBUG(("TRI: max was here\n")); /* \
+ s3v_draw_tex_triangle( vmesa, v0, v1, v2 ); */ \
+ vmesa->draw_tri( vmesa, v0, v1, v2 ); \
+} while (0)
+
+#define QUAD( v0, v1, v2, v3 ) \
+do { \
+ DEBUG(("QUAD: max was here\n")); \
+ vmesa->draw_quad( vmesa, v0, v1, v2, v3 ); \
+} while (0)
+
+#define LINE( v0, v1 ) \
+do { \
+ DEBUG(("LINE: max was here\n")); \
+ vmesa->draw_line( vmesa, v0, v1 ); \
+} while (0)
+
+#define POINT( v0 ) \
+do { \
+ vmesa->draw_point( vmesa, v0 ); \
+} while (0)
+
+
+/***********************************************************************
+ * Build render functions from dd templates *
+ ***********************************************************************/
+
+/*
+#define S3V_OFFSET_BIT 0x01
+#define S3V_TWOSIDE_BIT 0x02
+#define S3V_UNFILLED_BIT 0x04
+#define S3V_FALLBACK_BIT 0x08
+#define S3V_MAX_TRIFUNC 0x10
+
+
+static struct {
+ points_func points;
+ line_func line;
+ triangle_func triangle;
+ quad_func quad;
+} rast_tab[S3V_MAX_TRIFUNC];
+*/
+
+#define DO_FALLBACK (IND & S3V_FALLBACK_BIT)
+#define DO_OFFSET (IND & S3V_OFFSET_BIT)
+#define DO_UNFILLED (IND & S3V_UNFILLED_BIT)
+#define DO_TWOSIDE (IND & S3V_TWOSIDE_BIT)
+#define DO_FLAT 0
+#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_BACK_COLORS 0
+#define HAVE_HW_FLATSHADE 1
+#define VERTEX s3vVertex
+#define TAB rast_tab
+
+#define DEPTH_SCALE 1.0
+#define UNFILLED_TRI unfilled_tri
+#define UNFILLED_QUAD unfilled_quad
+#define VERT_X(_v) _v->v.x
+#define VERT_Y(_v) _v->v.y
+#define VERT_Z(_v) _v->v.z
+#define AREA_IS_CCW( a ) (a > 0)
+#define GET_VERTEX(e) (vmesa->verts + (e<<vmesa->vertex_stride_shift))
+
+#if 0
+#define VERT_SET_RGBA( v, c ) \
+do { \
+/* UNCLAMPED_FLOAT_TO_RGBA_CHAN( v->ub4[4], c) */ \
+} while (0)
+
+#define VERT_COPY_RGBA( v0, v1 ) v0->ui[4] = v1->ui[4]
+/*
+#define VERT_COPY_RGBA1( v0, v1 ) v0->ui[4] = v1->ui[4]
+*/
+#define VERT_SAVE_RGBA( idx ) color[idx] = v[idx]->ui[4]
+#define VERT_RESTORE_RGBA( idx ) v[idx]->ui[4] = color[idx]
+#endif
+
+#define LOCAL_VARS(n) \
+ s3vContextPtr vmesa = S3V_CONTEXT(ctx); \
+ GLuint color[n]; \
+ (void) color;
+
+
+/***********************************************************************
+ * Helpers for rendering unfilled primitives *
+ ***********************************************************************/
+
+static const GLuint hw_prim[GL_POLYGON+1] = {
+ PrimType_Points,
+ PrimType_Lines,
+ PrimType_Lines,
+ PrimType_Lines,
+ PrimType_Triangles,
+ PrimType_Triangles,
+ PrimType_Triangles,
+ PrimType_Triangles,
+ PrimType_Triangles,
+ PrimType_Triangles
+};
+
+static void s3vResetLineStipple( GLcontext *ctx );
+static void s3vRasterPrimitive( GLcontext *ctx, GLuint hwprim );
+static void s3vRenderPrimitive( GLcontext *ctx, GLenum prim );
+/*
+extern static void s3v_lines_emit(GLcontext *ctx, GLuint start, GLuint end);
+extern static void s3v_tris_emit(GLcontext *ctx, GLuint start, GLuint end);
+*/
+#define RASTERIZE(x) if (vmesa->hw_primitive != hw_prim[x]) \
+ s3vRasterPrimitive( ctx, hw_prim[x] )
+#define RENDER_PRIMITIVE vmesa->render_primitive
+#define TAG(x) x
+#define IND S3V_FALLBACK_BIT
+#include "tnl_dd/t_dd_unfilled.h"
+#undef IND
+
+/***********************************************************************
+ * Generate GL render functions *
+ ***********************************************************************/
+
+#define IND (0)
+#define TAG(x) x
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (S3V_OFFSET_BIT)
+#define TAG(x) x##_offset
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (S3V_TWOSIDE_BIT)
+#define TAG(x) x##_twoside
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (S3V_TWOSIDE_BIT|S3V_OFFSET_BIT)
+#define TAG(x) x##_twoside_offset
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (S3V_UNFILLED_BIT)
+#define TAG(x) x##_unfilled
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (S3V_OFFSET_BIT|S3V_UNFILLED_BIT)
+#define TAG(x) x##_offset_unfilled
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (S3V_TWOSIDE_BIT|S3V_UNFILLED_BIT)
+#define TAG(x) x##_twoside_unfilled
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (S3V_TWOSIDE_BIT|S3V_OFFSET_BIT|S3V_UNFILLED_BIT)
+#define TAG(x) x##_twoside_offset_unfilled
+#include "tnl_dd/t_dd_tritmp.h"
+
+
+static void init_render_tab( void )
+{
+ DEBUG(("*** init_render_tab ***\n"));
+
+ init();
+ init_offset();
+ init_twoside();
+ init_twoside_offset();
+ init_unfilled();
+ init_offset_unfilled();
+ init_twoside_unfilled();
+ init_twoside_offset_unfilled();
+}
+
+
+/**********************************************************************/
+/* Render unclipped begin/end objects */
+/**********************************************************************/
+
+#define VERT(x) (s3vVertex *)(s3vverts + (x << shift))
+
+#define RENDER_POINTS( start, count ) \
+ DEBUG(("RENDER_POINTS...(ok)\n")); \
+ for ( ; start < count ; start++) \
+ vmesa->draw_line( vmesa, VERT(start), VERT(start) )
+ /* vmesa->draw_point( vmesa, VERT(start) ) */
+
+#define RENDER_LINE( v0, v1 ) \
+ /* DEBUG(("RENDER_LINE...(ok)\n")); \ */ \
+ vmesa->draw_line( vmesa, VERT(v0), VERT(v1) ); \
+ DEBUG(("RENDER_LINE...(ok)\n"))
+
+#define RENDER_TRI( v0, v1, v2 ) \
+ DEBUG(("RENDER_TRI...(ok)\n")); \
+ vmesa->draw_tri( vmesa, VERT(v0), VERT(v1), VERT(v2) )
+
+#define RENDER_QUAD( v0, v1, v2, v3 ) \
+ DEBUG(("RENDER_QUAD...(ok)\n")); \
+ /* s3v_draw_quad( vmesa, VERT(v0), VERT(v1), VERT(v2),VERT(v3) ) */\
+ /* s3v_draw_triangle( vmesa, VERT(v0), VERT(v1), VERT(v2) ); \
+ s3v_draw_triangle( vmesa, VERT(v0), VERT(v2), VERT(v3) ) */ \
+ vmesa->draw_quad( vmesa, VERT(v0), VERT(v1), VERT(v2), VERT(v3) )
+
+#define INIT(x) s3vRenderPrimitive( ctx, x );
+#undef LOCAL_VARS
+#define LOCAL_VARS \
+ s3vContextPtr vmesa = S3V_CONTEXT(ctx); \
+ const GLuint shift = vmesa->vertex_stride_shift; \
+ const char *s3vverts = (char *)vmesa->verts; \
+ const GLboolean stipple = ctx->Line.StippleFlag; \
+ (void) stipple;
+#define RESET_STIPPLE if ( stipple ) s3vResetLineStipple( ctx );
+#define RESET_OCCLUSION
+#define PRESERVE_VB_DEFS
+#define ELT(x) (x)
+#define TAG(x) s3v_##x##_verts
+#include "tnl_dd/t_dd_rendertmp.h"
+
+
+/**********************************************************************/
+/* Render clipped primitives */
+/**********************************************************************/
+
+static void s3vRenderClippedPoly( GLcontext *ctx, const GLuint *elts,
+ GLuint n )
+{
+ s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+ struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ GLuint prim = vmesa->render_primitive;
+
+ DEBUG(("I AM in: s3vRenderClippedPoly\n"));
+
+ /* Render the new vertices as an unclipped polygon.
+ */
+ if (1)
+ {
+ GLuint *tmp = VB->Elts;
+ VB->Elts = (GLuint *)elts;
+ tnl->Driver.Render.PrimTabElts[GL_POLYGON]
+ ( ctx, 0, n, PRIM_BEGIN|PRIM_END );
+
+ VB->Elts = tmp;
+ }
+
+ /* Restore the render primitive
+ */
+#if 1
+ if (prim != GL_POLYGON) {
+ DEBUG(("and prim != GL_POLYGON\n"));
+ tnl->Driver.Render.PrimitiveNotify( ctx, prim );
+ }
+
+#endif
+}
+
+static void s3vRenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj )
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ /*tnl->Driver.LineFunc = s3v_line_tab[2];*/ /* _swsetup_Line; */
+
+ DEBUG(("I AM in: s3vRenderClippedLine\n"));
+ tnl->Driver.Render.Line( ctx, ii, jj );
+}
+
+
+/**********************************************************************/
+/* Choose render functions */
+/**********************************************************************/
+
+
+
+#define _S3V_NEW_RENDERSTATE (_DD_NEW_TRI_UNFILLED | \
+ _DD_NEW_TRI_LIGHT_TWOSIDE | \
+ _DD_NEW_TRI_OFFSET)
+
+#define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET|DD_TRI_UNFILLED)
+
+static void s3vChooseRenderState(GLcontext *ctx)
+{
+ s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ GLuint flags = ctx->_TriangleCaps;
+ GLuint index = 0;
+
+ DEBUG(("s3vChooseRenderState\n"));
+
+ if (flags & ANY_RASTER_FLAGS) {
+ if (flags & DD_TRI_LIGHT_TWOSIDE) index |= S3V_TWOSIDE_BIT;
+ if (flags & DD_TRI_OFFSET) index |= S3V_OFFSET_BIT;
+ if (flags & DD_TRI_UNFILLED) index |= S3V_UNFILLED_BIT;
+ }
+
+ DEBUG(("vmesa->RenderIndex = %i\n", vmesa->RenderIndex));
+ DEBUG(("index = %i\n", index));
+
+ if (vmesa->RenderIndex != index) {
+ vmesa->RenderIndex = index;
+
+ tnl->Driver.Render.Points = rast_tab[index].points;
+ tnl->Driver.Render.Line = rast_tab[index].line;
+ tnl->Driver.Render.Triangle = rast_tab[index].triangle;
+ tnl->Driver.Render.Quad = rast_tab[index].quad;
+
+ if (vmesa->RenderIndex == 0)
+ tnl->Driver.Render.PrimTabVerts = s3v_render_tab_verts;
+ else
+ tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts;
+ tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
+ tnl->Driver.Render.ClippedLine = s3vRenderClippedLine;
+ tnl->Driver.Render.ClippedPolygon = s3vRenderClippedPoly;
+ }
+}
+
+
+/**********************************************************************/
+/* High level hooks for t_vb_render.c */
+/**********************************************************************/
+
+
+
+/* Determine the rasterized primitive when not drawing unfilled
+ * polygons.
+ *
+ * Used only for the default render stage which always decomposes
+ * primitives to trianges/lines/points. For the accelerated stage,
+ * which renders strips as strips, the equivalent calculations are
+ * performed in s3v_render.c.
+ */
+
+static void s3vRasterPrimitive( GLcontext *ctx, GLuint hwprim )
+{
+ s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+/* __DRIdrawablePrivate *dPriv = vmesa->driDrawable; */
+ GLuint cmd = vmesa->CMD;
+
+ unsigned int _hw_prim = hwprim;
+
+ DEBUG(("s3vRasterPrimitive: hwprim = 0x%x ", _hw_prim));
+
+/* printf("* vmesa->CMD = 0x%x\n", vmesa->CMD); */
+
+ if (vmesa->hw_primitive != _hw_prim)
+ {
+ DEBUG(("(new one) ***\n"));
+ cmd &= ~DO_MASK;
+ cmd &= ~ALPHA_BLEND_MASK;
+ vmesa->hw_primitive = _hw_prim;
+
+ if (_hw_prim == PrimType_Triangles) {
+ /* TRI */
+ DEBUG(("->switching to tri\n"));
+ cmd |= (vmesa->_tri[vmesa->_3d_mode] | vmesa->_alpha[vmesa->_3d_mode]);
+ } else if (_hw_prim == PrimType_Lines
+ || _hw_prim == PrimType_Points) {
+ /* LINE */
+ DEBUG(("->switching to line\n"));
+ cmd |= (DO_3D_LINE | vmesa->_alpha[0]);
+ } else {
+ /* ugh? */
+ DEBUG(("->switching to your sis'ass\n"));
+ }
+
+ DEBUG(("\n"));
+
+ vmesa->restore_primitive = _hw_prim;
+ /* 0xacc16827: good value -> lightened newave!!! */
+ vmesa->CMD = cmd;
+ CMDCHANGE();
+ }
+}
+
+static void s3vRenderPrimitive( GLcontext *ctx, GLenum prim )
+{
+ s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+ __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
+ GLuint cmd = vmesa->CMD;
+
+ unsigned int _hw_prim = hw_prim[prim];
+
+ vmesa->render_primitive = prim;
+ vmesa->hw_primitive = _hw_prim;
+
+ DEBUG(("s3vRenderPrimitive #%i ", prim));
+ DEBUG(("_hw_prim = 0x%x\n", _hw_prim));
+
+/* printf(" vmesa->CMD = 0x%x\n", vmesa->CMD); */
+
+ if (_hw_prim != vmesa->restore_primitive) {
+ DEBUG(("_hw_prim != vmesa->restore_primitive (was 0x%x)\n",
+ vmesa->restore_primitive));
+#if 1
+ cmd &= ~DO_MASK;
+ cmd &= ~ALPHA_BLEND_MASK;
+/*
+ printf(" cmd = 0x%x\n", cmd);
+ printf(" vmesa->_3d_mode=%i; vmesa->_tri[vmesa->_3d_mode]=0x%x\n",
+ vmesa->_3d_mode, vmesa->_tri[vmesa->_3d_mode]);
+ printf("vmesa->alpha[0] = 0x%x; vmesa->alpha[1] = 0x%x\n",
+ vmesa->_alpha[0], vmesa->_alpha[1]);
+*/
+ if (_hw_prim == PrimType_Triangles) { /* TRI */
+ DEBUG(("->switching to tri\n"));
+ cmd |= (vmesa->_tri[vmesa->_3d_mode] | vmesa->_alpha[vmesa->_3d_mode]);
+ DEBUG(("vmesa->TexStride = %i\n", vmesa->TexStride));
+ DEBUG(("vmesa->TexOffset = %i\n", vmesa->TexOffset));
+ DMAOUT_CHECK(3DTRI_Z_BASE, 12);
+ } else { /* LINE */
+ DEBUG(("->switching to line\n"));
+ cmd |= (DO_3D_LINE | vmesa->_alpha[0]);
+ DMAOUT_CHECK(3DLINE_Z_BASE, 12);
+ }
+
+ DMAOUT(vmesa->s3vScreen->depthOffset & 0x003FFFF8);
+ DMAOUT(vmesa->DestBase);
+ /* DMAOUT(vmesa->ScissorLR); */
+ /* DMAOUT(vmesa->ScissorTB); */
+
+ /* NOTE: we need to restore all these values since we
+ * are coming back from a vmesa->restore_primitive */
+ DMAOUT( (0 << 16) | (dPriv->w-1) );
+ DMAOUT( (0 << 16) | (dPriv->h-1) );
+ DMAOUT( (vmesa->SrcStride << 16) | vmesa->TexStride );
+ DMAOUT(vmesa->SrcStride);
+ DMAOUT(vmesa->TexOffset);
+ DMAOUT(vmesa->TextureBorderColor);
+ DMAOUT(0); /* FOG */
+ DMAOUT(0);
+ DMAOUT(0);
+ DMAOUT(cmd);
+ /* 0xacc16827: good value -> lightened newave!!! */
+ DMAFINISH();
+
+ vmesa->CMD = cmd;
+#endif
+ }
+
+ DEBUG(("\n"));
+
+ vmesa->restore_primitive = _hw_prim;
+}
+
+static void s3vRunPipeline( GLcontext *ctx )
+{
+ s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+
+ DEBUG(("*** s3vRunPipeline ***\n"));
+
+ if ( vmesa->new_state )
+ s3vDDUpdateHWState( ctx );
+
+ if (vmesa->new_gl_state) {
+
+ if (vmesa->new_gl_state & _NEW_TEXTURE) {
+ s3vUpdateTextureState( ctx );
+ }
+
+ if (!vmesa->Fallback) {
+ if (vmesa->new_gl_state & _S3V_NEW_VERTEX)
+ s3vChooseVertexState( ctx );
+
+ if (vmesa->new_gl_state & _S3V_NEW_RASTER_STATE)
+ s3vChooseRasterState( ctx );
+
+ if (vmesa->new_gl_state & _S3V_NEW_RENDERSTATE)
+ s3vChooseRenderState( ctx );
+ }
+
+ vmesa->new_gl_state = 0;
+
+ }
+
+ _tnl_run_pipeline( ctx );
+}
+
+static void s3vRenderStart( GLcontext *ctx )
+{
+ /* Check for projective texturing. Make sure all texcoord
+ * pointers point to something. (fix in mesa?)
+ */
+
+ DEBUG(("s3vRenderStart\n"));
+ /* s3vCheckTexSizes( ctx ); */
+}
+
+static void s3vRenderFinish( GLcontext *ctx )
+{
+ if (0)
+ _swrast_flush( ctx ); /* never needed */
+}
+
+static void s3vResetLineStipple( GLcontext *ctx )
+{
+/* s3vContextPtr vmesa = S3V_CONTEXT(ctx); */
+
+ /* Reset the hardware stipple counter.
+ */
+/*
+ CHECK_DMA_BUFFER(vmesa, 1);
+ WRITE(vmesa->buf, UpdateLineStippleCounters, 0);
+*/
+}
+
+
+/**********************************************************************/
+/* Transition to/from hardware rasterization. */
+/**********************************************************************/
+
+
+void s3vFallback( s3vContextPtr vmesa, GLuint bit, GLboolean mode )
+{
+ GLcontext *ctx = vmesa->glCtx;
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ GLuint oldfallback = vmesa->Fallback;
+
+ DEBUG(("*** s3vFallback: "));
+
+ if (mode) {
+ vmesa->Fallback |= bit;
+ if (oldfallback == 0) {
+ DEBUG(("oldfallback == 0 ***\n"));
+ _swsetup_Wakeup( ctx );
+ _tnl_need_projected_coords( ctx, GL_TRUE );
+ vmesa->RenderIndex = ~0;
+ }
+ }
+ else {
+ DEBUG(("***\n"));
+ vmesa->Fallback &= ~bit;
+ if (oldfallback == bit) {
+ _swrast_flush( ctx );
+ tnl->Driver.Render.Start = s3vRenderStart;
+ tnl->Driver.Render.PrimitiveNotify = s3vRenderPrimitive;
+ tnl->Driver.Render.Finish = s3vRenderFinish;
+ tnl->Driver.Render.BuildVertices = s3vBuildVertices;
+ tnl->Driver.Render.ResetLineStipple = s3vResetLineStipple;
+ vmesa->new_gl_state |= (_S3V_NEW_RENDERSTATE|
+ _S3V_NEW_RASTER_STATE|
+ _S3V_NEW_VERTEX);
+ }
+ }
+}
+
+
+/**********************************************************************/
+/* Initialization. */
+/**********************************************************************/
+
+
+void s3vInitTriFuncs( GLcontext *ctx )
+{
+ s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ static int firsttime = 1;
+
+ if (firsttime) {
+ init_rast_tab();
+ init_render_tab();
+ firsttime = 0;
+ }
+
+ vmesa->RenderIndex = ~0;
+
+ tnl->Driver.RunPipeline = s3vRunPipeline;
+ tnl->Driver.Render.Start = s3vRenderStart;
+ tnl->Driver.Render.Finish = s3vRenderFinish;
+ tnl->Driver.Render.PrimitiveNotify = s3vRenderPrimitive;
+ tnl->Driver.Render.ResetLineStipple = s3vResetLineStipple;
+/*
+ tnl->Driver.RenderInterp = _swsetup_RenderInterp;
+ tnl->Driver.RenderCopyPV = _swsetup_RenderCopyPV;
+*/
+ tnl->Driver.Render.BuildVertices = s3vBuildVertices;
+}