From e9301b36fe8bb16cdcef920f7d22a4a4070c8c17 Mon Sep 17 00:00:00 2001 From: Jesse Natalie Date: Wed, 2 Jul 2025 14:16:08 -0700 Subject: [PATCH] d3d12: Store fence FD type in the fence Native sync fences represent point-in-time (fence + value) and can have CPU wait events. Timeline semaphores represent a full timeline, do not have a CPU wait event, and can have their value updated dynamically. Part-of: --- src/gallium/drivers/d3d12/d3d12_fence.cpp | 12 +++++++++--- src/gallium/drivers/d3d12/d3d12_fence.h | 5 ++++- src/gallium/drivers/d3d12/d3d12_screen.cpp | 2 +- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/gallium/drivers/d3d12/d3d12_fence.cpp b/src/gallium/drivers/d3d12/d3d12_fence.cpp index f6a9045cd9e..f1e16d36899 100644 --- a/src/gallium/drivers/d3d12/d3d12_fence.cpp +++ b/src/gallium/drivers/d3d12/d3d12_fence.cpp @@ -33,7 +33,10 @@ static void destroy_fence(struct d3d12_fence *fence) { - d3d12_fence_close_event(fence->event, fence->event_fd); + if (fence->type == PIPE_FD_TYPE_NATIVE_SYNC) + d3d12_fence_close_event(fence->event, fence->event_fd); + else + fence->cmdqueue_fence->Release(); FREE(fence); } @@ -65,6 +68,7 @@ d3d12_create_fence(struct d3d12_screen *screen, bool signal_new) return NULL; } + ret->type = PIPE_FD_TYPE_NATIVE_SYNC; uint64_t value = screen->fence_value; if (signal_new) { value = ++screen->fence_value; @@ -83,7 +87,7 @@ fail: } struct d3d12_fence * -d3d12_open_fence(struct d3d12_screen *screen, HANDLE handle, const void *name) +d3d12_open_fence(struct d3d12_screen *screen, HANDLE handle, const void *name, pipe_fd_type type) { struct d3d12_fence *ret = CALLOC_STRUCT(d3d12_fence); if (!ret) { @@ -104,6 +108,7 @@ d3d12_open_fence(struct d3d12_screen *screen, HANDLE handle, const void *name) return NULL; } + ret->type = type; /* A new value will be assigned later */ ret->value = 0; pipe_reference_init(&ret->reference, 1); @@ -130,9 +135,10 @@ fence_reference(struct pipe_screen *pscreen, bool d3d12_fence_finish(struct d3d12_fence *fence, uint64_t timeout_ns) { + assert(fence->type == PIPE_FD_TYPE_NATIVE_SYNC); if (fence->signaled) return true; - + bool complete = fence->cmdqueue_fence->GetCompletedValue() >= fence->value; if (!complete && timeout_ns) complete = d3d12_fence_wait_event(fence->event, fence->event_fd, timeout_ns); diff --git a/src/gallium/drivers/d3d12/d3d12_fence.h b/src/gallium/drivers/d3d12/d3d12_fence.h index 4eec48e166d..9b6303e7cf6 100644 --- a/src/gallium/drivers/d3d12/d3d12_fence.h +++ b/src/gallium/drivers/d3d12/d3d12_fence.h @@ -86,6 +86,9 @@ struct d3d12_screen; struct d3d12_fence { struct pipe_reference reference; ID3D12Fence *cmdqueue_fence; + pipe_fd_type type; + + // The below fields are only valid if type == PIPE_FD_TYPE_NATIVE_SYNC HANDLE event; int event_fd; uint64_t value; @@ -105,7 +108,7 @@ struct d3d12_fence * d3d12_create_fence(struct d3d12_screen *screen, bool signal_new); struct d3d12_fence * -d3d12_open_fence(struct d3d12_screen *screen, HANDLE handle, const void *name); +d3d12_open_fence(struct d3d12_screen *screen, HANDLE handle, const void *name, pipe_fd_type type); 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 9734f01e359..c0423246f50 100644 --- a/src/gallium/drivers/d3d12/d3d12_screen.cpp +++ b/src/gallium/drivers/d3d12/d3d12_screen.cpp @@ -1140,7 +1140,7 @@ d3d12_create_fence_win32(struct pipe_screen *pscreen, struct pipe_fence_handle * { d3d12_fence_reference((struct d3d12_fence **)pfence, nullptr); if(type == PIPE_FD_TYPE_TIMELINE_SEMAPHORE) - *pfence = (struct pipe_fence_handle*) d3d12_open_fence(d3d12_screen(pscreen), handle, name); + *pfence = (struct pipe_fence_handle*) d3d12_open_fence(d3d12_screen(pscreen), handle, name, type); } static void