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 <cwallez@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Shaobo Yan <shaobo.yan@intel.com>
This commit is contained in:
Yan,Shaobo 2023-02-16 13:49:23 +00:00 committed by Dawn LUCI CQ
parent 87b0ccb497
commit 86fbd1a7de
17 changed files with 627 additions and 390 deletions

View File

@ -80,6 +80,13 @@ config("internal_config") {
defines += [ "DAWN_ENABLE_BACKEND_VULKAN" ] 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) { if (dawn_use_wayland) {
defines += [ "DAWN_USE_WAYLAND" ] defines += [ "DAWN_USE_WAYLAND" ]
} }

View File

@ -29,6 +29,7 @@
// - POSIX // - POSIX
// - LINUX // - LINUX
// - ANDROID // - ANDROID
// - CHROMEOS
// - APPLE // - APPLE
// - IOS // - IOS
// - MACOS // - MACOS
@ -51,6 +52,9 @@
#if defined(__ANDROID__) #if defined(__ANDROID__)
#define DAWN_PLATFORM_IS_ANDROID 1 #define DAWN_PLATFORM_IS_ANDROID 1
#endif #endif
#if defined(DAWN_OS_CHROMEOS)
#define DAWN_PLATFORM_IS_CHROMEOS 1
#endif
#elif defined(__APPLE__) #elif defined(__APPLE__)
#define DAWN_PLATFORM_IS_APPLE 1 #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) #if !defined(DAWN_PLATFORM_IS_ANDROID)
#define DAWN_PLATFORM_IS_ANDROID 0 #define DAWN_PLATFORM_IS_ANDROID 0
#endif #endif
#if !defined(DAWN_PLATFORM_IS_CHROMEOS)
#define DAWN_PLATFORM_IS_CHROMEOS 0
#endif
#if !defined(DAWN_PLATFORM_IS_APPLE) #if !defined(DAWN_PLATFORM_IS_APPLE)
#define DAWN_PLATFORM_IS_APPLE 0 #define DAWN_PLATFORM_IS_APPLE 0

View File

@ -678,36 +678,34 @@ source_set("sources") {
"vulkan/VulkanInfo.h", "vulkan/VulkanInfo.h",
"vulkan/external_memory/MemoryService.cpp", "vulkan/external_memory/MemoryService.cpp",
"vulkan/external_memory/MemoryService.h", "vulkan/external_memory/MemoryService.h",
"vulkan/external_semaphore/SemaphoreService.cpp",
"vulkan/external_semaphore/SemaphoreService.h", "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 += [ sources += [
"vulkan/external_memory/MemoryServiceDmaBuf.cpp", "vulkan/external_semaphore/ServiceImplementationFD.cpp",
"vulkan/external_semaphore/SemaphoreServiceFD.cpp", "vulkan/external_semaphore/ServiceImplementationFD.h",
]
defines += [ "DAWN_USE_SYNC_FDS" ]
} else if (is_linux) {
sources += [
"vulkan/external_memory/MemoryServiceOpaqueFD.cpp",
"vulkan/external_semaphore/SemaphoreServiceFD.cpp",
] ]
} else if (is_fuchsia) { } else if (is_fuchsia) {
sources += [ sources += [
"vulkan/external_memory/MemoryServiceZirconHandle.cpp", "vulkan/external_semaphore/ServiceImplementationZirconHandle.cpp",
"vulkan/external_semaphore/SemaphoreServiceZirconHandle.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) { } else if (is_android) {
sources += [ sources += [ "vulkan/external_memory/MemoryServiceAHardwareBuffer.cpp" ]
"vulkan/external_memory/MemoryServiceAHardwareBuffer.cpp",
"vulkan/external_semaphore/SemaphoreServiceFD.cpp",
]
defines += [ "DAWN_USE_SYNC_FDS" ]
} else { } else {
sources += [ sources += [ "vulkan/external_memory/MemoryServiceNull.cpp" ]
"vulkan/external_memory/MemoryServiceNull.cpp",
"vulkan/external_semaphore/SemaphoreServiceNull.cpp",
]
} }
if (build_with_chromium && is_fuchsia) { if (build_with_chromium && is_fuchsia) {
# Necessary to ensure that the Vulkan libraries will be in the # Necessary to ensure that the Vulkan libraries will be in the

View File

@ -551,7 +551,10 @@ if (DAWN_ENABLE_VULKAN)
"vulkan/VulkanInfo.h" "vulkan/VulkanInfo.h"
"vulkan/external_memory/MemoryService.cpp" "vulkan/external_memory/MemoryService.cpp"
"vulkan/external_memory/MemoryService.h" "vulkan/external_memory/MemoryService.h"
"vulkan/external_semaphore/SemaphoreService.cpp"
"vulkan/external_semaphore/SemaphoreService.h" "vulkan/external_semaphore/SemaphoreService.h"
"vulkan/external_semaphore/ServiceImplementation.cpp"
"vulkan/external_semaphore/ServiceImplementation.h"
) )
target_link_libraries(dawn_native PUBLIC Vulkan-Headers) target_link_libraries(dawn_native PUBLIC Vulkan-Headers)
@ -560,12 +563,12 @@ if (DAWN_ENABLE_VULKAN)
if (UNIX AND NOT APPLE) if (UNIX AND NOT APPLE)
target_sources(dawn_native PRIVATE target_sources(dawn_native PRIVATE
"vulkan/external_memory/MemoryServiceOpaqueFD.cpp" "vulkan/external_memory/MemoryServiceOpaqueFD.cpp"
"vulkan/external_semaphore/SemaphoreServiceFD.cpp" "vulkan/external_semaphore/ServiceImplementationFD.cpp"
"vulkan/external_semaphore/ServiceImplementationFD.h"
) )
else() else()
target_sources(dawn_native PRIVATE target_sources(dawn_native PRIVATE
"vulkan/external_memory/MemoryServiceNull.cpp" "vulkan/external_memory/MemoryServiceNull.cpp"
"vulkan/external_semaphore/SemaphoreServiceNull.cpp"
) )
endif() endif()
endif() endif()

View File

@ -257,11 +257,11 @@ void Adapter::InitializeSupportedFeaturesImpl() {
mSupportedFeatures.EnableFeature(Feature::BGRA8UnormStorage); 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 // TODO(chromium:1258986): Precisely enable the feature by querying the device's format
// features. // features.
mSupportedFeatures.EnableFeature(Feature::MultiPlanarFormats); mSupportedFeatures.EnableFeature(Feature::MultiPlanarFormats);
#endif #endif // DAWN_PLATFORM_IS(ANDROID) || DAWN_PLATFORM_IS(CHROMEOS)
} }
MaybeError Adapter::InitializeSupportedLimitsImpl(CombinedLimits* limits) { MaybeError Adapter::InitializeSupportedLimitsImpl(CombinedLimits* limits) {

View File

@ -940,7 +940,9 @@ MaybeError Texture::ExportExternalTexture(VkImageLayout desiredLayout,
Texture::~Texture() { Texture::~Texture() {
if (mExternalSemaphoreHandle != kNullExternalSemaphoreHandle) { if (mExternalSemaphoreHandle != kNullExternalSemaphoreHandle) {
external_semaphore::Service::CloseHandle(mExternalSemaphoreHandle); ToBackend(GetDevice())
->GetExternalSemaphoreService()
->CloseHandle(mExternalSemaphoreHandle);
} }
mExternalSemaphoreHandle = kNullExternalSemaphoreHandle; mExternalSemaphoreHandle = kNullExternalSemaphoreHandle;
} }
@ -1354,7 +1356,9 @@ void Texture::EnsureSubresourceContentInitialized(CommandRecordingContext* recor
void Texture::UpdateExternalSemaphoreHandle(ExternalSemaphoreHandle handle) { void Texture::UpdateExternalSemaphoreHandle(ExternalSemaphoreHandle handle) {
if (mExternalSemaphoreHandle != kNullExternalSemaphoreHandle) { if (mExternalSemaphoreHandle != kNullExternalSemaphoreHandle) {
external_semaphore::Service::CloseHandle(mExternalSemaphoreHandle); ToBackend(GetDevice())
->GetExternalSemaphoreService()
->CloseHandle(mExternalSemaphoreHandle);
} }
mExternalSemaphoreHandle = handle; mExternalSemaphoreHandle = handle;
} }

View File

@ -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<VkSemaphore> Service::ImportSemaphore(ExternalSemaphoreHandle handle) {
ASSERT(mServiceImpl);
return mServiceImpl->ImportSemaphore(handle);
}
ResultOrError<VkSemaphore> Service::CreateExportableSemaphore() {
ASSERT(mServiceImpl);
return mServiceImpl->CreateExportableSemaphore();
}
ResultOrError<ExternalSemaphoreHandle> 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

View File

@ -15,17 +15,19 @@
#ifndef SRC_DAWN_NATIVE_VULKAN_EXTERNAL_SEMAPHORE_SEMAPHORESERVICE_H_ #ifndef SRC_DAWN_NATIVE_VULKAN_EXTERNAL_SEMAPHORE_SEMAPHORESERVICE_H_
#define SRC_DAWN_NATIVE_VULKAN_EXTERNAL_SEMAPHORE_SEMAPHORESERVICE_H_ #define SRC_DAWN_NATIVE_VULKAN_EXTERNAL_SEMAPHORE_SEMAPHORESERVICE_H_
#include "dawn/common/vulkan_platform.h" #include <memory>
#include "dawn/native/Error.h" #include "dawn/native/Error.h"
#include "dawn/native/vulkan/ExternalHandle.h" #include "dawn/native/vulkan/ExternalHandle.h"
#include "dawn/native/vulkan/VulkanFunctions.h"
#include "dawn/native/vulkan/VulkanInfo.h"
namespace dawn::native::vulkan { namespace dawn::native::vulkan {
class Device; class Device;
struct VulkanDeviceInfo;
struct VulkanFunctions;
} // namespace dawn::native::vulkan } // namespace dawn::native::vulkan
namespace dawn::native::vulkan::external_semaphore { namespace dawn::native::vulkan::external_semaphore {
class ServiceImplementation;
class Service { class Service {
public: public:
@ -35,6 +37,7 @@ class Service {
static bool CheckSupport(const VulkanDeviceInfo& deviceInfo, static bool CheckSupport(const VulkanDeviceInfo& deviceInfo,
VkPhysicalDevice physicalDevice, VkPhysicalDevice physicalDevice,
const VulkanFunctions& fn); const VulkanFunctions& fn);
void CloseHandle(ExternalSemaphoreHandle handle);
// True if the device reports it supports this feature // True if the device reports it supports this feature
bool Supported(); bool Supported();
@ -51,14 +54,9 @@ class Service {
// Duplicate a new external handle from the given one. // Duplicate a new external handle from the given one.
ExternalSemaphoreHandle DuplicateHandle(ExternalSemaphoreHandle handle); ExternalSemaphoreHandle DuplicateHandle(ExternalSemaphoreHandle handle);
// Close an external handle.
static void CloseHandle(ExternalSemaphoreHandle handle);
private: private:
Device* mDevice = nullptr; // Linux, ChromeOS and Android use FD semaphore and Fuchia uses ZirconHandle.
std::unique_ptr<ServiceImplementation> mServiceImpl;
// True if early checks pass that determine if the service is supported
bool mSupported = false;
}; };
} // namespace dawn::native::vulkan::external_semaphore } // namespace dawn::native::vulkan::external_semaphore

View File

@ -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 <unistd.h>
#include <utility>
#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<VkSemaphore> 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<VkSemaphore> 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<ExternalSemaphoreHandle> 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

View File

@ -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<VkSemaphore> Service::ImportSemaphore(ExternalSemaphoreHandle handle) {
return DAWN_UNIMPLEMENTED_ERROR("Using null semaphore service to interop inside Vulkan");
}
ResultOrError<VkSemaphore> Service::CreateExportableSemaphore() {
return DAWN_UNIMPLEMENTED_ERROR("Using null semaphore service to interop inside Vulkan");
}
ResultOrError<ExternalSemaphoreHandle> 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

View File

@ -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 <zircon/syscalls.h>
#include <utility>
#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<VkSemaphore> 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<VkSemaphore> 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<ExternalSemaphoreHandle> 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

View File

@ -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

View File

@ -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<VkSemaphore> ImportSemaphore(ExternalSemaphoreHandle handle) = 0;
// Create a VkSemaphore that is exportable into an external handle later
virtual ResultOrError<VkSemaphore> CreateExportableSemaphore() = 0;
// Export a VkSemaphore into an external handle
virtual ResultOrError<ExternalSemaphoreHandle> 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_

View File

@ -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 <unistd.h>
#include <utility>
#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<VkSemaphore> 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<VkSemaphore> 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<ExternalSemaphoreHandle> 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<ServiceImplementation> CreateFDService(Device* device) {
return std::make_unique<ServiceImplementationFD>(device);
}
bool CheckFDSupport(const VulkanDeviceInfo& deviceInfo,
VkPhysicalDevice physicalDevice,
const VulkanFunctions& fn) {
return ServiceImplementationFD::CheckSupport(deviceInfo, physicalDevice, fn);
}
} // namespace dawn::native::vulkan::external_semaphore

View File

@ -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 <memory>
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<ServiceImplementation> CreateFDService(Device* device);
} // namespace dawn::native::vulkan::external_semaphore
#endif // SRC_DAWN_NATIVE_VULKAN_EXTERNAL_SEMAPHORE_SERVICEIMPLEMENTATIONFD_H_

View File

@ -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 <zircon/syscalls.h>
#include <utility>
#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<VkSemaphore> 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<VkSemaphore> 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<ExternalSemaphoreHandle> 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<ServiceImplementation> CreateZirconHandleService(Device* device) {
return td::make_unique<ServiceImplementationZirconHandle>(device);
}
bool CheckZirconHandleSupport(const VulkanDeviceInfo& deviceInfo,
VkPhysicalDevice physicalDevice,
const VulkanFunctions& fn) {
return ServiceImplementationZirconHandle::CheckSupport(deviceInfo, physicalDevice, fn);
}
} // namespace dawn::native::vulkan::external_semaphore

View File

@ -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 <memory>
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<ServiceImplementation> CreateZirconHandleService(Device* device);
} // namespace dawn::native::vulkan::external_semaphore
#endif // SRC_DAWN_NATIVE_VULKAN_EXTERNAL_SEMAPHORE_SERVICEIMPLEMENTATIONZIRCONHANDLE_H_