From 2ff9fa8b728c5f206e19433a9d9b88eb8d97055b Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Tue, 17 Mar 2026 17:00:22 +0100 Subject: [PATCH] gallium/u_blitter: add a new fs_color_clear variant MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The referenced commit switched from a passthrough shader to fs_clear_color[write_all_cbufs=0]. It shouldn't matter since the shader isn't supposed to be executed - it's only setup to get the first color output active. On some chips (gfx8) it seems to cause issues (hangs or page fault) for some piglit tests, eg: framebuffer-blit-levels draw stencil To fix this, introduce a 3rd variant, where a constant buffer isn't required and instead the color is hardcoded in the shader. Fixes: ca09c173f6e ("gallium/u_blitter: remove UTIL_BLITTER_ATTRIB_COLOR, use a constant buffer") Reviewed-by: Marek Olšák Part-of: --- src/gallium/auxiliary/util/u_blitter.c | 41 +++++++++++++------ src/gallium/auxiliary/util/u_simple_shaders.c | 11 +++-- src/gallium/auxiliary/util/u_simple_shaders.h | 2 +- 3 files changed, 37 insertions(+), 17 deletions(-) diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c index 08e1b7e07ae..af77d1873a9 100644 --- a/src/gallium/auxiliary/util/u_blitter.c +++ b/src/gallium/auxiliary/util/u_blitter.c @@ -57,6 +57,13 @@ #define NUM_RESOLVE_FRAG_SHADERS 5 /* MSAA 2x, 4x, 8x, 16x, 32x */ #define GET_MSAA_RESOLVE_FS_IDX(nr_samples) (util_logbase2(nr_samples)-1) +enum blitter_fs_clear_color { + BLITTER_FS_CLEAR_COL_ALL_CBUF = 0, + BLITTER_FS_CLEAR_COL_ONE_CBUF, + BLITTER_FS_CLEAR_COL_ONE_CBUF_USE_CONST_BUF, + BLITTER_FS_CLEAR_COL_NUM +}; + struct blitter_context_priv { struct blitter_context base; @@ -75,7 +82,7 @@ struct blitter_context_priv /* Fragment shaders. */ void *fs_empty; - void *fs_clear_color[2]; + void *fs_clear_color[BLITTER_FS_CLEAR_COL_NUM]; /* FS which outputs a color from a texture where * the 1st index indicates the texture type / destination type, @@ -415,17 +422,21 @@ static void bind_fs_empty(struct blitter_context_priv *ctx) } static void bind_fs_clear_color(struct blitter_context_priv *ctx, - bool write_all_cbufs) + enum blitter_fs_clear_color fs) { struct pipe_context *pipe = ctx->base.pipe; - if (!ctx->fs_clear_color[write_all_cbufs]) { + if (!ctx->fs_clear_color[fs]) { assert(!ctx->cached_all_shaders); - ctx->fs_clear_color[write_all_cbufs] = - util_make_fs_clear_color(pipe, write_all_cbufs); + ctx->fs_clear_color[fs] = + util_make_fs_clear_color( + pipe, + fs == BLITTER_FS_CLEAR_COL_ALL_CBUF, + fs == BLITTER_FS_CLEAR_COL_ALL_CBUF || + fs == BLITTER_FS_CLEAR_COL_ONE_CBUF_USE_CONST_BUF); } - ctx->bind_fs_state(pipe, ctx->fs_clear_color[write_all_cbufs]); + ctx->bind_fs_state(pipe, ctx->fs_clear_color[fs]); } void util_blitter_destroy(struct blitter_context *blitter) @@ -1351,8 +1362,12 @@ void util_blitter_cache_all_shaders(struct blitter_context *blitter) ctx->fs_empty = util_make_empty_fragment_shader(pipe); - ctx->fs_clear_color[0] = util_make_fs_clear_color(pipe, false); - ctx->fs_clear_color[1] = util_make_fs_clear_color(pipe, true); + ctx->fs_clear_color[BLITTER_FS_CLEAR_COL_ONE_CBUF] = + util_make_fs_clear_color(pipe, false, false); + ctx->fs_clear_color[BLITTER_FS_CLEAR_COL_ONE_CBUF_USE_CONST_BUF] = + util_make_fs_clear_color(pipe, false, true); + ctx->fs_clear_color[BLITTER_FS_CLEAR_COL_ALL_CBUF] = + util_make_fs_clear_color(pipe, true, true); ctx->cached_all_shaders = true; } @@ -1581,7 +1596,7 @@ static void util_blitter_clear_custom(struct blitter_context *blitter, }; pipe->set_constant_buffer(pipe, MESA_SHADER_FRAGMENT, blitter->cb_slot, &cb); - bind_fs_clear_color(ctx, true); + bind_fs_clear_color(ctx, BLITTER_FS_CLEAR_COL_ALL_CBUF); } else { bind_fs_empty(ctx); } @@ -2436,7 +2451,7 @@ void util_blitter_clear_render_target(struct blitter_context *blitter, /* bind states */ pipe->bind_blend_state(pipe, ctx->blend[PIPE_MASK_RGBA][0]); pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); - bind_fs_clear_color(ctx, false); + bind_fs_clear_color(ctx, BLITTER_FS_CLEAR_COL_ONE_CBUF_USE_CONST_BUF); /* set a framebuffer state */ pipe_surface_size(dstsurf, &fb_state.width, &fb_state.height); @@ -2584,7 +2599,7 @@ void util_blitter_custom_depth_stencil(struct blitter_context *blitter, ctx->blend[0][0]); pipe->bind_depth_stencil_alpha_state(pipe, dsa_stage); if (cbsurf) - bind_fs_clear_color(ctx, false); + bind_fs_clear_color(ctx, BLITTER_FS_CLEAR_COL_ONE_CBUF); else bind_fs_empty(ctx); @@ -2638,7 +2653,7 @@ void util_blitter_custom_resolve_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); - bind_fs_clear_color(ctx, false); + bind_fs_clear_color(ctx, BLITTER_FS_CLEAR_COL_ONE_CBUF); pipe->set_sample_mask(pipe, sample_mask); if (pipe->set_min_samples) pipe->set_min_samples(pipe, 1); @@ -2699,7 +2714,7 @@ void util_blitter_custom_color(struct blitter_context *blitter, pipe->bind_blend_state(pipe, custom_blend ? custom_blend : ctx->blend[PIPE_MASK_RGBA][0]); pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); - bind_fs_clear_color(ctx, false); + bind_fs_clear_color(ctx, BLITTER_FS_CLEAR_COL_ONE_CBUF); /* set a framebuffer state */ pipe_surface_size(dstsurf, &fb_state.width, &fb_state.height); diff --git a/src/gallium/auxiliary/util/u_simple_shaders.c b/src/gallium/auxiliary/util/u_simple_shaders.c index c5337af996c..01e35cadb03 100644 --- a/src/gallium/auxiliary/util/u_simple_shaders.c +++ b/src/gallium/auxiliary/util/u_simple_shaders.c @@ -1329,19 +1329,24 @@ util_make_fs_stencil_blit(struct pipe_context *pipe, bool msaa_src, bool has_txq } void * -util_make_fs_clear_color(struct pipe_context *pipe, bool write_all_cbufs) +util_make_fs_clear_color(struct pipe_context *pipe, + bool write_all_cbufs, + bool use_const_buf) { static const char text_templ[] = "FRAG\n" "PROPERTY FS_COLOR0_WRITES_ALL_CBUFS %u\n" "DCL OUT[0], COLOR[0]\n" "DCL CONST[0][0]\n" + "IMM[0] INT32 {0, 0, 0, 0}\n" - "MOV OUT[0], CONST[0][0]\n" + "MOV OUT[0], %s\n" "END\n"; char text[1000]; - snprintf(text, ARRAY_SIZE(text), text_templ, write_all_cbufs); + snprintf(text, ARRAY_SIZE(text), text_templ, + write_all_cbufs, + use_const_buf ? "CONST[0][0]" : "IMM[0]"); struct tgsi_token tokens[1000]; struct pipe_shader_state state = { 0 }; diff --git a/src/gallium/auxiliary/util/u_simple_shaders.h b/src/gallium/auxiliary/util/u_simple_shaders.h index 76f8e92de10..7cf9b852a2e 100644 --- a/src/gallium/auxiliary/util/u_simple_shaders.h +++ b/src/gallium/auxiliary/util/u_simple_shaders.h @@ -172,7 +172,7 @@ void * util_make_fs_stencil_blit(struct pipe_context *pipe, bool msaa_src, bool has_txq); void * -util_make_fs_clear_color(struct pipe_context *pipe, bool write_all_cbufs); +util_make_fs_clear_color(struct pipe_context *pipe, bool write_all_cbufs, bool use_const_buf); #ifdef __cplusplus }