diff options
author | Brian Paul <[email protected]> | 2010-05-05 18:19:06 -0600 |
---|---|---|
committer | Brian Paul <[email protected]> | 2010-05-05 18:19:06 -0600 |
commit | cb136a93aba4dc64db7e446b0fbc36c9172e4017 (patch) | |
tree | f899c682980b4af56e4dd0c7cd2d08cefb4efce3 /src/gallium/auxiliary/draw | |
parent | a8bb49562938e94459f398a1733a76eb9c690f6c (diff) |
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.
Diffstat (limited to 'src/gallium/auxiliary/draw')
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pipe.c | 42 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pipe_clip.c | 36 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pipe_vbuf.c | 15 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pt_decompose.h | 71 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pt_vcache.c | 8 |
5 files changed, 123 insertions, 49 deletions
diff --git a/src/gallium/auxiliary/draw/draw_pipe.c b/src/gallium/auxiliary/draw/draw_pipe.c index 64c35025081..7ea04e38193 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 428ef4ef67a..d0532cb341e 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 abbf6247ab8..1fd083e54d0 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 02567d97f26..52f9593d46e 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 37ffbac4f92..bfcd709f25d 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, |