From cb136a93aba4dc64db7e446b0fbc36c9172e4017 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 5 May 2010 18:19:06 -0600 Subject: gallium: rework provoking vertex code Builds on commit ddb0e18f6c5582d4d2cc59ffd16ad9c4639ed059 and fixes regressions in glean clipFlat test. We assume that Gallium drivers observe flatshade_first for all triangles and that all the assorted per-triangle calls in the 'draw' module also follow flatshade_first. Everything else builds on those rules. Gallium does not use follow flatshade_first for GL quads, quad strips and polygons; the "last" vertex is always the provoking vertex for those prims. So now there are separate QUAD_FIRST_PV and QUAD_LAST_PV macros in the draw primitive decomposition code instead of one QUAD macro. --- src/gallium/auxiliary/draw/draw_pipe.c | 42 +++++++++++++-- src/gallium/auxiliary/draw/draw_pipe_clip.c | 36 ++++++++----- src/gallium/auxiliary/draw/draw_pipe_vbuf.c | 15 +----- src/gallium/auxiliary/draw/draw_pt_decompose.h | 71 ++++++++++++++++++++------ src/gallium/auxiliary/draw/draw_pt_vcache.c | 8 +-- 5 files changed, 123 insertions(+), 49 deletions(-) (limited to 'src/gallium/auxiliary/draw') diff --git a/src/gallium/auxiliary/draw/draw_pipe.c b/src/gallium/auxiliary/draw/draw_pipe.c index 64c3502508..7ea04e3819 100644 --- a/src/gallium/auxiliary/draw/draw_pipe.c +++ b/src/gallium/auxiliary/draw/draw_pipe.c @@ -170,7 +170,25 @@ static void do_triangle( struct draw_context *draw, * Set up macros for draw_pt_decompose.h template code. * This code uses vertex indexes / elements. */ -#define QUAD(i0,i1,i2,i3) \ + +/* emit first quad vertex as first vertex in triangles */ +#define QUAD_FIRST_PV(i0,i1,i2,i3) \ + do_triangle( draw, \ + ( DRAW_PIPE_RESET_STIPPLE | \ + DRAW_PIPE_EDGE_FLAG_0 | \ + DRAW_PIPE_EDGE_FLAG_1 ), \ + verts + stride * elts[i0], \ + verts + stride * elts[i1], \ + verts + stride * elts[i2]); \ + do_triangle( draw, \ + ( DRAW_PIPE_EDGE_FLAG_1 | \ + DRAW_PIPE_EDGE_FLAG_2 ), \ + verts + stride * elts[i0], \ + verts + stride * elts[i2], \ + verts + stride * elts[i3]) + +/* emit last quad vertex as last vertex in triangles */ +#define QUAD_LAST_PV(i0,i1,i2,i3) \ do_triangle( draw, \ ( DRAW_PIPE_RESET_STIPPLE | \ DRAW_PIPE_EDGE_FLAG_0 | \ @@ -261,9 +279,27 @@ void draw_pipeline_run( struct draw_context *draw, /* * Set up macros for draw_pt_decompose.h template code. - * This code is for non-indexed rendering (no elts). + * This code is for non-indexed (aka linear) rendering (no elts). */ -#define QUAD(i0,i1,i2,i3) \ + +/* emit first quad vertex as first vertex in triangles */ +#define QUAD_FIRST_PV(i0,i1,i2,i3) \ + do_triangle( draw, \ + ( DRAW_PIPE_RESET_STIPPLE | \ + DRAW_PIPE_EDGE_FLAG_0 | \ + DRAW_PIPE_EDGE_FLAG_1 ), \ + verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK), \ + verts + stride * (i1), \ + verts + stride * (i2)); \ + do_triangle( draw, \ + ( DRAW_PIPE_EDGE_FLAG_1 | \ + DRAW_PIPE_EDGE_FLAG_2 ), \ + verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK), \ + verts + stride * (i2), \ + verts + stride * (i3)) + +/* emit last quad vertex as last vertex in triangles */ +#define QUAD_LAST_PV(i0,i1,i2,i3) \ do_triangle( draw, \ ( DRAW_PIPE_RESET_STIPPLE | \ DRAW_PIPE_EDGE_FLAG_0 | \ diff --git a/src/gallium/auxiliary/draw/draw_pipe_clip.c b/src/gallium/auxiliary/draw/draw_pipe_clip.c index 428ef4ef67..d0532cb341 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_clip.c +++ b/src/gallium/auxiliary/draw/draw_pipe_clip.c @@ -164,10 +164,18 @@ static void emit_poly( struct draw_stage *stage, { struct prim_header header; unsigned i; + ushort edge_first, edge_middle, edge_last; - const ushort edge_first = DRAW_PIPE_EDGE_FLAG_2; - const ushort edge_middle = DRAW_PIPE_EDGE_FLAG_0; - const ushort edge_last = DRAW_PIPE_EDGE_FLAG_1; + if (stage->draw->rasterizer->flatshade_first) { + edge_first = DRAW_PIPE_EDGE_FLAG_0; + edge_middle = DRAW_PIPE_EDGE_FLAG_1; + edge_last = DRAW_PIPE_EDGE_FLAG_2; + } + else { + edge_first = DRAW_PIPE_EDGE_FLAG_2; + edge_middle = DRAW_PIPE_EDGE_FLAG_0; + edge_last = DRAW_PIPE_EDGE_FLAG_1; + } /* later stages may need the determinant, but only the sign matters */ header.det = origPrim->det; @@ -301,21 +309,21 @@ do_clip_tri( struct draw_stage *stage, /* If flat-shading, copy color to new provoking vertex. */ - if (stage->draw->rasterizer->flatshade_first) { - if (clipper->flat && inlist[0] != header->v[0]) { - inlist[0] = dup_vert(stage, inlist[0], tmpnr++); - - copy_colors(stage, inlist[0], header->v[0]); + if (clipper->flat) { + if (stage->draw->rasterizer->flatshade_first) { + if (inlist[0] != header->v[0]) { + inlist[0] = dup_vert(stage, inlist[0], tmpnr++); + copy_colors(stage, inlist[0], header->v[0]); + } } - } else { - if (clipper->flat && inlist[0] != header->v[2]) { - inlist[0] = dup_vert(stage, inlist[0], tmpnr++); - - copy_colors(stage, inlist[0], header->v[2]); + else { + if (inlist[0] != header->v[2]) { + inlist[0] = dup_vert(stage, inlist[0], tmpnr++); + copy_colors(stage, inlist[0], header->v[2]); + } } } - /* Emit the polygon as triangles to the setup stage: */ if (n >= 3) diff --git a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c index abbf6247ab..1fd083e54d 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c +++ b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c @@ -159,19 +159,8 @@ vbuf_tri( struct draw_stage *stage, check_space( vbuf, 3 ); - if (vbuf->stage.draw->rasterizer->flatshade_first) { - /* Put provoking vertex in position expected by the driver. - * Emit last provoking vertex in first pos. - * Swap verts 0 & 1 to preserve polygon winding. - */ - vbuf->indices[vbuf->nr_indices++] = emit_vertex( vbuf, prim->v[2] ); - vbuf->indices[vbuf->nr_indices++] = emit_vertex( vbuf, prim->v[0] ); - vbuf->indices[vbuf->nr_indices++] = emit_vertex( vbuf, prim->v[1] ); - } - else { - for (i = 0; i < 3; i++) { - vbuf->indices[vbuf->nr_indices++] = emit_vertex( vbuf, prim->v[i] ); - } + for (i = 0; i < 3; i++) { + vbuf->indices[vbuf->nr_indices++] = emit_vertex( vbuf, prim->v[i] ); } } diff --git a/src/gallium/auxiliary/draw/draw_pt_decompose.h b/src/gallium/auxiliary/draw/draw_pt_decompose.h index 02567d97f2..52f9593d46 100644 --- a/src/gallium/auxiliary/draw/draw_pt_decompose.h +++ b/src/gallium/auxiliary/draw/draw_pt_decompose.h @@ -57,6 +57,7 @@ static void FUNC( ARGS, case PIPE_PRIM_TRIANGLE_STRIP: if (flatfirst) { for (i = 0; i+2 < count; i++) { + /* Emit first triangle vertex as first triangle vertex */ TRIANGLE( DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, (i + 0), (i + 1 + (i&1)), @@ -65,6 +66,7 @@ static void FUNC( ARGS, } else { for (i = 0; i+2 < count; i++) { + /* Emit last triangle vertex as last triangle vertex */ TRIANGLE( DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, (i + 0 + (i&1)), (i + 1 - (i&1)), @@ -96,24 +98,52 @@ static void FUNC( ARGS, case PIPE_PRIM_QUADS: - for (i = 0; i+3 < count; i += 4) { - QUAD( (i + 0), - (i + 1), - (i + 2), - (i + 3)); + /* GL quads don't follow provoking vertex convention */ + if (flatfirst) { + for (i = 0; i+3 < count; i += 4) { + /* emit last quad vertex as first triangle vertex */ + QUAD_FIRST_PV( (i + 3), + (i + 0), + (i + 1), + (i + 2) ); + } + } + else { + for (i = 0; i+3 < count; i += 4) { + /* emit last quad vertex as last triangle vertex */ + QUAD_LAST_PV( (i + 0), + (i + 1), + (i + 2), + (i + 3) ); + } } break; case PIPE_PRIM_QUAD_STRIP: - for (i = 0; i+3 < count; i += 2) { - QUAD( (i + 2), - (i + 0), - (i + 1), - (i + 3)); + /* GL quad strips don't follow provoking vertex convention */ + if (flatfirst) { + for (i = 0; i+3 < count; i += 2) { + /* emit last quad vertex as first triangle vertex */ + QUAD_FIRST_PV( (i + 3), + (i + 2), + (i + 0), + (i + 1) ); + + } + } + else { + for (i = 0; i+3 < count; i += 2) { + /* emit last quad vertex as last triangle vertex */ + QUAD_LAST_PV( (i + 2), + (i + 0), + (i + 1), + (i + 3) ); + } } break; case PIPE_PRIM_POLYGON: + /* GL polygons don't follow provoking vertex convention */ { /* These bitflags look a little odd because we submit the * vertices as (1,2,0) to satisfy flatshade requirements. @@ -129,10 +159,20 @@ static void FUNC( ARGS, if (i + 3 == count) flags |= edge_last; - TRIANGLE( flags, - (i + 1), - (i + 2), - (0)); + if (flatfirst) { + /* emit first polygon vertex as first triangle vertex */ + TRIANGLE( flags, + (0), + (i + 1), + (i + 2) ); + } + else { + /* emit first polygon vertex as last triangle vertex */ + TRIANGLE( flags, + (i + 1), + (i + 2), + (0)); + } } } break; @@ -147,7 +187,8 @@ static void FUNC( ARGS, #undef TRIANGLE -#undef QUAD +#undef QUAD_FIRST_PV +#undef QUAD_LAST_PV #undef POINT #undef LINE #undef FUNC diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c index 37ffbac4f9..bfcd709f25 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vcache.c +++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c @@ -199,12 +199,12 @@ vcache_ef_quad( struct vcache_frontend *vcache, ( DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_0 | DRAW_PIPE_EDGE_FLAG_1 ), - i0, i1, i2 ); + i3, i0, i1 ); vcache_triangle_flags( vcache, - ( DRAW_PIPE_EDGE_FLAG_2 | - DRAW_PIPE_EDGE_FLAG_1 ), - i0, i2, i3 ); + ( DRAW_PIPE_EDGE_FLAG_1 | + DRAW_PIPE_EDGE_FLAG_2 ), + i3, i1, i2 ); } else { vcache_triangle_flags( vcache, -- cgit v1.2.3