zink: fix zink_create_fence_fd to properly import
This change fixes below:
1. Dup the fence fd, otherwise, since external semaphore import takes
the ownership of the fd, non-Vulkan part touches the fd leading to
undefined behavior. This can be hit on implementations that defer
the processing of the passed fd.
2. Use VK_SEMAPHORE_IMPORT_TEMPORARY_BIT for importing since that's
required for SYNC_FD handle type because of its copy transference.
Meanwhile, doing temporary import for opaque fd is fine in this path.
Fixes: 32597e116d
("zink: implement GL semaphores")
Signed-off-by: Yiwei Zhang <zzyiwei@chromium.org>
Reviewed-By: Mike Blumenkrantz <michael.blumenkrantz@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18453>
This commit is contained in:
@@ -28,6 +28,7 @@
|
|||||||
#include "zink_resource.h"
|
#include "zink_resource.h"
|
||||||
#include "zink_screen.h"
|
#include "zink_screen.h"
|
||||||
|
|
||||||
|
#include "util/os_file.h"
|
||||||
#include "util/set.h"
|
#include "util/set.h"
|
||||||
#include "util/u_memory.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)
|
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);
|
struct zink_screen *screen = zink_screen(pctx->screen);
|
||||||
VkResult ret = VK_ERROR_UNKNOWN;
|
VkResult result;
|
||||||
VkSemaphoreCreateInfo sci = {
|
|
||||||
VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
|
assert(fd >= 0);
|
||||||
NULL,
|
|
||||||
0
|
|
||||||
};
|
|
||||||
struct zink_tc_fence *mfence = zink_create_tc_fence();
|
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_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_SYNCOBJ] = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT,
|
||||||
};
|
};
|
||||||
VkImportSemaphoreFdInfoKHR sdi = {0};
|
|
||||||
assert(type < ARRAY_SIZE(flags));
|
assert(type < ARRAY_SIZE(flags));
|
||||||
|
|
||||||
*pfence = NULL;
|
const VkImportSemaphoreFdInfoKHR sdi = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR,
|
||||||
VkResult result = VKSCR(CreateSemaphore)(screen->dev, &sci, NULL, &mfence->sem);
|
.semaphore = mfence->sem,
|
||||||
if (result != VK_SUCCESS) {
|
.flags = VK_SEMAPHORE_IMPORT_TEMPORARY_BIT,
|
||||||
mesa_loge("ZINK: vkCreateSemaphore failed (%s)", vk_Result_to_str(result));
|
.handleType = flags[type],
|
||||||
FREE(mfence);
|
.fd = dup_fd,
|
||||||
return;
|
};
|
||||||
|
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;
|
*pfence = (struct pipe_fence_handle *)mfence;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fail:
|
fail_sem_import:
|
||||||
|
close(dup_fd);
|
||||||
|
fail_fd_dup:
|
||||||
VKSCR(DestroySemaphore)(screen->dev, mfence->sem, NULL);
|
VKSCR(DestroySemaphore)(screen->dev, mfence->sem, NULL);
|
||||||
|
fail_sem_create:
|
||||||
FREE(mfence);
|
FREE(mfence);
|
||||||
|
fail_tc_fence_create:
|
||||||
|
*pfence = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
Reference in New Issue
Block a user