mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-02 05:10:17 +01:00
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:
parent
3f332b16d5
commit
4304a7adc7
6 changed files with 63 additions and 13 deletions
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue