zink: add locking for zink_screen::copy_context and defer creation

the copy context isn't always used, so this allows its creation to
be deferred and potentially save a bunch of memory

also add locking for multi-context thread safety

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21452>
This commit is contained in:
Mike Blumenkrantz 2023-02-21 10:11:15 -05:00 committed by Marge Bot
parent a7b98dd4be
commit d78de2a962
5 changed files with 34 additions and 7 deletions

View file

@ -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, &timestamp);

View file

@ -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;
}

View file

@ -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 &&

View file

@ -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);

View file

@ -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;