dzn: Add an eventfd sync implementation

Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Bill Kristiansen <billkris@microsoft.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17340>
This commit is contained in:
Jesse Natalie 2022-07-01 09:05:25 -07:00 committed by Marge Bot
parent c7d8f1a7b8
commit 45ad8125f5
1 changed files with 35 additions and 7 deletions

View File

@ -30,6 +30,11 @@
#include "util/macros.h"
#include "util/os_time.h"
#ifndef _WIN32
#include <sys/eventfd.h>
#include <libsync.h>
#endif
static VkResult
dzn_sync_init(struct vk_device *device,
struct vk_sync *sync,
@ -128,9 +133,17 @@ dzn_sync_wait(struct vk_device *device,
{
struct dzn_device *ddev = container_of(device, struct dzn_device, vk);
#ifdef _WIN32
HANDLE event = CreateEventA(NULL, FALSE, FALSE, NULL);
if (event == NULL)
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
#else
int event_fd = eventfd(0, EFD_CLOEXEC);
if (event_fd == -1)
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
/* The D3D12 event-based APIs in WSL expect an eventfd file descriptor cast to HANDLE */
HANDLE event = (HANDLE)(intptr_t)event_fd;
#endif
STACK_ARRAY(ID3D12Fence *, fences, wait_count);
STACK_ARRAY(uint64_t, values, wait_count);
@ -155,14 +168,24 @@ dzn_sync_wait(struct vk_device *device,
event))) {
STACK_ARRAY_FINISH(fences);
STACK_ARRAY_FINISH(values);
#ifdef _WIN32
CloseHandle(event);
#else
close(event_fd);
#endif
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
}
#ifdef _WIN32
DWORD timeout_ms;
static const DWORD timeout_infinite = INFINITE;
#else
int timeout_ms;
static const int timeout_infinite = -1;
#endif
if (abs_timeout_ns == OS_TIMEOUT_INFINITE) {
timeout_ms = INFINITE;
timeout_ms = timeout_infinite;
} else {
uint64_t cur_time = os_time_get_nano();
uint64_t rel_timeout_ns =
@ -171,20 +194,25 @@ dzn_sync_wait(struct vk_device *device,
timeout_ms = (rel_timeout_ns / 1000000) + (rel_timeout_ns % 1000000 ? 1 : 0);
}
#ifdef _WIN32
DWORD res =
WaitForSingleObject(event, timeout_ms);
CloseHandle(event);
VkResult ret = VK_SUCCESS;
if (res == WAIT_TIMEOUT)
ret = VK_TIMEOUT;
else if (res != WAIT_OBJECT_0)
ret = vk_error(device, VK_ERROR_UNKNOWN);
#else
VkResult ret = sync_wait(event_fd, timeout_ms) != 0 ? VK_TIMEOUT : VK_SUCCESS;
close(event_fd);
#endif
STACK_ARRAY_FINISH(fences);
STACK_ARRAY_FINISH(values);
if (res == WAIT_TIMEOUT)
return VK_TIMEOUT;
else if (res != WAIT_OBJECT_0)
return vk_error(device, VK_ERROR_UNKNOWN);
return VK_SUCCESS;
return ret;
}
const struct vk_sync_type dzn_sync_type = {