zink: make timeline semaphores per-screen
I misread the spec, and it turns out timeline ids can't be reused across semaphores. This is obvious in retrospect, but what can be done? Reviewed-by: Erik Faye-Lund <erik.faye-lund@collabora.com> Tested-by: Erik Faye-Lund <erik.faye-lund@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10115>
This commit is contained in:

committed by
Marge Bot

parent
1ad295ed6f
commit
fa36a16c68
@@ -154,8 +154,6 @@ create_batch_state(struct zink_context *ctx)
|
||||
struct zink_screen *screen = zink_screen(ctx->base.screen);
|
||||
struct zink_batch_state *bs = rzalloc(NULL, struct zink_batch_state);
|
||||
bs->have_timelines = ctx->have_timelines;
|
||||
if (ctx->have_timelines)
|
||||
bs->sem = ctx->batch.sem;
|
||||
VkCommandPoolCreateInfo cpci = {};
|
||||
cpci.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
||||
cpci.queueFamilyIndex = screen->gfx_queue;
|
||||
@@ -252,20 +250,6 @@ get_batch_state(struct zink_context *ctx, struct zink_batch *batch)
|
||||
return bs;
|
||||
}
|
||||
|
||||
static void
|
||||
init_semaphore(struct zink_context *ctx, struct zink_batch *batch)
|
||||
{
|
||||
struct zink_screen *screen = zink_screen(ctx->base.screen);
|
||||
VkSemaphoreCreateInfo sci = {};
|
||||
VkSemaphoreTypeCreateInfo tci = {};
|
||||
sci.pNext = &tci;
|
||||
sci.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
||||
tci.sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO;
|
||||
tci.semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE;
|
||||
if (vkCreateSemaphore(screen->dev, &sci, NULL, &batch->sem) != VK_SUCCESS)
|
||||
ctx->have_timelines = false;
|
||||
}
|
||||
|
||||
void
|
||||
zink_reset_batch(struct zink_context *ctx, struct zink_batch *batch)
|
||||
{
|
||||
@@ -273,18 +257,12 @@ zink_reset_batch(struct zink_context *ctx, struct zink_batch *batch)
|
||||
bool fresh = !batch->state;
|
||||
|
||||
if (ctx->have_timelines) {
|
||||
bool do_reset = false;
|
||||
if (screen->last_finished > ctx->curr_batch && ctx->curr_batch == 1) {
|
||||
do_reset = true;
|
||||
/* semaphore signal values can never decrease,
|
||||
* so we need a new semaphore anytime we overflow
|
||||
*/
|
||||
if (ctx->batch.prev_sem)
|
||||
vkDestroySemaphore(screen->dev, ctx->batch.prev_sem, NULL);
|
||||
ctx->batch.prev_sem = ctx->batch.sem;
|
||||
if (fresh || (screen->last_finished > ctx->curr_batch && ctx->curr_batch == 1)) {
|
||||
if (!zink_screen_init_semaphore(screen)) {
|
||||
debug_printf("timeline init failed, things are about to go dramatically wrong.");
|
||||
ctx->have_timelines = false;
|
||||
}
|
||||
}
|
||||
if (fresh || do_reset)
|
||||
init_semaphore(ctx, batch);
|
||||
}
|
||||
|
||||
batch->state = get_batch_state(ctx, batch);
|
||||
@@ -351,7 +329,7 @@ submit_queue(void *data, int thread_index)
|
||||
tsi.signalSemaphoreValueCount = 1;
|
||||
tsi.pSignalSemaphoreValues = &batch_id;
|
||||
si.signalSemaphoreCount = 1;
|
||||
si.pSignalSemaphores = &bs->sem;
|
||||
si.pSignalSemaphores = &zink_screen(bs->ctx->base.screen)->sem;
|
||||
}
|
||||
|
||||
struct wsi_memory_signal_submit_info mem_signal = {
|
||||
|
@@ -89,8 +89,6 @@ struct zink_batch {
|
||||
uint32_t last_batch_id;
|
||||
VkQueue queue; //gfx+compute
|
||||
VkQueue thread_queue; //gfx+compute
|
||||
VkSemaphore sem;
|
||||
VkSemaphore prev_sem;
|
||||
struct util_queue flush_queue; //TODO: move to wsi
|
||||
|
||||
bool has_work;
|
||||
|
@@ -301,10 +301,6 @@ zink_context_destroy(struct pipe_context *pctx)
|
||||
|
||||
pipe_resource_reference(&ctx->dummy_vertex_buffer, NULL);
|
||||
pipe_resource_reference(&ctx->dummy_xfb_buffer, NULL);
|
||||
if (ctx->batch.sem)
|
||||
vkDestroySemaphore(screen->dev, ctx->batch.sem, NULL);
|
||||
if (ctx->batch.prev_sem)
|
||||
vkDestroySemaphore(screen->dev, ctx->batch.prev_sem, NULL);
|
||||
|
||||
if (ctx->tc)
|
||||
util_queue_destroy(&ctx->batch.flush_queue);
|
||||
@@ -2028,7 +2024,7 @@ timeline_wait(struct zink_context *ctx, uint32_t batch_id, uint64_t timeout)
|
||||
wi.sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO;
|
||||
wi.semaphoreCount = 1;
|
||||
/* handle batch_id overflow */
|
||||
wi.pSemaphores = batch_id > ctx->curr_batch ? &ctx->batch.prev_sem : &ctx->batch.sem;
|
||||
wi.pSemaphores = batch_id > ctx->curr_batch ? &screen->prev_sem : &screen->sem;
|
||||
uint64_t batch_id64 = batch_id;
|
||||
wi.pValues = &batch_id64;
|
||||
bool success = false;
|
||||
|
@@ -956,6 +956,12 @@ zink_destroy_screen(struct pipe_screen *pscreen)
|
||||
simple_mtx_destroy(&screen->mem_cache_mtx);
|
||||
vkDestroyPipelineCache(screen->dev, screen->pipeline_cache, NULL);
|
||||
|
||||
if (screen->sem)
|
||||
vkDestroySemaphore(screen->dev, screen->sem, NULL);
|
||||
if (screen->prev_sem)
|
||||
vkDestroySemaphore(screen->dev, screen->prev_sem, NULL);
|
||||
|
||||
|
||||
vkDestroyDevice(screen->dev, NULL);
|
||||
vkDestroyInstance(screen->instance, NULL);
|
||||
|
||||
@@ -1325,6 +1331,30 @@ populate_format_props(struct zink_screen *screen)
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
zink_screen_init_semaphore(struct zink_screen *screen)
|
||||
{
|
||||
VkSemaphoreCreateInfo sci = {};
|
||||
VkSemaphoreTypeCreateInfo tci = {};
|
||||
VkSemaphore sem;
|
||||
sci.pNext = &tci;
|
||||
sci.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
||||
tci.sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO;
|
||||
tci.semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE;
|
||||
|
||||
if (vkCreateSemaphore(screen->dev, &sci, NULL, &sem) == VK_SUCCESS) {
|
||||
/* semaphore signal values can never decrease,
|
||||
* so we need a new semaphore anytime we overflow
|
||||
*/
|
||||
if (screen->prev_sem)
|
||||
vkDestroySemaphore(screen->dev, screen->prev_sem, NULL);
|
||||
screen->sem = sem;
|
||||
return true;
|
||||
}
|
||||
screen->info.have_KHR_timeline_semaphore = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
zink_get_loader_version(void)
|
||||
{
|
||||
|
@@ -54,6 +54,8 @@ struct zink_screen {
|
||||
bool threaded;
|
||||
uint32_t curr_batch; //the current batch id
|
||||
uint32_t last_finished; //this is racy but ultimately doesn't matter
|
||||
VkSemaphore sem;
|
||||
VkSemaphore prev_sem;
|
||||
|
||||
bool device_lost;
|
||||
struct sw_winsys *winsys;
|
||||
@@ -191,6 +193,10 @@ zink_screen_check_last_finished(struct zink_screen *screen, uint32_t batch_id)
|
||||
return screen->last_finished >= batch_id;
|
||||
}
|
||||
|
||||
bool
|
||||
zink_screen_init_semaphore(struct zink_screen *screen);
|
||||
|
||||
|
||||
static inline struct zink_screen *
|
||||
zink_screen(struct pipe_screen *pipe)
|
||||
{
|
||||
|
Reference in New Issue
Block a user