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