[Mesa-dev] [PATCH] cso: store sampler views for all shader stages

Nicolai Hähnle nhaehnle at gmail.com
Thu Mar 23 19:34:37 UTC 2017


On 23.03.2017 19:44, Samuel Pitoiset wrote:
> Sampler views were only cached for the fragment shader stage, but
> this might help other stages.
>
> This is a small opt which should help civ6 a little bit.

Do you have benchmarks? This might help if we don't manage to filter out 
redundant state changes earlier, but it might also hurt by always doing 
more work and touching more memory.

The fragment views _must_ be tracked, because we need the ability to 
save and restore them.

Cheers,
Nicolai

>
> Signed-off-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
> ---
>  src/gallium/auxiliary/cso_cache/cso_context.c | 101 ++++++++++++++------------
>  1 file changed, 55 insertions(+), 46 deletions(-)
>
> diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c
> index 3d3c44cf81..cac1b4e8a5 100644
> --- a/src/gallium/auxiliary/cso_cache/cso_context.c
> +++ b/src/gallium/auxiliary/cso_cache/cso_context.c
> @@ -61,6 +61,14 @@ struct sampler_info
>  };
>
>
> +/**
> + * Per-shader sampler view information.
> + */
> +struct view_info {
> +   struct pipe_sampler_view *views[PIPE_MAX_SHADER_SAMPLER_VIEWS];
> +   unsigned nr_views;
> +};
> +
>
>  struct cso_context {
>     struct pipe_context *pipe;
> @@ -74,11 +82,8 @@ struct cso_context {
>
>     unsigned saved_state;  /**< bitmask of CSO_BIT_x flags */
>
> -   struct pipe_sampler_view *fragment_views[PIPE_MAX_SHADER_SAMPLER_VIEWS];
> -   unsigned nr_fragment_views;
> -
> -   struct pipe_sampler_view *fragment_views_saved[PIPE_MAX_SHADER_SAMPLER_VIEWS];
> -   unsigned nr_fragment_views_saved;
> +   struct view_info fragment_views_saved;
> +   struct view_info views[PIPE_SHADER_TYPES];
>
>     struct sampler_info fragment_samplers_saved;
>     struct sampler_info samplers[PIPE_SHADER_TYPES];
> @@ -346,7 +351,7 @@ out:
>   */
>  void cso_destroy_context( struct cso_context *ctx )
>  {
> -   unsigned i;
> +   unsigned i, j;
>
>     if (ctx->pipe) {
>        ctx->pipe->set_index_buffer(ctx->pipe, NULL);
> @@ -400,9 +405,14 @@ void cso_destroy_context( struct cso_context *ctx )
>           ctx->pipe->set_stream_output_targets(ctx->pipe, 0, NULL, NULL);
>     }
>
> +   for (i = 0; i < PIPE_SHADER_TYPES; i++) {
> +      for (j = 0; j < PIPE_MAX_SHADER_SAMPLER_VIEWS; j++) {
> +         pipe_sampler_view_reference(&ctx->views[i].views[j], NULL);
> +      }
> +   }
> +
>     for (i = 0; i < PIPE_MAX_SHADER_SAMPLER_VIEWS; i++) {
> -      pipe_sampler_view_reference(&ctx->fragment_views[i], NULL);
> -      pipe_sampler_view_reference(&ctx->fragment_views_saved[i], NULL);
> +      pipe_sampler_view_reference(&ctx->fragment_views_saved.views[i], NULL);
>     }
>
>     util_unreference_framebuffer_state(&ctx->fb);
> @@ -1348,46 +1358,43 @@ cso_set_sampler_views(struct cso_context *ctx,
>                        unsigned count,
>                        struct pipe_sampler_view **views)
>  {
> -   if (shader_stage == PIPE_SHADER_FRAGMENT) {
> -      unsigned i;
> -      boolean any_change = FALSE;
> -
> -      /* reference new views */
> -      for (i = 0; i < count; i++) {
> -         any_change |= ctx->fragment_views[i] != views[i];
> -         pipe_sampler_view_reference(&ctx->fragment_views[i], views[i]);
> -      }
> -      /* unref extra old views, if any */
> -      for (; i < ctx->nr_fragment_views; i++) {
> -         any_change |= ctx->fragment_views[i] != NULL;
> -         pipe_sampler_view_reference(&ctx->fragment_views[i], NULL);
> -      }
> +   struct view_info *info = &ctx->views[shader_stage];
> +   boolean any_change = FALSE;
> +   unsigned i;
>
> -      /* bind the new sampler views */
> -      if (any_change) {
> -         ctx->pipe->set_sampler_views(ctx->pipe, shader_stage, 0,
> -                                      MAX2(ctx->nr_fragment_views, count),
> -                                      ctx->fragment_views);
> -      }
> +   /* reference new views */
> +   for (i = 0; i < count; i++) {
> +      any_change |= info->views[i] != views[i];
> +      pipe_sampler_view_reference(&info->views[i], views[i]);
> +   }
> +   /* unref extra old views, if any */
> +   for (; i < info->nr_views; i++) {
> +      any_change |= info->views[i] != NULL;
> +      pipe_sampler_view_reference(&info->views[i], NULL);
> +   }
>
> -      ctx->nr_fragment_views = count;
> +   /* bind the new sampler views */
> +   if (any_change) {
> +      ctx->pipe->set_sampler_views(ctx->pipe, shader_stage, 0,
> +                                   MAX2(info->nr_views, count), info->views);
>     }
> -   else
> -      ctx->pipe->set_sampler_views(ctx->pipe, shader_stage, 0, count, views);
> +
> +   info->nr_views = count;
>  }
>
>
>  static void
>  cso_save_fragment_sampler_views(struct cso_context *ctx)
>  {
> +   struct view_info *info = &ctx->views[PIPE_SHADER_FRAGMENT];
> +   struct view_info *saved = &ctx->fragment_views_saved;
>     unsigned i;
>
> -   ctx->nr_fragment_views_saved = ctx->nr_fragment_views;
> +   saved->nr_views = info->nr_views;
>
> -   for (i = 0; i < ctx->nr_fragment_views; i++) {
> -      assert(!ctx->fragment_views_saved[i]);
> -      pipe_sampler_view_reference(&ctx->fragment_views_saved[i],
> -                                  ctx->fragment_views[i]);
> +   for (i = 0; i < info->nr_views; i++) {
> +      assert(!saved->views[i]);
> +      pipe_sampler_view_reference(&saved->views[i], info->views[i]);
>     }
>  }
>
> @@ -1395,27 +1402,29 @@ cso_save_fragment_sampler_views(struct cso_context *ctx)
>  static void
>  cso_restore_fragment_sampler_views(struct cso_context *ctx)
>  {
> -   unsigned i, nr_saved = ctx->nr_fragment_views_saved;
> +   struct view_info *info = &ctx->views[PIPE_SHADER_FRAGMENT];
> +   struct view_info *saved = &ctx->fragment_views_saved;
> +   unsigned i, nr_saved = saved->nr_views;
>     unsigned num;
>
>     for (i = 0; i < nr_saved; i++) {
> -      pipe_sampler_view_reference(&ctx->fragment_views[i], NULL);
> +      pipe_sampler_view_reference(&info->views[i], NULL);
>        /* move the reference from one pointer to another */
> -      ctx->fragment_views[i] = ctx->fragment_views_saved[i];
> -      ctx->fragment_views_saved[i] = NULL;
> +      info->views[i] = saved->views[i];
> +      saved->views[i] = NULL;
>     }
> -   for (; i < ctx->nr_fragment_views; i++) {
> -      pipe_sampler_view_reference(&ctx->fragment_views[i], NULL);
> +   for (; i < info->nr_views; i++) {
> +      pipe_sampler_view_reference(&info->views[i], NULL);
>     }
>
> -   num = MAX2(ctx->nr_fragment_views, nr_saved);
> +   num = MAX2(info->nr_views, nr_saved);
>
>     /* bind the old/saved sampler views */
>     ctx->pipe->set_sampler_views(ctx->pipe, PIPE_SHADER_FRAGMENT, 0, num,
> -                                ctx->fragment_views);
> +                                info->views);
>
> -   ctx->nr_fragment_views = nr_saved;
> -   ctx->nr_fragment_views_saved = 0;
> +   info->nr_views = nr_saved;
> +   saved->nr_views = 0;
>  }
>
>
>


-- 
Lerne, wie die Welt wirklich ist,
Aber vergiss niemals, wie sie sein sollte.


More information about the mesa-dev mailing list