From 86fbd1a7de5a7925b21803c604533dbad0072285 Mon Sep 17 00:00:00 2001 From: "Yan,Shaobo" Date: Thu, 16 Feb 2023 13:49:23 +0000 Subject: [PATCH] Refactor Semaphore Service In Vulkan Backend Dawn provides external semaphore service in static way by compiling implementation files based on OS type. A better way is to select external semaphore in runtime. This CL adds ServiceImplementation interface and implements it for different semaphore type. Semaphore service delegate work to implementation in runtime. This CL also removes "DAWN_USE_SYNC_FD" macro. Bug=dawn:1593 Change-Id: Idc3f7b644430aad76198ef66dc5ba13e8cfc5a4d Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/119321 Reviewed-by: Corentin Wallez Kokoro: Kokoro Reviewed-by: Austin Eng Commit-Queue: Shaobo Yan --- src/dawn/common/BUILD.gn | 7 + src/dawn/common/Platform.h | 7 + src/dawn/native/BUILD.gn | 38 ++-- src/dawn/native/CMakeLists.txt | 7 +- src/dawn/native/vulkan/AdapterVk.cpp | 4 +- src/dawn/native/vulkan/TextureVk.cpp | 8 +- .../external_semaphore/SemaphoreService.cpp | 86 +++++++++ .../external_semaphore/SemaphoreService.h | 18 +- .../external_semaphore/SemaphoreServiceFD.cpp | 151 ---------------- .../SemaphoreServiceNull.cpp | 57 ------ .../SemaphoreServiceZirconHandle.cpp | 146 --------------- .../ServiceImplementation.cpp | 23 +++ .../ServiceImplementation.h | 56 ++++++ .../ServiceImplementationFD.cpp | 169 ++++++++++++++++++ .../ServiceImplementationFD.h | 36 ++++ .../ServiceImplementationZirconHandle.cpp | 168 +++++++++++++++++ .../ServiceImplementationZirconHandle.h | 36 ++++ 17 files changed, 627 insertions(+), 390 deletions(-) create mode 100644 src/dawn/native/vulkan/external_semaphore/SemaphoreService.cpp delete mode 100644 src/dawn/native/vulkan/external_semaphore/SemaphoreServiceFD.cpp delete mode 100644 src/dawn/native/vulkan/external_semaphore/SemaphoreServiceNull.cpp delete mode 100644 src/dawn/native/vulkan/external_semaphore/SemaphoreServiceZirconHandle.cpp create mode 100644 src/dawn/native/vulkan/external_semaphore/ServiceImplementation.cpp create mode 100644 src/dawn/native/vulkan/external_semaphore/ServiceImplementation.h create mode 100644 src/dawn/native/vulkan/external_semaphore/ServiceImplementationFD.cpp create mode 100644 src/dawn/native/vulkan/external_semaphore/ServiceImplementationFD.h create mode 100644 src/dawn/native/vulkan/external_semaphore/ServiceImplementationZirconHandle.cpp create mode 100644 src/dawn/native/vulkan/external_semaphore/ServiceImplementationZirconHandle.h diff --git a/src/dawn/common/BUILD.gn b/src/dawn/common/BUILD.gn index f46d108747..ebc61e4ae2 100644 --- a/src/dawn/common/BUILD.gn +++ b/src/dawn/common/BUILD.gn @@ -80,6 +80,13 @@ config("internal_config") { defines += [ "DAWN_ENABLE_BACKEND_VULKAN" ] } + # OS_CHROMEOS cannot be autodetected in runtime and + # cannot be detected with regular compiler macros either. + # Inject it from the build system + if (is_chromeos) { + defines += [ "DAWN_OS_CHROMEOS" ] + } + if (dawn_use_wayland) { defines += [ "DAWN_USE_WAYLAND" ] } diff --git a/src/dawn/common/Platform.h b/src/dawn/common/Platform.h index e49fc4ff1e..dc8d79c01b 100644 --- a/src/dawn/common/Platform.h +++ b/src/dawn/common/Platform.h @@ -29,6 +29,7 @@ // - POSIX // - LINUX // - ANDROID +// - CHROMEOS // - APPLE // - IOS // - MACOS @@ -51,6 +52,9 @@ #if defined(__ANDROID__) #define DAWN_PLATFORM_IS_ANDROID 1 #endif +#if defined(DAWN_OS_CHROMEOS) +#define DAWN_PLATFORM_IS_CHROMEOS 1 +#endif #elif defined(__APPLE__) #define DAWN_PLATFORM_IS_APPLE 1 @@ -190,6 +194,9 @@ static_assert(sizeof(sizeof(char)) == 4, "Expect sizeof(size_t) == 4"); #if !defined(DAWN_PLATFORM_IS_ANDROID) #define DAWN_PLATFORM_IS_ANDROID 0 #endif +#if !defined(DAWN_PLATFORM_IS_CHROMEOS) +#define DAWN_PLATFORM_IS_CHROMEOS 0 +#endif #if !defined(DAWN_PLATFORM_IS_APPLE) #define DAWN_PLATFORM_IS_APPLE 0 diff --git a/src/dawn/native/BUILD.gn b/src/dawn/native/BUILD.gn index 11b8a13a4f..4f3027327f 100644 --- a/src/dawn/native/BUILD.gn +++ b/src/dawn/native/BUILD.gn @@ -678,36 +678,34 @@ source_set("sources") { "vulkan/VulkanInfo.h", "vulkan/external_memory/MemoryService.cpp", "vulkan/external_memory/MemoryService.h", + "vulkan/external_semaphore/SemaphoreService.cpp", "vulkan/external_semaphore/SemaphoreService.h", + "vulkan/external_semaphore/ServiceImplementation.cpp", + "vulkan/external_semaphore/ServiceImplementation.h", ] - if (is_chromeos) { + if (is_android || is_linux || is_chromeos) { sources += [ - "vulkan/external_memory/MemoryServiceDmaBuf.cpp", - "vulkan/external_semaphore/SemaphoreServiceFD.cpp", - ] - defines += [ "DAWN_USE_SYNC_FDS" ] - } else if (is_linux) { - sources += [ - "vulkan/external_memory/MemoryServiceOpaqueFD.cpp", - "vulkan/external_semaphore/SemaphoreServiceFD.cpp", + "vulkan/external_semaphore/ServiceImplementationFD.cpp", + "vulkan/external_semaphore/ServiceImplementationFD.h", ] } else if (is_fuchsia) { sources += [ - "vulkan/external_memory/MemoryServiceZirconHandle.cpp", - "vulkan/external_semaphore/SemaphoreServiceZirconHandle.cpp", + "vulkan/external_semaphore/ServiceImplementationZirconHandle.cpp", + "vulkan/external_semaphore/ServiceImplementationZirconHandle.h", ] + } + + if (is_chromeos) { + sources += [ "vulkan/external_memory/MemoryServiceDmaBuf.cpp" ] + } else if (is_linux) { + sources += [ "vulkan/external_memory/MemoryServiceOpaqueFD.cpp" ] + } else if (is_fuchsia) { + sources += [ "vulkan/external_memory/MemoryServiceZirconHandle.cpp" ] } else if (is_android) { - sources += [ - "vulkan/external_memory/MemoryServiceAHardwareBuffer.cpp", - "vulkan/external_semaphore/SemaphoreServiceFD.cpp", - ] - defines += [ "DAWN_USE_SYNC_FDS" ] + sources += [ "vulkan/external_memory/MemoryServiceAHardwareBuffer.cpp" ] } else { - sources += [ - "vulkan/external_memory/MemoryServiceNull.cpp", - "vulkan/external_semaphore/SemaphoreServiceNull.cpp", - ] + sources += [ "vulkan/external_memory/MemoryServiceNull.cpp" ] } if (build_with_chromium && is_fuchsia) { # Necessary to ensure that the Vulkan libraries will be in the diff --git a/src/dawn/native/CMakeLists.txt b/src/dawn/native/CMakeLists.txt index ca5d5143ca..0ce0af4801 100644 --- a/src/dawn/native/CMakeLists.txt +++ b/src/dawn/native/CMakeLists.txt @@ -551,7 +551,10 @@ if (DAWN_ENABLE_VULKAN) "vulkan/VulkanInfo.h" "vulkan/external_memory/MemoryService.cpp" "vulkan/external_memory/MemoryService.h" + "vulkan/external_semaphore/SemaphoreService.cpp" "vulkan/external_semaphore/SemaphoreService.h" + "vulkan/external_semaphore/ServiceImplementation.cpp" + "vulkan/external_semaphore/ServiceImplementation.h" ) target_link_libraries(dawn_native PUBLIC Vulkan-Headers) @@ -560,12 +563,12 @@ if (DAWN_ENABLE_VULKAN) if (UNIX AND NOT APPLE) target_sources(dawn_native PRIVATE "vulkan/external_memory/MemoryServiceOpaqueFD.cpp" - "vulkan/external_semaphore/SemaphoreServiceFD.cpp" + "vulkan/external_semaphore/ServiceImplementationFD.cpp" + "vulkan/external_semaphore/ServiceImplementationFD.h" ) else() target_sources(dawn_native PRIVATE "vulkan/external_memory/MemoryServiceNull.cpp" - "vulkan/external_semaphore/SemaphoreServiceNull.cpp" ) endif() endif() diff --git a/src/dawn/native/vulkan/AdapterVk.cpp b/src/dawn/native/vulkan/AdapterVk.cpp index 1d7822c3dc..19556823cb 100644 --- a/src/dawn/native/vulkan/AdapterVk.cpp +++ b/src/dawn/native/vulkan/AdapterVk.cpp @@ -257,11 +257,11 @@ void Adapter::InitializeSupportedFeaturesImpl() { mSupportedFeatures.EnableFeature(Feature::BGRA8UnormStorage); } -#if defined(DAWN_USE_SYNC_FDS) +#if DAWN_PLATFORM_IS(ANDROID) || DAWN_PLATFORM_IS(CHROMEOS) // TODO(chromium:1258986): Precisely enable the feature by querying the device's format // features. mSupportedFeatures.EnableFeature(Feature::MultiPlanarFormats); -#endif +#endif // DAWN_PLATFORM_IS(ANDROID) || DAWN_PLATFORM_IS(CHROMEOS) } MaybeError Adapter::InitializeSupportedLimitsImpl(CombinedLimits* limits) { diff --git a/src/dawn/native/vulkan/TextureVk.cpp b/src/dawn/native/vulkan/TextureVk.cpp index 13e0b28f6f..2f4ccbd918 100644 --- a/src/dawn/native/vulkan/TextureVk.cpp +++ b/src/dawn/native/vulkan/TextureVk.cpp @@ -940,7 +940,9 @@ MaybeError Texture::ExportExternalTexture(VkImageLayout desiredLayout, Texture::~Texture() { if (mExternalSemaphoreHandle != kNullExternalSemaphoreHandle) { - external_semaphore::Service::CloseHandle(mExternalSemaphoreHandle); + ToBackend(GetDevice()) + ->GetExternalSemaphoreService() + ->CloseHandle(mExternalSemaphoreHandle); } mExternalSemaphoreHandle = kNullExternalSemaphoreHandle; } @@ -1354,7 +1356,9 @@ void Texture::EnsureSubresourceContentInitialized(CommandRecordingContext* recor void Texture::UpdateExternalSemaphoreHandle(ExternalSemaphoreHandle handle) { if (mExternalSemaphoreHandle != kNullExternalSemaphoreHandle) { - external_semaphore::Service::CloseHandle(mExternalSemaphoreHandle); + ToBackend(GetDevice()) + ->GetExternalSemaphoreService() + ->CloseHandle(mExternalSemaphoreHandle); } mExternalSemaphoreHandle = handle; } diff --git a/src/dawn/native/vulkan/external_semaphore/SemaphoreService.cpp b/src/dawn/native/vulkan/external_semaphore/SemaphoreService.cpp new file mode 100644 index 0000000000..bf0a10eecd --- /dev/null +++ b/src/dawn/native/vulkan/external_semaphore/SemaphoreService.cpp @@ -0,0 +1,86 @@ +// Copyright 2023 The Dawn Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "dawn/native/vulkan/external_semaphore/SemaphoreService.h" +#include "dawn/native/vulkan/VulkanFunctions.h" +#include "dawn/native/vulkan/VulkanInfo.h" +#include "dawn/native/vulkan/external_semaphore/ServiceImplementation.h" + +#if DAWN_PLATFORM_IS(FUCHSIA) +#include "dawn/native/vulkan/external_semaphore/ServiceImplementationZirconHandle.h" +#endif // DAWN_PLATFORM_IS(FUCHSIA) + +// Android, ChromeOS and Linux +#if DAWN_PLATFORM_IS(LINUX) +#include "dawn/native/vulkan/external_semaphore/ServiceImplementationFD.h" +#endif // DAWN_PLATFORM_IS(LINUX) + +namespace dawn::native::vulkan::external_semaphore { +// static +bool Service::CheckSupport(const VulkanDeviceInfo& deviceInfo, + VkPhysicalDevice physicalDevice, + const VulkanFunctions& fn) { +#if DAWN_PLATFORM_IS(FUCHSIA) + return CheckZirconHandleSupport(deviceInfo, physicalDevice, fn); +#elif DAWN_PLATFORM_IS(LINUX) // Android, ChromeOS and Linux + return CheckFDSupport(deviceInfo, physicalDevice, fn); +#else + return false; +#endif +} + +Service::Service(Device* device) { +#if DAWN_PLATFORM_IS(FUCHSIA) // Fuchsia + mServiceImpl = CreateZirconHandleService(device); +#elif DAWN_PLATFORM_IS(LINUX) || DAWN_PLATFORM_IS(CHROMEOS) // Android, ChromeOS and Linux + mServiceImpl = CreateFDService(device); +#endif +} + +Service::~Service() = default; + +bool Service::Supported() { + if (!mServiceImpl) { + return false; + } + + return mServiceImpl->Supported(); +} + +void Service::CloseHandle(ExternalSemaphoreHandle handle) { + ASSERT(mServiceImpl); + mServiceImpl->CloseHandle(handle); +} + +ResultOrError Service::ImportSemaphore(ExternalSemaphoreHandle handle) { + ASSERT(mServiceImpl); + return mServiceImpl->ImportSemaphore(handle); +} + +ResultOrError Service::CreateExportableSemaphore() { + ASSERT(mServiceImpl); + return mServiceImpl->CreateExportableSemaphore(); +} + +ResultOrError Service::ExportSemaphore(VkSemaphore semaphore) { + ASSERT(mServiceImpl); + return mServiceImpl->ExportSemaphore(semaphore); +} + +ExternalSemaphoreHandle Service::DuplicateHandle(ExternalSemaphoreHandle handle) { + ASSERT(mServiceImpl); + return mServiceImpl->DuplicateHandle(handle); +} + +} // namespace dawn::native::vulkan::external_semaphore diff --git a/src/dawn/native/vulkan/external_semaphore/SemaphoreService.h b/src/dawn/native/vulkan/external_semaphore/SemaphoreService.h index 58a3ef5379..1f4e278da7 100644 --- a/src/dawn/native/vulkan/external_semaphore/SemaphoreService.h +++ b/src/dawn/native/vulkan/external_semaphore/SemaphoreService.h @@ -15,17 +15,19 @@ #ifndef SRC_DAWN_NATIVE_VULKAN_EXTERNAL_SEMAPHORE_SEMAPHORESERVICE_H_ #define SRC_DAWN_NATIVE_VULKAN_EXTERNAL_SEMAPHORE_SEMAPHORESERVICE_H_ -#include "dawn/common/vulkan_platform.h" +#include + #include "dawn/native/Error.h" #include "dawn/native/vulkan/ExternalHandle.h" -#include "dawn/native/vulkan/VulkanFunctions.h" -#include "dawn/native/vulkan/VulkanInfo.h" namespace dawn::native::vulkan { class Device; +struct VulkanDeviceInfo; +struct VulkanFunctions; } // namespace dawn::native::vulkan namespace dawn::native::vulkan::external_semaphore { +class ServiceImplementation; class Service { public: @@ -35,6 +37,7 @@ class Service { static bool CheckSupport(const VulkanDeviceInfo& deviceInfo, VkPhysicalDevice physicalDevice, const VulkanFunctions& fn); + void CloseHandle(ExternalSemaphoreHandle handle); // True if the device reports it supports this feature bool Supported(); @@ -51,14 +54,9 @@ class Service { // Duplicate a new external handle from the given one. ExternalSemaphoreHandle DuplicateHandle(ExternalSemaphoreHandle handle); - // Close an external handle. - static void CloseHandle(ExternalSemaphoreHandle handle); - private: - Device* mDevice = nullptr; - - // True if early checks pass that determine if the service is supported - bool mSupported = false; + // Linux, ChromeOS and Android use FD semaphore and Fuchia uses ZirconHandle. + std::unique_ptr mServiceImpl; }; } // namespace dawn::native::vulkan::external_semaphore diff --git a/src/dawn/native/vulkan/external_semaphore/SemaphoreServiceFD.cpp b/src/dawn/native/vulkan/external_semaphore/SemaphoreServiceFD.cpp deleted file mode 100644 index f80c583f83..0000000000 --- a/src/dawn/native/vulkan/external_semaphore/SemaphoreServiceFD.cpp +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright 2019 The Dawn Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include -#include - -#include "dawn/native/vulkan/AdapterVk.h" -#include "dawn/native/vulkan/BackendVk.h" -#include "dawn/native/vulkan/DeviceVk.h" -#include "dawn/native/vulkan/VulkanError.h" -#include "dawn/native/vulkan/external_semaphore/SemaphoreService.h" - -static constexpr VkExternalSemaphoreHandleTypeFlagBits kHandleType = -#if defined(DAWN_USE_SYNC_FDS) - VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT; -#else - VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR; -#endif // defined(DAWN_USE_SYNC_FDS) - -namespace dawn::native::vulkan::external_semaphore { - -Service::Service(Device* device) - : mDevice(device), - mSupported(CheckSupport(device->GetDeviceInfo(), - ToBackend(device->GetAdapter())->GetPhysicalDevice(), - device->fn)) {} - -Service::~Service() = default; - -// static -bool Service::CheckSupport(const VulkanDeviceInfo& deviceInfo, - VkPhysicalDevice physicalDevice, - const VulkanFunctions& fn) { - if (!deviceInfo.HasExt(DeviceExt::ExternalSemaphoreFD)) { - return false; - } - - VkPhysicalDeviceExternalSemaphoreInfoKHR semaphoreInfo; - semaphoreInfo.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO_KHR; - semaphoreInfo.pNext = nullptr; - semaphoreInfo.handleType = kHandleType; - - VkExternalSemaphorePropertiesKHR semaphoreProperties; - semaphoreProperties.sType = VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR; - semaphoreProperties.pNext = nullptr; - - fn.GetPhysicalDeviceExternalSemaphoreProperties(physicalDevice, &semaphoreInfo, - &semaphoreProperties); - - VkFlags requiredFlags = VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT_KHR | - VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT_KHR; - - return IsSubset(requiredFlags, semaphoreProperties.externalSemaphoreFeatures); -} - -bool Service::Supported() { - return mSupported; -} - -ResultOrError Service::ImportSemaphore(ExternalSemaphoreHandle handle) { - DAWN_INVALID_IF(handle < 0, "Importing a semaphore with an invalid handle."); - - VkSemaphore semaphore = VK_NULL_HANDLE; - VkSemaphoreCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; - - DAWN_TRY(CheckVkSuccess( - mDevice->fn.CreateSemaphore(mDevice->GetVkDevice(), &info, nullptr, &*semaphore), - "vkCreateSemaphore")); - - VkImportSemaphoreFdInfoKHR importSemaphoreFdInfo; - importSemaphoreFdInfo.sType = VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR; - importSemaphoreFdInfo.pNext = nullptr; - importSemaphoreFdInfo.semaphore = semaphore; - importSemaphoreFdInfo.flags = 0; - importSemaphoreFdInfo.handleType = kHandleType; - importSemaphoreFdInfo.fd = handle; - - MaybeError status = CheckVkSuccess( - mDevice->fn.ImportSemaphoreFdKHR(mDevice->GetVkDevice(), &importSemaphoreFdInfo), - "vkImportSemaphoreFdKHR"); - - if (status.IsError()) { - mDevice->fn.DestroySemaphore(mDevice->GetVkDevice(), semaphore, nullptr); - DAWN_TRY(std::move(status)); - } - - return semaphore; -} - -ResultOrError Service::CreateExportableSemaphore() { - VkExportSemaphoreCreateInfoKHR exportSemaphoreInfo; - exportSemaphoreInfo.sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO_KHR; - exportSemaphoreInfo.pNext = nullptr; - exportSemaphoreInfo.handleTypes = kHandleType; - - VkSemaphoreCreateInfo semaphoreCreateInfo; - semaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; - semaphoreCreateInfo.pNext = &exportSemaphoreInfo; - semaphoreCreateInfo.flags = 0; - - VkSemaphore signalSemaphore; - DAWN_TRY( - CheckVkSuccess(mDevice->fn.CreateSemaphore(mDevice->GetVkDevice(), &semaphoreCreateInfo, - nullptr, &*signalSemaphore), - "vkCreateSemaphore")); - return signalSemaphore; -} - -ResultOrError Service::ExportSemaphore(VkSemaphore semaphore) { - VkSemaphoreGetFdInfoKHR semaphoreGetFdInfo; - semaphoreGetFdInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR; - semaphoreGetFdInfo.pNext = nullptr; - semaphoreGetFdInfo.semaphore = semaphore; - semaphoreGetFdInfo.handleType = kHandleType; - - int fd = -1; - DAWN_TRY(CheckVkSuccess( - mDevice->fn.GetSemaphoreFdKHR(mDevice->GetVkDevice(), &semaphoreGetFdInfo, &fd), - "vkGetSemaphoreFdKHR")); - - ASSERT(fd >= 0); - return fd; -} - -ExternalSemaphoreHandle Service::DuplicateHandle(ExternalSemaphoreHandle handle) { - int fd = dup(handle); - ASSERT(fd >= 0); - return fd; -} - -// static -void Service::CloseHandle(ExternalSemaphoreHandle handle) { - int ret = close(handle); - ASSERT(ret == 0); -} - -} // namespace dawn::native::vulkan::external_semaphore diff --git a/src/dawn/native/vulkan/external_semaphore/SemaphoreServiceNull.cpp b/src/dawn/native/vulkan/external_semaphore/SemaphoreServiceNull.cpp deleted file mode 100644 index 9bc3f9ad94..0000000000 --- a/src/dawn/native/vulkan/external_semaphore/SemaphoreServiceNull.cpp +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2019 The Dawn Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "dawn/native/vulkan/DeviceVk.h" -#include "dawn/native/vulkan/external_semaphore/SemaphoreService.h" - -namespace dawn::native::vulkan::external_semaphore { - -Service::Service(Device* device) : mDevice(device) { - DAWN_UNUSED(mDevice); - DAWN_UNUSED(mSupported); -} - -Service::~Service() = default; - -// static -bool Service::CheckSupport(const VulkanDeviceInfo& deviceInfo, - VkPhysicalDevice physicalDevice, - const VulkanFunctions& fn) { - return false; -} - -bool Service::Supported() { - return false; -} - -ResultOrError Service::ImportSemaphore(ExternalSemaphoreHandle handle) { - return DAWN_UNIMPLEMENTED_ERROR("Using null semaphore service to interop inside Vulkan"); -} - -ResultOrError Service::CreateExportableSemaphore() { - return DAWN_UNIMPLEMENTED_ERROR("Using null semaphore service to interop inside Vulkan"); -} - -ResultOrError Service::ExportSemaphore(VkSemaphore semaphore) { - return DAWN_UNIMPLEMENTED_ERROR("Using null semaphore service to interop inside Vulkan"); -} - -ExternalSemaphoreHandle Service::DuplicateHandle(ExternalSemaphoreHandle handle) { - return kNullExternalSemaphoreHandle; -} - -// static -void Service::CloseHandle(ExternalSemaphoreHandle handle) {} - -} // namespace dawn::native::vulkan::external_semaphore diff --git a/src/dawn/native/vulkan/external_semaphore/SemaphoreServiceZirconHandle.cpp b/src/dawn/native/vulkan/external_semaphore/SemaphoreServiceZirconHandle.cpp deleted file mode 100644 index a58fbe99ca..0000000000 --- a/src/dawn/native/vulkan/external_semaphore/SemaphoreServiceZirconHandle.cpp +++ /dev/null @@ -1,146 +0,0 @@ -// Copyright 2019 The Dawn Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include -#include - -#include "dawn/native/vulkan/AdapterVk.h" -#include "dawn/native/vulkan/BackendVk.h" -#include "dawn/native/vulkan/DeviceVk.h" -#include "dawn/native/vulkan/VulkanError.h" -#include "dawn/native/vulkan/external_semaphore/SemaphoreService.h" - -namespace dawn::native::vulkan::external_semaphore { - -Service::Service(Device* device) - : mDevice(device), - mSupported(CheckSupport(device->GetDeviceInfo(), - ToBackend(device->GetAdapter())->GetPhysicalDevice(), - device->fn)) {} - -Service::~Service() = default; - -// static -bool Service::CheckSupport(const VulkanDeviceInfo& deviceInfo, - VkPhysicalDevice physicalDevice, - const VulkanFunctions& fn) { - if (!deviceInfo.HasExt(DeviceExt::ExternalSemaphoreZirconHandle)) { - return false; - } - - VkPhysicalDeviceExternalSemaphoreInfoKHR semaphoreInfo; - semaphoreInfo.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO_KHR; - semaphoreInfo.pNext = nullptr; - semaphoreInfo.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_ZIRCON_EVENT_BIT_FUCHSIA; - - VkExternalSemaphorePropertiesKHR semaphoreProperties; - semaphoreProperties.sType = VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR; - semaphoreProperties.pNext = nullptr; - - fn.GetPhysicalDeviceExternalSemaphoreProperties(physicalDevice, &semaphoreInfo, - &semaphoreProperties); - - VkFlags requiredFlags = VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT_KHR | - VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT_KHR; - - return IsSubset(requiredFlags, semaphoreProperties.externalSemaphoreFeatures); -} - -bool Service::Supported() { - return mSupported; -} - -ResultOrError Service::ImportSemaphore(ExternalSemaphoreHandle handle) { - DAWN_INVALID_IF(handle == ZX_HANDLE_INVALID, "Importing a semaphore with an invalid handle."); - - VkSemaphore semaphore = VK_NULL_HANDLE; - VkSemaphoreCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; - - DAWN_TRY(CheckVkSuccess( - mDevice->fn.CreateSemaphore(mDevice->GetVkDevice(), &info, nullptr, &*semaphore), - "vkCreateSemaphore")); - - VkImportSemaphoreZirconHandleInfoFUCHSIA importSemaphoreHandleInfo; - importSemaphoreHandleInfo.sType = VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_ZIRCON_HANDLE_INFO_FUCHSIA; - importSemaphoreHandleInfo.pNext = nullptr; - importSemaphoreHandleInfo.semaphore = semaphore; - importSemaphoreHandleInfo.flags = 0; - importSemaphoreHandleInfo.handleType = - VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_ZIRCON_EVENT_BIT_FUCHSIA; - importSemaphoreHandleInfo.handle = handle; - - MaybeError status = CheckVkSuccess(mDevice->fn.ImportSemaphoreZirconHandleFUCHSIA( - mDevice->GetVkDevice(), &importSemaphoreHandleInfo), - "vkImportSemaphoreZirconHandleFUCHSIA"); - - if (status.IsError()) { - mDevice->fn.DestroySemaphore(mDevice->GetVkDevice(), semaphore, nullptr); - DAWN_TRY(std::move(status)); - } - - return semaphore; -} - -ResultOrError Service::CreateExportableSemaphore() { - VkExportSemaphoreCreateInfoKHR exportSemaphoreInfo; - exportSemaphoreInfo.sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO_KHR; - exportSemaphoreInfo.pNext = nullptr; - exportSemaphoreInfo.handleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_ZIRCON_EVENT_BIT_FUCHSIA; - - VkSemaphoreCreateInfo semaphoreCreateInfo; - semaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; - semaphoreCreateInfo.pNext = &exportSemaphoreInfo; - semaphoreCreateInfo.flags = 0; - - VkSemaphore signalSemaphore; - DAWN_TRY( - CheckVkSuccess(mDevice->fn.CreateSemaphore(mDevice->GetVkDevice(), &semaphoreCreateInfo, - nullptr, &*signalSemaphore), - "vkCreateSemaphore")); - return signalSemaphore; -} - -ResultOrError Service::ExportSemaphore(VkSemaphore semaphore) { - VkSemaphoreGetZirconHandleInfoFUCHSIA semaphoreGetHandleInfo; - semaphoreGetHandleInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_ZIRCON_HANDLE_INFO_FUCHSIA; - semaphoreGetHandleInfo.pNext = nullptr; - semaphoreGetHandleInfo.semaphore = semaphore; - semaphoreGetHandleInfo.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_ZIRCON_EVENT_BIT_FUCHSIA; - - zx_handle_t handle = ZX_HANDLE_INVALID; - DAWN_TRY(CheckVkSuccess(mDevice->fn.GetSemaphoreZirconHandleFUCHSIA( - mDevice->GetVkDevice(), &semaphoreGetHandleInfo, &handle), - "VkSemaphoreGetZirconHandleInfoFUCHSIA")); - - ASSERT(handle != ZX_HANDLE_INVALID); - return handle; -} - -ExternalSemaphoreHandle Service::DuplicateHandle(ExternalSemaphoreHandle handle) { - zx_handle_t out_handle = ZX_HANDLE_INVALID; - zx_status_t status = zx_handle_duplicate(handle, ZX_RIGHT_SAME_RIGHTS, &out_handle); - ASSERT(status == ZX_OK); - return out_handle; -} - -// static -void Service::CloseHandle(ExternalSemaphoreHandle handle) { - zx_status_t status = zx_handle_close(handle); - ASSERT(status == ZX_OK); -} - -} // namespace dawn::native::vulkan::external_semaphore diff --git a/src/dawn/native/vulkan/external_semaphore/ServiceImplementation.cpp b/src/dawn/native/vulkan/external_semaphore/ServiceImplementation.cpp new file mode 100644 index 0000000000..d7f9a4bf87 --- /dev/null +++ b/src/dawn/native/vulkan/external_semaphore/ServiceImplementation.cpp @@ -0,0 +1,23 @@ +// Copyright 2023 The Dawn Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "dawn/native/vulkan/external_semaphore/ServiceImplementation.h" + +namespace dawn::native::vulkan::external_semaphore { + +ServiceImplementation::ServiceImplementation(Device* device) : mDevice(device) {} + +ServiceImplementation::~ServiceImplementation() = default; + +} // namespace dawn::native::vulkan::external_semaphore diff --git a/src/dawn/native/vulkan/external_semaphore/ServiceImplementation.h b/src/dawn/native/vulkan/external_semaphore/ServiceImplementation.h new file mode 100644 index 0000000000..ac636c2d1f --- /dev/null +++ b/src/dawn/native/vulkan/external_semaphore/ServiceImplementation.h @@ -0,0 +1,56 @@ +// Copyright 2023 The Dawn Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SRC_DAWN_NATIVE_VULKAN_EXTERNAL_SEMAPHORE_SERVICEIMPLEMENTATION_H_ +#define SRC_DAWN_NATIVE_VULKAN_EXTERNAL_SEMAPHORE_SERVICEIMPLEMENTATION_H_ + +#include "dawn/native/Error.h" +#include "dawn/native/vulkan/ExternalHandle.h" + +namespace dawn::native::vulkan { +class Device; +} // namespace dawn::native::vulkan + +namespace dawn::native::vulkan::external_semaphore { + +class ServiceImplementation { + public: + explicit ServiceImplementation(Device* device); + virtual ~ServiceImplementation(); + + // True if the device reports it supports this feature + virtual bool Supported() = 0; + + // Given an external handle, import it into a VkSemaphore + virtual ResultOrError ImportSemaphore(ExternalSemaphoreHandle handle) = 0; + + // Create a VkSemaphore that is exportable into an external handle later + virtual ResultOrError CreateExportableSemaphore() = 0; + + // Export a VkSemaphore into an external handle + virtual ResultOrError ExportSemaphore(VkSemaphore semaphore) = 0; + + // Duplicate a new external handle from the given one. + virtual ExternalSemaphoreHandle DuplicateHandle(ExternalSemaphoreHandle handle) = 0; + + // Close external handle to release it. + virtual void CloseHandle(ExternalSemaphoreHandle handle) = 0; + + protected: + Device* mDevice = nullptr; +}; + +} // namespace dawn::native::vulkan::external_semaphore + +#endif // SRC_DAWN_NATIVE_VULKAN_EXTERNAL_SEMAPHORE_SERVICEIMPLEMENTATION_H_ diff --git a/src/dawn/native/vulkan/external_semaphore/ServiceImplementationFD.cpp b/src/dawn/native/vulkan/external_semaphore/ServiceImplementationFD.cpp new file mode 100644 index 0000000000..6b402c52d5 --- /dev/null +++ b/src/dawn/native/vulkan/external_semaphore/ServiceImplementationFD.cpp @@ -0,0 +1,169 @@ +// Copyright 2023 The Dawn Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include + +#include "dawn/native/vulkan/AdapterVk.h" +#include "dawn/native/vulkan/BackendVk.h" +#include "dawn/native/vulkan/DeviceVk.h" +#include "dawn/native/vulkan/VulkanError.h" +#include "dawn/native/vulkan/external_semaphore/ServiceImplementation.h" +#include "dawn/native/vulkan/external_semaphore/ServiceImplementationFD.h" + +static constexpr VkExternalSemaphoreHandleTypeFlagBits kHandleType = +#if DAWN_PLATFORM_IS(ANDROID) || DAWN_PLATFORM_IS(CHROMEOS) + VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT; +#else + VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR; +#endif + +namespace dawn::native::vulkan::external_semaphore { + +class ServiceImplementationFD : public ServiceImplementation { + public: + explicit ServiceImplementationFD(Device* device) + : ServiceImplementation(device), + mSupported(CheckSupport(device->GetDeviceInfo(), + ToBackend(device->GetAdapter())->GetPhysicalDevice(), + device->fn)) {} + + ~ServiceImplementationFD() override = default; + + static bool CheckSupport(const VulkanDeviceInfo& deviceInfo, + VkPhysicalDevice physicalDevice, + const VulkanFunctions& fn) { + if (!deviceInfo.HasExt(DeviceExt::ExternalSemaphoreFD)) { + return false; + } + + VkPhysicalDeviceExternalSemaphoreInfoKHR semaphoreInfo; + semaphoreInfo.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO_KHR; + semaphoreInfo.pNext = nullptr; + semaphoreInfo.handleType = kHandleType; + + VkExternalSemaphorePropertiesKHR semaphoreProperties; + semaphoreProperties.sType = VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR; + semaphoreProperties.pNext = nullptr; + + fn.GetPhysicalDeviceExternalSemaphoreProperties(physicalDevice, &semaphoreInfo, + &semaphoreProperties); + + VkFlags requiredFlags = VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT_KHR | + VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT_KHR; + + return IsSubset(requiredFlags, semaphoreProperties.externalSemaphoreFeatures); + } + + // True if the device reports it supports this feature + bool Supported() override { return mSupported; } + + // Given an external handle, import it into a VkSemaphore + ResultOrError ImportSemaphore(ExternalSemaphoreHandle handle) override { + DAWN_INVALID_IF(handle < 0, "Importing a semaphore with an invalid handle."); + + VkSemaphore semaphore = VK_NULL_HANDLE; + VkSemaphoreCreateInfo info; + info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; + info.pNext = nullptr; + info.flags = 0; + + DAWN_TRY(CheckVkSuccess( + mDevice->fn.CreateSemaphore(mDevice->GetVkDevice(), &info, nullptr, &*semaphore), + "vkCreateSemaphore")); + + VkImportSemaphoreFdInfoKHR importSemaphoreFdInfo; + importSemaphoreFdInfo.sType = VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR; + importSemaphoreFdInfo.pNext = nullptr; + importSemaphoreFdInfo.semaphore = semaphore; + importSemaphoreFdInfo.flags = 0; + importSemaphoreFdInfo.handleType = kHandleType; + importSemaphoreFdInfo.fd = handle; + + MaybeError status = CheckVkSuccess( + mDevice->fn.ImportSemaphoreFdKHR(mDevice->GetVkDevice(), &importSemaphoreFdInfo), + "vkImportSemaphoreFdKHR"); + + if (status.IsError()) { + mDevice->fn.DestroySemaphore(mDevice->GetVkDevice(), semaphore, nullptr); + DAWN_TRY(std::move(status)); + } + + return semaphore; + } + + // Create a VkSemaphore that is exportable into an external handle later + ResultOrError CreateExportableSemaphore() override { + VkExportSemaphoreCreateInfoKHR exportSemaphoreInfo; + exportSemaphoreInfo.sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO_KHR; + exportSemaphoreInfo.pNext = nullptr; + exportSemaphoreInfo.handleTypes = kHandleType; + + VkSemaphoreCreateInfo semaphoreCreateInfo; + semaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; + semaphoreCreateInfo.pNext = &exportSemaphoreInfo; + semaphoreCreateInfo.flags = 0; + + VkSemaphore signalSemaphore; + DAWN_TRY( + CheckVkSuccess(mDevice->fn.CreateSemaphore(mDevice->GetVkDevice(), &semaphoreCreateInfo, + nullptr, &*signalSemaphore), + "vkCreateSemaphore")); + return signalSemaphore; + } + + // Export a VkSemaphore into an external handle + ResultOrError ExportSemaphore(VkSemaphore semaphore) override { + VkSemaphoreGetFdInfoKHR semaphoreGetFdInfo; + semaphoreGetFdInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR; + semaphoreGetFdInfo.pNext = nullptr; + semaphoreGetFdInfo.semaphore = semaphore; + semaphoreGetFdInfo.handleType = kHandleType; + + int fd = -1; + DAWN_TRY(CheckVkSuccess( + mDevice->fn.GetSemaphoreFdKHR(mDevice->GetVkDevice(), &semaphoreGetFdInfo, &fd), + "vkGetSemaphoreFdKHR")); + + ASSERT(fd >= 0); + return fd; + } + + // Duplicate a new external handle from the given one. + ExternalSemaphoreHandle DuplicateHandle(ExternalSemaphoreHandle handle) override { + int fd = dup(handle); + ASSERT(fd >= 0); + return fd; + } + + void CloseHandle(ExternalSemaphoreHandle handle) override { + int ret = close(handle); + ASSERT(ret == 0); + } + + private: + bool mSupported = false; +}; + +std::unique_ptr CreateFDService(Device* device) { + return std::make_unique(device); +} + +bool CheckFDSupport(const VulkanDeviceInfo& deviceInfo, + VkPhysicalDevice physicalDevice, + const VulkanFunctions& fn) { + return ServiceImplementationFD::CheckSupport(deviceInfo, physicalDevice, fn); +} + +} // namespace dawn::native::vulkan::external_semaphore diff --git a/src/dawn/native/vulkan/external_semaphore/ServiceImplementationFD.h b/src/dawn/native/vulkan/external_semaphore/ServiceImplementationFD.h new file mode 100644 index 0000000000..10c51af593 --- /dev/null +++ b/src/dawn/native/vulkan/external_semaphore/ServiceImplementationFD.h @@ -0,0 +1,36 @@ +// Copyright 2023 The Dawn Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SRC_DAWN_NATIVE_VULKAN_EXTERNAL_SEMAPHORE_SERVICEIMPLEMENTATIONFD_H_ +#define SRC_DAWN_NATIVE_VULKAN_EXTERNAL_SEMAPHORE_SERVICEIMPLEMENTATIONFD_H_ + +#include + +namespace dawn::native::vulkan { +class Device; +struct VulkanDeviceInfo; +struct VulkanFunctions; +} // namespace dawn::native::vulkan + +namespace dawn::native::vulkan::external_semaphore { +class ServiceImplementation; + +bool CheckFDSupport(const VulkanDeviceInfo& deviceInfo, + VkPhysicalDevice physicalDevice, + const VulkanFunctions& fn); +std::unique_ptr CreateFDService(Device* device); + +} // namespace dawn::native::vulkan::external_semaphore + +#endif // SRC_DAWN_NATIVE_VULKAN_EXTERNAL_SEMAPHORE_SERVICEIMPLEMENTATIONFD_H_ diff --git a/src/dawn/native/vulkan/external_semaphore/ServiceImplementationZirconHandle.cpp b/src/dawn/native/vulkan/external_semaphore/ServiceImplementationZirconHandle.cpp new file mode 100644 index 0000000000..c2ed196c4e --- /dev/null +++ b/src/dawn/native/vulkan/external_semaphore/ServiceImplementationZirconHandle.cpp @@ -0,0 +1,168 @@ +// Copyright 2023 The Dawn Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include + +#include "dawn/native/vulkan/AdapterVk.h" +#include "dawn/native/vulkan/BackendVk.h" +#include "dawn/native/vulkan/DeviceVk.h" +#include "dawn/native/vulkan/VulkanError.h" +#include "dawn/native/vulkan/external_semaphore/ServiceImplementation.h" +#include "dawn/native/vulkan/external_semaphore/ServiceImplementationZirconHandle.h" + +namespace dawn::native::vulkan::external_semaphore { + +class ServiceImplementationZirconHandle : public ServiceImplementation { + public: + explicit ServiceImplementationZirconHandle(Device* device) + : ServiceImplementation(device), + mSupported(CheckSupport(device->GetDeviceInfo(), + ToBackend(device->GetAdapter())->GetPhysicalDevice(), + device->fn)) {} + + ~ServiceImplementationZirconHandle() override = default; + + static bool CheckSupport( + const VulkanDeviceInfo& deviceInfo, + VkPhysicalDevice physicalDevice, + const VulkanFunctions& fn) static void CloseHandle(ExternalSemaphoreHandle handle) { + if (!deviceInfo.HasExt(DeviceExt::ExternalSemaphoreZirconHandle)) { + return false; + } + + VkPhysicalDeviceExternalSemaphoreInfoKHR semaphoreInfo; + semaphoreInfo.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO_KHR; + semaphoreInfo.pNext = nullptr; + semaphoreInfo.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_ZIRCON_EVENT_BIT_FUCHSIA; + + VkExternalSemaphorePropertiesKHR semaphoreProperties; + semaphoreProperties.sType = VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR; + semaphoreProperties.pNext = nullptr; + + fn.GetPhysicalDeviceExternalSemaphoreProperties(physicalDevice, &semaphoreInfo, + &semaphoreProperties); + + VkFlags requiredFlags = VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT_KHR | + VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT_KHR; + + return IsSubset(requiredFlags, semaphoreProperties.externalSemaphoreFeatures); + } + + // True if the device reports it supports this feature + bool Supported() override { return mSupported; } + + // Given an external handle, import it into a VkSemaphore + ResultOrError ImportSemaphore(ExternalSemaphoreHandle handle) override { + DAWN_INVALID_IF(handle == ZX_HANDLE_INVALID, + "Importing a semaphore with an invalid handle."); + + VkSemaphore semaphore = VK_NULL_HANDLE; + VkSemaphoreCreateInfo info; + info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; + info.pNext = nullptr; + info.flags = 0; + + DAWN_TRY(CheckVkSuccess( + mDevice->fn.CreateSemaphore(mDevice->GetVkDevice(), &info, nullptr, &*semaphore), + "vkCreateSemaphore")); + + VkImportSemaphoreZirconHandleInfoFUCHSIA importSemaphoreHandleInfo; + importSemaphoreHandleInfo.sType = + VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_ZIRCON_HANDLE_INFO_FUCHSIA; + importSemaphoreHandleInfo.pNext = nullptr; + importSemaphoreHandleInfo.semaphore = semaphore; + importSemaphoreHandleInfo.flags = 0; + importSemaphoreHandleInfo.handleType = + VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_ZIRCON_EVENT_BIT_FUCHSIA; + importSemaphoreHandleInfo.handle = handle; + + MaybeError status = CheckVkSuccess(mDevice->fn.ImportSemaphoreZirconHandleFUCHSIA( + mDevice->GetVkDevice(), &importSemaphoreHandleInfo), + "vkImportSemaphoreZirconHandleFUCHSIA"); + + if (status.IsError()) { + mDevice->fn.DestroySemaphore(mDevice->GetVkDevice(), semaphore, nullptr); + DAWN_TRY(std::move(status)); + } + + return semaphore; + } + + // Create a VkSemaphore that is exportable into an external handle later + ResultOrError CreateExportableSemaphore() override { + VkExportSemaphoreCreateInfoKHR exportSemaphoreInfo; + exportSemaphoreInfo.sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO_KHR; + exportSemaphoreInfo.pNext = nullptr; + exportSemaphoreInfo.handleTypes = + VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_ZIRCON_EVENT_BIT_FUCHSIA; + + VkSemaphoreCreateInfo semaphoreCreateInfo; + semaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; + semaphoreCreateInfo.pNext = &exportSemaphoreInfo; + semaphoreCreateInfo.flags = 0; + + VkSemaphore signalSemaphore; + DAWN_TRY( + CheckVkSuccess(mDevice->fn.CreateSemaphore(mDevice->GetVkDevice(), &semaphoreCreateInfo, + nullptr, &*signalSemaphore), + "vkCreateSemaphore")); + return signalSemaphore; + } + + // Export a VkSemaphore into an external handle + ResultOrError ExportSemaphore(VkSemaphore semaphore) override { + VkSemaphoreGetZirconHandleInfoFUCHSIA semaphoreGetHandleInfo; + semaphoreGetHandleInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_ZIRCON_HANDLE_INFO_FUCHSIA; + semaphoreGetHandleInfo.pNext = nullptr; + semaphoreGetHandleInfo.semaphore = semaphore; + semaphoreGetHandleInfo.handleType = + VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_ZIRCON_EVENT_BIT_FUCHSIA; + + zx_handle_t handle = ZX_HANDLE_INVALID; + DAWN_TRY(CheckVkSuccess(mDevice->fn.GetSemaphoreZirconHandleFUCHSIA( + mDevice->GetVkDevice(), &semaphoreGetHandleInfo, &handle), + "VkSemaphoreGetZirconHandleInfoFUCHSIA")); + + ASSERT(handle != ZX_HANDLE_INVALID); + return handle; + } + + // Duplicate a new external handle from the given one. + ExternalSemaphoreHandle DuplicateHandle(ExternalSemaphoreHandle handle) override { + zx_handle_t out_handle = ZX_HANDLE_INVALID; + zx_status_t status = zx_handle_duplicate(handle, ZX_RIGHT_SAME_RIGHTS, &out_handle); + ASSERT(status == ZX_OK); + return out_handle; + } + + void ServiceImplementationZirconHandle::CloseHandle(ExternalSemaphoreHandle handle) override { + zx_status_t status = zx_handle_close(handle); + ASSERT(status == ZX_OK); + } + + private: + bool mSupported = false; +}; + +std::unique_ptr CreateZirconHandleService(Device* device) { + return td::make_unique(device); +} +bool CheckZirconHandleSupport(const VulkanDeviceInfo& deviceInfo, + VkPhysicalDevice physicalDevice, + const VulkanFunctions& fn) { + return ServiceImplementationZirconHandle::CheckSupport(deviceInfo, physicalDevice, fn); +} + +} // namespace dawn::native::vulkan::external_semaphore diff --git a/src/dawn/native/vulkan/external_semaphore/ServiceImplementationZirconHandle.h b/src/dawn/native/vulkan/external_semaphore/ServiceImplementationZirconHandle.h new file mode 100644 index 0000000000..b07585f0d5 --- /dev/null +++ b/src/dawn/native/vulkan/external_semaphore/ServiceImplementationZirconHandle.h @@ -0,0 +1,36 @@ +// Copyright 2023 The Dawn Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SRC_DAWN_NATIVE_VULKAN_EXTERNAL_SEMAPHORE_SERVICEIMPLEMENTATIONZIRCONHANDLE_H_ +#define SRC_DAWN_NATIVE_VULKAN_EXTERNAL_SEMAPHORE_SERVICEIMPLEMENTATIONZIRCONHANDLE_H_ + +#include + +namespace dawn::native::vulkan { +class Device; +struct VulkanDeviceInfo; +struct VulkanFunctions; +} // namespace dawn::native::vulkan + +namespace dawn::native::vulkan::external_semaphore { +class ServiceImplementation; + +bool CheckZirconHandleSupport(const VulkanDeviceInfo& deviceInfo, + VkPhysicalDevice physicalDevice, + const VulkanFunctions& fn); +std::unique_ptr CreateZirconHandleService(Device* device); + +} // namespace dawn::native::vulkan::external_semaphore + +#endif // SRC_DAWN_NATIVE_VULKAN_EXTERNAL_SEMAPHORE_SERVICEIMPLEMENTATIONZIRCONHANDLE_H_