Merge git://proxy01.pd.intel.com:9419/git/mesa/mesa into crestline
[mesa.git] / src / mesa / drivers / dri / unichrome / via_tris.c
index ff46de18c03970c9ccadc7315f12b904002ef0cd..4cc7942b1b617fe88b3a8b21fb6fc92212ba5d2e 100644 (file)
 #include "via_state.h"
 #include "via_span.h"
 #include "via_ioctl.h"
+#include "via_3d_reg.h"
+#include "via_tex.h"
 
 /***********************************************************************
  *                    Emit primitives as inline vertices               *
  ***********************************************************************/
+#define LINE_FALLBACK (0)
+#define POINT_FALLBACK (0)
+#define TRI_FALLBACK (0)
+#define ANY_FALLBACK_FLAGS (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK)
+#define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET|DD_TRI_UNFILLED)
+
 
-#if 1
+#if 0
+#define COPY_DWORDS(vb, vertsize, v)           \
+do {                                           \
+   via_sse_memcpy(vb, v, vertsize * 4);                \
+   vb += vertsize;                             \
+} while (0)
+#else
+#if defined( USE_X86_ASM )
 #define COPY_DWORDS(vb, vertsize, v)                                   \
     do {                                                               \
         int j;                                                         \
@@ -67,8 +82,9 @@
         vb += vertsize;                                \
     } while (0)
 #endif
+#endif
 
-static void via_draw_triangle(viaContextPtr vmesa,
+static void via_draw_triangle(struct via_context *vmesa,
                              viaVertexPtr v0,
                              viaVertexPtr v1,
                              viaVertexPtr v2)
@@ -82,7 +98,7 @@ static void via_draw_triangle(viaContextPtr vmesa,
 }
 
 
-static void via_draw_quad(viaContextPtr vmesa,
+static void via_draw_quad(struct via_context *vmesa,
                          viaVertexPtr v0,
                          viaVertexPtr v1,
                          viaVertexPtr v2,
@@ -99,7 +115,7 @@ static void via_draw_quad(viaContextPtr vmesa,
    COPY_DWORDS(vb, vertsize, v3);
 }
 
-static void via_draw_line(viaContextPtr vmesa,
+static void via_draw_line(struct via_context *vmesa,
                          viaVertexPtr v0,
                          viaVertexPtr v1)
 {
@@ -110,7 +126,7 @@ static void via_draw_line(viaContextPtr vmesa,
 }
 
 
-static void via_draw_point(viaContextPtr vmesa,
+static void via_draw_point(struct via_context *vmesa,
                           viaVertexPtr v0)
 {
    GLuint vertsize = vmesa->vertexSize;
@@ -132,7 +148,7 @@ do {                                                        \
    tmp.f[vertex_size-1] *= rhw;                                \
 } while (0)
 
-static void via_ptex_tri (viaContextPtr vmesa,
+static void via_ptex_tri (struct via_context *vmesa,
                          viaVertexPtr v0,
                          viaVertexPtr v1,
                          viaVertexPtr v2)
@@ -146,7 +162,7 @@ static void via_ptex_tri (viaContextPtr vmesa,
    PTEX_VERTEX(tmp, vertsize, v2); COPY_DWORDS(vb, vertsize, &tmp);
 }
 
-static void via_ptex_line (viaContextPtr vmesa,
+static void via_ptex_line (struct via_context *vmesa,
                           viaVertexPtr v0,
                           viaVertexPtr v1)
 {
@@ -158,7 +174,7 @@ static void via_ptex_line (viaContextPtr vmesa,
    PTEX_VERTEX(tmp, vertsize, v1); COPY_DWORDS(vb, vertsize, &tmp);
 }
 
-static void via_ptex_point (viaContextPtr vmesa,
+static void via_ptex_point (struct via_context *vmesa,
                            viaVertexPtr v0)
 {
    GLuint vertsize = vmesa->hwVertexSize;
@@ -227,7 +243,7 @@ static struct {
     tnl_line_func            line;
     tnl_triangle_func        triangle;
     tnl_quad_func            quad;
-} rast_tab[VIA_MAX_TRIFUNC];
+} rast_tab[VIA_MAX_TRIFUNC + 1];
 
 
 #define DO_FALLBACK (IND & VIA_FALLBACK_BIT)
@@ -287,20 +303,21 @@ do {                                                              \
 
 #define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset]
 
-#define VERT_SET_SPEC( v0, c )                                 \
+#define VERT_SET_SPEC( v, c )                                  \
 do {                                                           \
    if (specoffset) {                                           \
-      UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.red, (c)[0]);    \
-      UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.green, (c)[1]);  \
-      UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.blue, (c)[2]);   \
+     via_color_t *color = (via_color_t *)&((v)->ui[specoffset]);       \
+     UNCLAMPED_FLOAT_TO_UBYTE(color->red, (c)[0]);             \
+     UNCLAMPED_FLOAT_TO_UBYTE(color->green, (c)[1]);           \
+     UNCLAMPED_FLOAT_TO_UBYTE(color->blue, (c)[2]);            \
    }                                                           \
 } while (0)
 #define VERT_COPY_SPEC( v0, v1 )                       \
 do {                                                   \
    if (specoffset) {                                   \
-      v0->v.specular.red   = v1->v.specular.red;       \
-      v0->v.specular.green = v1->v.specular.green;     \
-      v0->v.specular.blue  = v1->v.specular.blue;      \
+      v0->ub4[specoffset][0] = v1->ub4[specoffset][0]; \
+      v0->ub4[specoffset][1] = v1->ub4[specoffset][1]; \
+      v0->ub4[specoffset][2] = v1->ub4[specoffset][2]; \
    }                                                   \
 } while (0)
 
@@ -312,7 +329,7 @@ do {                                                        \
 
 
 #define LOCAL_VARS(n)                                                   \
-    viaContextPtr vmesa = VIA_CONTEXT(ctx);                             \
+    struct via_context *vmesa = VIA_CONTEXT(ctx);                             \
     GLuint color[n], spec[n];                                           \
     GLuint coloroffset = vmesa->coloroffset;              \
     GLuint specoffset = vmesa->specoffset;                       \
@@ -323,7 +340,7 @@ do {                                                        \
  *                Helpers for rendering unfilled primitives            *
  ***********************************************************************/
 
-static const GLenum hwPrim[GL_POLYGON + 1] = {
+static const GLenum hwPrim[GL_POLYGON + 2] = {
     GL_POINTS,
     GL_LINES,
     GL_LINES,
@@ -333,7 +350,8 @@ static const GLenum hwPrim[GL_POLYGON + 1] = {
     GL_TRIANGLES,
     GL_TRIANGLES,
     GL_TRIANGLES,
-    GL_TRIANGLES
+    GL_TRIANGLES,
+    GL_POLYGON+1
 };
 
 
@@ -416,6 +434,24 @@ static const GLenum hwPrim[GL_POLYGON + 1] = {
 #include "tnl_dd/t_dd_tritmp.h"
 
 
+/* Catchall case for flat, separate specular triangles (via has flat
+ * diffuse shading, but always does specular color with gouraud).
+ */
+#undef  DO_FALLBACK
+#undef  DO_OFFSET
+#undef  DO_UNFILLED
+#undef  DO_TWOSIDE
+#undef  DO_FLAT
+#define DO_FALLBACK (0)
+#define DO_OFFSET   (ctx->_TriangleCaps & DD_TRI_OFFSET)
+#define DO_UNFILLED (ctx->_TriangleCaps & DD_TRI_UNFILLED)
+#define DO_TWOSIDE  (ctx->_TriangleCaps & DD_TRI_LIGHT_TWOSIDE)
+#define DO_FLAT     1
+#define TAG(x) x##_flat_specular
+#define IND VIA_MAX_TRIFUNC
+#include "tnl_dd/t_dd_tritmp.h"
+
+
 static void init_rast_tab(void)
 {
     init();
@@ -434,6 +470,8 @@ static void init_rast_tab(void)
     init_offset_unfilled_fallback();
     init_twoside_unfilled_fallback();
     init_twoside_offset_unfilled_fallback();
+
+    init_flat_specular();      /* special! */
 }
 
 
@@ -447,7 +485,7 @@ static void init_rast_tab(void)
  * primitives.
  */
 static void
-via_fallback_tri(viaContextPtr vmesa,
+via_fallback_tri(struct via_context *vmesa,
                  viaVertex *v0,
                  viaVertex *v1,
                  viaVertex *v2)
@@ -464,7 +502,7 @@ via_fallback_tri(viaContextPtr vmesa,
 
 
 static void
-via_fallback_line(viaContextPtr vmesa,
+via_fallback_line(struct via_context *vmesa,
                   viaVertex *v0,
                   viaVertex *v1)
 {
@@ -479,7 +517,7 @@ via_fallback_line(viaContextPtr vmesa,
 
 
 static void
-via_fallback_point(viaContextPtr vmesa,
+via_fallback_point(struct via_context *vmesa,
                    viaVertex *v0)
 {
     GLcontext *ctx = vmesa->glCtx;
@@ -492,7 +530,7 @@ via_fallback_point(viaContextPtr vmesa,
 
 static void viaResetLineStipple( GLcontext *ctx )
 {
-   viaContextPtr vmesa = VIA_CONTEXT(ctx);
+   struct via_context *vmesa = VIA_CONTEXT(ctx);
    vmesa->regCmdB |= HC_HLPrst_MASK;
 }
 
@@ -509,13 +547,13 @@ static void viaResetLineStipple( GLcontext *ctx )
 #define INIT(x) viaRasterPrimitive(ctx, x, hwPrim[x])
 #undef LOCAL_VARS
 #define LOCAL_VARS                                              \
-    viaContextPtr vmesa = VIA_CONTEXT(ctx);                     \
+    struct via_context *vmesa = VIA_CONTEXT(ctx);                     \
     GLubyte *vertptr = (GLubyte *)vmesa->verts;                 \
     const GLuint vertsize = vmesa->vertexSize;          \
     const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts;       \
    const GLboolean stipple = ctx->Line.StippleFlag;            \
    (void) elt; (void) stipple;
-#define RESET_STIPPLE  if ( stipple ) { printf("RESET\n"); viaResetLineStipple( ctx ); }
+#define RESET_STIPPLE  if ( stipple ) viaResetLineStipple( ctx );
 #define RESET_OCCLUSION
 #define PRESERVE_VB_DEFS
 #define ELT(x) x
@@ -559,7 +597,8 @@ static void viaRenderClippedPoly(GLcontext *ctx, const GLuint *elts,
 
     /* Restore the render primitive
      */
-    if (prim != GL_POLYGON)
+    if (prim != GL_POLYGON &&
+       prim != GL_POLYGON + 1)
        tnl->Driver.Render.PrimitiveNotify( ctx, prim );
 }
 
@@ -572,7 +611,7 @@ static void viaRenderClippedLine(GLcontext *ctx, GLuint ii, GLuint jj)
 static void viaFastRenderClippedPoly(GLcontext *ctx, const GLuint *elts,
                                      GLuint n)
 {
-    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+    struct via_context *vmesa = VIA_CONTEXT(ctx);
     GLuint vertsize = vmesa->vertexSize;
     GLuint *vb = viaExtendPrimitive(vmesa, (n - 2) * 3 * 4 * vertsize);
     GLubyte *vertptr = (GLubyte *)vmesa->verts;
@@ -606,16 +645,11 @@ static void viaFastRenderClippedPoly(GLcontext *ctx, const GLuint *elts,
                               _DD_NEW_TRI_STIPPLE |             \
                               _NEW_POLYGONSTIPPLE)
 
-#define LINE_FALLBACK (0)
-#define POINT_FALLBACK (0)
-#define TRI_FALLBACK (0)
-#define ANY_FALLBACK_FLAGS (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK)
-#define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET|DD_TRI_UNFILLED)
 
 static void viaChooseRenderState(GLcontext *ctx)
 {
    TNLcontext *tnl = TNL_CONTEXT(ctx);
-   viaContextPtr vmesa = VIA_CONTEXT(ctx);
+   struct via_context *vmesa = VIA_CONTEXT(ctx);
    GLuint flags = ctx->_TriangleCaps;
    GLuint index = 0;
 
@@ -649,6 +683,12 @@ static void viaChooseRenderState(GLcontext *ctx)
         vmesa->drawTri = via_fallback_tri;
    }
 
+
+   if ((flags & DD_SEPARATE_SPECULAR) &&
+       ctx->Light.ShadeModel == GL_FLAT) {
+      index = VIA_MAX_TRIFUNC; /* flat specular */
+   }
+
    if (vmesa->renderIndex != index) {
       vmesa->renderIndex = index;
 
@@ -702,18 +742,20 @@ do {                                                                      \
 
 static void viaChooseVertexState( GLcontext *ctx )
 {
-   viaContextPtr vmesa = VIA_CONTEXT(ctx);
+   struct via_context *vmesa = VIA_CONTEXT(ctx);
    TNLcontext *tnl = TNL_CONTEXT(ctx);
-   GLuint index = tnl->render_inputs;
+   DECLARE_RENDERINPUTS(index_bitset);
    GLuint regCmdB = HC_HVPMSK_X | HC_HVPMSK_Y | HC_HVPMSK_Z;
    GLuint setupIndex = 0;
 
+   RENDERINPUTS_COPY( index_bitset, tnl->render_inputs_bitset );
    vmesa->vertex_attr_count = 0;
  
    /* EMIT_ATTR's must be in order as they tell t_vertex.c how to
     * build up a hardware vertex.
     */
-   if (index & (_TNL_BITS_TEX_ANY|_TNL_BIT_FOG)) {
+   if (RENDERINPUTS_TEST_RANGE( index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX ) ||
+       RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG )) {
       EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, VIA_EMIT_W, HC_HVPMSK_W );
       vmesa->coloroffset = 4;
    }
@@ -723,32 +765,38 @@ static void viaChooseVertexState( GLcontext *ctx )
    }
 
    /* t_context.c always includes a diffuse color */
-   EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA, VIA_EMIT_RGBA, HC_HVPMSK_Cd );
+   EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA, VIA_EMIT_RGBA, 
+             HC_HVPMSK_Cd );
       
    vmesa->specoffset = 0;
-   if (index & (_TNL_BIT_COLOR1|_TNL_BIT_FOG)) {
-      if ((index & _TNL_BIT_COLOR1)) {
+   if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 ) ||
+       RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG )) {
+      if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 )) {
         vmesa->specoffset = vmesa->coloroffset + 1;
-        EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, VIA_EMIT_SPEC, HC_HVPMSK_Cs );
+        EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, VIA_EMIT_SPEC, 
+                   HC_HVPMSK_Cs );
       }
       else
         EMIT_PAD( 3 );
 
-      if ((index & _TNL_BIT_FOG))
+      if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG ))
         EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F, VIA_EMIT_FOG, HC_HVPMSK_Cs );
       else
         EMIT_PAD( 1 );
    }
 
-   if (index & _TNL_BIT_TEX(0)) {
+   if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX0 )) {
       if (vmesa->ptexHack)
-        EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_3F_XYW, VIA_EMIT_PTEX0, (HC_HVPMSK_S | HC_HVPMSK_T) );
+        EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_3F_XYW, VIA_EMIT_PTEX0, 
+                   (HC_HVPMSK_S | HC_HVPMSK_T) );
       else 
-        EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_2F, VIA_EMIT_TEX0, (HC_HVPMSK_S | HC_HVPMSK_T) );
+        EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_2F, VIA_EMIT_TEX0, 
+                   (HC_HVPMSK_S | HC_HVPMSK_T) );
    }
 
-   if (index & _TNL_BIT_TEX(1)) {
-      EMIT_ATTR( _TNL_ATTRIB_TEX1, EMIT_2F, VIA_EMIT_TEX1, (HC_HVPMSK_S | HC_HVPMSK_T) );
+   if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX1 )) {
+      EMIT_ATTR( _TNL_ATTRIB_TEX1, EMIT_2F, VIA_EMIT_TEX1, 
+                (HC_HVPMSK_S | HC_HVPMSK_T) );
    }
 
    if (setupIndex != vmesa->setupIndex) {
@@ -779,17 +827,19 @@ static GLboolean viaCheckPTexHack( GLcontext *ctx )
 {
    TNLcontext *tnl = TNL_CONTEXT(ctx);
    struct vertex_buffer *VB = &tnl->vb;
-   GLuint index = tnl->render_inputs;
+   DECLARE_RENDERINPUTS(index_bitset);
    GLboolean fallback = GL_FALSE;
    GLboolean ptexHack = GL_FALSE;
 
-   if (index & _TNL_BIT_TEX(0) && VB->TexCoordPtr[0]->size == 4) {
-      if ((index & _TNL_BITS_TEX_ANY) == _TNL_BIT_TEX(0))
+   RENDERINPUTS_COPY( index_bitset, tnl->render_inputs_bitset );
+
+   if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX0 ) && VB->TexCoordPtr[0]->size == 4) {
+      if (!RENDERINPUTS_TEST_RANGE( index_bitset, _TNL_ATTRIB_TEX1, _TNL_LAST_TEX ))
         ptexHack = GL_TRUE; 
       else
         fallback = GL_TRUE;
    }
-   if ((index & _TNL_BIT_TEX(1)) && VB->TexCoordPtr[1]->size == 4)
+   if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX1 ) && VB->TexCoordPtr[1]->size == 4)
       fallback = GL_TRUE;
 
    FALLBACK(VIA_CONTEXT(ctx), VIA_FALLBACK_PROJ_TEXTURE, fallback);
@@ -806,7 +856,7 @@ static GLboolean viaCheckPTexHack( GLcontext *ctx )
 
 static void viaRenderStart(GLcontext *ctx)
 {
-   viaContextPtr vmesa = VIA_CONTEXT(ctx);
+   struct via_context *vmesa = VIA_CONTEXT(ctx);
    TNLcontext *tnl = TNL_CONTEXT(ctx);
    struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
 
@@ -852,20 +902,27 @@ void viaRasterPrimitive(GLcontext *ctx,
                        GLenum glprim,
                        GLenum hwprim)
 {
-   viaContextPtr vmesa = VIA_CONTEXT(ctx);
+   struct via_context *vmesa = VIA_CONTEXT(ctx);
    GLuint regCmdB;
    RING_VARS;
 
-   if (VIA_DEBUG) 
-      fprintf(stderr, "%s: %s/%s\n", __FUNCTION__, _mesa_lookup_enum_by_nr(glprim),
-             _mesa_lookup_enum_by_nr(hwprim));
+   if (VIA_DEBUG & DEBUG_PRIMS) 
+      fprintf(stderr, "%s: %s/%s/%s\n", 
+             __FUNCTION__, _mesa_lookup_enum_by_nr(glprim),
+             _mesa_lookup_enum_by_nr(hwprim),
+             _mesa_lookup_enum_by_nr(ctx->Light.ShadeModel));
+
+   assert (!vmesa->newState);
 
    vmesa->renderPrimitive = glprim;
 
-   if (hwprim != vmesa->hwPrimitive) {
+   if (hwprim != vmesa->hwPrimitive ||
+       ctx->Light.ShadeModel != vmesa->hwShadeModel) {
+
       VIA_FINISH_PRIM(vmesa);
-    
-      viaCheckDma( vmesa, 1024 );      /* Ensure no wrapping inside this function  */
+
+      /* Ensure no wrapping inside this function  */    
+      viaCheckDma( vmesa, 1024 );      
 
       if (vmesa->newEmitState) {
         viaEmitState(vmesa);
@@ -876,16 +933,19 @@ void viaRasterPrimitive(GLcontext *ctx,
       if (ctx->Light.ShadeModel == GL_SMOOTH) {
         vmesa->regCmdA_End |= HC_HShading_Gouraud;
       }
-
+      
+      vmesa->hwShadeModel = ctx->Light.ShadeModel;
       regCmdB = vmesa->regCmdB;
 
       switch (hwprim) {
       case GL_POINTS:
         vmesa->regCmdA_End |= HC_HPMType_Point | HC_HVCycle_Full;
-        vmesa->regCmdA_End |= HC_HShading_Gouraud; /* always Gouraud shade points?!? */
+        vmesa->regCmdA_End |= HC_HShading_Gouraud; /* always Gouraud 
+                                                      shade points?!? */
         break;
       case GL_LINES:
         vmesa->regCmdA_End |= HC_HPMType_Line | HC_HVCycle_Full;
+         regCmdB |= HC_HLPrst_MASK;
         if (ctx->Light.ShadeModel == GL_FLAT)
             vmesa->regCmdA_End |= HC_HShading_FlatB; 
         break;
@@ -907,7 +967,7 @@ void viaRasterPrimitive(GLcontext *ctx,
            HC_HVCycle_AC | HC_HVCycle_BB | HC_HVCycle_NewC;
         regCmdB |= HC_HVCycle_AA | HC_HVCycle_BC | HC_HVCycle_NewC;
         if (ctx->Light.ShadeModel == GL_FLAT)
-            vmesa->regCmdA_End |= HC_HShading_FlatB
+            vmesa->regCmdA_End |= HC_HShading_FlatC
         break;
       case GL_TRIANGLE_FAN:
         vmesa->regCmdA_End |= HC_HPMType_Tri | HC_HVCycle_AFP |
@@ -937,7 +997,8 @@ void viaRasterPrimitive(GLcontext *ctx,
 /*     assert((vmesa->dmaLow & 0x4) == 0); */
 
       if (vmesa->dmaCliprectAddr == ~0) {
-        if (VIA_DEBUG) fprintf(stderr, "reserve cliprect space at %x\n", vmesa->dmaLow);
+        if (VIA_DEBUG & DEBUG_DMA) 
+           fprintf(stderr, "reserve cliprect space at %x\n", vmesa->dmaLow);
         vmesa->dmaCliprectAddr = vmesa->dmaLow;
         BEGIN_RING(8);
         OUT_RING( HC_HEADER2 );    
@@ -981,16 +1042,17 @@ static void viaRenderPrimitive( GLcontext *ctx, GLuint prim )
 }
 
 
-void viaFinishPrimitive(viaContextPtr vmesa)
+void viaFinishPrimitive(struct via_context *vmesa)
 {
-   if (VIA_DEBUG)
+   if (VIA_DEBUG & (DEBUG_DMA|DEBUG_PRIMS)) 
       fprintf(stderr, "%s\n", __FUNCTION__);
 
    if (!vmesa->dmaLastPrim || vmesa->dmaCliprectAddr == ~0) {
       assert(0);
    }
    else if (vmesa->dmaLow != vmesa->dmaLastPrim) {
-      GLuint cmdA = vmesa->regCmdA_End | HC_HPLEND_MASK | HC_HPMValidN_MASK | HC_HE3Fire_MASK;    
+      GLuint cmdA = (vmesa->regCmdA_End | HC_HPLEND_MASK | 
+                    HC_HPMValidN_MASK | HC_HE3Fire_MASK); 
       RING_VARS;
 
       vmesa->dmaLastPrim = 0;
@@ -1013,7 +1075,7 @@ void viaFinishPrimitive(viaContextPtr vmesa)
         viaFlushDma( vmesa );
    }
    else {
-      if (VIA_DEBUG)
+      if (VIA_DEBUG & (DEBUG_DMA|DEBUG_PRIMS)) 
         fprintf(stderr, "remove empty primitive\n");
 
       /* Remove the primitive header:
@@ -1040,18 +1102,20 @@ void viaFinishPrimitive(viaContextPtr vmesa)
 /**********************************************************************/
 
 
-void viaFallback(viaContextPtr vmesa, GLuint bit, GLboolean mode)
+void viaFallback(struct via_context *vmesa, GLuint bit, GLboolean mode)
 {
     GLcontext *ctx = vmesa->glCtx;
     TNLcontext *tnl = TNL_CONTEXT(ctx);
     GLuint oldfallback = vmesa->Fallback;
-    if (VIA_DEBUG) fprintf(stderr, "%s old %x bit %x mode %d\n", __FUNCTION__,
-                   vmesa->Fallback, bit, mode);
     
     if (mode) {
         vmesa->Fallback |= bit;
         if (oldfallback == 0) {
            VIA_FLUSH_DMA(vmesa);
+
+           if (VIA_DEBUG & DEBUG_FALLBACKS) 
+              fprintf(stderr, "ENTER FALLBACK %x\n", bit);
+
             _swsetup_Wakeup(ctx);
             vmesa->renderIndex = ~0;
         }
@@ -1061,6 +1125,9 @@ void viaFallback(viaContextPtr vmesa, GLuint bit, GLboolean mode)
         if (oldfallback == bit) {
            _swrast_flush( ctx );
 
+           if (VIA_DEBUG & DEBUG_FALLBACKS) 
+              fprintf(stderr, "LEAVE FALLBACK %x\n", bit);
+
            tnl->Driver.Render.Start = viaRenderStart;
             tnl->Driver.Render.PrimitiveNotify = viaRenderPrimitive;
             tnl->Driver.Render.Finish = viaRenderFinish;
@@ -1082,6 +1149,18 @@ void viaFallback(viaContextPtr vmesa, GLuint bit, GLboolean mode)
     }    
 }
 
+static void viaRunPipeline( GLcontext *ctx )
+{
+   struct via_context *vmesa = VIA_CONTEXT(ctx);
+
+   if (vmesa->newState) {
+      vmesa->newRenderState |= vmesa->newState;
+      viaValidateState( ctx );
+   }
+
+   _tnl_run_pipeline( ctx );
+}
+
 
 /**********************************************************************/
 /*                            Initialization.                         */
@@ -1090,7 +1169,7 @@ void viaFallback(viaContextPtr vmesa, GLuint bit, GLboolean mode)
 
 void viaInitTriFuncs(GLcontext *ctx)
 {
-    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+    struct via_context *vmesa = VIA_CONTEXT(ctx);
     TNLcontext *tnl = TNL_CONTEXT(ctx);
     static int firsttime = 1;
 
@@ -1099,7 +1178,7 @@ void viaInitTriFuncs(GLcontext *ctx)
         firsttime = 0;
     }
 
-    tnl->Driver.RunPipeline = _tnl_run_pipeline;
+    tnl->Driver.RunPipeline = viaRunPipeline;
     tnl->Driver.Render.Start = viaRenderStart;
     tnl->Driver.Render.Finish = viaRenderFinish;
     tnl->Driver.Render.PrimitiveNotify = viaRenderPrimitive;