Fixed linux wsi extensions being added erroneously

Previously, on linux all three windowing extensions would be added
(xcb, xlib, wayland) even if they weren't available.
Now, InstanceBuilder first makes sure they are present before
adding them.

Also added a new error code to represent the lack of wsi extensions
This commit is contained in:
Charles Giessen 2020-05-19 10:44:40 -06:00
parent 3bbc4831f5
commit 698be4e09b
2 changed files with 20 additions and 10 deletions

View File

@ -241,6 +241,8 @@ const char* to_string (InstanceError err) {
return "requested_layers_not_present"; return "requested_layers_not_present";
case InstanceError::requested_extensions_not_present: case InstanceError::requested_extensions_not_present:
return "requested_extensions_not_present"; return "requested_extensions_not_present";
case InstanceError::windowing_extensions_not_present:
return "windowing_extensions_not_present";
default: default:
return ""; return "";
} }
@ -400,25 +402,32 @@ detail::Result<Instance> InstanceBuilder::build () const {
std::vector<const char*> extensions; std::vector<const char*> extensions;
for (auto& ext : info.extensions) for (auto& ext : info.extensions)
extensions.push_back (ext); extensions.push_back (ext);
if (info.debug_callback != nullptr) { if (info.debug_callback != nullptr && system.debug_utils_available) {
extensions.push_back (VK_EXT_DEBUG_UTILS_EXTENSION_NAME); extensions.push_back (VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
} }
if (!info.headless_context) { if (!info.headless_context) {
extensions.push_back ("VK_KHR_surface"); auto check_add_window_ext = [&] (const char* name) -> bool {
if (!detail::check_extension_supported(system.available_extensions, name))
return false;
extensions.push_back(name);
return true;
};
bool khr_surface_added = check_add_window_ext ("VK_KHR_surface");
#if defined(_WIN32) #if defined(_WIN32)
extensions.push_back ("VK_KHR_win32_surface"); bool added_window_exts = check_add_window_ext("VK_KHR_win32_surface");
#elif defined(__ANDROID__) #elif defined(__ANDROID__)
extensions.push_back ("VK_KHR_android_surface"); bool added_window_exts = check_add_window_ext("VK_KHR_android_surface");
#elif defined(_DIRECT2DISPLAY) #elif defined(_DIRECT2DISPLAY)
extensions.push_back ("VK_KHR_display"); bool added_window_exts = check_add_window_ext ("VK_KHR_display");
#elif defined(__linux__) #elif defined(__linux__)
extensions.push_back ("VK_KHR_xcb_surface"); bool added_window_exts = check_add_window_ext ("VK_KHR_xcb_surface") || check_add_window_ext ("VK_KHR_xlib_surface") || check_add_window_ext ("VK_KHR_wayland_surface");
extensions.push_back ("VK_KHR_xlib_surface");
extensions.push_back ("VK_KHR_wayland_surface");
#elif defined(__APPLE__) #elif defined(__APPLE__)
extensions.push_back ("VK_KHR_metal_surface"); bool added_window_exts = check_add_window_ext ("VK_KHR_metal_surface");
#endif #endif
if (!khr_surface_added || !added_window_exts)
return make_error_code(InstanceError::windowing_extensions_not_present);
} }
bool all_extensions_supported = detail::check_extensions_supported (system.available_extensions, extensions); bool all_extensions_supported = detail::check_extensions_supported (system.available_extensions, extensions);
if (!all_extensions_supported) { if (!all_extensions_supported) {

View File

@ -106,7 +106,8 @@ enum class InstanceError {
failed_create_instance, failed_create_instance,
failed_create_debug_messenger, failed_create_debug_messenger,
requested_layers_not_present, requested_layers_not_present,
requested_extensions_not_present requested_extensions_not_present,
windowing_extensions_not_present,
}; };
enum class PhysicalDeviceError { enum class PhysicalDeviceError {
no_surface_provided, no_surface_provided,