I'm okay with that. Marek
On Mon, Oct 8, 2012 at 10:05 PM, Stéphane Marchesin <stephane.marche...@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 <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