[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