1 // Copyright 2019 The Dawn Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include "dawn_native/vulkan/AdapterVk.h" 16 #include "dawn_native/vulkan/BackendVk.h" 17 #include "dawn_native/vulkan/DeviceVk.h" 18 #include "dawn_native/vulkan/VulkanError.h" 19 #include "dawn_native/vulkan/external_semaphore/SemaphoreService.h" 20 21 static constexpr VkExternalSemaphoreHandleTypeFlagBits kHandleType = 22 #if defined(DAWN_USE_SYNC_FDS) 23 VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT; 24 #else 25 VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR; 26 #endif // defined(DAWN_USE_SYNC_FDS) 27 28 namespace dawn_native { namespace vulkan { namespace external_semaphore { 29 Service(Device * device)30 Service::Service(Device* device) 31 : mDevice(device), 32 mSupported(CheckSupport(device->GetDeviceInfo(), 33 ToBackend(device->GetAdapter())->GetPhysicalDevice(), 34 device->fn)) { 35 } 36 37 Service::~Service() = default; 38 39 // static CheckSupport(const VulkanDeviceInfo & deviceInfo,VkPhysicalDevice physicalDevice,const VulkanFunctions & fn)40 bool Service::CheckSupport(const VulkanDeviceInfo& deviceInfo, 41 VkPhysicalDevice physicalDevice, 42 const VulkanFunctions& fn) { 43 if (!deviceInfo.HasExt(DeviceExt::ExternalSemaphoreFD)) { 44 return false; 45 } 46 47 VkPhysicalDeviceExternalSemaphoreInfoKHR semaphoreInfo; 48 semaphoreInfo.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO_KHR; 49 semaphoreInfo.pNext = nullptr; 50 semaphoreInfo.handleType = kHandleType; 51 52 VkExternalSemaphorePropertiesKHR semaphoreProperties; 53 semaphoreProperties.sType = VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR; 54 semaphoreProperties.pNext = nullptr; 55 56 fn.GetPhysicalDeviceExternalSemaphoreProperties(physicalDevice, &semaphoreInfo, 57 &semaphoreProperties); 58 59 VkFlags requiredFlags = VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT_KHR | 60 VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT_KHR; 61 62 return IsSubset(requiredFlags, semaphoreProperties.externalSemaphoreFeatures); 63 } 64 Supported()65 bool Service::Supported() { 66 return mSupported; 67 } 68 ImportSemaphore(ExternalSemaphoreHandle handle)69 ResultOrError<VkSemaphore> Service::ImportSemaphore(ExternalSemaphoreHandle handle) { 70 DAWN_INVALID_IF(handle < 0, "Importing a semaphore with an invalid handle."); 71 72 VkSemaphore semaphore = VK_NULL_HANDLE; 73 VkSemaphoreCreateInfo info; 74 info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; 75 info.pNext = nullptr; 76 info.flags = 0; 77 78 DAWN_TRY(CheckVkSuccess( 79 mDevice->fn.CreateSemaphore(mDevice->GetVkDevice(), &info, nullptr, &*semaphore), 80 "vkCreateSemaphore")); 81 82 VkImportSemaphoreFdInfoKHR importSemaphoreFdInfo; 83 importSemaphoreFdInfo.sType = VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR; 84 importSemaphoreFdInfo.pNext = nullptr; 85 importSemaphoreFdInfo.semaphore = semaphore; 86 importSemaphoreFdInfo.flags = 0; 87 importSemaphoreFdInfo.handleType = kHandleType; 88 importSemaphoreFdInfo.fd = handle; 89 90 MaybeError status = CheckVkSuccess( 91 mDevice->fn.ImportSemaphoreFdKHR(mDevice->GetVkDevice(), &importSemaphoreFdInfo), 92 "vkImportSemaphoreFdKHR"); 93 94 if (status.IsError()) { 95 mDevice->fn.DestroySemaphore(mDevice->GetVkDevice(), semaphore, nullptr); 96 DAWN_TRY(std::move(status)); 97 } 98 99 return semaphore; 100 } 101 CreateExportableSemaphore()102 ResultOrError<VkSemaphore> Service::CreateExportableSemaphore() { 103 VkExportSemaphoreCreateInfoKHR exportSemaphoreInfo; 104 exportSemaphoreInfo.sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO_KHR; 105 exportSemaphoreInfo.pNext = nullptr; 106 exportSemaphoreInfo.handleTypes = kHandleType; 107 108 VkSemaphoreCreateInfo semaphoreCreateInfo; 109 semaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; 110 semaphoreCreateInfo.pNext = &exportSemaphoreInfo; 111 semaphoreCreateInfo.flags = 0; 112 113 VkSemaphore signalSemaphore; 114 DAWN_TRY( 115 CheckVkSuccess(mDevice->fn.CreateSemaphore(mDevice->GetVkDevice(), &semaphoreCreateInfo, 116 nullptr, &*signalSemaphore), 117 "vkCreateSemaphore")); 118 return signalSemaphore; 119 } 120 ExportSemaphore(VkSemaphore semaphore)121 ResultOrError<ExternalSemaphoreHandle> Service::ExportSemaphore(VkSemaphore semaphore) { 122 VkSemaphoreGetFdInfoKHR semaphoreGetFdInfo; 123 semaphoreGetFdInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR; 124 semaphoreGetFdInfo.pNext = nullptr; 125 semaphoreGetFdInfo.semaphore = semaphore; 126 semaphoreGetFdInfo.handleType = kHandleType; 127 128 int fd = -1; 129 DAWN_TRY(CheckVkSuccess( 130 mDevice->fn.GetSemaphoreFdKHR(mDevice->GetVkDevice(), &semaphoreGetFdInfo, &fd), 131 "vkGetSemaphoreFdKHR")); 132 133 ASSERT(fd >= 0); 134 return fd; 135 } 136 137 }}} // namespace dawn_native::vulkan::external_semaphore 138