Module: Mesa
Branch: main
Commit: 3892c133811f71d7f9eefda34bf282ccd1e6859b
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=3892c133811f71d7f9eefda34bf282ccd1e6859b

Author: Mike Blumenkrantz <[email protected]>
Date:   Sun Mar 13 12:46:25 2022 -0400

zink: add an alternate path for EXT_color_write_enable usage

for drivers where this is broken/missing, the same effect can be achieved
by feeding the renderpass a framebuffer with null/dummy attachments

Acked-by: Dave Airlie <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15392>

---

 src/gallium/drivers/zink/zink_context.c     |  9 +++++++-
 src/gallium/drivers/zink/zink_context.h     |  1 +
 src/gallium/drivers/zink/zink_framebuffer.c | 34 +++++++++++++++--------------
 3 files changed, 27 insertions(+), 17 deletions(-)

diff --git a/src/gallium/drivers/zink/zink_context.c 
b/src/gallium/drivers/zink/zink_context.c
index adbf58508f5..65c226b0e72 100644
--- a/src/gallium/drivers/zink/zink_context.c
+++ b/src/gallium/drivers/zink/zink_context.c
@@ -2572,8 +2572,15 @@ void
 zink_set_color_write_enables(struct zink_context *ctx)
 {
    const VkBool32 enables[PIPE_MAX_COLOR_BUFS] = {1, 1, 1, 1, 1, 1, 1, 1};
+   const VkBool32 disables[PIPE_MAX_COLOR_BUFS] = {0};
    const unsigned max_att = MIN2(PIPE_MAX_COLOR_BUFS, 
zink_screen(ctx->base.screen)->info.props.limits.maxColorAttachments);
-   VKCTX(CmdSetColorWriteEnableEXT)(ctx->batch.state->cmdbuf, max_att, 
enables);
+   if (zink_screen(ctx->base.screen)->driver_workarounds.color_write_missing) {
+      /* use dummy color buffers instead of the more sane option */
+      zink_end_render_pass(ctx);
+      update_framebuffer_state(ctx, ctx->fb_state.width, ctx->fb_state.height);
+   } else {
+      VKCTX(CmdSetColorWriteEnableEXT)(ctx->batch.state->cmdbuf, max_att, 
enables);
+   }
 }
 
 static void
diff --git a/src/gallium/drivers/zink/zink_context.h 
b/src/gallium/drivers/zink/zink_context.h
index 976c0bd940d..ea74123fe89 100644
--- a/src/gallium/drivers/zink/zink_context.h
+++ b/src/gallium/drivers/zink/zink_context.h
@@ -290,6 +290,7 @@ struct zink_context {
    struct list_head suspended_queries;
    struct list_head primitives_generated_queries;
    struct zink_query *vertices_query;
+   bool disable_color_writes;
    bool primitives_generated_active;
    bool queries_disabled, render_condition_active;
    struct {
diff --git a/src/gallium/drivers/zink/zink_framebuffer.c 
b/src/gallium/drivers/zink/zink_framebuffer.c
index eddb9fe5c45..fdbed2bd7f5 100644
--- a/src/gallium/drivers/zink/zink_framebuffer.c
+++ b/src/gallium/drivers/zink/zink_framebuffer.c
@@ -149,7 +149,7 @@ zink_get_framebuffer_imageless(struct zink_context *ctx)
    unsigned num_resolves = 0;
    for (int i = 0; i < ctx->fb_state.nr_cbufs; i++) {
       struct pipe_surface *psurf = ctx->fb_state.cbufs[i];
-      if (!psurf)
+      if (!psurf || ctx->disable_color_writes)
          psurf = 
ctx->dummy_surface[util_logbase2_ceil(ctx->gfx_pipeline_state.rast_samples+1)];
       struct zink_surface *surface = zink_csurface(psurf);
       struct zink_surface *transient = zink_transient_surface(psurf);
@@ -300,24 +300,26 @@ zink_get_framebuffer(struct zink_context *ctx)
    unsigned num_resolves = 0;
 
    struct zink_framebuffer_state state = {0};
-   for (int i = 0; i < ctx->fb_state.nr_cbufs; i++) {
-      struct pipe_surface *psurf = ctx->fb_state.cbufs[i];
-      if (psurf) {
-         struct zink_surface *surf = zink_csurface(psurf);
-         struct zink_surface *transient = zink_transient_surface(psurf);
-         if (transient) {
-            state.attachments[i] = transient->image_view;
-            state.attachments[cresolve_offset + i] = surf->image_view;
-            attachments[cresolve_offset + i] = psurf;
-            psurf = &transient->base;
-            num_resolves++;
+   if (!ctx->disable_color_writes) {
+      for (int i = 0; i < ctx->fb_state.nr_cbufs; i++) {
+         struct pipe_surface *psurf = ctx->fb_state.cbufs[i];
+         if (psurf) {
+            struct zink_surface *surf = zink_csurface(psurf);
+            struct zink_surface *transient = zink_transient_surface(psurf);
+            if (transient) {
+               state.attachments[i] = transient->image_view;
+               state.attachments[cresolve_offset + i] = surf->image_view;
+               attachments[cresolve_offset + i] = psurf;
+               psurf = &transient->base;
+               num_resolves++;
+            } else {
+               state.attachments[i] = surf->image_view;
+            }
          } else {
-            state.attachments[i] = surf->image_view;
+            state.attachments[i] = VK_NULL_HANDLE;
          }
-      } else {
-         state.attachments[i] = VK_NULL_HANDLE;
+         attachments[i] = psurf;
       }
-      attachments[i] = psurf;
    }
 
    state.num_attachments = ctx->fb_state.nr_cbufs;

Reply via email to