[Mesa-dev] [PATCH 06/23] gallium/u_blitter: facilitate co-existence with the Draw module

Marek Olšák maraeo at gmail.com
Mon Oct 8 13:10:34 PDT 2012


I'm okay with that.

Marek

On Mon, Oct 8, 2012 at 10:05 PM, Stéphane Marchesin
<stephane.marchesin at gmail.com> wrote:
> I'd like to cherry-pick this into 9.0, any objections?
>
> Stéphane
>
>
> On Fri, Sep 14, 2012 at 10:09 AM, Marek Olšák <maraeo at gmail.com> wrote:
>> ---
>>  src/gallium/auxiliary/util/u_blitter.c |  168 +++++++++++++++++++++-----------
>>  src/gallium/auxiliary/util/u_blitter.h |    2 +
>>  2 files changed, 111 insertions(+), 59 deletions(-)
>>
>> diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c
>> index b94366b..3f0d1b1 100644
>> --- a/src/gallium/auxiliary/util/u_blitter.c
>> +++ b/src/gallium/auxiliary/util/u_blitter.c
>> @@ -122,8 +122,12 @@ struct blitter_context_priv
>>     boolean has_stream_out;
>>     boolean has_stencil_export;
>>     boolean has_texture_multisample;
>> -};
>>
>> +   /* The Draw module overrides these functions.
>> +    * Always create the blitter before Draw. */
>> +   void   (*bind_fs_state)(struct pipe_context *, void *);
>> +   void   (*delete_fs_state)(struct pipe_context *, void *);
>> +};
>>
>>  struct blitter_context *util_blitter_create(struct pipe_context *pipe)
>>  {
>> @@ -142,6 +146,9 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
>>     ctx->base.pipe = pipe;
>>     ctx->base.draw_rectangle = util_blitter_draw_rectangle;
>>
>> +   ctx->bind_fs_state = pipe->bind_fs_state;
>> +   ctx->delete_fs_state = pipe->delete_fs_state;
>> +
>>     /* init state objects for them to be considered invalid */
>>     ctx->base.saved_blend_state = INVALID_PTR;
>>     ctx->base.saved_dsa_state = INVALID_PTR;
>> @@ -321,20 +328,20 @@ void util_blitter_destroy(struct blitter_context *blitter)
>>
>>     for (i = 0; i < PIPE_MAX_TEXTURE_TYPES; i++) {
>>        if (ctx->fs_texfetch_col[i])
>> -         pipe->delete_fs_state(pipe, ctx->fs_texfetch_col[i]);
>> +         ctx->delete_fs_state(pipe, ctx->fs_texfetch_col[i]);
>>        if (ctx->fs_texfetch_depth[i])
>> -         pipe->delete_fs_state(pipe, ctx->fs_texfetch_depth[i]);
>> +         ctx->delete_fs_state(pipe, ctx->fs_texfetch_depth[i]);
>>        if (ctx->fs_texfetch_depthstencil[i])
>> -         pipe->delete_fs_state(pipe, ctx->fs_texfetch_depthstencil[i]);
>> +         ctx->delete_fs_state(pipe, ctx->fs_texfetch_depthstencil[i]);
>>        if (ctx->fs_texfetch_stencil[i])
>> -         pipe->delete_fs_state(pipe, ctx->fs_texfetch_stencil[i]);
>> +         ctx->delete_fs_state(pipe, ctx->fs_texfetch_stencil[i]);
>>     }
>>
>>     for (i = 0; i <= PIPE_MAX_COLOR_BUFS; i++) {
>>        if (ctx->fs_col[i])
>> -         pipe->delete_fs_state(pipe, ctx->fs_col[i]);
>> +         ctx->delete_fs_state(pipe, ctx->fs_col[i]);
>>        if (ctx->fs_col_int[i])
>> -         pipe->delete_fs_state(pipe, ctx->fs_col_int[i]);
>> +         ctx->delete_fs_state(pipe, ctx->fs_col_int[i]);
>>     }
>>
>>     pipe->delete_sampler_state(pipe, ctx->sampler_state);
>> @@ -431,7 +438,7 @@ static void blitter_restore_fragment_states(struct blitter_context_priv *ctx)
>>     struct pipe_context *pipe = ctx->base.pipe;
>>
>>     /* Fragment shader. */
>> -   pipe->bind_fs_state(pipe, ctx->base.saved_fs);
>> +   ctx->bind_fs_state(pipe, ctx->base.saved_fs);
>>     ctx->base.saved_fs = INVALID_PTR;
>>
>>     /* Depth, stencil, alpha. */
>> @@ -657,9 +664,8 @@ static void blitter_set_dst_dimensions(struct blitter_context_priv *ctx,
>>     ctx->dst_height = height;
>>  }
>>
>> -static INLINE
>> -void *blitter_get_fs_col(struct blitter_context_priv *ctx, unsigned num_cbufs,
>> -                         boolean int_format)
>> +static void *blitter_get_fs_col(struct blitter_context_priv *ctx,
>> +                                unsigned num_cbufs, boolean int_format)
>>  {
>>     struct pipe_context *pipe = ctx->base.pipe;
>>
>> @@ -682,32 +688,32 @@ void *blitter_get_fs_col(struct blitter_context_priv *ctx, unsigned num_cbufs,
>>     }
>>  }
>>
>> -static INLINE
>> -void *blitter_get_fs_texfetch_col(struct blitter_context_priv *ctx,
>> -                                  struct pipe_resource *tex)
>> +static void *blitter_get_fs_texfetch_col(struct blitter_context_priv *ctx,
>> +                                         enum pipe_texture_target target,
>> +                                         unsigned nr_samples)
>>  {
>>     struct pipe_context *pipe = ctx->base.pipe;
>>
>> -   assert(tex->target < PIPE_MAX_TEXTURE_TYPES);
>> +   assert(target < PIPE_MAX_TEXTURE_TYPES);
>>
>> -   if (tex->nr_samples > 1) {
>> -      void **shader = &ctx->fs_texfetch_col_msaa[tex->target];
>> +   if (nr_samples > 1) {
>> +      void **shader = &ctx->fs_texfetch_col_msaa[target];
>>
>>        /* Create the fragment shader on-demand. */
>>        if (!*shader) {
>> -         unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(tex->target,
>> -                                                       tex->nr_samples);
>> +         unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(target,
>> +                                                       nr_samples);
>>
>>           *shader = util_make_fs_blit_msaa_color(pipe, tgsi_tex);
>>        }
>>
>>        return *shader;
>>     } else {
>> -      void **shader = &ctx->fs_texfetch_col[tex->target];
>> +      void **shader = &ctx->fs_texfetch_col[target];
>>
>>        /* Create the fragment shader on-demand. */
>>        if (!*shader) {
>> -         unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(tex->target, 0);
>> +         unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(target, 0);
>>
>>           *shader =
>>              util_make_fragment_tex_shader(pipe, tgsi_tex,
>> @@ -720,19 +726,20 @@ void *blitter_get_fs_texfetch_col(struct blitter_context_priv *ctx,
>>
>>  static INLINE
>>  void *blitter_get_fs_texfetch_depth(struct blitter_context_priv *ctx,
>> -                                    struct pipe_resource *tex)
>> +                                    enum pipe_texture_target target,
>> +                                    unsigned nr_samples)
>>  {
>>     struct pipe_context *pipe = ctx->base.pipe;
>>
>> -   assert(tex->target < PIPE_MAX_TEXTURE_TYPES);
>> +   assert(target < PIPE_MAX_TEXTURE_TYPES);
>>
>> -   if (tex->nr_samples > 1) {
>> -      void **shader = &ctx->fs_texfetch_depth_msaa[tex->target];
>> +   if (nr_samples > 1) {
>> +      void **shader = &ctx->fs_texfetch_depth_msaa[target];
>>
>>        /* Create the fragment shader on-demand. */
>>        if (!*shader) {
>> -         unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(tex->target,
>> -                                                       tex->nr_samples);
>> +         unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(target,
>> +                                                       nr_samples);
>>
>>           *shader =
>>              util_make_fs_blit_msaa_depth(pipe, tgsi_tex);
>> @@ -740,11 +747,11 @@ void *blitter_get_fs_texfetch_depth(struct blitter_context_priv *ctx,
>>
>>        return *shader;
>>     } else {
>> -      void **shader = &ctx->fs_texfetch_depth[tex->target];
>> +      void **shader = &ctx->fs_texfetch_depth[target];
>>
>>        /* Create the fragment shader on-demand. */
>>        if (!*shader) {
>> -         unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(tex->target, 0);
>> +         unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(target, 0);
>>
>>           *shader =
>>              util_make_fragment_tex_shader_writedepth(pipe, tgsi_tex,
>> @@ -757,19 +764,20 @@ void *blitter_get_fs_texfetch_depth(struct blitter_context_priv *ctx,
>>
>>  static INLINE
>>  void *blitter_get_fs_texfetch_depthstencil(struct blitter_context_priv *ctx,
>> -                                           struct pipe_resource *tex)
>> +                                           enum pipe_texture_target target,
>> +                                           unsigned nr_samples)
>>  {
>>     struct pipe_context *pipe = ctx->base.pipe;
>>
>> -   assert(tex->target < PIPE_MAX_TEXTURE_TYPES);
>> +   assert(target < PIPE_MAX_TEXTURE_TYPES);
>>
>> -   if (tex->nr_samples > 1) {
>> -      void **shader = &ctx->fs_texfetch_depthstencil_msaa[tex->target];
>> +   if (nr_samples > 1) {
>> +      void **shader = &ctx->fs_texfetch_depthstencil_msaa[target];
>>
>>        /* Create the fragment shader on-demand. */
>>        if (!*shader) {
>> -         unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(tex->target,
>> -                                                       tex->nr_samples);
>> +         unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(target,
>> +                                                       nr_samples);
>>
>>           *shader =
>>              util_make_fs_blit_msaa_depthstencil(pipe, tgsi_tex);
>> @@ -777,11 +785,11 @@ void *blitter_get_fs_texfetch_depthstencil(struct blitter_context_priv *ctx,
>>
>>        return *shader;
>>     } else {
>> -      void **shader = &ctx->fs_texfetch_depthstencil[tex->target];
>> +      void **shader = &ctx->fs_texfetch_depthstencil[target];
>>
>>        /* Create the fragment shader on-demand. */
>>        if (!*shader) {
>> -         unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(tex->target, 0);
>> +         unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(target, 0);
>>
>>           *shader =
>>              util_make_fragment_tex_shader_writedepthstencil(pipe, tgsi_tex,
>> @@ -794,19 +802,20 @@ void *blitter_get_fs_texfetch_depthstencil(struct blitter_context_priv *ctx,
>>
>>  static INLINE
>>  void *blitter_get_fs_texfetch_stencil(struct blitter_context_priv *ctx,
>> -                                      struct pipe_resource *tex)
>> +                                      enum pipe_texture_target target,
>> +                                      unsigned nr_samples)
>>  {
>>     struct pipe_context *pipe = ctx->base.pipe;
>>
>> -   assert(tex->target < PIPE_MAX_TEXTURE_TYPES);
>> +   assert(target < PIPE_MAX_TEXTURE_TYPES);
>>
>> -   if (tex->nr_samples > 1) {
>> -      void **shader = &ctx->fs_texfetch_stencil_msaa[tex->target];
>> +   if (nr_samples > 1) {
>> +      void **shader = &ctx->fs_texfetch_stencil_msaa[target];
>>
>>        /* Create the fragment shader on-demand. */
>>        if (!*shader) {
>> -         unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(tex->target,
>> -                                                       tex->nr_samples);
>> +         unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(target,
>> +                                                       nr_samples);
>>
>>           *shader =
>>              util_make_fs_blit_msaa_stencil(pipe, tgsi_tex);
>> @@ -814,11 +823,11 @@ void *blitter_get_fs_texfetch_stencil(struct blitter_context_priv *ctx,
>>
>>        return *shader;
>>     } else {
>> -      void **shader = &ctx->fs_texfetch_stencil[tex->target];
>> +      void **shader = &ctx->fs_texfetch_stencil[target];
>>
>>        /* Create the fragment shader on-demand. */
>>        if (!*shader) {
>> -         unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(tex->target, 0);
>> +         unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(target, 0);
>>
>>           *shader =
>>              util_make_fragment_tex_shader_writestencil(pipe, tgsi_tex,
>> @@ -829,6 +838,43 @@ void *blitter_get_fs_texfetch_stencil(struct blitter_context_priv *ctx,
>>     }
>>  }
>>
>> +void util_blitter_cache_all_shaders(struct blitter_context *blitter)
>> +{
>> +   struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
>> +   struct pipe_screen *screen = blitter->pipe->screen;
>> +   unsigned num_cbufs, i, target, max_samples;
>> +   boolean has_arraytex;
>> +
>> +   num_cbufs = MAX2(screen->get_param(screen,
>> +                                      PIPE_CAP_MAX_RENDER_TARGETS), 1);
>> +   max_samples = ctx->has_texture_multisample ? 2 : 1;
>> +   has_arraytex = screen->get_param(screen,
>> +                                    PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS) != 0;
>> +
>> +   for (i = 0; i < num_cbufs; i++) {
>> +      blitter_get_fs_col(ctx, i, FALSE);
>> +      blitter_get_fs_col(ctx, i, TRUE);
>> +   }
>> +
>> +   /* It only matters if i <= 1 or > 1. */
>> +   for (i = 1; i <= max_samples; i++) {
>> +      for (target = PIPE_TEXTURE_1D; target < PIPE_MAX_TEXTURE_TYPES; target++) {
>> +         if (!has_arraytex &&
>> +             (target == PIPE_TEXTURE_1D_ARRAY ||
>> +              target == PIPE_TEXTURE_2D_ARRAY)) {
>> +            continue;
>> +         }
>> +
>> +         blitter_get_fs_texfetch_col(ctx, target, i);
>> +         blitter_get_fs_texfetch_depth(ctx, target, i);
>> +         if (ctx->has_stencil_export) {
>> +            blitter_get_fs_texfetch_depthstencil(ctx, target, i);
>> +            blitter_get_fs_texfetch_stencil(ctx, target, i);
>> +         }
>> +      }
>> +   }
>> +}
>> +
>>  static void blitter_set_common_draw_rect_state(struct blitter_context_priv *ctx)
>>  {
>>     struct pipe_context *pipe = ctx->base.pipe;
>> @@ -933,7 +979,7 @@ static void util_blitter_clear_custom(struct blitter_context *blitter,
>>     } else {
>>        pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
>>     }
>> -   pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, num_cbufs, int_format));
>> +   ctx->bind_fs_state(pipe, blitter_get_fs_col(ctx, num_cbufs, int_format));
>>     pipe->set_sample_mask(pipe, ~0);
>>
>>     blitter_set_common_draw_rect_state(ctx);
>> @@ -1177,18 +1223,21 @@ void util_blitter_copy_texture_view(struct blitter_context *blitter,
>>        if (blit_depth && blit_stencil) {
>>           pipe->bind_depth_stencil_alpha_state(pipe,
>>                                                ctx->dsa_write_depth_stencil);
>> -         pipe->bind_fs_state(pipe,
>> -               blitter_get_fs_texfetch_depthstencil(ctx, src->texture));
>> +         ctx->bind_fs_state(pipe,
>> +               blitter_get_fs_texfetch_depthstencil(ctx, src->texture->target,
>> +                                                    src->texture->nr_samples));
>>        } else if (blit_depth) {
>>           pipe->bind_depth_stencil_alpha_state(pipe,
>>                                                ctx->dsa_write_depth_keep_stencil);
>> -         pipe->bind_fs_state(pipe,
>> -               blitter_get_fs_texfetch_depth(ctx, src->texture));
>> +         ctx->bind_fs_state(pipe,
>> +               blitter_get_fs_texfetch_depth(ctx, src->texture->target,
>> +                                             src->texture->nr_samples));
>>        } else { /* is_stencil */
>>           pipe->bind_depth_stencil_alpha_state(pipe,
>>                                                ctx->dsa_keep_depth_write_stencil);
>> -         pipe->bind_fs_state(pipe,
>> -               blitter_get_fs_texfetch_stencil(ctx, src->texture));
>> +         ctx->bind_fs_state(pipe,
>> +               blitter_get_fs_texfetch_stencil(ctx, src->texture->target,
>> +                                               src->texture->nr_samples));
>>        }
>>
>>        fb_state.nr_cbufs = 0;
>> @@ -1196,8 +1245,9 @@ void util_blitter_copy_texture_view(struct blitter_context *blitter,
>>     } else {
>>        pipe->bind_blend_state(pipe, ctx->blend_write_color);
>>        pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
>> -      pipe->bind_fs_state(pipe,
>> -            blitter_get_fs_texfetch_col(ctx, src->texture));
>> +      ctx->bind_fs_state(pipe,
>> +            blitter_get_fs_texfetch_col(ctx, src->texture->target,
>> +                                        src->texture->nr_samples));
>>
>>        fb_state.nr_cbufs = 1;
>>        fb_state.cbufs[0] = dst;
>> @@ -1306,7 +1356,7 @@ void util_blitter_clear_render_target(struct blitter_context *blitter,
>>     /* bind states */
>>     pipe->bind_blend_state(pipe, ctx->blend_write_color);
>>     pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
>> -   pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, 1, FALSE));
>> +   ctx->bind_fs_state(pipe, blitter_get_fs_col(ctx, 1, FALSE));
>>     pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
>>
>>     /* set a framebuffer state */
>> @@ -1372,7 +1422,7 @@ void util_blitter_clear_depth_stencil(struct blitter_context *blitter,
>>        /* hmm that should be illegal probably, or make it a no-op somewhere */
>>        pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
>>
>> -   pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, 0, FALSE));
>> +   ctx->bind_fs_state(pipe, blitter_get_fs_col(ctx, 0, FALSE));
>>     pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
>>
>>     /* set a framebuffer state */
>> @@ -1419,7 +1469,7 @@ void util_blitter_custom_depth_stencil(struct blitter_context *blitter,
>>     /* bind states */
>>     pipe->bind_blend_state(pipe, ctx->blend_write_color);
>>     pipe->bind_depth_stencil_alpha_state(pipe, dsa_stage);
>> -   pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, 0, FALSE));
>> +   ctx->bind_fs_state(pipe, blitter_get_fs_col(ctx, 0, FALSE));
>>     pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
>>
>>     /* set a framebuffer state */
>> @@ -1531,7 +1581,7 @@ void util_blitter_custom_resolve_color(struct blitter_context *blitter,
>>     pipe->bind_blend_state(pipe, custom_blend);
>>     pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
>>     pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
>> -   pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, 1, FALSE));
>> +   ctx->bind_fs_state(pipe, blitter_get_fs_col(ctx, 1, FALSE));
>>     pipe->set_sample_mask(pipe, sample_mask);
>>
>>     memset(&surf_tmpl, 0, sizeof(surf_tmpl));
>> @@ -1592,7 +1642,7 @@ void util_blitter_custom_color(struct blitter_context *blitter,
>>     /* bind states */
>>     pipe->bind_blend_state(pipe, custom_blend);
>>     pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
>> -   pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, 1, FALSE));
>> +   ctx->bind_fs_state(pipe, blitter_get_fs_col(ctx, 1, FALSE));
>>     pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
>>     pipe->set_sample_mask(pipe, (1ull << MAX2(1, dstsurf->texture->nr_samples)) - 1);
>>
>> diff --git a/src/gallium/auxiliary/util/u_blitter.h b/src/gallium/auxiliary/util/u_blitter.h
>> index 6804073..d458f69 100644
>> --- a/src/gallium/auxiliary/util/u_blitter.h
>> +++ b/src/gallium/auxiliary/util/u_blitter.h
>> @@ -120,6 +120,8 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe);
>>   */
>>  void util_blitter_destroy(struct blitter_context *blitter);
>>
>> +void util_blitter_cache_all_shaders(struct blitter_context *blitter);
>> +
>>  /**
>>   * Return the pipe context associated with a blitter context.
>>   */
>> --
>> 1.7.9.5
>>
>> _______________________________________________
>> mesa-dev mailing list
>> mesa-dev at lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list