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> (cherry picked from commitc1b827d6a2
)
This commit is contained in:
@@ -3037,7 +3037,7 @@
|
||||
"description": "zink: fix zink_create_fence_fd to properly import",
|
||||
"nominated": true,
|
||||
"nomination_type": 1,
|
||||
"resolution": 0,
|
||||
"resolution": 1,
|
||||
"main_sha": null,
|
||||
"because_sha": "32597e116d7317127ef8a7caf8dc75b50f48b8e1"
|
||||
},
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user