Mesa (main): zink: use DONTCARE renderpass when a new scanout fb attachment is set

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue May 11 00:20:18 UTC 2021


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

Author: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Date:   Tue Jan 12 12:29:25 2021 -0500

zink: use DONTCARE renderpass when a new scanout fb attachment is set

using DONTCARE for the loadOp is more optimal for this case

Reviewed-by: Dave Airlie <airlied at redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10698>

---

 src/gallium/drivers/zink/zink_context.c     | 14 ++++++++++----
 src/gallium/drivers/zink/zink_context.h     |  1 +
 src/gallium/drivers/zink/zink_render_pass.c |  5 ++++-
 src/gallium/drivers/zink/zink_render_pass.h |  2 ++
 4 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c
index 6b180d932fb..4f3e0f7fb49 100644
--- a/src/gallium/drivers/zink/zink_context.c
+++ b/src/gallium/drivers/zink/zink_context.c
@@ -1016,6 +1016,7 @@ get_render_pass(struct zink_context *ctx)
    const struct pipe_framebuffer_state *fb = &ctx->fb_state;
    struct zink_render_pass_state state = { 0 };
    uint32_t clears = 0;
+   state.swapchain_init = ctx->new_swapchain;
 
    for (int i = 0; i < fb->nr_cbufs; i++) {
       struct pipe_surface *surf = fb->cbufs[i];
@@ -1025,6 +1026,7 @@ get_render_pass(struct zink_context *ctx)
                                                        VK_SAMPLE_COUNT_1_BIT;
          state.rts[i].clear_color = zink_fb_clear_enabled(ctx, i) && !zink_fb_clear_first_needs_explicit(&ctx->fb_clears[i]);
          clears |= !!state.rts[i].clear_color ? BITFIELD_BIT(i) : 0;
+         state.rts[i].swapchain = surf->texture->bind & PIPE_BIND_SCANOUT;
       } else {
          state.rts[i].format = VK_FORMAT_R8_UINT;
          state.rts[i].samples = MAX2(fb->samples, 1);
@@ -1213,6 +1215,7 @@ zink_begin_render_pass(struct zink_context *ctx, struct zink_batch *batch)
 
    vkCmdBeginRenderPass(batch->state->cmdbuf, &rpbi, VK_SUBPASS_CONTENTS_INLINE);
    batch->in_rp = true;
+   ctx->new_swapchain = false;
 
    if (ctx->render_condition.query)
       zink_start_conditional_render(ctx);
@@ -1299,11 +1302,14 @@ rebind_fb_surface(struct zink_context *ctx, struct pipe_surface **surf, struct z
 }
 
 static bool
-rebind_fb_state(struct zink_context *ctx, struct zink_resource *match_res)
+rebind_fb_state(struct zink_context *ctx, struct zink_resource *match_res, bool from_set_fb)
 {
    bool rebind = false;
-   for (int i = 0; i < ctx->fb_state.nr_cbufs; i++)
+   for (int i = 0; i < ctx->fb_state.nr_cbufs; i++) {
       rebind |= rebind_fb_surface(ctx, &ctx->fb_state.cbufs[i], match_res);
+      if (from_set_fb && ctx->fb_state.cbufs[i] && ctx->fb_state.cbufs[i]->texture->bind & PIPE_BIND_SCANOUT)
+         ctx->new_swapchain = true;
+   }
    rebind |= rebind_fb_surface(ctx, &ctx->fb_state.zsbuf, match_res);
    return rebind;
 }
@@ -1326,7 +1332,7 @@ zink_set_framebuffer_state(struct pipe_context *pctx,
    }
 
    util_copy_framebuffer_state(&ctx->fb_state, state);
-   rebind_fb_state(ctx, NULL);
+   rebind_fb_state(ctx, NULL, true);
    /* get_framebuffer adds a ref if the fb is reused or created;
     * always do get_framebuffer first to avoid deleting the same fb
     * we're about to use
@@ -2373,7 +2379,7 @@ zink_rebind_framebuffer(struct zink_context *ctx, struct zink_resource *res)
       zink_rebind_surface(ctx, &ctx->framebuffer->surfaces[i]);
       zink_batch_no_rp(ctx);
    }
-   if (rebind_fb_state(ctx, res))
+   if (rebind_fb_state(ctx, res, false))
       zink_batch_no_rp(ctx);
 }
 
diff --git a/src/gallium/drivers/zink/zink_context.h b/src/gallium/drivers/zink/zink_context.h
index 6aa79940e5f..4f223ae8c78 100644
--- a/src/gallium/drivers/zink/zink_context.h
+++ b/src/gallium/drivers/zink/zink_context.h
@@ -178,6 +178,7 @@ struct zink_context {
    bool last_vertex_stage_dirty;
 
    struct hash_table *render_pass_cache;
+   bool new_swapchain;
 
    struct primconvert_context *primconvert;
 
diff --git a/src/gallium/drivers/zink/zink_render_pass.c b/src/gallium/drivers/zink/zink_render_pass.c
index f62f5c47994..38ddab7187c 100644
--- a/src/gallium/drivers/zink/zink_render_pass.c
+++ b/src/gallium/drivers/zink/zink_render_pass.c
@@ -42,7 +42,10 @@ create_render_pass(VkDevice dev, struct zink_render_pass_state *state)
       attachments[i].flags = 0;
       attachments[i].format = rt->format;
       attachments[i].samples = rt->samples;
-      attachments[i].loadOp = rt->clear_color ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD;
+      attachments[i].loadOp = rt->clear_color ? VK_ATTACHMENT_LOAD_OP_CLEAR :
+                                                state->swapchain_init && rt->swapchain ?
+                                                VK_ATTACHMENT_LOAD_OP_DONT_CARE :
+                                                VK_ATTACHMENT_LOAD_OP_LOAD;
       attachments[i].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
       attachments[i].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
       attachments[i].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
diff --git a/src/gallium/drivers/zink/zink_render_pass.h b/src/gallium/drivers/zink/zink_render_pass.h
index 02dc2119439..920a56b9c32 100644
--- a/src/gallium/drivers/zink/zink_render_pass.h
+++ b/src/gallium/drivers/zink/zink_render_pass.h
@@ -36,11 +36,13 @@ struct zink_rt_attrib {
   VkSampleCountFlagBits samples;
   bool clear_color;
   bool clear_stencil;
+  bool swapchain;
 };
 
 struct zink_render_pass_state {
    uint8_t num_cbufs : 4; /* PIPE_MAX_COLOR_BUFS = 8 */
    uint8_t have_zsbuf : 1;
+   bool swapchain_init;
    struct zink_rt_attrib rts[PIPE_MAX_COLOR_BUFS + 1];
    unsigned num_rts;
 #ifndef NDEBUG



More information about the mesa-commit mailing list