diff --git a/src/gallium/drivers/zink/zink_query.c b/src/gallium/drivers/zink/zink_query.c index 37f1dbdac3d..155354aced0 100644 --- a/src/gallium/drivers/zink/zink_query.c +++ b/src/gallium/drivers/zink/zink_query.c @@ -4,6 +4,7 @@ #include "zink_clear.h" #include "zink_program.h" #include "zink_resource.h" +#include "zink_screen.h" #include "util/u_dump.h" #include "util/u_inlines.h" @@ -1322,6 +1323,7 @@ zink_get_timestamp(struct pipe_screen *pscreen) mesa_loge("ZINK: vkGetCalibratedTimestampsEXT failed (%s)", vk_Result_to_str(result)); } } else { + zink_screen_lock_context(screen); struct pipe_context *pctx = &screen->copy_context->base; struct pipe_query *pquery = pctx->create_query(pctx, PIPE_QUERY_TIMESTAMP, 0); if (!pquery) @@ -1331,6 +1333,7 @@ zink_get_timestamp(struct pipe_screen *pscreen) pctx->end_query(pctx, pquery); pctx->get_query_result(pctx, pquery, true, &result); pctx->destroy_query(pctx, pquery); + zink_screen_unlock_context(screen); timestamp = result.u64; } timestamp_to_nanoseconds(screen, ×tamp); diff --git a/src/gallium/drivers/zink/zink_resource.c b/src/gallium/drivers/zink/zink_resource.c index 41f3b50d87d..95dd34eaa1e 100644 --- a/src/gallium/drivers/zink/zink_resource.c +++ b/src/gallium/drivers/zink/zink_resource.c @@ -1486,10 +1486,14 @@ zink_resource_get_handle(struct pipe_screen *pscreen, unsigned bind = ZINK_BIND_DMABUF; if (!(res->base.b.bind & PIPE_BIND_SHARED)) bind |= PIPE_BIND_SHARED; - if (!add_resource_bind(screen->copy_context, res, bind)) + zink_screen_lock_context(screen); + if (!add_resource_bind(screen->copy_context, res, bind)) { + zink_screen_unlock_context(screen); return false; + } p_atomic_inc(&screen->image_rebind_counter); screen->copy_context->base.flush(&screen->copy_context->base, NULL, 0); + zink_screen_unlock_context(screen); obj = res->obj; } diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c index c23f3ca6518..40f4fad23fb 100644 --- a/src/gallium/drivers/zink/zink_screen.c +++ b/src/gallium/drivers/zink/zink_screen.c @@ -1415,6 +1415,7 @@ zink_destroy_screen(struct pipe_screen *pscreen) zink_kopper_deinit_displaytarget(screen, entry->data); simple_mtx_destroy(&screen->dt_lock); + simple_mtx_destroy(&screen->copy_context_lock); if (screen->copy_context) screen->copy_context->base.destroy(&screen->copy_context->base); @@ -2577,6 +2578,24 @@ zink_create_semaphore(struct zink_screen *screen) return ret == VK_SUCCESS ? sem : VK_NULL_HANDLE; } +void +zink_screen_lock_context(struct zink_screen *screen) +{ + simple_mtx_lock(&screen->copy_context_lock); + if (!screen->copy_context) + screen->copy_context = zink_context(screen->base.context_create(&screen->base, NULL, ZINK_CONTEXT_COPY_ONLY)); + if (!screen->copy_context) { + mesa_loge("zink: failed to create copy context"); + /* realistically there's nothing that can be done here */ + } +} + +void +zink_screen_unlock_context(struct zink_screen *screen) +{ + simple_mtx_unlock(&screen->copy_context_lock); +} + static bool init_layouts(struct zink_screen *screen) { @@ -2997,12 +3016,7 @@ zink_internal_create_screen(const struct pipe_screen_config *config) if (!zink_descriptor_layouts_init(screen)) goto fail; - - screen->copy_context = zink_context(screen->base.context_create(&screen->base, NULL, ZINK_CONTEXT_COPY_ONLY)); - if (!screen->copy_context) { - mesa_loge("zink: failed to create copy context"); - goto fail; - } + simple_mtx_init(&screen->copy_context_lock, mtx_plain); screen->optimal_keys = !screen->need_decompose_attrs && screen->info.have_EXT_non_seamless_cube_map && diff --git a/src/gallium/drivers/zink/zink_screen.h b/src/gallium/drivers/zink/zink_screen.h index d65f50ac88d..b6b30b9ec57 100644 --- a/src/gallium/drivers/zink/zink_screen.h +++ b/src/gallium/drivers/zink/zink_screen.h @@ -102,6 +102,11 @@ zink_screen_handle_vkresult(struct zink_screen *screen, VkResult ret) VkSemaphore zink_create_semaphore(struct zink_screen *screen); +void +zink_screen_lock_context(struct zink_screen *screen); +void +zink_screen_unlock_context(struct zink_screen *screen); + VkFormat zink_get_format(struct zink_screen *screen, enum pipe_format format); diff --git a/src/gallium/drivers/zink/zink_types.h b/src/gallium/drivers/zink/zink_types.h index de2629878bb..78be78360ab 100644 --- a/src/gallium/drivers/zink/zink_types.h +++ b/src/gallium/drivers/zink/zink_types.h @@ -1276,6 +1276,7 @@ struct zink_screen { VkSemaphore sem; VkFence fence; struct util_queue flush_queue; + simple_mtx_t copy_context_lock; struct zink_context *copy_context; simple_mtx_t semaphores_lock;