From 66ba87d717067c5335e8da40f9bd310681738fb4 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Mon, 30 Jun 2025 15:54:21 -0400 Subject: [PATCH] zink: support NV_timeline_semaphore this is just adding new value arrays to the existing semaphore mechanics Part-of: --- src/gallium/drivers/zink/zink_batch.c | 29 +++++++++++++++++++++++--- src/gallium/drivers/zink/zink_fence.c | 18 ++++++++++++++-- src/gallium/drivers/zink/zink_screen.c | 2 ++ src/gallium/drivers/zink/zink_types.h | 2 ++ 4 files changed, 46 insertions(+), 5 deletions(-) diff --git a/src/gallium/drivers/zink/zink_batch.c b/src/gallium/drivers/zink/zink_batch.c index 3a2bd2895d6..a9cea0624ef 100644 --- a/src/gallium/drivers/zink/zink_batch.c +++ b/src/gallium/drivers/zink/zink_batch.c @@ -127,8 +127,10 @@ zink_reset_batch_state(struct zink_context *ctx, struct zink_batch_state *bs) bs->signal_semaphore = VK_NULL_HANDLE; bs->sparse_semaphore = VK_NULL_HANDLE; util_dynarray_clear(&bs->wait_semaphore_stages); + util_dynarray_clear(&bs->wait_semaphore_values); util_dynarray_clear(&bs->wait_semaphores); util_dynarray_clear(&bs->user_signal_semaphores); + util_dynarray_clear(&bs->user_signal_semaphore_values); bs->present = VK_NULL_HANDLE; /* check the arrays first to avoid locking unnecessarily */ @@ -263,8 +265,10 @@ zink_batch_state_destroy(struct zink_screen *screen, struct zink_batch_state *bs util_dynarray_fini(&bs->acquires); util_dynarray_fini(&bs->signal_semaphores); util_dynarray_fini(&bs->user_signal_semaphores); + util_dynarray_fini(&bs->user_signal_semaphore_values); util_dynarray_fini(&bs->wait_semaphores); util_dynarray_fini(&bs->wait_semaphore_stages); + util_dynarray_fini(&bs->wait_semaphore_values); util_dynarray_fini(&bs->fd_wait_semaphores); util_dynarray_fini(&bs->fd_wait_semaphore_stages); util_dynarray_fini(&bs->tracked_semaphores); @@ -366,12 +370,14 @@ create_batch_state(struct zink_context *ctx) SET_CREATE_OR_FAIL(&bs->dmabuf_exports); util_dynarray_init(&bs->signal_semaphores, NULL); util_dynarray_init(&bs->user_signal_semaphores, NULL); + util_dynarray_init(&bs->user_signal_semaphore_values, NULL); util_dynarray_init(&bs->wait_semaphores, NULL); util_dynarray_init(&bs->tracked_semaphores, NULL); util_dynarray_init(&bs->fd_wait_semaphores, NULL); util_dynarray_init(&bs->fences, NULL); util_dynarray_init(&bs->dead_querypools, NULL); util_dynarray_init(&bs->wait_semaphore_stages, NULL); + util_dynarray_init(&bs->wait_semaphore_values, NULL); util_dynarray_init(&bs->fd_wait_semaphore_stages, NULL); util_dynarray_init(&bs->zombie_samplers, NULL); util_dynarray_init(&bs->freed_sparse_backing_bos, NULL); @@ -650,6 +656,14 @@ submit_queue(void *data, void *gdata, int thread_index) si[ZINK_SUBMIT_CMDBUF].waitSemaphoreCount = util_dynarray_num_elements(&bs->wait_semaphores, VkSemaphore); si[ZINK_SUBMIT_CMDBUF].pWaitSemaphores = bs->wait_semaphores.data; si[ZINK_SUBMIT_CMDBUF].pWaitDstStageMask = bs->wait_semaphore_stages.data; + VkTimelineSemaphoreSubmitInfo sem_submit = { + VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO, + NULL, + si[ZINK_SUBMIT_CMDBUF].waitSemaphoreCount, + bs->wait_semaphore_values.data + }; + if (si[ZINK_SUBMIT_CMDBUF].waitSemaphoreCount) + si[ZINK_SUBMIT_CMDBUF].pNext = &sem_submit; VkCommandBuffer cmdbufs[3]; unsigned c = 0; if (bs->has_unsync) @@ -685,9 +699,18 @@ submit_queue(void *data, void *gdata, int thread_index) assert(si[ZINK_SUBMIT_SIGNAL_INTERNAL].signalSemaphoreCount <= ZINK_MAX_SIGNALS); assert(tsi.signalSemaphoreValueCount <= ZINK_MAX_SIGNALS); - if (util_dynarray_num_elements(&bs->user_signal_semaphores, VkSemaphore)) { - si[ZINK_SUBMIT_SIGNAL_USER].signalSemaphoreCount = util_dynarray_num_elements(&bs->user_signal_semaphores, VkSemaphore); - si[ZINK_SUBMIT_SIGNAL_USER].pSignalSemaphores = bs->user_signal_semaphores.data; + si[ZINK_SUBMIT_SIGNAL_USER].signalSemaphoreCount = util_dynarray_num_elements(&bs->user_signal_semaphores, VkSemaphore); + si[ZINK_SUBMIT_SIGNAL_USER].pSignalSemaphores = bs->user_signal_semaphores.data; + VkTimelineSemaphoreSubmitInfo user_sem_submit = { + VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO, + NULL, + 0, + NULL, + si[ZINK_SUBMIT_SIGNAL_USER].signalSemaphoreCount, + bs->user_signal_semaphore_values.data + }; + if (si[ZINK_SUBMIT_SIGNAL_USER].signalSemaphoreCount) { + si[ZINK_SUBMIT_SIGNAL_USER].pNext = &user_sem_submit; } else { num_si--; if (!si[ZINK_SUBMIT_SIGNAL_INTERNAL].signalSemaphoreCount) diff --git a/src/gallium/drivers/zink/zink_fence.c b/src/gallium/drivers/zink/zink_fence.c index 6048bb12218..f28d335aecf 100644 --- a/src/gallium/drivers/zink/zink_fence.c +++ b/src/gallium/drivers/zink/zink_fence.c @@ -237,9 +237,9 @@ zink_fence_server_signal(struct pipe_context *pctx, struct pipe_fence_handle *pf struct zink_context *ctx = zink_context(pctx); struct zink_tc_fence *mfence = (struct zink_tc_fence *)pfence; struct zink_batch_state *bs = ctx->bs; - assert(!value); util_dynarray_append(&ctx->bs->user_signal_semaphores, VkSemaphore, mfence->sem); + util_dynarray_append(&ctx->bs->user_signal_semaphore_values, uint64_t, value); bs->has_work = true; @@ -254,7 +254,6 @@ zink_fence_server_sync(struct pipe_context *pctx, struct pipe_fence_handle *pfen { struct zink_context *ctx = zink_context(pctx); struct zink_tc_fence *mfence = (struct zink_tc_fence *)pfence; - assert(!value); if (mfence->deferred_ctx == pctx || !mfence->sem) return; @@ -264,6 +263,7 @@ zink_fence_server_sync(struct pipe_context *pctx, struct pipe_fence_handle *pfen VkPipelineStageFlags flag = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; util_dynarray_append(&ctx->bs->wait_semaphores, VkSemaphore, mfence->sem); util_dynarray_append(&ctx->bs->wait_semaphore_stages, VkPipelineStageFlags, flag); + util_dynarray_append(&ctx->bs->wait_semaphore_values, uint64_t, value); pipe_reference(NULL, &mfence->reference); util_dynarray_append(&ctx->bs->fences, struct zink_tc_fence*, mfence); } @@ -273,6 +273,11 @@ zink_create_fence_fd(struct pipe_context *pctx, struct pipe_fence_handle **pfenc { struct zink_screen *screen = zink_screen(pctx->screen); VkResult result; + VkSemaphoreType semtype[] = { + [PIPE_FD_TYPE_NATIVE_SYNC] = VK_SEMAPHORE_TYPE_BINARY, + [PIPE_FD_TYPE_SYNCOBJ] = VK_SEMAPHORE_TYPE_BINARY, + [PIPE_FD_TYPE_TIMELINE_SEMAPHORE_VK] = VK_SEMAPHORE_TYPE_TIMELINE, + }; assert(fd >= 0); @@ -280,9 +285,16 @@ zink_create_fence_fd(struct pipe_context *pctx, struct pipe_fence_handle **pfenc if (!mfence) goto fail_tc_fence_create; + const VkSemaphoreTypeCreateInfo tci = { + VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO, + NULL, + semtype[type], + }; const VkSemaphoreCreateInfo sci = { .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, + &tci }; + result = VKSCR(CreateSemaphore)(screen->dev, &sci, NULL, &mfence->sem); if (result != VK_SUCCESS) { mesa_loge("ZINK: vkCreateSemaphore failed (%s)", vk_Result_to_str(result)); @@ -296,12 +308,14 @@ zink_create_fence_fd(struct pipe_context *pctx, struct pipe_fence_handle **pfenc static const VkExternalSemaphoreHandleTypeFlagBits handle_type[] = { [PIPE_FD_TYPE_NATIVE_SYNC] = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT, [PIPE_FD_TYPE_SYNCOBJ] = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT, + [PIPE_FD_TYPE_TIMELINE_SEMAPHORE_VK] = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT, }; assert(type < ARRAY_SIZE(handle_type)); static const VkSemaphoreImportFlagBits flags[] = { [PIPE_FD_TYPE_NATIVE_SYNC] = VK_SEMAPHORE_IMPORT_TEMPORARY_BIT, [PIPE_FD_TYPE_SYNCOBJ] = 0, + [PIPE_FD_TYPE_TIMELINE_SEMAPHORE_VK] = 0, }; assert(type < ARRAY_SIZE(flags)); diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c index 78c605f2403..6ef06fbfebb 100644 --- a/src/gallium/drivers/zink/zink_screen.c +++ b/src/gallium/drivers/zink/zink_screen.c @@ -924,6 +924,8 @@ zink_init_screen_caps(struct zink_screen *screen) caps->min_texel_offset = screen->info.props.limits.minTexelOffset; caps->max_texel_offset = screen->info.props.limits.maxTexelOffset; + caps->max_timeline_semaphore_difference = screen->info.timeline_props.maxTimelineSemaphoreValueDifference; + caps->vertex_color_unclamped = true; caps->conditional_render = true; diff --git a/src/gallium/drivers/zink/zink_types.h b/src/gallium/drivers/zink/zink_types.h index 20cf8288158..7a127f2ead0 100644 --- a/src/gallium/drivers/zink/zink_types.h +++ b/src/gallium/drivers/zink/zink_types.h @@ -602,8 +602,10 @@ struct zink_batch_state { VkSemaphore signal_semaphore; //external signal semaphore struct util_dynarray signal_semaphores; //internal signal semaphores struct util_dynarray user_signal_semaphores; //api signal semaphores + struct util_dynarray user_signal_semaphore_values; //api signal semaphores struct util_dynarray wait_semaphores; //external wait semaphores struct util_dynarray wait_semaphore_stages; //external wait semaphores + struct util_dynarray wait_semaphore_values; //external wait semaphores struct util_dynarray fd_wait_semaphores; //dmabuf wait semaphores struct util_dynarray fd_wait_semaphore_stages; //dmabuf wait semaphores struct util_dynarray tracked_semaphores; //semaphores which are just tracked