[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