summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Paul <brian.paul@tungstengraphics.com>2008-06-18 14:50:35 -0600
committerBrian Paul <brian.paul@tungstengraphics.com>2008-06-18 14:55:12 -0600
commit7d7f3e2c9451b2233c196d82d523c50b5d2616cc (patch)
tree74d0cb7a84b4e353d09d71dbf515cc472a04bc89
parentb623fa9e2d6f97f9febc978c158d790b26e175a7 (diff)
gallium: split long prims into chunks with an even number of vertices
This fixes culling "parity" errors when splitting long tri strips. Splitting strips into chunks with an odd number of vertices causes front/back-face orientation to get reversed and upsets culling.
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c9
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_varray.c4
2 files changed, 13 insertions, 0 deletions
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c
index 5ce3aba2a2..fdf9b6fe6a 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c
@@ -193,6 +193,15 @@ static void fse_prepare( struct draw_pt_middle_end *middle,
*max_vertices = (draw->render->max_vertex_buffer_bytes /
(vinfo->size * 4));
+ /* Return an even number of verts.
+ * This prevents "parity" errors when splitting long triangle strips which
+ * can lead to front/back culling mix-ups.
+ * Every other triangle in a strip has an alternate front/back orientation
+ * so splitting at an odd position can cause the orientation of subsequent
+ * triangles to get reversed.
+ */
+ *max_vertices = *max_vertices & ~1;
+
/* Probably need to do this somewhere (or fix exec shader not to
* need it):
*/
diff --git a/src/gallium/auxiliary/draw/draw_pt_varray.c b/src/gallium/auxiliary/draw/draw_pt_varray.c
index 4479963db1..2cc08a9e93 100644
--- a/src/gallium/auxiliary/draw/draw_pt_varray.c
+++ b/src/gallium/auxiliary/draw/draw_pt_varray.c
@@ -147,6 +147,10 @@ static void varray_prepare(struct draw_pt_front_end *frontend,
varray->middle = middle;
middle->prepare(middle, varray->output_prim, opt, &varray->driver_fetch_max );
+
+ /* check that the max is even */
+ assert((varray->driver_fetch_max & 1) == 0);
+
varray->fetch_max = MIN2(FETCH_MAX, varray->driver_fetch_max);
}