diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index 28abc3d2e41..2a97f130f85 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -1159,10 +1159,22 @@ pipeline_access_stage(VkAccessFlags flags) return VK_PIPELINE_STAGE_TRANSFER_BIT; } +bool +zink_resource_buffer_needs_barrier(struct zink_resource *res, VkAccessFlags flags, VkPipelineStageFlags pipeline) +{ + 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); +} + void zink_resource_buffer_barrier(VkCommandBuffer cmdbuf, struct zink_resource *res, VkAccessFlags flags, VkPipelineStageFlags pipeline) { - /* TODO: maybe make this more flexible using flags? */ + if (!pipeline) + pipeline = pipeline_access_stage(flags); + if (!zink_resource_buffer_needs_barrier(res, flags, pipeline)) + return; VkBufferMemoryBarrier bmb = { VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, NULL, @@ -1178,14 +1190,14 @@ zink_resource_buffer_barrier(VkCommandBuffer cmdbuf, struct zink_resource *res, vkCmdPipelineBarrier( cmdbuf, res->access_stage ? res->access_stage : pipeline_access_stage(res->access), - pipeline ? pipeline : pipeline_access_stage(flags), + pipeline, 0, 0, NULL, 1, &bmb, 0, NULL ); res->access = flags; - res->access_stage = pipeline ? pipeline : pipeline_access_stage(flags); + res->access_stage = pipeline; } VkShaderStageFlagBits diff --git a/src/gallium/drivers/zink/zink_context.h b/src/gallium/drivers/zink/zink_context.h index 630bb7f4c07..7d28dae9460 100644 --- a/src/gallium/drivers/zink/zink_context.h +++ b/src/gallium/drivers/zink/zink_context.h @@ -195,6 +195,9 @@ zink_wait_on_batch(struct zink_context *ctx, int batch_id); bool zink_resource_access_is_write(VkAccessFlags flags); +bool +zink_resource_buffer_needs_barrier(struct zink_resource *res, VkAccessFlags flags, VkPipelineStageFlags pipeline); + void zink_resource_buffer_barrier(VkCommandBuffer cmdbuf, struct zink_resource *res, VkAccessFlags flags, VkPipelineStageFlags pipeline);