[Mesa-dev] [PATCH] draw: fix line stippling with unfilled prims

Jose Fonseca jfonseca at vmware.com
Thu Jan 7 07:48:37 PST 2016


On 06/01/16 22:26, sroland at vmware.com wrote:
> From: Roland Scheidegger <sroland at vmware.com>
>
> The unfilled stage was not filling in the prim header, and the line stage
> then decided to reset the stipple counter or not based on the uninitialized
> data. This causes some failures in conform linestipple test (albeit quite
> randomly happening depending on environment).
> So fill in the prim header in the unfilled stage - I am not entirely sure
> if anybody really needs determinant after that stage, but there's at least
> later stages (wide line for instance) which copy over the determinant as well.
> ---
>   src/gallium/auxiliary/draw/draw_pipe_unfilled.c | 56 +++++++++++++++++--------
>   1 file changed, 38 insertions(+), 18 deletions(-)
>
> diff --git a/src/gallium/auxiliary/draw/draw_pipe_unfilled.c b/src/gallium/auxiliary/draw/draw_pipe_unfilled.c
> index 8e6435c..b9ded14 100644
> --- a/src/gallium/auxiliary/draw/draw_pipe_unfilled.c
> +++ b/src/gallium/auxiliary/draw/draw_pipe_unfilled.c
> @@ -86,27 +86,33 @@ inject_front_face_info(struct draw_stage *stage,
>   }
>
>
> -static void point( struct draw_stage *stage,
> -		   struct vertex_header *v0 )
> +static void point(struct draw_stage *stage,
> +                  struct prim_header *header,
> +                  struct vertex_header *v0)
>   {
>      struct prim_header tmp;
> +   tmp.det = header->det;
> +   tmp.flags = 0;
>      tmp.v[0] = v0;
> -   stage->next->point( stage->next, &tmp );
> +   stage->next->point(stage->next, &tmp);
>   }
>
> -static void line( struct draw_stage *stage,
> -		  struct vertex_header *v0,
> -		  struct vertex_header *v1 )
> +static void line(struct draw_stage *stage,
> +                 struct prim_header *header,
> +                 struct vertex_header *v0,
> +                 struct vertex_header *v1)
>   {
>      struct prim_header tmp;
> +   tmp.det = header->det;
> +   tmp.flags = 0;
>      tmp.v[0] = v0;
>      tmp.v[1] = v1;
> -   stage->next->line( stage->next, &tmp );
> +   stage->next->line(stage->next, &tmp);
>   }
>
>
> -static void points( struct draw_stage *stage,
> -		    struct prim_header *header )
> +static void points(struct draw_stage *stage,
> +                   struct prim_header *header)
>   {
>      struct vertex_header *v0 = header->v[0];
>      struct vertex_header *v1 = header->v[1];
> @@ -114,27 +120,41 @@ static void points( struct draw_stage *stage,
>
>      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 );
> +   if ((header->flags & DRAW_PIPE_EDGE_FLAG_0) && v0->edgeflag)
> +      point(stage, header, v0);
> +   if ((header->flags & DRAW_PIPE_EDGE_FLAG_1) && v1->edgeflag)
> +      point(stage, header, v1);
> +   if ((header->flags & DRAW_PIPE_EDGE_FLAG_2) && v2->edgeflag)
> +      point(stage, header, v2);
>   }
>
>
> -static void lines( struct draw_stage *stage,
> -		   struct prim_header *header )
> +static void lines(struct draw_stage *stage,
> +                  struct prim_header *header)
>   {
>      struct vertex_header *v0 = header->v[0];
>      struct vertex_header *v1 = header->v[1];
>      struct vertex_header *v2 = header->v[2];
>
>      if (header->flags & DRAW_PIPE_RESET_STIPPLE)
> -      stage->next->reset_stipple_counter( stage->next );
> +      /*
> +       * XXX could revisit this. The only stage which cares is the line
> +       * stipple stage. Could just emit correct reset flags here and not
> +       * bother about all the calling through reset_stipple_counter
> +       * stages. Though technically it is necessary if line stipple is
> +       * handled by the driver, but this is not actually hooked up when
> +       * using vbuf (vbuf stage reset_stipple_counter does nothing).
> +       */
> +      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 );
> +   if ((header->flags & DRAW_PIPE_EDGE_FLAG_2) && v2->edgeflag)
> +      line(stage, header, v2, v0);
> +   if ((header->flags & DRAW_PIPE_EDGE_FLAG_0) && v0->edgeflag)
> +      line(stage, header, v0, v1);
> +   if ((header->flags & DRAW_PIPE_EDGE_FLAG_1) && v1->edgeflag)
> +      line(stage, header, v1, v2);
>   }
>
>
>

LGTM.

Reviewed-by: Jose Fonseca <jfonseca at vmware.com>

But doing `git grep -A10 '\s\+struct prim_header \w\+'` highlights a few 
other potential places that need initialization of flags (and sometimes 
det):

- src/gallium/auxiliary/draw/draw_pipe_aaline.c
- src/gallium/auxiliary/draw/draw_pipe_aapoint.c
- src/gallium/auxiliary/draw/draw_pipe_clip.c:   struct prim_header newprim;
- src/gallium/auxiliary/draw/draw_pipe_wide_line.c
- src/gallium/auxiliary/draw/draw_pipe_wide_point.c



More information about the mesa-dev mailing list