[Mesa-dev] [PATCH] draw: don't clear the so targets until we stream out

Roland Scheidegger sroland at vmware.com
Thu Jun 13 16:37:58 PDT 2013


Am 14.06.2013 00:04, schrieb Zack Rusin:
> Since draw auto fetches the count from the buffers, we can't
> just clear them on bind, we need to wait until the actual
> stream out is performed. Otherwise the count for draw auto
> will be zero. Plus is cleaner to have draw do it rather
> than drivers having to mess with draw's internals.
> 
> Signed-off-by: Zack Rusin <zackr at vmware.com>
> ---
>  src/gallium/auxiliary/draw/draw_context.c     |    4 +++-
>  src/gallium/auxiliary/draw/draw_context.h     |    3 ++-
>  src/gallium/auxiliary/draw/draw_private.h     |    1 +
>  src/gallium/auxiliary/draw/draw_pt_so_emit.c  |   20 ++++++++++++++++++++
>  src/gallium/drivers/llvmpipe/lp_context.h     |    1 +
>  src/gallium/drivers/llvmpipe/lp_draw_arrays.c |    4 ++--
>  src/gallium/drivers/llvmpipe/lp_state_so.c    |    8 ++------
>  src/gallium/drivers/softpipe/sp_context.h     |    1 +
>  src/gallium/drivers/softpipe/sp_draw_arrays.c |    4 ++--
>  src/gallium/drivers/softpipe/sp_state_so.c    |    1 +
>  10 files changed, 35 insertions(+), 12 deletions(-)
> 
> diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c
> index 4a08765..f463739 100644
> --- a/src/gallium/auxiliary/draw/draw_context.c
> +++ b/src/gallium/auxiliary/draw/draw_context.c
> @@ -810,7 +810,8 @@ draw_get_rasterizer_no_cull( struct draw_context *draw,
>  void
>  draw_set_mapped_so_targets(struct draw_context *draw,
>                             int num_targets,
> -                           struct draw_so_target *targets[PIPE_MAX_SO_BUFFERS])
> +                           struct draw_so_target *targets[PIPE_MAX_SO_BUFFERS],
> +                           unsigned append_bitmask)
>  {
>     int i;
>  
> @@ -820,6 +821,7 @@ draw_set_mapped_so_targets(struct draw_context *draw,
>        draw->so.targets[i] = NULL;
>  
>     draw->so.num_targets = num_targets;
> +   draw->so.append_bitmask = append_bitmask;
>  }
>  
>  void
> diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h
> index 4a1b27e..ae63068 100644
> --- a/src/gallium/auxiliary/draw/draw_context.h
> +++ b/src/gallium/auxiliary/draw/draw_context.h
> @@ -231,7 +231,8 @@ draw_set_mapped_constant_buffer(struct draw_context *draw,
>  void
>  draw_set_mapped_so_targets(struct draw_context *draw,
>                             int num_targets,
> -                           struct draw_so_target *targets[PIPE_MAX_SO_BUFFERS]);
> +                           struct draw_so_target *targets[PIPE_MAX_SO_BUFFERS],
> +                           unsigned append_bitmask);
>  
>  
>  /***********************************************************************
> diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h
> index fd52c2d..4dda90e 100644
> --- a/src/gallium/auxiliary/draw/draw_private.h
> +++ b/src/gallium/auxiliary/draw/draw_private.h
> @@ -290,6 +290,7 @@ struct draw_context
>     struct {
>        struct draw_so_target *targets[PIPE_MAX_SO_BUFFERS];
>        uint num_targets;
> +      uint append_bitmask;
>     } so;
>  
>     /* Clip derived state:
> diff --git a/src/gallium/auxiliary/draw/draw_pt_so_emit.c b/src/gallium/auxiliary/draw/draw_pt_so_emit.c
> index d624a99..785aa34 100644
> --- a/src/gallium/auxiliary/draw/draw_pt_so_emit.c
> +++ b/src/gallium/auxiliary/draw/draw_pt_so_emit.c
> @@ -77,6 +77,24 @@ draw_has_so(const struct draw_context *draw)
>     return FALSE;
>  }
>  
> +static void
> +clean_so_buffers(struct pt_so_emit *emit)
> +{
> +   struct draw_context *draw = emit->draw;
> +   unsigned i;
> +
> +   debug_assert(emit->has_so);
> +
> +   for (i = 0; i < draw->so.num_targets; i++) {
> +      /* if we're not appending then lets reset the internal
> +         data of our so target */
> +      if (!(draw->so.append_bitmask & (1 << i)) && draw->so.targets[i]) {
> +         draw->so.targets[i]->internal_offset = 0;
> +         draw->so.targets[i]->emitted_vertices = 0;
> +      }
> +   }
> +}
> +
>  void draw_pt_so_emit_prepare(struct pt_so_emit *emit, boolean use_pre_clip_pos)
>  {
>     struct draw_context *draw = emit->draw;
> @@ -257,6 +275,8 @@ void draw_pt_so_emit( struct pt_so_emit *emit,
>     if (!draw->so.num_targets)
>        return;
>  
> +   clean_so_buffers(emit);
> +
>     emit->emitted_vertices = 0;
>     emit->emitted_primitives = 0;
>     emit->generated_primitives = 0;
> diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h
> index abfe852..0515968 100644
> --- a/src/gallium/drivers/llvmpipe/lp_context.h
> +++ b/src/gallium/drivers/llvmpipe/lp_context.h
> @@ -91,6 +91,7 @@ struct llvmpipe_context {
>  
>     struct draw_so_target *so_targets[PIPE_MAX_SO_BUFFERS];
>     int num_so_targets;
> +   unsigned so_append_bitmask;
>     struct pipe_query_data_so_statistics so_stats;
>     unsigned num_primitives_generated;
>  
> diff --git a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c
> index 4e23904..11b665a 100644
> --- a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c
> +++ b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c
> @@ -104,7 +104,7 @@ llvmpipe_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
>        }
>     }
>     draw_set_mapped_so_targets(draw, lp->num_so_targets,
> -                              lp->so_targets);
> +                              lp->so_targets, lp->so_append_bitmask);
>  
>     llvmpipe_prepare_vertex_sampling(lp,
>                                      lp->num_sampler_views[PIPE_SHADER_VERTEX],
> @@ -134,7 +134,7 @@ llvmpipe_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
>     if (mapped_indices) {
>        draw_set_indexes(draw, NULL, 0, 0);
>     }
> -   draw_set_mapped_so_targets(draw, 0, NULL);
> +   draw_set_mapped_so_targets(draw, 0, NULL, 0);
>  
>     if (lp->gs && !lp->gs->shader.tokens) {
>        /* we have attached stream output to the vs for rendering,
> diff --git a/src/gallium/drivers/llvmpipe/lp_state_so.c b/src/gallium/drivers/llvmpipe/lp_state_so.c
> index fa58f79..c20ff26 100644
> --- a/src/gallium/drivers/llvmpipe/lp_state_so.c
> +++ b/src/gallium/drivers/llvmpipe/lp_state_so.c
> @@ -70,17 +70,13 @@ llvmpipe_set_so_targets(struct pipe_context *pipe,
>     int i;
>     for (i = 0; i < num_targets; i++) {
>        pipe_so_target_reference((struct pipe_stream_output_target **)&llvmpipe->so_targets[i], targets[i]);
> -      /* if we're not appending then lets reset the internal
> -         data of our so target */
> -      if (!(append_bitmask & (1 << i)) && llvmpipe->so_targets[i]) {
> -         llvmpipe->so_targets[i]->internal_offset = 0;
> -         llvmpipe->so_targets[i]->emitted_vertices = 0;
> -      }
>     }
>  
>     for (; i < llvmpipe->num_so_targets; i++) {
>        pipe_so_target_reference((struct pipe_stream_output_target **)&llvmpipe->so_targets[i], NULL);
>     }
> +
> +   llvmpipe->so_append_bitmask = append_bitmask;
>     llvmpipe->num_so_targets = num_targets;
>  }
>  
> diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h
> index 431864a..ea6c0f9 100644
> --- a/src/gallium/drivers/softpipe/sp_context.h
> +++ b/src/gallium/drivers/softpipe/sp_context.h
> @@ -88,6 +88,7 @@ struct softpipe_context {
>  
>     struct draw_so_target *so_targets[PIPE_MAX_SO_BUFFERS];
>     unsigned num_so_targets;
> +   unsigned so_append_bitmask;
>     
>     struct pipe_query_data_so_statistics so_stats;
>     unsigned num_primitives_generated;
> diff --git a/src/gallium/drivers/softpipe/sp_draw_arrays.c b/src/gallium/drivers/softpipe/sp_draw_arrays.c
> index 45b1390..cde4d51 100644
> --- a/src/gallium/drivers/softpipe/sp_draw_arrays.c
> +++ b/src/gallium/drivers/softpipe/sp_draw_arrays.c
> @@ -112,7 +112,7 @@ softpipe_draw_vbo(struct pipe_context *pipe,
>     }
>  
>     draw_set_mapped_so_targets(draw, sp->num_so_targets,
> -                              sp->so_targets);
> +                              sp->so_targets, sp->so_append_bitmask);
>  
>     if (sp->gs && !sp->gs->shader.tokens) {
>        /* we have an empty geometry shader with stream output, so
> @@ -135,7 +135,7 @@ softpipe_draw_vbo(struct pipe_context *pipe,
>        draw_set_indexes(draw, NULL, 0, 0);
>     }
>  
> -   draw_set_mapped_so_targets(draw, 0, NULL);
> +   draw_set_mapped_so_targets(draw, 0, NULL, 0);
>  
>     /*
>      * TODO: Flush only when a user vertex/index buffer is present
> diff --git a/src/gallium/drivers/softpipe/sp_state_so.c b/src/gallium/drivers/softpipe/sp_state_so.c
> index 3682c6c..96bb6b1 100644
> --- a/src/gallium/drivers/softpipe/sp_state_so.c
> +++ b/src/gallium/drivers/softpipe/sp_state_so.c
> @@ -77,6 +77,7 @@ softpipe_set_so_targets(struct pipe_context *pipe,
>     }
>  
>     softpipe->num_so_targets = num_targets;
> +   softpipe->so_append_bitmask = append_bitmask;
>  }
>  
>  void
> 

Reviewed-by: Roland Scheidegger <sroland at vmware.com>
Though I find stream output very confusing...

Roland


More information about the mesa-dev mailing list