diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index ad2ef7e3e3a..94548ab3422 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -3837,7 +3837,9 @@ zink_resource_image_transfer_dst_barrier(struct zink_context *ctx, struct zink_r if (res->obj->copies_need_reset) zink_resource_copies_reset(res); /* skip TRANSFER_DST barrier if no intersection from previous copies */ - if (res->layout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL || zink_resource_copy_box_intersects(res, level, box)) { + if (res->layout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL || + zink_screen(ctx->base.screen)->driver_workarounds.broken_cache_semantics || + zink_resource_copy_box_intersects(res, level, box)) { zink_screen(ctx->base.screen)->image_barrier(ctx, res, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); } else { res->obj->access = VK_ACCESS_TRANSFER_WRITE_BIT; @@ -3855,7 +3857,8 @@ zink_resource_buffer_transfer_dst_barrier(struct zink_context *ctx, struct zink_ 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) { + if (zink_screen(ctx->base.screen)->driver_workarounds.broken_cache_semantics || + 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; diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c index 867efc635cb..9d19adabdca 100644 --- a/src/gallium/drivers/zink/zink_screen.c +++ b/src/gallium/drivers/zink/zink_screen.c @@ -2548,6 +2548,16 @@ init_driver_workarounds(struct zink_screen *screen) screen->driver_workarounds.track_renderpasses = true; else if (zink_debug & ZINK_DEBUG_NORP) screen->driver_workarounds.track_renderpasses = false; + + /* these drivers can't optimize non-overlapping copy ops */ + switch (screen->info.driver_props.driverID) { + case VK_DRIVER_ID_MESA_TURNIP: + case VK_DRIVER_ID_QUALCOMM_PROPRIETARY: + screen->driver_workarounds.broken_cache_semantics = true; + break; + default: + break; + } } static struct disk_cache * @@ -3113,4 +3123,4 @@ zink_screen_debug_marker_end(struct zink_screen *screen, bool emitted) { if (emitted) VKSCR(QueueEndDebugUtilsLabelEXT)(screen->queue); -} \ No newline at end of file +} diff --git a/src/gallium/drivers/zink/zink_types.h b/src/gallium/drivers/zink/zink_types.h index c12e4a4711e..06827dbab89 100644 --- a/src/gallium/drivers/zink/zink_types.h +++ b/src/gallium/drivers/zink/zink_types.h @@ -1398,6 +1398,10 @@ struct zink_screen { struct { bool broken_l4a4; + /* https://gitlab.khronos.org/vulkan/vulkan/-/issues/3306 + * HI TURNIP + */ + bool broken_cache_semantics; bool implicit_sync; bool always_feedback_loop; bool always_feedback_loop_zs;