Skip to content

Commit 15c47a5

Browse files
committed
[dxvk] Open the D3DKMT local semaphore handle on creation
1 parent 663b762 commit 15c47a5

4 files changed

Lines changed: 98 additions & 1 deletion

File tree

src/dxvk/dxvk_fence.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,41 @@ namespace dxvk {
5656
Logger::warn(str::format("Importing semaphores of type ", info.sharedType, " not supported by device"));
5757
}
5858
}
59+
60+
#ifdef _WIN32
61+
if (info.sharedType != VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_FLAG_BITS_MAX_ENUM) {
62+
VkSemaphoreGetWin32HandleInfoKHR win32HandleInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR };
63+
win32HandleInfo.semaphore = m_semaphore;
64+
win32HandleInfo.handleType = m_info.sharedType;
65+
66+
HANDLE sharedHandle = INVALID_HANDLE_VALUE;
67+
VkResult vr = m_vkd->vkGetSemaphoreWin32HandleKHR(m_vkd->device(), &win32HandleInfo, &sharedHandle);
68+
69+
if (vr != VK_SUCCESS) {
70+
Logger::err(str::format("Failed to get semaphore handle: ", vr));
71+
} else if (m_info.sharedType == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT) {
72+
D3DKMT_OPENSYNCHRONIZATIONOBJECT desc = { };
73+
desc.hSharedHandle = (uintptr_t)sharedHandle;
74+
75+
if (D3DKMTOpenSynchronizationObject(&desc)) {
76+
Logger::warn("DxvkFence::DxvkFence: Failed to open shared D3DKMT handle");
77+
} else {
78+
m_kmtLocal = desc.hSyncObject;
79+
m_kmtGlobal = desc.hSharedHandle;
80+
}
81+
} else {
82+
D3DKMT_OPENSYNCOBJECTFROMNTHANDLE desc = { };
83+
desc.hNtHandle = sharedHandle;
84+
85+
if (D3DKMTOpenSyncObjectFromNtHandle(&desc)) {
86+
Logger::warn("DxvkFence::DxvkFence: Failed to open shared NT handle");
87+
} else {
88+
m_kmtLocal = desc.hSyncObject;
89+
}
90+
CloseHandle(sharedHandle);
91+
}
92+
}
93+
#endif
5994
}
6095

6196

@@ -68,6 +103,11 @@ namespace dxvk {
68103
}
69104
m_thread.join();
70105
}
106+
if (m_kmtLocal) {
107+
D3DKMT_DESTROYSYNCHRONIZATIONOBJECT desc = { };
108+
desc.hSyncObject = m_kmtLocal;
109+
D3DKMTDestroySynchronizationObject(&desc);
110+
}
71111
m_vkd->vkDestroySemaphore(m_vkd->device(), m_semaphore, nullptr);
72112
}
73113

src/dxvk/dxvk_fence.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <vector>
77

88
#include "dxvk_include.h"
9+
#include "dxvk_adapter.h"
910

1011
#include "../util/thread.h"
1112

@@ -65,6 +66,24 @@ namespace dxvk {
6566
VkSemaphore handle() const {
6667
return m_semaphore;
6768
}
69+
70+
/**
71+
* \brief D3DKMT sync object local handle
72+
* \returns The sync object D3DKMT local handle
73+
* \returns \c 0 if fence is not shared
74+
*/
75+
D3DKMT_HANDLE kmtLocal() const {
76+
return m_kmtLocal;
77+
}
78+
79+
/**
80+
* \brief D3DKMT sync object global handle
81+
* \returns The sync object D3DKMT global handle
82+
* \returns \c 0 if sync object is not shared or shared with NT handle
83+
*/
84+
D3DKMT_HANDLE kmtGlobal() const {
85+
return m_kmtGlobal;
86+
}
6887

6988
/**
7089
* \brief Retrieves current semaphore value
@@ -118,6 +137,8 @@ namespace dxvk {
118137
Rc<vk::DeviceFn> m_vkd;
119138
DxvkFenceCreateInfo m_info;
120139
VkSemaphore m_semaphore;
140+
D3DKMT_HANDLE m_kmtLocal = 0;
141+
D3DKMT_HANDLE m_kmtGlobal = 0;
121142

122143
std::priority_queue<QueueItem> m_queue;
123144
bool m_running = false;

src/util/util_gdi.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ namespace dxvk {
3434
return -1;
3535
}
3636

37+
NTSTATUS WINAPI D3DKMTDestroySynchronizationObject(const D3DKMT_DESTROYSYNCHRONIZATIONOBJECT *desc) {
38+
Logger::warn("D3DKMTDestroySynchronizationObject: Not available on this platform.");
39+
return -1;
40+
}
41+
3742
NTSTATUS D3DKMTOpenAdapterFromLuid(D3DKMT_OPENADAPTERFROMLUID *desc) {
3843
Logger::warn("D3DKMTOpenAdapterFromLuid: Not available on this platform.");
3944
return -1;
@@ -48,6 +53,16 @@ namespace dxvk {
4853
Logger::warn("D3DKMTOpenResourceFromNtHandle: Not available on this platform.");
4954
return -1;
5055
}
56+
57+
NTSTATUS WINAPI D3DKMTOpenSynchronizationObject(D3DKMT_OPENSYNCHRONIZATIONOBJECT *desc) {
58+
Logger::warn("D3DKMTOpenSynchronizationObject: Not available on this platform.");
59+
return -1;
60+
}
61+
62+
NTSTATUS WINAPI D3DKMTOpenSyncObjectFromNtHandle(D3DKMT_OPENSYNCOBJECTFROMNTHANDLE *desc) {
63+
Logger::warn("D3DKMTOpenSyncObjectFromNtHandle: Not available on this platform.");
64+
return -1;
65+
}
5166
#endif
5267

53-
}
68+
}

src/util/util_gdi.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,11 @@ namespace dxvk {
109109
D3DKMT_HANDLE hDevice;
110110
} D3DKMT_DESTROYDEVICE;
111111

112+
typedef struct _D3DKMT_DESTROYSYNCHRONIZATIONOBJECT
113+
{
114+
D3DKMT_HANDLE hSyncObject;
115+
} D3DKMT_DESTROYSYNCHRONIZATIONOBJECT;
116+
112117
typedef struct _D3DKMT_OPENADAPTERFROMLUID
113118
{
114119
LUID AdapterLuid;
@@ -169,13 +174,29 @@ namespace dxvk {
169174
D3DKMT_HANDLE hSyncObject;
170175
} D3DKMT_OPENRESOURCEFROMNTHANDLE;
171176

177+
typedef struct _D3DKMT_OPENSYNCHRONIZATIONOBJECT
178+
{
179+
D3DKMT_HANDLE hSharedHandle;
180+
D3DKMT_HANDLE hSyncObject;
181+
UINT64 Reserved[8];
182+
} D3DKMT_OPENSYNCHRONIZATIONOBJECT;
183+
184+
typedef struct _D3DKMT_OPENSYNCOBJECTFROMNTHANDLE
185+
{
186+
HANDLE hNtHandle;
187+
D3DKMT_HANDLE hSyncObject;
188+
} D3DKMT_OPENSYNCOBJECTFROMNTHANDLE;
189+
172190
EXTERN_C WINBASEAPI NTSTATUS WINAPI D3DKMTCloseAdapter(const D3DKMT_CLOSEADAPTER *desc);
173191
EXTERN_C WINBASEAPI NTSTATUS WINAPI D3DKMTCreateDCFromMemory(D3DKMT_CREATEDCFROMMEMORY *desc);
174192
EXTERN_C WINBASEAPI NTSTATUS WINAPI D3DKMTCreateDevice(D3DKMT_CREATEDEVICE *desc);
175193
EXTERN_C WINBASEAPI NTSTATUS WINAPI D3DKMTDestroyAllocation(const D3DKMT_DESTROYALLOCATION *desc);
176194
EXTERN_C WINBASEAPI NTSTATUS WINAPI D3DKMTDestroyDCFromMemory(const D3DKMT_DESTROYDCFROMMEMORY *desc);
177195
EXTERN_C WINBASEAPI NTSTATUS WINAPI D3DKMTDestroyDevice(const D3DKMT_DESTROYDEVICE *desc);
196+
EXTERN_C WINBASEAPI NTSTATUS WINAPI D3DKMTDestroySynchronizationObject(const D3DKMT_DESTROYSYNCHRONIZATIONOBJECT *desc);
178197
EXTERN_C WINBASEAPI NTSTATUS WINAPI D3DKMTOpenAdapterFromLuid(D3DKMT_OPENADAPTERFROMLUID *desc);
179198
EXTERN_C WINBASEAPI NTSTATUS WINAPI D3DKMTOpenResource2(D3DKMT_OPENRESOURCE *desc);
180199
EXTERN_C WINBASEAPI NTSTATUS WINAPI D3DKMTOpenResourceFromNtHandle(D3DKMT_OPENRESOURCEFROMNTHANDLE *desc);
200+
EXTERN_C WINBASEAPI NTSTATUS WINAPI D3DKMTOpenSynchronizationObject(D3DKMT_OPENSYNCHRONIZATIONOBJECT *desc);
201+
EXTERN_C WINBASEAPI NTSTATUS WINAPI D3DKMTOpenSyncObjectFromNtHandle(D3DKMT_OPENSYNCOBJECTFROMNTHANDLE *desc);
181202
}

0 commit comments

Comments
 (0)