From: Jesse Natalie Date: Tue, 8 Dec 2020 22:57:12 +0000 (-0800) Subject: d3d12: Support Linux eventfds for fences X-Git-Tag: upstream/21.0.0~1329 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0b60d6a24d405066c4077154095a76204c103cc1;p=platform%2Fupstream%2Fmesa.git d3d12: Support Linux eventfds for fences Acked-by: Erik Faye-Lund Part-of: --- diff --git a/src/gallium/drivers/d3d12/d3d12_fence.cpp b/src/gallium/drivers/d3d12/d3d12_fence.cpp index a9d12b150d1..453c72b55e8 100644 --- a/src/gallium/drivers/d3d12/d3d12_fence.cpp +++ b/src/gallium/drivers/d3d12/d3d12_fence.cpp @@ -28,11 +28,58 @@ #include "util/u_memory.h" +#ifdef _WIN32 +static void +close_event(HANDLE event, int fd) +{ + if (event) + CloseHandle(event); +} + +static HANDLE +create_event(int *fd) +{ + *fd = -1; + return CreateEvent(NULL, FALSE, FALSE, NULL); +} + +static bool +wait_event(HANDLE event, int event_fd, uint64_t timeout_ns) +{ + DWORD timeout_ms = (timeout_ns == PIPE_TIMEOUT_INFINITE) ? INFINITE : timeout_ns / 1000000; + return WaitForSingleObject(event, timeout_ms) == WAIT_OBJECT_0; +} +#else +#include +#include +#include + +static void +close_event(HANDLE event, int fd) +{ + if (fd != -1) + close(fd); +} + +static HANDLE +create_event(int *fd) +{ + *fd = eventfd(0, 0); + return (HANDLE)(size_t)*fd; +} + +static bool +wait_event(HANDLE event, int event_fd, uint64_t timeout_ns) +{ + int timeout_ms = (timeout_ns == PIPE_TIMEOUT_INFINITE) ? -1 : timeout_ns / 1000000; + return sync_wait(event_fd, timeout_ms); +} +#endif + static void destroy_fence(struct d3d12_fence *fence) { - if (fence->event) - CloseHandle(fence->event); + close_event(fence->event, fence->event_fd); FREE(fence); } @@ -47,7 +94,7 @@ d3d12_create_fence(struct d3d12_screen *screen, struct d3d12_context *ctx) ret->cmdqueue_fence = ctx->cmdqueue_fence; ret->value = ++ctx->fence_value; - ret->event = CreateEvent(NULL, FALSE, FALSE, NULL); + ret->event = create_event(&ret->event_fd); if (FAILED(ctx->cmdqueue_fence->SetEventOnCompletion(ret->value, ret->event))) goto fail; if (FAILED(screen->cmdqueue->Signal(ctx->cmdqueue_fence, ret->value))) @@ -85,10 +132,8 @@ d3d12_fence_finish(struct d3d12_fence *fence, uint64_t timeout_ns) return true; bool complete = fence->cmdqueue_fence->GetCompletedValue() >= fence->value; - if (!complete && timeout_ns) { - DWORD timeout_ms = (timeout_ns == PIPE_TIMEOUT_INFINITE) ? INFINITE : timeout_ns / 1000000; - complete = WaitForSingleObject(fence->event, timeout_ms) == WAIT_OBJECT_0; - } + if (!complete && timeout_ns) + complete = wait_event(fence->event, fence->event_fd, timeout_ns); fence->signaled = complete; return complete; diff --git a/src/gallium/drivers/d3d12/d3d12_fence.h b/src/gallium/drivers/d3d12/d3d12_fence.h index 1ff9160a066..e9fdd64278b 100644 --- a/src/gallium/drivers/d3d12/d3d12_fence.h +++ b/src/gallium/drivers/d3d12/d3d12_fence.h @@ -39,6 +39,7 @@ struct d3d12_fence { struct pipe_reference reference; ID3D12Fence *cmdqueue_fence; HANDLE event; + int event_fd; uint64_t value; bool signaled; };