zink: use VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL when possible

this is allowed for fb attachments, so we can use it to avoid needing to
change layouts for zs textures if we know that it isn't going to be written
to during a given subpass

Reviewed-by: Dave Airlie <airlied@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11130>
This commit is contained in:
Mike Blumenkrantz 2021-03-03 15:26:02 -05:00 committed by Marge Bot
parent 3f332b16d5
commit 4304a7adc7
6 changed files with 63 additions and 13 deletions

View file

@ -379,7 +379,9 @@ get_layout_for_binding(struct zink_resource *res, enum zink_descriptor_type type
switch (type) {
case ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW:
return res->bind_history & BITFIELD64_BIT(ZINK_DESCRIPTOR_TYPE_IMAGE) ?
VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
VK_IMAGE_LAYOUT_GENERAL :
res->aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) ?
VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
case ZINK_DESCRIPTOR_TYPE_IMAGE:
return VK_IMAGE_LAYOUT_GENERAL;
default:
@ -1149,7 +1151,7 @@ unbind_shader_image(struct zink_context *ctx, enum pipe_shader_type stage, unsig
!res->image_bind_count[is_compute]) {
for (unsigned i = 0; i < PIPE_SHADER_TYPES; i++) {
if (res->sampler_binds[i]) {
zink_resource_image_barrier(ctx, NULL, res, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
zink_resource_image_barrier(ctx, NULL, res, get_layout_for_binding(res, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW),
VK_ACCESS_SHADER_READ_BIT,
zink_pipeline_flags_from_stage(zink_shader_stage(i)));
break;
@ -1438,6 +1440,11 @@ get_render_pass(struct zink_context *ctx)
clears |= PIPE_CLEAR_DEPTH;
if (state.rts[fb->nr_cbufs].clear_stencil)
clears |= PIPE_CLEAR_STENCIL;
const uint64_t outputs_written = ctx->gfx_stages[PIPE_SHADER_FRAGMENT] ?
ctx->gfx_stages[PIPE_SHADER_FRAGMENT]->nir->info.outputs_written : 0;
bool needs_write = (ctx->dsa_state && ctx->dsa_state->hw_state.depth_write) ||
outputs_written & (BITFIELD64_BIT(FRAG_RESULT_DEPTH) | BITFIELD64_BIT(FRAG_RESULT_STENCIL));
state.rts[fb->nr_cbufs].needs_write = needs_write || state.rts[fb->nr_cbufs].clear_color || state.rts[fb->nr_cbufs].clear_stencil;
state.num_rts++;
}
state.have_zsbuf = fb->zsbuf != NULL;
@ -1594,11 +1601,12 @@ begin_render_pass(struct zink_context *ctx)
zink_batch_reference_resource_rw(batch, zink_resource(surf->base.texture), true);
zink_batch_reference_surface(batch, surf);
VkImageLayout layout = i == ctx->framebuffer->state.num_attachments - 1 && fb_state->zsbuf ?
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL :
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
struct zink_resource *res = zink_resource(surf->base.texture);
zink_resource_image_barrier(ctx, NULL, res, layout, 0, 0);
VkAccessFlags access;
VkPipelineStageFlags pipeline;
VkImageLayout layout = zink_render_pass_attachment_get_barrier_info(ctx->gfx_pipeline_state.render_pass,
i, &pipeline, &access);
zink_resource_image_barrier(ctx, NULL, res, layout, access, pipeline);
}
}

View file

@ -1237,7 +1237,9 @@ update_sampler_descriptors(struct zink_context *ctx, struct zink_descriptor_set
} else if (res) {
imageview = sampler_view->image_view->image_view;
layout = (res->bind_history & BITFIELD64_BIT(ZINK_DESCRIPTOR_TYPE_IMAGE)) ?
VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
VK_IMAGE_LAYOUT_GENERAL :
res->aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) ?
VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
sampler = ctx->sampler_states[stage][index + k];
}
assert(num_resources < num_bindings);

View file

@ -385,7 +385,9 @@ update_barriers(struct zink_context *ctx, bool is_compute)
if (res->base.b.target == PIPE_BUFFER)
zink_resource_buffer_barrier(ctx, NULL, res, access, pipeline);
else {
VkImageLayout layout = res->image_bind_count[is_compute] ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
VkImageLayout layout = res->image_bind_count[is_compute] ? VK_IMAGE_LAYOUT_GENERAL :
res->aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) ?
VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
zink_resource_image_barrier(ctx, NULL, res, layout, access, pipeline);
}
/* always barrier on draw if this resource has either multiple image write binds or

View file

@ -62,6 +62,8 @@ create_render_pass(VkDevice dev, struct zink_render_pass_state *state)
int num_attachments = state->num_cbufs;
if (state->have_zsbuf) {
struct zink_rt_attrib *rt = state->rts + state->num_cbufs;
bool has_clear = rt->clear_color || rt->clear_stencil;
VkImageLayout layout = rt->needs_write || has_clear ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
attachments[num_attachments].flags = 0;
attachments[num_attachments].format = rt->format;
attachments[num_attachments].samples = rt->samples;
@ -69,17 +71,18 @@ create_render_pass(VkDevice dev, struct zink_render_pass_state *state)
attachments[num_attachments].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
attachments[num_attachments].stencilLoadOp = rt->clear_stencil ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD;
attachments[num_attachments].stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
attachments[num_attachments].initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
attachments[num_attachments].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
attachments[num_attachments].initialLayout = layout;
attachments[num_attachments].finalLayout = layout;
dep_pipeline |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
dep_pipeline |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
if (layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)
dep_access |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
if (attachments[num_attachments].loadOp == VK_ATTACHMENT_LOAD_OP_LOAD ||
attachments[num_attachments].stencilLoadOp == VK_ATTACHMENT_LOAD_OP_LOAD)
dep_access |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
zs_ref.attachment = num_attachments++;
zs_ref.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
zs_ref.layout = layout;
}
VkSubpassDependency deps[] = {
@ -138,3 +141,28 @@ zink_destroy_render_pass(struct zink_screen *screen,
vkDestroyRenderPass(screen->dev, rp->render_pass, NULL);
FREE(rp);
}
VkImageLayout
zink_render_pass_attachment_get_barrier_info(const struct zink_render_pass *rp, unsigned idx,
VkPipelineStageFlags *pipeline, VkAccessFlags *access)
{
*access = 0;
assert(idx < rp->state.num_rts);
const struct zink_rt_attrib *rt = &rp->state.rts[idx];
if (idx < rp->state.num_cbufs) {
*pipeline = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
*access |= VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
if (!rt->clear_color && (!rp->state.swapchain_init || !rt->swapchain))
*access |= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT;
return VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
}
assert(rp->state.have_zsbuf);
*pipeline = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
if (!rp->state.rts[idx].clear_color && !rp->state.rts[idx].clear_stencil)
*access |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
if (!rp->state.rts[idx].clear_color && !rp->state.rts[idx].clear_stencil && !rp->state.rts[idx].needs_write)
return VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
*access |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
return VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
}

View file

@ -36,7 +36,10 @@ struct zink_rt_attrib {
VkSampleCountFlagBits samples;
bool clear_color;
bool clear_stencil;
bool swapchain;
union {
bool swapchain;
bool needs_write;
};
};
struct zink_render_pass_state {
@ -61,4 +64,6 @@ void
zink_destroy_render_pass(struct zink_screen *screen,
struct zink_render_pass *rp);
VkImageLayout
zink_render_pass_attachment_get_barrier_info(const struct zink_render_pass *rp, unsigned idx, VkPipelineStageFlags *pipeline, VkAccessFlags *access);
#endif

View file

@ -389,6 +389,7 @@ zink_bind_depth_stencil_alpha_state(struct pipe_context *pctx, void *cso)
{
struct zink_context *ctx = zink_context(pctx);
bool prev_zwrite = ctx->dsa_state ? ctx->dsa_state->hw_state.depth_write : false;
ctx->dsa_state = cso;
if (cso) {
@ -398,6 +399,10 @@ zink_bind_depth_stencil_alpha_state(struct pipe_context *pctx, void *cso)
state->dirty |= !zink_screen(pctx->screen)->info.have_EXT_extended_dynamic_state;
}
}
if (prev_zwrite != (ctx->dsa_state ? ctx->dsa_state->hw_state.depth_write : false)) {
ctx->rp_changed = true;
zink_batch_no_rp(ctx);
}
}
static void