zink: inject a 0,0,0,1 clear for RGBX formats
authorMike Blumenkrantz <michael.blumenkrantz@gmail.com>
Wed, 13 Jul 2022 16:17:29 +0000 (12:17 -0400)
committerMarge Bot <emma+marge@anholt.net>
Mon, 18 Jul 2022 03:40:38 +0000 (03:40 +0000)
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 <airlied@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17366>

src/gallium/drivers/zink/zink_clear.c
src/gallium/drivers/zink/zink_context.c
src/gallium/drivers/zink/zink_context.h

index db53600..26ba2c1 100644 (file)
@@ -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]) {
index 45ab6f7..145c0d9 100644 (file)
@@ -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)
index 8cb07e3..c4e62cd 100644 (file)
@@ -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;