[Mesa-dev] [PATCH] draw: fix splitting of line loops (v2)

Roland Scheidegger sroland at vmware.com
Tue Oct 20 16:47:35 PDT 2015


Looks good to me - this stuff is tricky...

Reviewed-by: Roland Scheidegger <sroland at vmware.com>

Am 21.10.2015 um 01:21 schrieb Brian Paul:
> When the draw module splits long line loops, the sections are emitted
> as line strips.  But the primitive type wasn't set correctly so each
> section was being drawn as a loop, introducing extra line segments.
> 
> To fix this, we pass a new DRAW_LINE_LOOP_AS_STRIP flag to the run()
> function.  The linear/elt_run() functions have to check for this flag
> and set their primitive type accordingly.
> 
> No piglit regressions.  Fixes piglit's lineloop with -count 4097 or
> higher.
> 
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=81174
> ---
>  src/gallium/auxiliary/draw/draw_private.h                |  5 +++--
>  .../auxiliary/draw/draw_pt_fetch_shade_pipeline.c        | 16 +++++++++++++---
>  .../auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c   | 16 +++++++++++++---
>  src/gallium/auxiliary/draw/draw_pt_vsplit_tmp.h          |  3 +++
>  4 files changed, 32 insertions(+), 8 deletions(-)
> 
> diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h
> index 0ad94bb..5584c4a 100644
> --- a/src/gallium/auxiliary/draw/draw_private.h
> +++ b/src/gallium/auxiliary/draw/draw_private.h
> @@ -355,8 +355,9 @@ struct draw_vertex_info {
>  };
>  
>  /* these flags are set if the primitive is a segment of a larger one */
> -#define DRAW_SPLIT_BEFORE 0x1
> -#define DRAW_SPLIT_AFTER  0x2
> +#define DRAW_SPLIT_BEFORE        0x1
> +#define DRAW_SPLIT_AFTER         0x2
> +#define DRAW_LINE_LOOP_AS_STRIP  0x4
>  
>  struct draw_prim_info {
>     boolean linear;
> diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
> index ffec863..aa20b91 100644
> --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
> +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
> @@ -359,6 +359,16 @@ fetch_pipeline_generic(struct draw_pt_middle_end *middle,
>  }
>  
>  
> +static inline unsigned
> +prim_type(unsigned prim, unsigned flags)
> +{
> +   if (flags & DRAW_LINE_LOOP_AS_STRIP)
> +      return PIPE_PRIM_LINE_STRIP;
> +   else
> +      return prim;
> +}
> +
> +
>  static void
>  fetch_pipeline_run(struct draw_pt_middle_end *middle,
>                     const unsigned *fetch_elts,
> @@ -380,7 +390,7 @@ fetch_pipeline_run(struct draw_pt_middle_end *middle,
>     prim_info.start = 0;
>     prim_info.count = draw_count;
>     prim_info.elts = draw_elts;
> -   prim_info.prim = fpme->input_prim;
> +   prim_info.prim = prim_type(fpme->input_prim, prim_flags);
>     prim_info.flags = prim_flags;
>     prim_info.primitive_count = 1;
>     prim_info.primitive_lengths = &draw_count;
> @@ -408,7 +418,7 @@ fetch_pipeline_linear_run(struct draw_pt_middle_end *middle,
>     prim_info.start = 0;
>     prim_info.count = count;
>     prim_info.elts = NULL;
> -   prim_info.prim = fpme->input_prim;
> +   prim_info.prim = prim_type(fpme->input_prim, prim_flags);
>     prim_info.flags = prim_flags;
>     prim_info.primitive_count = 1;
>     prim_info.primitive_lengths = &count;
> @@ -439,7 +449,7 @@ fetch_pipeline_linear_run_elts(struct draw_pt_middle_end *middle,
>     prim_info.start = 0;
>     prim_info.count = draw_count;
>     prim_info.elts = draw_elts;
> -   prim_info.prim = fpme->input_prim;
> +   prim_info.prim = prim_type(fpme->input_prim, prim_flags);
>     prim_info.flags = prim_flags;
>     prim_info.primitive_count = 1;
>     prim_info.primitive_lengths = &draw_count;
> diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c
> index e42c4af..2d7569b 100644
> --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c
> +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c
> @@ -473,6 +473,16 @@ llvm_pipeline_generic(struct draw_pt_middle_end *middle,
>  }
>  
>  
> +static inline unsigned
> +prim_type(unsigned prim, unsigned flags)
> +{
> +   if (flags & DRAW_LINE_LOOP_AS_STRIP)
> +      return PIPE_PRIM_LINE_STRIP;
> +   else
> +      return prim;
> +}
> +
> +
>  static void
>  llvm_middle_end_run(struct draw_pt_middle_end *middle,
>                      const unsigned *fetch_elts,
> @@ -494,7 +504,7 @@ llvm_middle_end_run(struct draw_pt_middle_end *middle,
>     prim_info.start = 0;
>     prim_info.count = draw_count;
>     prim_info.elts = draw_elts;
> -   prim_info.prim = fpme->input_prim;
> +   prim_info.prim = prim_type(fpme->input_prim, prim_flags);
>     prim_info.flags = prim_flags;
>     prim_info.primitive_count = 1;
>     prim_info.primitive_lengths = &draw_count;
> @@ -522,7 +532,7 @@ llvm_middle_end_linear_run(struct draw_pt_middle_end *middle,
>     prim_info.start = 0;
>     prim_info.count = count;
>     prim_info.elts = NULL;
> -   prim_info.prim = fpme->input_prim;
> +   prim_info.prim = prim_type(fpme->input_prim, prim_flags);
>     prim_info.flags = prim_flags;
>     prim_info.primitive_count = 1;
>     prim_info.primitive_lengths = &count;
> @@ -552,7 +562,7 @@ llvm_middle_end_linear_run_elts(struct draw_pt_middle_end *middle,
>     prim_info.start = 0;
>     prim_info.count = draw_count;
>     prim_info.elts = draw_elts;
> -   prim_info.prim = fpme->input_prim;
> +   prim_info.prim = prim_type(fpme->input_prim, prim_flags);
>     prim_info.flags = prim_flags;
>     prim_info.primitive_count = 1;
>     prim_info.primitive_lengths = &draw_count;
> diff --git a/src/gallium/auxiliary/draw/draw_pt_vsplit_tmp.h b/src/gallium/auxiliary/draw/draw_pt_vsplit_tmp.h
> index 0afabb0..6da79b9 100644
> --- a/src/gallium/auxiliary/draw/draw_pt_vsplit_tmp.h
> +++ b/src/gallium/auxiliary/draw/draw_pt_vsplit_tmp.h
> @@ -249,6 +249,9 @@ vsplit_segment_loop_linear(struct vsplit_frontend *vsplit, unsigned flags,
>  
>     assert(icount + !!close_loop <= vsplit->segment_size);
>  
> +   /* need to draw the sections of the line loop as line strips */
> +   flags |= DRAW_LINE_LOOP_AS_STRIP;
> +
>     if (close_loop) {
>        for (nr = 0; nr < icount; nr++)
>           vsplit->fetch_elts[nr] = istart + nr;
> 



More information about the mesa-dev mailing list