diff --git a/src/gallium/drivers/zink/zink_fence.c b/src/gallium/drivers/zink/zink_fence.c index 91f1499ea00..425136f6e10 100644 --- a/src/gallium/drivers/zink/zink_fence.c +++ b/src/gallium/drivers/zink/zink_fence.c @@ -28,6 +28,7 @@ #include "zink_resource.h" #include "zink_screen.h" +#include "util/os_file.h" #include "util/set.h" #include "util/u_memory.h" @@ -226,43 +227,57 @@ void zink_create_fence_fd(struct pipe_context *pctx, struct pipe_fence_handle **pfence, int fd, enum pipe_fd_type type) { struct zink_screen *screen = zink_screen(pctx->screen); - VkResult ret = VK_ERROR_UNKNOWN; - VkSemaphoreCreateInfo sci = { - VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, - NULL, - 0 - }; + VkResult result; + + assert(fd >= 0); + struct zink_tc_fence *mfence = zink_create_tc_fence(); - VkExternalSemaphoreHandleTypeFlagBits flags[] = { + if (!mfence) + goto fail_tc_fence_create; + + const VkSemaphoreCreateInfo sci = { + .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, + }; + result = VKSCR(CreateSemaphore)(screen->dev, &sci, NULL, &mfence->sem); + if (result != VK_SUCCESS) { + mesa_loge("ZINK: vkCreateSemaphore failed (%s)", vk_Result_to_str(result)); + goto fail_sem_create; + } + + int dup_fd = os_dupfd_cloexec(fd); + if (dup_fd < 0) + goto fail_fd_dup; + + static const VkExternalSemaphoreHandleTypeFlagBits flags[] = { [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, }; - VkImportSemaphoreFdInfoKHR sdi = {0}; assert(type < ARRAY_SIZE(flags)); - *pfence = NULL; - - VkResult result = VKSCR(CreateSemaphore)(screen->dev, &sci, NULL, &mfence->sem); - if (result != VK_SUCCESS) { - mesa_loge("ZINK: vkCreateSemaphore failed (%s)", vk_Result_to_str(result)); - FREE(mfence); - return; + const VkImportSemaphoreFdInfoKHR sdi = { + .sType = VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR, + .semaphore = mfence->sem, + .flags = VK_SEMAPHORE_IMPORT_TEMPORARY_BIT, + .handleType = flags[type], + .fd = dup_fd, + }; + result = VKSCR(ImportSemaphoreFdKHR)(screen->dev, &sdi); + if (!zink_screen_handle_vkresult(screen, result)) { + mesa_loge("ZINK: vkImportSemaphoreFdKHR failed (%s)", vk_Result_to_str(result)); + goto fail_sem_import; } - sdi.sType = VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR; - sdi.semaphore = mfence->sem; - sdi.handleType = flags[type]; - sdi.fd = fd; - ret = VKSCR(ImportSemaphoreFdKHR)(screen->dev, &sdi); - - if (!zink_screen_handle_vkresult(screen, ret)) - goto fail; *pfence = (struct pipe_fence_handle *)mfence; return; -fail: +fail_sem_import: + close(dup_fd); +fail_fd_dup: VKSCR(DestroySemaphore)(screen->dev, mfence->sem, NULL); +fail_sem_create: FREE(mfence); +fail_tc_fence_create: + *pfence = NULL; } #ifdef _WIN32