softpipe: do our own culling, don't rely on the draw module.
authorKeith Whitwell <keith@tungstengraphics.com>
Mon, 14 Apr 2008 10:32:50 +0000 (11:32 +0100)
committerKeith Whitwell <keith@tungstengraphics.com>
Mon, 14 Apr 2008 10:32:50 +0000 (11:32 +0100)
May not always happen due to passthrough modes, etc.

src/gallium/drivers/softpipe/sp_prim_vbuf.c
src/gallium/drivers/softpipe/sp_setup.c

index 025a0113bf12bffbc17286057d2e863b029c320e..74cd675908c5e8242e2b7906a7081eb46fa24844 100644 (file)
@@ -120,8 +120,9 @@ sp_vbuf_set_primitive(struct vbuf_render *vbr, unsigned prim)
 
 
 /**
- * Recalculate prim's determinant.
- * XXX is this needed?
+ * Recalculate prim's determinant.  This is needed as we don't have
+ * get this information through the vbuf_render interface & we must
+ * calculate it here.
  */
 static float
 calc_det( const float (*v0)[4],
@@ -144,12 +145,21 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr_indices)
 {
    struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
    struct softpipe_context *softpipe = cvbr->softpipe;
-   struct draw_stage *setup = softpipe->setup;
    unsigned vertex_size = softpipe->vertex_info_vbuf.size * sizeof(float);
    unsigned i, j;
    void *vertex_buffer = cvbr->vertex_buffer;
    cptrf4 v[3];
-   struct setup_context *setup_ctx = sp_draw_setup_context(setup);
+
+   /* XXX: break this dependency - make setup_context live under
+    * softpipe, rename the old "setup" draw stage to something else.
+    */
+   struct draw_stage *setup = softpipe->setup;
+   struct setup_context *setup_ctx = sp_draw_setup_context(softpipe->setup);
+   
+   /* XXX: call this from allocate_vertices: 
+    */
+   setup_prepare( setup_ctx );
+
 
    switch (cvbr->prim) {
    case PIPE_PRIM_TRIANGLES:
@@ -189,6 +199,9 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr_indices)
       break;
    }
 
+   /* XXX: why are we calling this???  If we had to call something, it
+    * would be a function in sp_setup.c:
+    */
    sp_draw_flush( setup );
 }
 
index 48617a66ed296a95bc283573b7f443bec5e5d714..5a3078885047e03516e13f2d66e5f2fc8835634b 100644 (file)
@@ -97,31 +97,35 @@ struct setup_context {
    uint numFragsEmitted;  /**< per primitive */
    uint numFragsWritten;  /**< per primitive */
 #endif
+
+   unsigned winding;           /* which winding to cull */
 };
 
 
 
 
 
-/**
- * Recalculate prim's determinant.
- * XXX is this needed?
- */
-static INLINE float
-calc_det( const float (*v0)[4],
-          const float (*v1)[4],
-          const float (*v2)[4] )
+static boolean cull_tri( struct setup_context *setup,
+                     float det )
 {
-   /* edge vectors e = v0 - v2, f = v1 - v2 */
-   const float ex = v0[0][0] - v2[0][0];
-   const float ey = v0[0][1] - v2[0][1];
-   const float fx = v1[0][0] - v2[0][0];
-   const float fy = v1[0][1] - v2[0][1];
-
-   /* det = cross(e,f).z */
-   return ex * fy - ey * fx;
+   if (det != 0) 
+   {   
+      /* if (det < 0 then Z points toward camera and triangle is 
+       * counter-clockwise winding.
+       */
+      unsigned winding = (det < 0) ? PIPE_WINDING_CCW : PIPE_WINDING_CW;
+      
+      if ((winding & setup->winding) == 0) 
+        return FALSE;
+   }
+
+   /* Culled:
+    */
+   return TRUE;
 }
 
+
+
 /**
  * Clip setup->quad against the scissor/surface bounds.
  */
@@ -709,8 +713,10 @@ void setup_tri( struct setup_context *setup,
    setup->numFragsWritten = 0;
 #endif
 
-   setup_sort_vertices( setup, calc_det(v0, v1, v2),
-                        v0, v1, v2 );
+   if (cull_tri( setup, det ))
+      return;
+
+   setup_sort_vertices( setup, det, v0, v1, v2 );
    setup_tri_coefficients( setup );
    setup_tri_edges( setup );
 
@@ -1223,6 +1229,8 @@ void setup_prepare( struct setup_context *setup )
       setup->quad.nr_attrs = fs->info.num_inputs;
       sp->quad.first->begin(sp->quad.first);
    }
+
+   setup->winding = sp->rasterizer->cull_mode;
 }