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_