From 67bea64070acf222fd51fee204d1140cfb7f01bc Mon Sep 17 00:00:00 2001 From: baldurk Date: Tue, 19 Sep 2017 17:01:58 +0100 Subject: [PATCH] Make it non-fatal to be missing WSI extensions at runtime * Instead of erroring and failing to replay a capture if WSI is not present when replaying even though enabled at compile time, we just print a warning and allow the supported windowing systems list to become empty. * The UI or whichever app is controlling things must then respect this and not try to create any outputs. If the replay is happening completely headless there are then no more errors. --- renderdoc/driver/vulkan/vk_core.h | 2 +- renderdoc/driver/vulkan/vk_posix.cpp | 87 +++++++++++-------- renderdoc/driver/vulkan/vk_win32.cpp | 41 ++++----- .../vulkan/wrappers/vk_device_funcs.cpp | 6 +- 4 files changed, 73 insertions(+), 63 deletions(-) diff --git a/renderdoc/driver/vulkan/vk_core.h b/renderdoc/driver/vulkan/vk_core.h index d75cffaf7..13183b10c 100644 --- a/renderdoc/driver/vulkan/vk_core.h +++ b/renderdoc/driver/vulkan/vk_core.h @@ -658,7 +658,7 @@ private: bool m_ExtensionsEnabled[VkCheckExt_Max]; // in vk_.cpp - bool AddRequiredExtensions(bool instance, vector &extensionList, + void AddRequiredExtensions(bool instance, vector &extensionList, const std::set &supportedExtensions); void InsertDrawsAndRefreshIDs(vector &cmdBufNodes); diff --git a/renderdoc/driver/vulkan/vk_posix.cpp b/renderdoc/driver/vulkan/vk_posix.cpp index ec5432062..8e1baee39 100644 --- a/renderdoc/driver/vulkan/vk_posix.cpp +++ b/renderdoc/driver/vulkan/vk_posix.cpp @@ -35,33 +35,33 @@ bool VulkanReplay::IsOutputWindowVisible(uint64_t id) return true; } -bool WrappedVulkan::AddRequiredExtensions(bool instance, vector &extensionList, +void WrappedVulkan::AddRequiredExtensions(bool instance, vector &extensionList, const std::set &supportedExtensions) { bool device = !instance; +// check if our compile-time options expect any WSI to be available, or if it's all disabled +#define EXPECT_WSI 0 + +#if(defined(VK_USE_PLATFORM_ANDROID_KHR) || defined(VK_USE_PLATFORM_XCB_KHR) || \ + defined(VK_USE_PLATFORM_XLIB_KHR)) + +#undef EXPECT_WSI +#define EXPECT_WSI 1 + +#endif + if(instance) { - // we must have VK_KHR_surface - if(supportedExtensions.find(VK_KHR_SURFACE_EXTENSION_NAME) == supportedExtensions.end()) - { - RDCERR("Unsupported required instance extension '%s'", VK_KHR_SURFACE_EXTENSION_NAME); - return false; - } - // don't add duplicates if(std::find(extensionList.begin(), extensionList.end(), VK_KHR_SURFACE_EXTENSION_NAME) == extensionList.end()) extensionList.push_back(VK_KHR_SURFACE_EXTENSION_NAME); - bool oneSurfaceTypeSupported = false; - #if defined(VK_USE_PLATFORM_XCB_KHR) // check if supported if(supportedExtensions.find(VK_KHR_XCB_SURFACE_EXTENSION_NAME) != supportedExtensions.end()) { - oneSurfaceTypeSupported = true; - m_SupportedWindowSystems.push_back(WindowingSystem::XCB); // don't add duplicates @@ -77,8 +77,6 @@ bool WrappedVulkan::AddRequiredExtensions(bool instance, vector &extensi // check if supported if(supportedExtensions.find(VK_KHR_XLIB_SURFACE_EXTENSION_NAME) != supportedExtensions.end()) { - oneSurfaceTypeSupported = true; - m_SupportedWindowSystems.push_back(WindowingSystem::Xlib); // don't add duplicates @@ -95,7 +93,6 @@ bool WrappedVulkan::AddRequiredExtensions(bool instance, vector &extensi RDCASSERT(supportedExtensions.find(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME) != supportedExtensions.end()); - oneSurfaceTypeSupported = true; m_SupportedWindowSystems.push_back(WindowingSystem::Android); // don't add duplicates, application will have added this but just be sure @@ -106,40 +103,56 @@ bool WrappedVulkan::AddRequiredExtensions(bool instance, vector &extensi } #endif - if(!oneSurfaceTypeSupported) +#if EXPECT_WSI + // we must have VK_KHR_surface to support WSI at all + if(supportedExtensions.find(VK_KHR_SURFACE_EXTENSION_NAME) == supportedExtensions.end()) { + RDCWARN("Unsupported instance extension '%s' - disabling WSI support.", + VK_KHR_SURFACE_EXTENSION_NAME); + m_SupportedWindowSystems.clear(); + } +#endif + +#if EXPECT_WSI + + // if we expected WSI support, warn about it but continue. The UI will have no supported + // window systems to work with so will be forced to be headless. + if(m_SupportedWindowSystems.empty()) + { + RDCWARN("No WSI support - only headless replay allowed."); + #if defined(VK_USE_PLATFORM_ANDROID_KHR) + RDCWARN("Android Output requires the '%s' extension to be present", + VK_KHR_ANDROID_SURFACE_EXTENSION_NAME); +#endif - RDCERR("Require the '%s' extension to be present", VK_KHR_ANDROID_SURFACE_EXTENSION_NAME); - return false; - -#elif defined(VK_USE_PLATFORM_XCB_KHR) || defined(VK_USE_PLATFORM_XLIB_KHR) - - RDCERR("Require either the '%s' or '%s' extension to be present", - VK_KHR_XCB_SURFACE_EXTENSION_NAME, VK_KHR_XLIB_SURFACE_EXTENSION_NAME); - return false; - -#else - - // No windowing system support compiled in - allow this to continue, - // but this will only work for headless replay (which is feasible on some platforms) - return true; +#if defined(VK_USE_PLATFORM_XCB_KHR) + RDCWARN("XCB Output requires the '%s' extension to be present", + VK_KHR_XCB_SURFACE_EXTENSION_NAME); +#endif +#if defined(VK_USE_PLATFORM_XLIB_KHR) + RDCWARN("XLib Output requires the '%s' extension to be present", + VK_KHR_XLIB_SURFACE_EXTENSION_NAME); #endif } + +#endif } else if(device) { - if(supportedExtensions.find(VK_KHR_SWAPCHAIN_EXTENSION_NAME) == supportedExtensions.end()) + if(!m_SupportedWindowSystems.empty()) { - RDCERR("Unsupported required device extension '%s'", VK_KHR_SWAPCHAIN_EXTENSION_NAME); - return false; + if(supportedExtensions.find(VK_KHR_SWAPCHAIN_EXTENSION_NAME) == supportedExtensions.end()) + { + RDCWARN("Unsupported required device extension '%s'", VK_KHR_SWAPCHAIN_EXTENSION_NAME); + } + else + { + extensionList.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME); + } } - - extensionList.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME); } - - return true; } #if defined(VK_USE_PLATFORM_XCB_KHR) diff --git a/renderdoc/driver/vulkan/vk_win32.cpp b/renderdoc/driver/vulkan/vk_win32.cpp index 2928f3f86..7847492a4 100644 --- a/renderdoc/driver/vulkan/vk_win32.cpp +++ b/renderdoc/driver/vulkan/vk_win32.cpp @@ -72,7 +72,7 @@ bool VulkanReplay::IsOutputWindowVisible(uint64_t id) return (IsWindowVisible(m_OutputWindows[id].wnd) == TRUE); } -bool WrappedVulkan::AddRequiredExtensions(bool instance, vector &extensionList, +void WrappedVulkan::AddRequiredExtensions(bool instance, vector &extensionList, const std::set &supportedExtensions) { bool device = !instance; @@ -83,39 +83,40 @@ bool WrappedVulkan::AddRequiredExtensions(bool instance, vector &extensi if(supportedExtensions.find(VK_KHR_SURFACE_EXTENSION_NAME) == supportedExtensions.end()) { RDCERR("Unsupported required instance extension '%s'", VK_KHR_SURFACE_EXTENSION_NAME); - return false; + } + else + { + // don't add duplicates + if(std::find(extensionList.begin(), extensionList.end(), VK_KHR_SURFACE_EXTENSION_NAME) == + extensionList.end()) + extensionList.push_back(VK_KHR_SURFACE_EXTENSION_NAME); } if(supportedExtensions.find(VK_KHR_WIN32_SURFACE_EXTENSION_NAME) == supportedExtensions.end()) { RDCERR("Unsupported required instance extension '%s'", VK_KHR_WIN32_SURFACE_EXTENSION_NAME); - return false; } - - // don't add duplicates - if(std::find(extensionList.begin(), extensionList.end(), VK_KHR_SURFACE_EXTENSION_NAME) == - extensionList.end()) - extensionList.push_back(VK_KHR_SURFACE_EXTENSION_NAME); - - if(std::find(extensionList.begin(), extensionList.end(), VK_KHR_WIN32_SURFACE_EXTENSION_NAME) == - extensionList.end()) - extensionList.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); + else + { + if(std::find(extensionList.begin(), extensionList.end(), + VK_KHR_WIN32_SURFACE_EXTENSION_NAME) == extensionList.end()) + extensionList.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); + } } else if(device) { if(supportedExtensions.find(VK_KHR_SWAPCHAIN_EXTENSION_NAME) == supportedExtensions.end()) { RDCERR("Unsupported required device extension '%s'", VK_KHR_SWAPCHAIN_EXTENSION_NAME); - return false; } - - // don't add duplicates - if(std::find(extensionList.begin(), extensionList.end(), VK_KHR_SWAPCHAIN_EXTENSION_NAME) == - extensionList.end()) - extensionList.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME); + else + { + // don't add duplicates + if(std::find(extensionList.begin(), extensionList.end(), VK_KHR_SWAPCHAIN_EXTENSION_NAME) == + extensionList.end()) + extensionList.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME); + } } - - return true; } #if !defined(VK_USE_PLATFORM_WIN32_KHR) diff --git a/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp index a5001abb4..b7a957395 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp @@ -162,11 +162,7 @@ ReplayStatus WrappedVulkan::Initialise(VkInitParams ¶ms) SAFE_DELETE_ARRAY(props); } - bool ok = AddRequiredExtensions(true, params.Extensions, supportedExtensions); - - // error message will be printed to log in above function if something went wrong - if(!ok) - return ReplayStatus::APIHardwareUnsupported; + AddRequiredExtensions(true, params.Extensions, supportedExtensions); // verify that extensions & layers are supported for(size_t i = 0; i < params.Layers.size(); i++)