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 <mar...@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@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev