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

Samuel Pitoiset samuel.pitoiset at gmail.com
Thu Mar 23 23:50:40 UTC 2017



On 03/23/2017 08:53 PM, Marek Olšák wrote:
> NAK.
>
> I wouldn't like more overhead in cso_context when better solutions are
> available. There are several ways of dealing with texture update
> overhead:
>
> 1) Split _NEW_TEXTURE into multiple flags, each covering a disjoint
> set of states smaller than _NEW_TEXTURE.
>
> 2) Use a stage-specific flag (e.g. _NEW_VS_TEXTURE) instead of
> _NEW_TEXTURE. glBindTexture can look at current shaders to know where
> the texture is being used.
>
> 3) Threaded Gallium dispatch:
> https://cgit.freedesktop.org/~mareko/mesa/log/?h=gallium-threaded
> (missing: DISCARD_RANGE, deferred fences, bug fixes)
>
> 4) glthread

Okay, no worries about that patch because 1) and 2) look better to me, 
thanks for the pointers.

I will provide some benchmarks for that patch just for curiosity. But 
yeah, it seems like we can do a better thing in that codepath without 
adding overhead in cso.

>
> Marek
>
>
>
> On Thu, Mar 23, 2017 at 7:44 PM, Samuel Pitoiset
> <samuel.pitoiset at gmail.com> 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.
>>
>> 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;
>>  }
>>
>>
>> --
>> 2.12.0
>>
>> _______________________________________________
>> mesa-dev mailing list
>> mesa-dev at lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list