diff options
author | Jesse Natalie <jenatali@microsoft.com> | 2023-05-05 08:41:45 -0700 |
---|---|---|
committer | Marge Bot <emma+marge@anholt.net> | 2023-05-15 17:14:20 +0000 |
commit | c64f1b6650f9f81a0329390d92f8c27bcb046e7c (patch) | |
tree | df84c96e7cf59d8619a0bff43abe20a4c53b4481 | |
parent | cd5e372f1c8018bf76315ce179eac26ae26bc6a8 (diff) | |
download | mesa-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.h | 1 | ||||
-rw-r--r-- | src/microsoft/vulkan/dzn_sync.c | 74 |
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 }; |