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.
This commit is contained in:
baldurk
2017-09-19 17:01:58 +01:00
parent 86c3ee4086
commit 67bea64070
4 changed files with 73 additions and 63 deletions
+1 -1
View File
@@ -658,7 +658,7 @@ private:
bool m_ExtensionsEnabled[VkCheckExt_Max];
// in vk_<platform>.cpp
bool AddRequiredExtensions(bool instance, vector<string> &extensionList,
void AddRequiredExtensions(bool instance, vector<string> &extensionList,
const std::set<string> &supportedExtensions);
void InsertDrawsAndRefreshIDs(vector<VulkanDrawcallTreeNode> &cmdBufNodes);
+50 -37
View File
@@ -35,33 +35,33 @@ bool VulkanReplay::IsOutputWindowVisible(uint64_t id)
return true;
}
bool WrappedVulkan::AddRequiredExtensions(bool instance, vector<string> &extensionList,
void WrappedVulkan::AddRequiredExtensions(bool instance, vector<string> &extensionList,
const std::set<string> &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<string> &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<string> &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<string> &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)
+21 -20
View File
@@ -72,7 +72,7 @@ bool VulkanReplay::IsOutputWindowVisible(uint64_t id)
return (IsWindowVisible(m_OutputWindows[id].wnd) == TRUE);
}
bool WrappedVulkan::AddRequiredExtensions(bool instance, vector<string> &extensionList,
void WrappedVulkan::AddRequiredExtensions(bool instance, vector<string> &extensionList,
const std::set<string> &supportedExtensions)
{
bool device = !instance;
@@ -83,39 +83,40 @@ bool WrappedVulkan::AddRequiredExtensions(bool instance, vector<string> &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)
@@ -162,11 +162,7 @@ ReplayStatus WrappedVulkan::Initialise(VkInitParams &params)
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++)