diff options
author | Zack Rusin <[email protected]> | 2013-07-31 07:34:49 -0400 |
---|---|---|
committer | Zack Rusin <[email protected]> | 2013-08-02 20:11:18 -0400 |
commit | d6b3a193d4d525c5048ebf793e6a63fd98f92d64 (patch) | |
tree | 03fa602befb47cfa29efad7bc1c85e1ec645e92a /src/gallium/auxiliary/draw/draw_pipe_unfilled.c | |
parent | 05487ef88ded5fea0b1de7bc08d44846648d1ce2 (diff) |
draw: inject frontface info into wireframe outputs
Draw module can decompose primitives into wireframe models, which
is a fancy word for 'lines', unfortunately that decomposition means
that we weren't able to preserve the original front-face info which
could be derived from the original primitives (lines don't have a
'face'). To fix it allow draw module to inject a fake face semantic
into outputs from which the backends can figure out the original
frontfacing info of the primitives.
Signed-off-by: Zack Rusin <[email protected]>
Reviewed-by: Roland Scheidegger <[email protected]>
Reviewed-by: Jose Fonseca <[email protected]>
Diffstat (limited to 'src/gallium/auxiliary/draw/draw_pipe_unfilled.c')
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pipe_unfilled.c | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/src/gallium/auxiliary/draw/draw_pipe_unfilled.c b/src/gallium/auxiliary/draw/draw_pipe_unfilled.c index d87741b91e7..d8a603f61cb 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_unfilled.c +++ b/src/gallium/auxiliary/draw/draw_pipe_unfilled.c @@ -47,6 +47,8 @@ struct unfilled_stage { * and PIPE_POLYGON_MODE_POINT, */ unsigned mode[2]; + + int face_slot; }; @@ -55,8 +57,31 @@ static INLINE struct unfilled_stage *unfilled_stage( struct draw_stage *stage ) return (struct unfilled_stage *)stage; } +static void +inject_front_face_info(struct draw_stage *stage, + struct prim_header *header) +{ + struct unfilled_stage *unfilled = unfilled_stage(stage); + unsigned ccw = header->det < 0.0; + boolean is_front_face = ( + (stage->draw->rasterizer->front_ccw && ccw) || + (!stage->draw->rasterizer->front_ccw && !ccw)); + unsigned slot = unfilled->face_slot; + struct vertex_header *v0 = header->v[0]; + struct vertex_header *v1 = header->v[1]; + struct vertex_header *v2 = header->v[2]; + + /* In case the backend doesn't care about it */ + if (slot < 0) { + return; + } + v0->data[slot][0] = is_front_face; + v1->data[slot][0] = is_front_face; + v2->data[slot][0] = is_front_face; +} + static void point( struct draw_stage *stage, struct vertex_header *v0 ) { @@ -83,6 +108,8 @@ static void points( struct draw_stage *stage, struct vertex_header *v1 = header->v[1]; struct vertex_header *v2 = header->v[2]; + inject_front_face_info(stage, header); + if ((header->flags & DRAW_PIPE_EDGE_FLAG_0) && v0->edgeflag) point( stage, v0 ); if ((header->flags & DRAW_PIPE_EDGE_FLAG_1) && v1->edgeflag) point( stage, v1 ); if ((header->flags & DRAW_PIPE_EDGE_FLAG_2) && v2->edgeflag) point( stage, v2 ); @@ -99,6 +126,8 @@ static void lines( struct draw_stage *stage, if (header->flags & DRAW_PIPE_RESET_STIPPLE) stage->next->reset_stipple_counter( stage->next ); + inject_front_face_info(stage, header); + if ((header->flags & DRAW_PIPE_EDGE_FLAG_2) && v2->edgeflag) line( stage, v2, v0 ); if ((header->flags & DRAW_PIPE_EDGE_FLAG_0) && v0->edgeflag) line( stage, v0, v1 ); if ((header->flags & DRAW_PIPE_EDGE_FLAG_1) && v1->edgeflag) line( stage, v1, v2 ); @@ -192,6 +221,26 @@ static void unfilled_destroy( struct draw_stage *stage ) FREE( stage ); } +/* + * Try to allocate an output slot which we can use + * to preserve the front face information. + */ +void +draw_unfilled_prepare_outputs( struct draw_context *draw, + struct draw_stage *stage ) +{ + struct unfilled_stage *unfilled = unfilled_stage(stage); + const struct pipe_rasterizer_state *rast = draw ? draw->rasterizer : 0; + if (rast && + (rast->fill_front != PIPE_POLYGON_MODE_FILL || + rast->fill_back != PIPE_POLYGON_MODE_FILL)) { + unfilled->face_slot = draw_alloc_extra_vertex_attrib( + stage->draw, TGSI_SEMANTIC_FACE, 0); + } else { + unfilled->face_slot = -1; + } +} + /** * Create unfilled triangle stage. |