Fix some wrapping bugs in the last commit. Probably there are more
[mesa.git] / src / mesa / drivers / dri / unichrome / via_tris.c
index 7bb850372dcb3702ec6e9724a46ccfef9bee41e9..862c827300f47e3a037cb61301cf5bf3e8d67e05 100644 (file)
@@ -40,6 +40,7 @@
 #include "via_context.h"
 #include "via_tris.h"
 #include "via_state.h"
+#include "via_span.h"
 #include "via_vb.h"
 #include "via_ioctl.h"
 
@@ -74,7 +75,7 @@ static void __inline__ via_draw_triangle(viaContextPtr vmesa,
                                          viaVertexPtr v2)
 {
     GLuint vertsize = vmesa->vertexSize;
-    GLuint *vb = viaAllocDma(vmesa, 3 * 4 * vertsize);
+    GLuint *vb = viaExtendPrimitive(vmesa, 3 * 4 * vertsize);
 /*     fprintf(stderr, "%s: %p %p %p\n", __FUNCTION__, v0, v1, v2); */
     COPY_DWORDS(vb, vertsize, v0);
     COPY_DWORDS(vb, vertsize, v1);
@@ -89,7 +90,7 @@ static void __inline__ via_draw_quad(viaContextPtr vmesa,
                                      viaVertexPtr v3)
 {
     GLuint vertsize = vmesa->vertexSize;
-    GLuint *vb = viaAllocDma(vmesa, 6 * 4 * vertsize);
+    GLuint *vb = viaExtendPrimitive(vmesa, 6 * 4 * vertsize);
 
 /*     fprintf(stderr, "%s: %p %p %p %p\n", __FUNCTION__, v0, v1, v2, v3); */
     COPY_DWORDS(vb, vertsize, v0);
@@ -105,7 +106,7 @@ static __inline__ void via_draw_line(viaContextPtr vmesa,
                                      viaVertexPtr v1)
 {
     GLuint vertsize = vmesa->vertexSize;
-    GLuint *vb = viaAllocDma(vmesa, 2 * 4 * vertsize);
+    GLuint *vb = viaExtendPrimitive(vmesa, 2 * 4 * vertsize);
     COPY_DWORDS(vb, vertsize, v0);
     COPY_DWORDS(vb, vertsize, v1);
 }
@@ -115,7 +116,7 @@ static __inline__ void via_draw_point(viaContextPtr vmesa,
                                       viaVertexPtr v0)
 {
     GLuint vertsize = vmesa->vertexSize;
-    GLuint *vb = viaAllocDma(vmesa, 4 * vertsize);
+    GLuint *vb = viaExtendPrimitive(vmesa, 4 * vertsize);
     COPY_DWORDS(vb, vertsize, v0);
 }
 
@@ -230,14 +231,39 @@ static struct {
 #define AREA_IS_CCW(a) (a > 0)
 #define GET_VERTEX(e) (vmesa->verts + (e * vmesa->vertexSize * sizeof(int)))
 
-#define VERT_SET_RGBA(v, c)    VIA_COLOR(v->ub4[coloroffset], c)
-#define VERT_COPY_RGBA(v0, v1) v0->ui[coloroffset] = v1->ui[coloroffset]
-#define VERT_SAVE_RGBA(idx)    color[idx] = v[idx]->ui[coloroffset]
-#define VERT_RESTORE_RGBA(idx) v[idx]->ui[coloroffset] = color[idx]
-#define VERT_SET_SPEC(v, c)    if (havespec) VIA_SPEC(v->ub4[5], c)
-#define VERT_COPY_SPEC(v0, v1) if (havespec) COPY_3V(v0->ub4[5], v1->ub4[5])
-#define VERT_SAVE_SPEC(idx)    if (havespec) spec[idx] = v[idx]->ui[5]
-#define VERT_RESTORE_SPEC(idx) if (havespec) v[idx]->ui[5] = spec[idx]
+#define VERT_SET_RGBA( v, c )                                          \
+do {                                                           \
+   via_color_t *color = (via_color_t *)&((v)->ui[coloroffset]);        \
+   UNCLAMPED_FLOAT_TO_UBYTE(color->red, (c)[0]);               \
+   UNCLAMPED_FLOAT_TO_UBYTE(color->green, (c)[1]);             \
+   UNCLAMPED_FLOAT_TO_UBYTE(color->blue, (c)[2]);              \
+   UNCLAMPED_FLOAT_TO_UBYTE(color->alpha, (c)[3]);             \
+} while (0)
+
+#define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset]
+
+#define VERT_SET_SPEC( v0, c )                                 \
+do {                                                           \
+   if (havespec) {                                             \
+      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]);   \
+   }                                                           \
+} while (0)
+#define VERT_COPY_SPEC( v0, v1 )                       \
+do {                                                   \
+   if (havespec) {                                     \
+      v0->v.specular.red   = v1->v.specular.red;       \
+      v0->v.specular.green = v1->v.specular.green;     \
+      v0->v.specular.blue  = v1->v.specular.blue;      \
+   }                                                   \
+} while (0)
+
+
+#define VERT_SAVE_RGBA( idx )    color[idx] = v[idx]->ui[coloroffset]
+#define VERT_RESTORE_RGBA( idx ) v[idx]->ui[coloroffset] = color[idx]
+#define VERT_SAVE_SPEC( idx )    if (havespec) spec[idx] = v[idx]->ui[5]
+#define VERT_RESTORE_SPEC( idx ) if (havespec) v[idx]->ui[5] = spec[idx]
 
 
 #define LOCAL_VARS(n)                                                   \
@@ -386,7 +412,9 @@ via_fallback_tri(viaContextPtr vmesa,
     via_translate_vertex(ctx, v0, &v[0]);
     via_translate_vertex(ctx, v1, &v[1]);
     via_translate_vertex(ctx, v2, &v[2]);
+    viaSpanRenderStart( ctx );
     _swrast_Triangle(ctx, &v[0], &v[1], &v[2]);
+    viaSpanRenderFinish( ctx );
 }
 
 
@@ -399,7 +427,9 @@ via_fallback_line(viaContextPtr vmesa,
     SWvertex v[2];
     via_translate_vertex(ctx, v0, &v[0]);
     via_translate_vertex(ctx, v1, &v[1]);
+    viaSpanRenderStart( ctx );
     _swrast_Line(ctx, &v[0], &v[1]);
+    viaSpanRenderFinish( ctx );
 }
 
 
@@ -410,7 +440,9 @@ via_fallback_point(viaContextPtr vmesa,
     GLcontext *ctx = vmesa->glCtx;
     SWvertex v[1];
     via_translate_vertex(ctx, v0, &v[0]);
+    viaSpanRenderStart( ctx );
     _swrast_Point(ctx, &v[0]);
+    viaSpanRenderFinish( ctx );
 }
 
 /**********************************************************************/
@@ -490,7 +522,7 @@ static void viaFastRenderClippedPoly(GLcontext *ctx, const GLuint *elts,
 {
     viaContextPtr vmesa = VIA_CONTEXT(ctx);
     GLuint vertsize = vmesa->vertexSize;
-    GLuint *vb = viaAllocDma(vmesa, (n - 2) * 3 * 4 * vertsize);
+    GLuint *vb = viaExtendPrimitive(vmesa, (n - 2) * 3 * 4 * vertsize);
     GLubyte *vertptr = (GLubyte *)vmesa->verts;
     const GLuint *start = (const GLuint *)V(elts[0]);
     int i;
@@ -515,15 +547,16 @@ static void viaFastRenderClippedPoly(GLcontext *ctx, const GLuint *elts,
                               _DD_NEW_TRI_STIPPLE |             \
                               _NEW_POLYGONSTIPPLE)
 
+/* Via does support line stipple in hardware, and it is partially
+ * working in the older versions of this driver:
+ */
+#define LINE_FALLBACK (DD_LINE_STIPPLE)
 #define POINT_FALLBACK (0)
-/*#define LINE_FALLBACK (DD_LINE_STIPPLE)
-*/
-#define LINE_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)
+void viaChooseRenderState(GLcontext *ctx)
 {
     TNLcontext *tnl = TNL_CONTEXT(ctx);
     viaContextPtr vmesa = VIA_CONTEXT(ctx);
@@ -600,12 +633,9 @@ static void viaRunPipeline(GLcontext *ctx)
     viaContextPtr vmesa = VIA_CONTEXT(ctx);
     
     if (vmesa->newState) {
+       viaChooseVertexState(ctx);
+       viaChooseRenderState(ctx);
        viaValidateState( ctx );
-
-       if (!vmesa->Fallback) {
-         viaChooseVertexState(ctx);
-         viaChooseRenderState(ctx);
-       }
     }
 
     _tnl_run_pipeline(ctx);
@@ -645,9 +675,14 @@ void viaRasterPrimitive(GLcontext *ctx,
               _mesa_lookup_enum_by_nr(hwprim));
 
     VIA_FINISH_PRIM(vmesa);
-
-    vmesa->renderPrimitive = glprim;
     
+    viaCheckDma( vmesa, 1024 );        /* Ensure no wrapping inside this function  */
+
+    if (vmesa->newEmitState) {
+       viaEmitState(vmesa);
+    }
+       
+
     regCmdB = vmesa->regCmdB;
 
     switch (hwprim) {
@@ -706,7 +741,24 @@ void viaRasterPrimitive(GLcontext *ctx,
         return;
     }
     
-    assert((vmesa->dmaLow & 0x4) == 0);
+/*     assert((vmesa->dmaLow & 0x4) == 0); */
+
+    if (vmesa->dmaCliprectAddr == 0) {
+       if (VIA_DEBUG) fprintf(stderr, "reserve cliprect space at %x\n", vmesa->dmaLow);
+       assert(vmesa->dmaLow);
+       vmesa->dmaCliprectAddr = vmesa->dmaLow;
+       BEGIN_RING(8);
+       OUT_RING( HC_HEADER2 );    
+       OUT_RING( (HC_ParaType_NotTex << 16) );
+       OUT_RING( 0xCCCCCCCC );
+       OUT_RING( 0xCCCCCCCC );
+       OUT_RING( 0xCCCCCCCC );
+       OUT_RING( 0xCCCCCCCC );
+       OUT_RING( 0xCCCCCCCC );
+       OUT_RING( 0xCCCCCCCC );
+       ADVANCE_RING();
+    }
+
 
     BEGIN_RING(8);
     OUT_RING( HC_HEADER2 );    
@@ -720,8 +772,10 @@ void viaRasterPrimitive(GLcontext *ctx,
     OUT_RING( vmesa->regCmdA_End );
     ADVANCE_RING();
 
+
+    vmesa->renderPrimitive = glprim;
+    vmesa->hwPrimitive = hwprim;        
     vmesa->dmaLastPrim = vmesa->dmaLow;
-    vmesa->hwPrimitive = hwprim;    
 }
 
 /* Callback for mesa:
@@ -734,36 +788,50 @@ static void viaRenderPrimitive( GLcontext *ctx, GLuint prim )
 
 void viaFinishPrimitive(viaContextPtr vmesa)
 {
-    if (!vmesa->dmaLastPrim) {
-       return;
-    }
-    else if (vmesa->dmaLow != vmesa->dmaLastPrim) {
-       GLuint cmdA = vmesa->regCmdA_End | HC_HPLEND_MASK | HC_HPMValidN_MASK | HC_HE3Fire_MASK;    
-       RING_VARS;
-
-       /* KW: modified 0x1 to 0x4 below:
-        */
-       if ((vmesa->dmaLow & 0x1) || !vmesa->useAgp) {
-          BEGIN_RING_NOCHECK( 1 );
-          OUT_RING( cmdA );
-          ADVANCE_RING();
-       }   
-       else {      
-          BEGIN_RING_NOCHECK( 2 );
-          OUT_RING( cmdA );
-          OUT_RING( cmdA );
-          ADVANCE_RING();
-        }   
-       vmesa->dmaLastPrim = 0;
-
-       if (1 || vmesa->dmaLow > VIA_DMA_HIGHWATER)
-          viaFlushPrims( vmesa );
-    }
-    else {
-       assert(vmesa->dmaLow >= (32 + DMA_OFFSET));
-       vmesa->dmaLow -= 32;
-       vmesa->dmaLastPrim = 0;
-    }
+   if (VIA_DEBUG) fprintf(stderr, "%s\n", __FUNCTION__);
+
+   if (!vmesa->dmaLastPrim) {
+   }
+   else if (vmesa->dmaLow != vmesa->dmaLastPrim) {
+      GLuint cmdA = vmesa->regCmdA_End | HC_HPLEND_MASK | HC_HPMValidN_MASK | HC_HE3Fire_MASK;    
+      RING_VARS;
+
+      vmesa->dmaLastPrim = 0;
+
+      /* KW: modified 0x1 to 0x4 below:
+       */
+      if ((vmesa->dmaLow & 0x1) || !vmesa->useAgp) {
+        BEGIN_RING_NOCHECK( 1 );
+        OUT_RING( cmdA );
+        ADVANCE_RING();
+      }   
+      else {      
+        BEGIN_RING_NOCHECK( 2 );
+        OUT_RING( cmdA );
+        OUT_RING( cmdA );
+        ADVANCE_RING();
+      }   
+
+      if (vmesa->dmaLow > VIA_DMA_HIGHWATER)
+        viaFlushDma( vmesa );
+   }
+   else {
+      /* Remove the primitive header:
+       */
+      vmesa->dmaLastPrim = 0;
+      vmesa->dmaLow -= 8 * sizeof(GLuint);
+
+      /* Maybe remove the cliprect as well:
+       */
+      if (vmesa->dmaCliprectAddr == vmesa->dmaLow - 8 * sizeof(GLuint)) {
+        vmesa->dmaLow -= 8 * sizeof(GLuint);
+        vmesa->dmaCliprectAddr = 0;
+      }
+   }
+
+   vmesa->renderPrimitive = GL_POLYGON + 1;
+   vmesa->hwPrimitive = GL_POLYGON + 1;
+   vmesa->dmaLastPrim = 0;
 }