summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeith Whitwell <[email protected]>2008-04-14 11:32:50 +0100
committerKeith Whitwell <[email protected]>2008-04-14 11:32:50 +0100
commit8e7326832a7420154fc0d526ac682494db1be160 (patch)
tree3c080a2c490fbe18bb65b27d1844f847db50ef35
parent0c1cb54923f3ab31caa2821e095685277174dd2f (diff)
softpipe: do our own culling, don't rely on the draw module.
May not always happen due to passthrough modes, etc.
-rw-r--r--src/gallium/drivers/softpipe/sp_prim_vbuf.c21
-rw-r--r--src/gallium/drivers/softpipe/sp_setup.c44
2 files changed, 43 insertions, 22 deletions
diff --git a/src/gallium/drivers/softpipe/sp_prim_vbuf.c b/src/gallium/drivers/softpipe/sp_prim_vbuf.c
index 025a0113bf1..74cd675908c 100644
--- a/src/gallium/drivers/softpipe/sp_prim_vbuf.c
+++ b/src/gallium/drivers/softpipe/sp_prim_vbuf.c
@@ -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 );
}
diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c
index 48617a66ed2..5a307888504 100644
--- a/src/gallium/drivers/softpipe/sp_setup.c
+++ b/src/gallium/drivers/softpipe/sp_setup.c
@@ -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;
}