From c1cb4d9d1826ccc3eccb33093746ced5bd165782 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 2 Aug 2022 14:33:41 +0200 Subject: [PATCH] [dxvk] Add feature check for external semaphores --- src/dxvk/dxvk_fence.cpp | 39 +++++++++++++++++++++++++++++--------- src/vulkan/vulkan_loader.h | 1 + 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/dxvk/dxvk_fence.cpp b/src/dxvk/dxvk_fence.cpp index 3f3a7746d..f9c3dc536 100644 --- a/src/dxvk/dxvk_fence.cpp +++ b/src/dxvk/dxvk_fence.cpp @@ -14,8 +14,25 @@ namespace dxvk { VkExportSemaphoreCreateInfo exportInfo = { VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO }; exportInfo.handleTypes = info.sharedType; - if (info.sharedType != VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_FLAG_BITS_MAX_ENUM) - typeInfo.pNext = &exportInfo; + VkExternalSemaphoreFeatureFlags externalFeatures = 0; + + if (info.sharedType != VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_FLAG_BITS_MAX_ENUM) { + auto vki = device->adapter()->vki(); + + VkPhysicalDeviceExternalSemaphoreInfo externalInfo = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO, &typeInfo }; + externalInfo.handleType = info.sharedType; + + VkExternalSemaphoreProperties externalProperties = { }; + vki->vkGetPhysicalDeviceExternalSemaphoreProperties( + device->adapter()->handle(), &externalInfo, &externalProperties); + + externalFeatures = externalProperties.externalSemaphoreFeatures; + + if (externalFeatures & VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT) + typeInfo.pNext = &exportInfo; + else + Logger::warn(str::format("Exporting semaphores of type ", info.sharedType, " not supported by device")); + } VkSemaphoreCreateInfo semaphoreInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, &typeInfo }; @@ -26,14 +43,18 @@ namespace dxvk { throw DxvkError("Failed to create timeline semaphore"); if (info.sharedHandle != INVALID_HANDLE_VALUE) { - VkImportSemaphoreWin32HandleInfoKHR importInfo = { VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR }; - importInfo.semaphore = m_semaphore; - importInfo.handleType = info.sharedType; - importInfo.handle = info.sharedHandle; + if (externalFeatures & VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT) { + VkImportSemaphoreWin32HandleInfoKHR importInfo = { VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR }; + importInfo.semaphore = m_semaphore; + importInfo.handleType = info.sharedType; + importInfo.handle = info.sharedHandle; - vr = m_vkd->vkImportSemaphoreWin32HandleKHR(m_vkd->device(), &importInfo); - if (vr != VK_SUCCESS) - throw DxvkError("Failed to import timeline semaphore"); + vr = m_vkd->vkImportSemaphoreWin32HandleKHR(m_vkd->device(), &importInfo); + if (vr != VK_SUCCESS) + throw DxvkError("Failed to import timeline semaphore"); + } else { + Logger::warn(str::format("Importing semaphores of type ", info.sharedType, " not supported by device")); + } } m_thread = dxvk::thread([this] { run(); }); diff --git a/src/vulkan/vulkan_loader.h b/src/vulkan/vulkan_loader.h index 47c26eed8..6f469c650 100644 --- a/src/vulkan/vulkan_loader.h +++ b/src/vulkan/vulkan_loader.h @@ -85,6 +85,7 @@ namespace dxvk::vk { VULKAN_FN(vkDestroyInstance); VULKAN_FN(vkEnumerateDeviceExtensionProperties); VULKAN_FN(vkEnumeratePhysicalDevices); + VULKAN_FN(vkGetPhysicalDeviceExternalSemaphoreProperties); VULKAN_FN(vkGetPhysicalDeviceFeatures); VULKAN_FN(vkGetPhysicalDeviceFeatures2); VULKAN_FN(vkGetPhysicalDeviceFormatProperties);