zink: add access param for image resource barriers

we need more detail on some of these to ensure proper synchronization
and availability/visibility of image data between commands/stages

the signature for needs_barrier() is still funky here to avoid breaking
usage in update_descriptors()

Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8945>
This commit is contained in:
Mike Blumenkrantz 2020-09-07 10:34:24 -04:00 committed by Marge Bot
parent 3f6d104ba8
commit ab3a2fa690
6 changed files with 34 additions and 26 deletions

View file

@ -127,7 +127,7 @@ clear_color_no_rp(struct zink_batch *batch, struct zink_resource *res, const uni
color.float32[3] = pcolor->f[3];
if (res->layout != VK_IMAGE_LAYOUT_GENERAL && res->layout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
zink_resource_barrier(batch, res, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0);
zink_resource_barrier(batch, res, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0, 0);
vkCmdClearColorImage(batch->cmdbuf, res->image, res->layout, &color, 1, &range);
}
@ -144,7 +144,7 @@ clear_zs_no_rp(struct zink_batch *batch, struct zink_resource *res, VkImageAspec
VkClearDepthStencilValue zs_value = {depth, stencil};
if (res->layout != VK_IMAGE_LAYOUT_GENERAL && res->layout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
zink_resource_barrier(batch, res, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0);
zink_resource_barrier(batch, res, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0, 0);
vkCmdClearDepthStencilImage(batch->cmdbuf, res->image, res->layout, &zs_value, 1, &range);
}

View file

@ -810,14 +810,14 @@ framebuffer_state_buffer_barriers_setup(struct zink_context *ctx,
struct zink_resource *res = zink_resource(surf->texture);
if (res->layout != VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)
zink_resource_barrier(batch, res,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 0);
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 0, 0);
}
if (state->zsbuf) {
struct zink_resource *res = zink_resource(state->zsbuf->texture);
if (res->layout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)
zink_resource_barrier(batch, res,
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 0);
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 0, 0);
}
}
@ -1076,23 +1076,28 @@ zink_resource_access_is_write(VkAccessFlags flags)
}
bool
zink_resource_image_needs_barrier(struct zink_resource *res, VkImageLayout new_layout, VkPipelineStageFlags pipeline)
zink_resource_image_needs_barrier(struct zink_resource *res, VkImageLayout new_layout, VkAccessFlags flags, VkPipelineStageFlags pipeline)
{
if (!pipeline)
pipeline = pipeline_dst_stage(new_layout);
if (!flags)
flags = access_dst_flags(new_layout);
return res->layout != new_layout || (res->access_stage & pipeline) != pipeline ||
(access_src_flags(res->layout) & access_dst_flags(new_layout)) != access_dst_flags(new_layout) ||
(zink_resource_access_is_write(access_dst_flags(new_layout)) && util_bitcount(access_dst_flags(new_layout)) > 1);
(res->access & flags) != flags ||
zink_resource_access_is_write(res->access) ||
zink_resource_access_is_write(flags);
}
void
zink_resource_barrier(struct zink_batch *batch, struct zink_resource *res,
VkImageLayout new_layout, VkPipelineStageFlags pipeline)
VkImageLayout new_layout, VkAccessFlags flags, VkPipelineStageFlags pipeline)
{
assert(!batch->in_rp);
if (!pipeline)
pipeline = pipeline_dst_stage(new_layout);
if (!zink_resource_image_needs_barrier(res, new_layout, pipeline))
if (!flags)
flags = access_dst_flags(new_layout);
if (!zink_resource_image_needs_barrier(res, new_layout, flags, pipeline))
return;
VkImageSubresourceRange isr = {
res->aspect,
@ -1103,8 +1108,8 @@ zink_resource_barrier(struct zink_batch *batch, struct zink_resource *res,
VkImageMemoryBarrier imb = {
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
NULL,
access_src_flags(res->layout),
access_dst_flags(new_layout),
res->access ?: access_src_flags(res->layout),
flags,
res->layout,
new_layout,
VK_QUEUE_FAMILY_IGNORED,
@ -1124,6 +1129,7 @@ zink_resource_barrier(struct zink_batch *batch, struct zink_resource *res,
res->layout = new_layout;
res->access_stage = pipeline;
res->access = flags;
}
@ -1172,7 +1178,8 @@ zink_resource_buffer_needs_barrier(struct zink_resource *res, VkAccessFlags flag
if (!pipeline)
pipeline = pipeline_access_stage(flags);
return (res->access_stage & pipeline) != pipeline || (res->access & flags) != flags ||
(zink_resource_access_is_write(flags) && util_bitcount(flags) > 1);
zink_resource_access_is_write(res->access) ||
zink_resource_access_is_write(flags);
}
void
@ -1209,11 +1216,11 @@ zink_resource_buffer_barrier(struct zink_batch *batch, struct zink_resource *res
}
bool
zink_resource_needs_barrier(struct zink_resource *res, unsigned flags, VkPipelineStageFlags pipeline)
zink_resource_needs_barrier(struct zink_resource *res, unsigned layout, VkAccessFlags flags, VkPipelineStageFlags pipeline)
{
if (res->base.target == PIPE_BUFFER)
return zink_resource_buffer_needs_barrier(res, flags, pipeline);
return zink_resource_image_needs_barrier(res, flags, pipeline);
return zink_resource_buffer_needs_barrier(res, layout, pipeline);
return zink_resource_image_needs_barrier(res, layout, flags, pipeline);
}
VkShaderStageFlagBits

View file

@ -218,13 +218,13 @@ void
zink_resource_buffer_barrier(struct zink_batch *batch, struct zink_resource *res, VkAccessFlags flags, VkPipelineStageFlags pipeline);
bool
zink_resource_image_needs_barrier(struct zink_resource *res, VkImageLayout new_layout, VkPipelineStageFlags pipeline);
zink_resource_image_needs_barrier(struct zink_resource *res, VkImageLayout new_layout, VkAccessFlags flags, VkPipelineStageFlags pipeline);
void
zink_resource_barrier(struct zink_batch *batch, struct zink_resource *res,
VkImageLayout new_layout, VkPipelineStageFlags pipeline);
VkImageLayout new_layout, VkAccessFlags flags, VkPipelineStageFlags pipeline);
bool
zink_resource_needs_barrier(struct zink_resource *res, unsigned flags, VkPipelineStageFlags pipeline);
zink_resource_needs_barrier(struct zink_resource *res, unsigned layout, VkAccessFlags flags, VkPipelineStageFlags pipeline);
void
zink_begin_render_pass(struct zink_context *ctx,

View file

@ -480,6 +480,7 @@ update_descriptors(struct zink_context *ctx, struct zink_screen *screen, bool is
for (int i = 0; i < num_transitions; ++i) {
if (!zink_resource_needs_barrier(transitions[i].res,
transitions[i].layout,
0,
transitions[i].stage))
continue;
if (is_compute)
@ -492,7 +493,7 @@ update_descriptors(struct zink_context *ctx, struct zink_screen *screen, bool is
transitions[i].layout, transitions[i].stage);
else
zink_resource_barrier(batch, transitions[i].res,
transitions[i].layout, transitions[i].stage);
transitions[i].layout, 0, transitions[i].stage);
}
}

View file

@ -450,12 +450,12 @@ zink_transfer_copy_bufimage(struct zink_context *ctx,
if (buf2img) {
if (res->layout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) {
zink_resource_barrier(batch, res,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0);
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0, 0);
}
} else {
if (res->layout != VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) {
zink_resource_barrier(batch, res,
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 0);
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 0, 0);
}
}
@ -757,16 +757,16 @@ zink_resource_setup_transfer_layouts(struct zink_batch *batch, struct zink_resou
* VK_IMAGE_LAYOUT_GENERAL. And since this isn't a present-related
* operation, VK_IMAGE_LAYOUT_GENERAL seems most appropriate.
*/
zink_resource_barrier(batch, src,
VK_IMAGE_LAYOUT_GENERAL, VK_PIPELINE_STAGE_TRANSFER_BIT);
zink_resource_barrier(batch, src,
VK_IMAGE_LAYOUT_GENERAL, 0, VK_PIPELINE_STAGE_TRANSFER_BIT);
} else {
if (src->layout != VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL)
zink_resource_barrier(batch, src,
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_PIPELINE_STAGE_TRANSFER_BIT);
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 0, VK_PIPELINE_STAGE_TRANSFER_BIT);
if (dst->layout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
zink_resource_barrier(batch, dst,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_PIPELINE_STAGE_TRANSFER_BIT);
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0, VK_PIPELINE_STAGE_TRANSFER_BIT);
}
}

View file

@ -42,9 +42,9 @@ struct zink_resource {
enum pipe_format internal_format:16;
VkPipelineStageFlagBits access_stage;
VkAccessFlags access;
union {
struct {
VkAccessFlags access;
VkBuffer buffer;
struct util_range valid_buffer_range;
};