From 38ab178c4addb1e45a61d7fc7aa00f0d5254f5f6 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Tue, 26 Apr 2022 08:32:54 -0400 Subject: [PATCH] util/blitter: fix sampler restore with 0 saved samplers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit in a sequence where a driver saves 0 sampler/views before calling u_blitter, the previous state of having 0 sampler/views bound would not be restored as expected, resulting in stale sampler/views which could affect behavior before new sampler/views were bound cc: mesa-stable Reviewed-by: Marek Olšák Part-of: --- src/gallium/auxiliary/util/u_blitter.c | 41 +++++++++++++++++++------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c index aa10cec7706..bea898edcae 100644 --- a/src/gallium/auxiliary/util/u_blitter.c +++ b/src/gallium/auxiliary/util/u_blitter.c @@ -778,23 +778,35 @@ static void blitter_check_saved_textures(ASSERTED struct blitter_context_priv *c assert(ctx->base.saved_num_sampler_views != ~0u); } -void util_blitter_restore_textures(struct blitter_context *blitter) +static void util_blitter_restore_textures_internal(struct blitter_context *blitter, unsigned count) { struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; struct pipe_context *pipe = ctx->base.pipe; unsigned i; /* Fragment sampler states. */ - pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT, 0, - ctx->base.saved_num_sampler_states, - ctx->base.saved_sampler_states); + void *states[2] = {NULL}; + assert(count <= ARRAY_SIZE(states)); + if (ctx->base.saved_num_sampler_states) + pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT, 0, + ctx->base.saved_num_sampler_states, + ctx->base.saved_sampler_states); + else if (count) + pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT, 0, + count, + states); ctx->base.saved_num_sampler_states = ~0; /* Fragment sampler views. */ - pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, - ctx->base.saved_num_sampler_views, 0, true, - ctx->base.saved_sampler_views); + if (ctx->base.saved_num_sampler_views) + pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, + ctx->base.saved_num_sampler_views, 0, true, + ctx->base.saved_sampler_views); + else if (count) + pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, + 0, count, true, + NULL); /* Just clear them to NULL because set_sampler_views(take_ownership = true). */ for (i = 0; i < ctx->base.saved_num_sampler_views; i++) @@ -803,6 +815,11 @@ void util_blitter_restore_textures(struct blitter_context *blitter) ctx->base.saved_num_sampler_views = ~0; } +void util_blitter_restore_textures(struct blitter_context *blitter) +{ + util_blitter_restore_textures_internal(blitter, 0); +} + void util_blitter_restore_constant_buffer_state(struct blitter_context *blitter) { struct pipe_context *pipe = blitter->pipe; @@ -2136,6 +2153,7 @@ void util_blitter_blit_generic(struct blitter_context *blitter, } /* Set samplers. */ + unsigned count = 0; if (src_has_depth && src_has_stencil && (dst_has_color || (dst_has_depth && dst_has_stencil))) { /* Setup two samplers, one for depth and the other one for stencil. */ @@ -2150,6 +2168,7 @@ void util_blitter_blit_generic(struct blitter_context *blitter, views[0] = src; views[1] = pipe->create_sampler_view(pipe, src->texture, &templ); + count = 2; pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 2, 0, false, views); pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT, 0, 2, samplers); @@ -2165,12 +2184,14 @@ void util_blitter_blit_generic(struct blitter_context *blitter, view = pipe->create_sampler_view(pipe, src->texture, &templ); + count = 1; pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 1, 0, false, &view); pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT, 0, 1, &sampler_state); pipe_sampler_view_reference(&view, NULL); } else { + count = 1; pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 1, 0, false, &src); pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT, 0, 1, &sampler_state); @@ -2187,7 +2208,7 @@ void util_blitter_blit_generic(struct blitter_context *blitter, util_blitter_restore_vertex_states(blitter); util_blitter_restore_fragment_states(blitter); - util_blitter_restore_textures(blitter); + util_blitter_restore_textures_internal(blitter, count); util_blitter_restore_fb_state(blitter); if (scissor) { pipe->set_scissor_states(pipe, 0, 1, &ctx->base.saved_scissor); @@ -2329,7 +2350,7 @@ void util_blitter_generate_mipmap(struct blitter_context *blitter, util_blitter_restore_vertex_states(blitter); util_blitter_restore_fragment_states(blitter); - util_blitter_restore_textures(blitter); + util_blitter_restore_textures_internal(blitter, 1); util_blitter_restore_fb_state(blitter); util_blitter_restore_render_cond(blitter); util_blitter_unset_running_flag(blitter); @@ -3008,7 +3029,7 @@ util_blitter_stencil_fallback(struct blitter_context *blitter, util_blitter_restore_vertex_states(blitter); util_blitter_restore_fragment_states(blitter); - util_blitter_restore_textures(blitter); + util_blitter_restore_textures_internal(blitter, 1); util_blitter_restore_fb_state(blitter); util_blitter_restore_render_cond(blitter); util_blitter_restore_constant_buffer_state(blitter);