summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesse Natalie <jenatali@microsoft.com>2023-05-05 08:41:45 -0700
committerMarge Bot <emma+marge@anholt.net>2023-05-15 17:14:20 +0000
commitc64f1b6650f9f81a0329390d92f8c27bcb046e7c (patch)
treedf84c96e7cf59d8619a0bff43abe20a4c53b4481
parentcd5e372f1c8018bf76315ce179eac26ae26bc6a8 (diff)
downloadmesa-c64f1b6650f9f81a0329390d92f8c27bcb046e7c.tar.gz
dzn: Hook up win32 semaphore import/export
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22879>
-rw-r--r--src/microsoft/vulkan/dzn_private.h1
-rw-r--r--src/microsoft/vulkan/dzn_sync.c74
2 files changed, 73 insertions, 2 deletions
diff --git a/src/microsoft/vulkan/dzn_private.h b/src/microsoft/vulkan/dzn_private.h
index c4f903e2b35..8d0ffa367d3 100644
--- a/src/microsoft/vulkan/dzn_private.h
+++ b/src/microsoft/vulkan/dzn_private.h
@@ -1267,6 +1267,7 @@ struct dzn_event {
struct dzn_sync {
struct vk_sync vk;
ID3D12Fence *fence;
+ HANDLE export_handle;
};
extern const struct vk_sync_type dzn_sync_type;
diff --git a/src/microsoft/vulkan/dzn_sync.c b/src/microsoft/vulkan/dzn_sync.c
index f2cc8f85f0c..5b19330949b 100644
--- a/src/microsoft/vulkan/dzn_sync.c
+++ b/src/microsoft/vulkan/dzn_sync.c
@@ -43,10 +43,11 @@ dzn_sync_init(struct vk_device *device,
struct dzn_sync *dsync = container_of(sync, struct dzn_sync, vk);
struct dzn_device *ddev = container_of(device, struct dzn_device, vk);
- assert(!(sync->flags & VK_SYNC_IS_SHAREABLE));
+ D3D12_FENCE_FLAGS flags = (sync->flags & VK_SYNC_IS_SHAREABLE) ?
+ D3D12_FENCE_FLAG_SHARED : D3D12_FENCE_FLAG_NONE;
if (FAILED(ID3D12Device1_CreateFence(ddev->dev, initial_value,
- D3D12_FENCE_FLAG_NONE,
+ flags,
&IID_ID3D12Fence,
(void **)&dsync->fence)))
return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
@@ -61,6 +62,11 @@ dzn_sync_finish(struct vk_device *device,
struct dzn_sync *dsync = container_of(sync, struct dzn_sync, vk);
ID3D12Fence_Release(dsync->fence);
+
+#ifdef _WIN32
+ if (dsync->export_handle)
+ CloseHandle(dsync->export_handle);
+#endif
}
static VkResult
@@ -215,6 +221,65 @@ dzn_sync_wait(struct vk_device *device,
return ret;
}
+#ifdef _WIN32
+static VkResult
+dzn_sync_import_win32_handle(struct vk_device *device, struct vk_sync *sync,
+ HANDLE handle, LPCWSTR name)
+{
+ struct dzn_sync *dsync = container_of(sync, struct dzn_sync, vk);
+ struct dzn_device *ddev = container_of(device, struct dzn_device, vk);
+
+ dzn_sync_finish(device, sync);
+
+ HANDLE handle_to_close = NULL;
+ if (name) {
+ if (FAILED(ID3D12Device_OpenSharedHandleByName(ddev->dev, name, GENERIC_ALL, &handle_to_close)))
+ return vk_error(device, VK_ERROR_INVALID_EXTERNAL_HANDLE);
+ handle = handle_to_close;
+ }
+
+ HRESULT hr = ID3D12Device_OpenSharedHandle(ddev->dev, handle, &IID_ID3D12Fence, (void **)&dsync->fence);
+ if (handle_to_close)
+ CloseHandle(handle_to_close);
+ if (FAILED(hr))
+ return vk_error(device, VK_ERROR_INVALID_EXTERNAL_HANDLE);
+ return VK_SUCCESS;
+}
+
+static VkResult
+dzn_sync_export_win32_handle(struct vk_device *device, struct vk_sync *sync, HANDLE *handle)
+{
+ struct dzn_sync *dsync = container_of(sync, struct dzn_sync, vk);
+ if (dsync->export_handle) {
+ if (!DuplicateHandle(GetCurrentProcess(), dsync->export_handle,
+ GetCurrentProcess(), handle,
+ 0, FALSE, DUPLICATE_SAME_ACCESS))
+ return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
+ return VK_SUCCESS;
+ }
+
+ struct dzn_device *ddev = container_of(device, struct dzn_device, vk);
+ if (FAILED(ID3D12Device_CreateSharedHandle(ddev->dev, (ID3D12DeviceChild *)dsync->fence,
+ NULL, GENERIC_ALL, NULL, handle)))
+ return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
+ return VK_SUCCESS;
+}
+
+static VkResult
+dzn_sync_prep_win32_export(struct vk_device *device, struct vk_sync *sync,
+ const void *security_attributes, uint32_t access,
+ const wchar_t *name)
+{
+ struct dzn_sync *dsync = container_of(sync, struct dzn_sync, vk);
+ struct dzn_device *ddev = container_of(device, struct dzn_device, vk);
+ if (FAILED(ID3D12Device_CreateSharedHandle(ddev->dev, (ID3D12DeviceChild *)dsync->fence,
+ (const LPSECURITY_ATTRIBUTES)security_attributes,
+ access, name, &dsync->export_handle)))
+ return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
+ return VK_SUCCESS;
+}
+#endif
+
const struct vk_sync_type dzn_sync_type = {
.size = sizeof(struct dzn_sync),
.features = (enum vk_sync_features)
@@ -232,4 +297,9 @@ const struct vk_sync_type dzn_sync_type = {
.reset = dzn_sync_reset,
.move = dzn_sync_move,
.wait_many = dzn_sync_wait,
+#ifdef _WIN32
+ .import_win32_handle = dzn_sync_import_win32_handle,
+ .export_win32_handle = dzn_sync_export_win32_handle,
+ .set_win32_export_params = dzn_sync_prep_win32_export,
+#endif
};