From: Mike Blumenkrantz Date: Mon, 27 Feb 2023 18:48:48 +0000 (-0500) Subject: zink: add a mechanism for managing TRANSFER_DST buffer barriers X-Git-Tag: upstream/23.3.3~11981 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=aaca91eb79ddecb02a939efa945ce4f9f7b29478;p=platform%2Fupstream%2Fmesa.git zink: add a mechanism for managing TRANSFER_DST buffer barriers this enables successive or unrelated transfer writes to avoid triggering barriers, and ensuing reads of those writes should trigger their own barriers Part-of: --- diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index d04f0df..5d540da 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -3821,6 +3821,16 @@ zink_resource_image_barrier2(struct zink_context *ctx, struct zink_resource *res zink_resource_copies_reset(res); } +bool +zink_check_transfer_dst_barrier(struct zink_resource *res, unsigned level, const struct pipe_box *box) +{ + /* always barrier against previous non-transfer writes */ + bool non_transfer_write = res->obj->last_write && res->obj->last_write != VK_ACCESS_TRANSFER_WRITE_BIT; + /* must barrier if clobbering a previous write */ + bool transfer_clobber = res->obj->last_write == VK_ACCESS_TRANSFER_WRITE_BIT && zink_resource_copy_box_intersects(res, level, box); + return non_transfer_write || transfer_clobber; +} + void zink_resource_image_transfer_dst_barrier(struct zink_context *ctx, struct zink_resource *res, unsigned level, const struct pipe_box *box) { @@ -3833,7 +3843,22 @@ zink_resource_image_transfer_dst_barrier(struct zink_context *ctx, struct zink_r res->obj->access_stage = VK_PIPELINE_STAGE_TRANSFER_BIT; } zink_resource_copy_box_add(res, level, box); +} +void +zink_resource_buffer_transfer_dst_barrier(struct zink_context *ctx, struct zink_resource *res, unsigned offset, unsigned size) +{ + struct pipe_box box = {offset, 0, 0, size, 0, 0}; + /* must barrier if something read the valid buffer range */ + bool valid_read = res->obj->access && util_ranges_intersect(&res->valid_buffer_range, offset, offset + size) && !unordered_res_exec(ctx, res, true); + if (zink_check_transfer_dst_barrier(res, 0, &box) || valid_read) { + zink_screen(ctx->base.screen)->buffer_barrier(ctx, res, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); + } else { + res->obj->access = VK_ACCESS_TRANSFER_WRITE_BIT; + res->obj->last_write = VK_ACCESS_TRANSFER_WRITE_BIT; + res->obj->access_stage = VK_PIPELINE_STAGE_TRANSFER_BIT; + } + zink_resource_copy_box_add(res, 0, &box); } VkPipelineStageFlags @@ -3939,6 +3964,8 @@ zink_resource_buffer_barrier(struct zink_context *ctx, struct zink_resource *res res->obj->access = flags; res->obj->access_stage = pipeline; + if (pipeline != VK_PIPELINE_STAGE_TRANSFER_BIT && is_write) + zink_resource_copies_reset(res); } void @@ -3996,6 +4023,8 @@ zink_resource_buffer_barrier2(struct zink_context *ctx, struct zink_resource *re res->obj->access = flags; res->obj->access_stage = pipeline; + if (pipeline != VK_PIPELINE_STAGE_TRANSFER_BIT && is_write) + zink_resource_copies_reset(res); } bool @@ -5027,6 +5056,7 @@ zink_context_replace_buffer_storage(struct pipe_context *pctx, struct pipe_resou /* don't be too creative */ zink_resource_object_reference(screen, &d->obj, s->obj); d->valid_buffer_range = s->valid_buffer_range; + zink_resource_copies_reset(d); /* force counter buffer reset */ d->so_valid = false; if (num_rebinds && rebind_buffer(ctx, d, rebind_mask, num_rebinds) < num_rebinds) diff --git a/src/gallium/drivers/zink/zink_context.h b/src/gallium/drivers/zink/zink_context.h index 36fa82b..7598575 100644 --- a/src/gallium/drivers/zink/zink_context.h +++ b/src/gallium/drivers/zink/zink_context.h @@ -114,9 +114,13 @@ void zink_resource_image_barrier2(struct zink_context *ctx, struct zink_resource *res, VkImageLayout new_layout, VkAccessFlags flags, VkPipelineStageFlags pipeline); bool zink_resource_needs_barrier(struct zink_resource *res, VkImageLayout layout, VkAccessFlags flags, VkPipelineStageFlags pipeline); +bool +zink_check_transfer_dst_barrier(struct zink_resource *res, unsigned level, const struct pipe_box *box); void zink_resource_image_transfer_dst_barrier(struct zink_context *ctx, struct zink_resource *res, unsigned level, const struct pipe_box *box); void +zink_resource_buffer_transfer_dst_barrier(struct zink_context *ctx, struct zink_resource *res, unsigned offset, unsigned size); +void zink_update_descriptor_refs(struct zink_context *ctx, bool compute); void zink_init_vk_sample_locations(struct zink_context *ctx, VkSampleLocationsInfoEXT *loc); diff --git a/src/gallium/drivers/zink/zink_resource.c b/src/gallium/drivers/zink/zink_resource.c index c0ef489..5a9373c 100644 --- a/src/gallium/drivers/zink/zink_resource.c +++ b/src/gallium/drivers/zink/zink_resource.c @@ -1939,6 +1939,7 @@ overwrite: res->obj->access = 0; res->obj->access_stage = 0; res->obj->last_write = 0; + zink_resource_copies_reset(res); } if (!ptr) {