[Mesa-dev] [PATCH 2/2] llvmpipe: ditch ref counting for vertex/geometry shader sampler views

Jose Fonseca jfonseca at vmware.com
Fri Jan 15 09:28:05 PST 2016


On 15/01/16 02:30, sroland at vmware.com wrote:
> From: Roland Scheidegger <sroland at vmware.com>
>
> The cleaning up was quite a performance hog (making pipe_resource_reference
> the number two in profilers on the vertex path, and 3rd overall, with its
> cousin pipe_reference_described not far behind) if there were lots
> of tiny draw calls (ipers). Now the reason was really that it was blindly
> calling this for all potential shader views (so 32 each for vs and gs) even
> though the app never touched a single one which could have been fixed,
> however I can't come up with a good reason why we refcount these. We've got
> references, of course, in the sampler views, which should be quite sufficient
> as we do all vertex and geometry shader execution fully synchronous.
> (Calling prepare_shader_sampling for all draw calls even if there were no
> changes looks quite suboptimal too, but generally we don't really expect vs/gs
> shader sampling to be used much with llvmpipe, and there's even an early exit
> if there aren't any views to avoid the "null loop" albeit it's now no longer
> always trying to loop through all 32 slots. Maybe improve another time...).
> Of course, if we manage to make vertex loads run asynchronously some day,
> we need references again, but adding that back would be the least of the
> problems...
> Also only set LP_NEW_SAMPLER_VIEW for fragment sampler views. Nothing on the
> vertex side depends on it (I suppose we'd really wanted a separate flag in
> any case).
> (Good for a 3% improvement or so in ipers under the right conditions.)
> ---
>   src/gallium/drivers/llvmpipe/lp_context.h       |  2 --
>   src/gallium/drivers/llvmpipe/lp_draw_arrays.c   |  3 --
>   src/gallium/drivers/llvmpipe/lp_state.h         |  6 ----
>   src/gallium/drivers/llvmpipe/lp_state_sampler.c | 47 +++++++------------------
>   4 files changed, 12 insertions(+), 46 deletions(-)
>
> diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h
> index 62d99bb..d4bd02d 100644
> --- a/src/gallium/drivers/llvmpipe/lp_context.h
> +++ b/src/gallium/drivers/llvmpipe/lp_context.h
> @@ -82,8 +82,6 @@ struct llvmpipe_context {
>      struct pipe_viewport_state viewports[PIPE_MAX_VIEWPORTS];
>      struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
>      struct pipe_index_buffer index_buffer;
> -   struct pipe_resource *mapped_vs_tex[PIPE_MAX_SHADER_SAMPLER_VIEWS];
> -   struct pipe_resource *mapped_gs_tex[PIPE_MAX_SHADER_SAMPLER_VIEWS];
>
>      unsigned num_samplers[PIPE_SHADER_TYPES];
>      unsigned num_sampler_views[PIPE_SHADER_TYPES];
> diff --git a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c
> index edfb204..22ef5fc 100644
> --- a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c
> +++ b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c
> @@ -149,9 +149,6 @@ llvmpipe_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
>            draw_vs_reset_so(lp->vs);
>         }
>      }
> -
> -   llvmpipe_cleanup_vertex_sampling(lp);
> -   llvmpipe_cleanup_geometry_sampling(lp);
>
>      /*
>       * TODO: Flush only when a user vertex/index buffer is present
> diff --git a/src/gallium/drivers/llvmpipe/lp_state.h b/src/gallium/drivers/llvmpipe/lp_state.h
> index 2da6caa..78918cf 100644
> --- a/src/gallium/drivers/llvmpipe/lp_state.h
> +++ b/src/gallium/drivers/llvmpipe/lp_state.h
> @@ -130,16 +130,10 @@ void
>   llvmpipe_prepare_vertex_sampling(struct llvmpipe_context *ctx,
>                                    unsigned num,
>                                    struct pipe_sampler_view **views);
> -void
> -llvmpipe_cleanup_vertex_sampling(struct llvmpipe_context *ctx);
> -
>
>   void
>   llvmpipe_prepare_geometry_sampling(struct llvmpipe_context *ctx,
>                                      unsigned num,
>                                      struct pipe_sampler_view **views);
> -void
> -llvmpipe_cleanup_geometry_sampling(struct llvmpipe_context *ctx);
> -
>
>   #endif
> diff --git a/src/gallium/drivers/llvmpipe/lp_state_sampler.c b/src/gallium/drivers/llvmpipe/lp_state_sampler.c
> index 1e05587..69af38e 100644
> --- a/src/gallium/drivers/llvmpipe/lp_state_sampler.c
> +++ b/src/gallium/drivers/llvmpipe/lp_state_sampler.c
> @@ -98,8 +98,9 @@ llvmpipe_bind_sampler_states(struct pipe_context *pipe,
>                           llvmpipe->samplers[shader],
>                           llvmpipe->num_samplers[shader]);
>      }
> -
> -   llvmpipe->dirty |= LP_NEW_SAMPLER;
> +   else {
> +      llvmpipe->dirty |= LP_NEW_SAMPLER;
> +   }
>   }
>
>
> @@ -146,8 +147,9 @@ llvmpipe_set_sampler_views(struct pipe_context *pipe,
>                                llvmpipe->sampler_views[shader],
>                                llvmpipe->num_sampler_views[shader]);
>      }
> -
> -   llvmpipe->dirty |= LP_NEW_SAMPLER_VIEW;
> +   else {
> +      llvmpipe->dirty |= LP_NEW_SAMPLER_VIEW;
> +   }
>   }
>
>
> @@ -228,8 +230,7 @@ prepare_shader_sampling(
>      struct llvmpipe_context *lp,
>      unsigned num,
>      struct pipe_sampler_view **views,
> -   unsigned shader_type,
> -   struct pipe_resource *mapped_tex[PIPE_MAX_SHADER_SAMPLER_VIEWS])
> +   unsigned shader_type)
>   {
>
>      unsigned i;
> @@ -242,7 +243,7 @@ prepare_shader_sampling(
>      if (!num)
>         return;
>
> -   for (i = 0; i < PIPE_MAX_SHADER_SAMPLER_VIEWS; i++) {
> +   for (i = 0; i < num; i++) {
>         struct pipe_sampler_view *view = i < num ? views[i] : NULL;
>
>         if (view) {
> @@ -253,11 +254,6 @@ prepare_shader_sampling(
>            unsigned first_level = 0;
>            unsigned last_level = 0;
>
> -         /* We're referencing the texture's internal data, so save a
> -          * reference to it.
> -          */
> -         pipe_resource_reference(&mapped_tex[i], tex);
> -
>            if (!lp_tex->dt) {
>               /* regular texture - setup array of mipmap level offsets */
>               struct pipe_resource *res = view->texture;
> @@ -335,47 +331,28 @@ prepare_shader_sampling(
>
>
>   /**
> - * Called during state validation when LP_NEW_SAMPLER_VIEW is set.
> + * Called whenever we're about to draw (no dirty flag, FIXME?).
>    */
>   void
>   llvmpipe_prepare_vertex_sampling(struct llvmpipe_context *lp,
>                                    unsigned num,
>                                    struct pipe_sampler_view **views)
>   {
> -   prepare_shader_sampling(lp, num, views, PIPE_SHADER_VERTEX,
> -                           lp->mapped_vs_tex);
> -}
> -
> -void
> -llvmpipe_cleanup_vertex_sampling(struct llvmpipe_context *ctx)
> -{
> -   unsigned i;
> -   for (i = 0; i < Elements(ctx->mapped_vs_tex); i++) {
> -      pipe_resource_reference(&ctx->mapped_vs_tex[i], NULL);
> -   }
> +   prepare_shader_sampling(lp, num, views, PIPE_SHADER_VERTEX);
>   }
>
>
>   /**
> - * Called during state validation when LP_NEW_SAMPLER_VIEW is set.
> + * Called whenever we're about to draw (no dirty flag, FIXME?).
>    */
>   void
>   llvmpipe_prepare_geometry_sampling(struct llvmpipe_context *lp,
>                                      unsigned num,
>                                      struct pipe_sampler_view **views)
>   {
> -   prepare_shader_sampling(lp, num, views, PIPE_SHADER_GEOMETRY,
> -                           lp->mapped_gs_tex);
> +   prepare_shader_sampling(lp, num, views, PIPE_SHADER_GEOMETRY);
>   }
>
> -void
> -llvmpipe_cleanup_geometry_sampling(struct llvmpipe_context *ctx)
> -{
> -   unsigned i;
> -   for (i = 0; i < Elements(ctx->mapped_gs_tex); i++) {
> -      pipe_resource_reference(&ctx->mapped_gs_tex[i], NULL);
> -   }
> -}
>
>   void
>   llvmpipe_init_sampler_funcs(struct llvmpipe_context *llvmpipe)
>


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


More information about the mesa-dev mailing list