aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium/auxiliary/draw/draw_pipe_unfilled.c
diff options
context:
space:
mode:
authorZack Rusin <[email protected]>2013-07-31 07:34:49 -0400
committerZack Rusin <[email protected]>2013-08-02 20:11:18 -0400
commitd6b3a193d4d525c5048ebf793e6a63fd98f92d64 (patch)
tree03fa602befb47cfa29efad7bc1c85e1ec645e92a /src/gallium/auxiliary/draw/draw_pipe_unfilled.c
parent05487ef88ded5fea0b1de7bc08d44846648d1ce2 (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.c49
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.