From 7ea7d0687b87d8612e64ed5cc2fb09b2a9f4c60e Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Wed, 13 Jul 2022 12:17:29 -0400 Subject: [PATCH] zink: inject a 0,0,0,1 clear for RGBX formats this ensures the alpha component is full if it must be read for fbfetch fixes (RGBX swapchain config): KHR-GL46.blend_equation_advanced* Acked-by: Dave Airlie Part-of: --- src/gallium/drivers/zink/zink_clear.c | 21 ++++++++++++++++++++- src/gallium/drivers/zink/zink_context.c | 14 +++++++++++++- src/gallium/drivers/zink/zink_context.h | 1 + 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/gallium/drivers/zink/zink_clear.c b/src/gallium/drivers/zink/zink_clear.c index db53600774e..26ba2c1da8e 100644 --- a/src/gallium/drivers/zink/zink_clear.c +++ b/src/gallium/drivers/zink/zink_clear.c @@ -215,9 +215,19 @@ zink_clear(struct pipe_context *pctx, unsigned clear_buffers = buffers >> 2; for (unsigned i = 0; i < ctx->fb_state.nr_cbufs; i++) { if (ctx->fb_state.cbufs[i] && - (ctx->fb_layer_mismatch & clear_buffers & BITFIELD_BIT(i))) + (ctx->fb_layer_mismatch & clear_buffers & BITFIELD_BIT(i))) { + if (ctx->void_clears & (PIPE_CLEAR_COLOR0 << i)) { + union pipe_color_union color; + color.f[0] = color.f[1] = color.f[2] = 0; + color.f[3] = 1.0; + pctx->clear_render_target(pctx, ctx->fb_state.cbufs[i], &color, + 0, 0, + ctx->fb_state.cbufs[i]->width, ctx->fb_state.cbufs[i]->height, + ctx->render_condition_active); + } pctx->clear_render_target(pctx, ctx->fb_state.cbufs[i], pcolor, x, y, w, h, ctx->render_condition_active); + } } if (ctx->fb_state.zsbuf && (buffers & PIPE_CLEAR_DEPTHSTENCIL)) pctx->clear_depth_stencil(pctx, ctx->fb_state.zsbuf, buffers & PIPE_CLEAR_DEPTHSTENCIL, depth, stencil, @@ -229,6 +239,15 @@ zink_clear(struct pipe_context *pctx, return; } + if (ctx->void_clears & buffers) { + unsigned void_clears = ctx->void_clears & buffers; + ctx->void_clears &= ~buffers; + union pipe_color_union color; + color.f[0] = color.f[1] = color.f[2] = 0; + color.f[3] = 1.0; + pctx->clear(pctx, void_clears, NULL, &color, 0, 0); + } + if (buffers & PIPE_CLEAR_COLOR) { for (unsigned i = 0; i < fb->nr_cbufs; i++) { if ((buffers & (PIPE_CLEAR_COLOR0 << i)) && fb->cbufs[i]) { diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index 45ab6f7267b..145c0d93a43 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -2287,6 +2287,13 @@ zink_batch_rp(struct zink_context *ctx) { if (ctx->batch.in_rp) return; + if (!ctx->batch.in_rp && ctx->void_clears) { + union pipe_color_union color; + color.f[0] = color.f[1] = color.f[2] = 0; + color.f[3] = 1.0; + ctx->base.clear(&ctx->base, ctx->void_clears, NULL, &color, 0, 0); + ctx->void_clears = 0; + } unsigned clear_buffers; /* use renderpass for multisample-to-singlesample or fbfetch: * - msrtss is TODO @@ -2757,6 +2764,7 @@ zink_set_framebuffer_state(struct pipe_context *pctx, ctx->dynamic_fb.info.layerCount = layers; ctx->gfx_pipeline_state.rendering_info.colorAttachmentCount = ctx->fb_state.nr_cbufs; + ctx->void_clears = 0; for (int i = 0; i < ctx->fb_state.nr_cbufs; i++) { struct pipe_surface *psurf = ctx->fb_state.cbufs[i]; if (psurf) { @@ -2784,7 +2792,11 @@ zink_set_framebuffer_state(struct pipe_context *pctx, } } res->fb_binds++; - ctx->gfx_pipeline_state.void_alpha_attachments |= util_format_has_alpha1(psurf->format) ? BITFIELD_BIT(i) : 0; + if (util_format_has_alpha1(psurf->format)) { + ctx->gfx_pipeline_state.void_alpha_attachments |= BITFIELD_BIT(i); + if (!res->valid) + ctx->void_clears |= (PIPE_CLEAR_COLOR0 << i); + } } } if (ctx->gfx_pipeline_state.void_alpha_attachments != prev_void_alpha_attachments) diff --git a/src/gallium/drivers/zink/zink_context.h b/src/gallium/drivers/zink/zink_context.h index 8cb07e3cd33..c4e62cd9efc 100644 --- a/src/gallium/drivers/zink/zink_context.h +++ b/src/gallium/drivers/zink/zink_context.h @@ -280,6 +280,7 @@ struct zink_context { struct zink_framebuffer_clear fb_clears[PIPE_MAX_COLOR_BUFS + 1]; uint16_t clears_enabled; uint16_t rp_clears_enabled; + uint16_t void_clears; uint16_t fbfetch_outputs; struct zink_resource *needs_present;