From 416f10fc3fb84475ec1bac07c355beba886a8fc2 Mon Sep 17 00:00:00 2001 From: Jesse Natalie Date: Sat, 9 Jul 2022 20:58:13 -0700 Subject: [PATCH] d3d12: Support importing fences / timeline semaphores Reviewed-by: Bill Kristiansen Reviewed-by: Giancarlo Devich Part-of: --- src/gallium/drivers/d3d12/d3d12_fence.cpp | 30 ++++++++++++++++++++++ src/gallium/drivers/d3d12/d3d12_fence.h | 3 +++ src/gallium/drivers/d3d12/d3d12_screen.cpp | 17 ++++++++++++ 3 files changed, 50 insertions(+) diff --git a/src/gallium/drivers/d3d12/d3d12_fence.cpp b/src/gallium/drivers/d3d12/d3d12_fence.cpp index 23592fce3df..d1d811a0f73 100644 --- a/src/gallium/drivers/d3d12/d3d12_fence.cpp +++ b/src/gallium/drivers/d3d12/d3d12_fence.cpp @@ -28,6 +28,8 @@ #include "util/u_memory.h" +#include + constexpr uint64_t NsPerMs = 1000000; constexpr uint64_t MaxTimeoutInNs = (uint64_t)UINT_MAX * NsPerMs; @@ -111,6 +113,34 @@ fail: return NULL; } +struct d3d12_fence * +d3d12_open_fence(struct d3d12_screen *screen, HANDLE handle, const void *name) +{ + struct d3d12_fence *ret = CALLOC_STRUCT(d3d12_fence); + if (!ret) { + debug_printf("CALLOC_STRUCT failed\n"); + return NULL; + } + + HANDLE handle_to_close = nullptr; + assert(!!handle ^ !!name); + if (name) { + screen->dev->OpenSharedHandleByName((LPCWSTR)name, GENERIC_ALL, &handle_to_close); + handle = handle_to_close; + } + + screen->dev->OpenSharedHandle(handle, IID_PPV_ARGS(&ret->cmdqueue_fence)); + if (!ret->cmdqueue_fence) { + free(ret); + return NULL; + } + + /* A new value will be assigned later */ + ret->value = 0; + pipe_reference_init(&ret->reference, 1); + return ret; +} + void d3d12_fence_reference(struct d3d12_fence **ptr, struct d3d12_fence *fence) { diff --git a/src/gallium/drivers/d3d12/d3d12_fence.h b/src/gallium/drivers/d3d12/d3d12_fence.h index 00c117f0911..1d013bac5be 100644 --- a/src/gallium/drivers/d3d12/d3d12_fence.h +++ b/src/gallium/drivers/d3d12/d3d12_fence.h @@ -49,6 +49,9 @@ d3d12_fence(struct pipe_fence_handle *pfence) struct d3d12_fence * d3d12_create_fence(struct d3d12_screen *screen); +struct d3d12_fence * +d3d12_open_fence(struct d3d12_screen *screen, HANDLE handle, const void *name); + void d3d12_fence_reference(struct d3d12_fence **ptr, struct d3d12_fence *fence); diff --git a/src/gallium/drivers/d3d12/d3d12_screen.cpp b/src/gallium/drivers/d3d12/d3d12_screen.cpp index 951587eb309..c6deb3e8227 100644 --- a/src/gallium/drivers/d3d12/d3d12_screen.cpp +++ b/src/gallium/drivers/d3d12/d3d12_screen.cpp @@ -1120,6 +1120,21 @@ d3d12_get_node_mask(struct pipe_screen *pscreen) return 1; } +static void +d3d12_create_fence_win32(struct pipe_screen *pscreen, struct pipe_fence_handle **pfence, void *handle, const void *name, enum pipe_fd_type type) +{ + d3d12_fence_reference((struct d3d12_fence **)pfence, + type == PIPE_FD_TYPE_TIMELINE_SEMAPHORE ? + d3d12_open_fence(d3d12_screen(pscreen), handle, name) : + nullptr); +} + +static void +d3d12_set_fence_timeline_value(struct pipe_screen *pscreen, struct pipe_fence_handle *pfence, uint64_t value) +{ + d3d12_fence(pfence)->value = value; +} + void d3d12_init_screen_base(struct d3d12_screen *screen, struct sw_winsys *winsys, LUID *adapter_luid) { @@ -1145,6 +1160,8 @@ d3d12_init_screen_base(struct d3d12_screen *screen, struct sw_winsys *winsys, LU screen->base.get_device_uuid = d3d12_get_device_uuid; screen->base.get_driver_uuid = d3d12_get_driver_uuid; screen->base.get_device_node_mask = d3d12_get_node_mask; + screen->base.create_fence_win32 = d3d12_create_fence_win32; + screen->base.set_fence_timeline_value = d3d12_set_fence_timeline_value; } bool