From 57f66ce6093b6a89284f71b49d6bf01bd4a3bce8 Mon Sep 17 00:00:00 2001 From: Charles Giessen Date: Wed, 23 Oct 2024 16:16:19 -0500 Subject: [PATCH 1/5] Refactor instance extension checks into single function Loader now generates a struct that contains of bools for each instance extension and a function to set the bool to true if the extension is in the list passed in. This consolidates that logic into one place rather than having it spread out across the codebase. It also enable further changes that will require each drivers list of supported instance extensions. --- loader/debug_utils.c | 10 - loader/generated/vk_loader_extensions.c | 122 ++++++----- loader/generated/vk_loader_extensions.h | 59 +++++- loader/loader.c | 25 +-- loader/loader_common.h | 47 +---- loader/trampoline.c | 5 +- loader/wsi.c | 269 ++++++++---------------- loader/wsi.h | 1 - scripts/loader_extension_generator.py | 93 +++----- 9 files changed, 264 insertions(+), 367 deletions(-) diff --git a/loader/debug_utils.c b/loader/debug_utils.c index 1506dc530..f697f7943 100644 --- a/loader/debug_utils.c +++ b/loader/debug_utils.c @@ -612,16 +612,6 @@ VkResult add_debug_extensions_to_ext_list(const struct loader_instance *inst, st debug_utils_extension_info); } -void check_for_enabled_debug_extensions(struct loader_instance *ptr_instance, const VkInstanceCreateInfo *pCreateInfo) { - for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) { - if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_DEBUG_REPORT_EXTENSION_NAME) == 0) { - ptr_instance->enabled_known_extensions.ext_debug_report = 1; - } else if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_DEBUG_UTILS_EXTENSION_NAME) == 0) { - ptr_instance->enabled_known_extensions.ext_debug_utils = 1; - } - } -} - bool debug_extensions_InstanceGpa(struct loader_instance *ptr_instance, const char *name, void **addr) { bool ret_type = false; diff --git a/loader/generated/vk_loader_extensions.c b/loader/generated/vk_loader_extensions.c index d5d607dd4..a10c91079 100644 --- a/loader/generated/vk_loader_extensions.c +++ b/loader/generated/vk_loader_extensions.c @@ -12169,58 +12169,77 @@ bool extension_instance_gpa(struct loader_instance *ptr_instance, const char *na return false; } -// A function that can be used to query enabled extensions during a vkCreateInstance call -void extensions_create_instance(struct loader_instance *ptr_instance, const VkInstanceCreateInfo *pCreateInfo) { - for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) { - - // ---- VK_KHR_get_physical_device_properties2 extension commands - if (0 == strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { - ptr_instance->enabled_known_extensions.khr_get_physical_device_properties2 = 1; - - // ---- VK_KHR_device_group_creation extension commands - } else if (0 == strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_DEVICE_GROUP_CREATION_EXTENSION_NAME)) { - ptr_instance->enabled_known_extensions.khr_device_group_creation = 1; - - // ---- VK_KHR_external_memory_capabilities extension commands - } else if (0 == strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME)) { - ptr_instance->enabled_known_extensions.khr_external_memory_capabilities = 1; - - // ---- VK_KHR_external_semaphore_capabilities extension commands - } else if (0 == strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME)) { - ptr_instance->enabled_known_extensions.khr_external_semaphore_capabilities = 1; - - // ---- VK_KHR_external_fence_capabilities extension commands - } else if (0 == strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME)) { - ptr_instance->enabled_known_extensions.khr_external_fence_capabilities = 1; - - // ---- VK_NV_external_memory_capabilities extension commands - } else if (0 == strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_NV_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME)) { - ptr_instance->enabled_known_extensions.nv_external_memory_capabilities = 1; - - // ---- VK_EXT_direct_mode_display extension commands - } else if (0 == strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME)) { - ptr_instance->enabled_known_extensions.ext_direct_mode_display = 1; - - // ---- VK_EXT_acquire_xlib_display extension commands +void fill_out_enabled_instance_extensions(uint32_t extension_count, const char *const * extension_list, struct loader_instance_extension_enables* enables) { + for(uint32_t i = 0; i < extension_count; i++) { + if (strcmp(extension_list[i], VK_KHR_SURFACE_EXTENSION_NAME) == 0) { enables->khr_surface = true; } + if (strcmp(extension_list[i], VK_KHR_DISPLAY_EXTENSION_NAME) == 0) { enables->khr_display = true; } +#if defined(VK_USE_PLATFORM_XLIB_KHR) + if (strcmp(extension_list[i], VK_KHR_XLIB_SURFACE_EXTENSION_NAME) == 0) { enables->khr_xlib_surface = true; } +#endif // defined(VK_USE_PLATFORM_XLIB_KHR) +#if defined(VK_USE_PLATFORM_XCB_KHR) + if (strcmp(extension_list[i], VK_KHR_XCB_SURFACE_EXTENSION_NAME) == 0) { enables->khr_xcb_surface = true; } +#endif // defined(VK_USE_PLATFORM_XCB_KHR) +#if defined(VK_USE_PLATFORM_WAYLAND_KHR) + if (strcmp(extension_list[i], VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME) == 0) { enables->khr_wayland_surface = true; } +#endif // defined(VK_USE_PLATFORM_WAYLAND_KHR) +#if defined(VK_USE_PLATFORM_ANDROID_KHR) + if (strcmp(extension_list[i], VK_KHR_ANDROID_SURFACE_EXTENSION_NAME) == 0) { enables->khr_android_surface = true; } +#endif // defined(VK_USE_PLATFORM_ANDROID_KHR) +#if defined(VK_USE_PLATFORM_WIN32_KHR) + if (strcmp(extension_list[i], VK_KHR_WIN32_SURFACE_EXTENSION_NAME) == 0) { enables->khr_win32_surface = true; } +#endif // defined(VK_USE_PLATFORM_WIN32_KHR) + if (strcmp(extension_list[i], VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME) == 0) { enables->khr_get_physical_device_properties2 = true; } + if (strcmp(extension_list[i], VK_KHR_DEVICE_GROUP_CREATION_EXTENSION_NAME) == 0) { enables->khr_device_group_creation = true; } + if (strcmp(extension_list[i], VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME) == 0) { enables->khr_external_memory_capabilities = true; } + if (strcmp(extension_list[i], VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME) == 0) { enables->khr_external_semaphore_capabilities = true; } + if (strcmp(extension_list[i], VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME) == 0) { enables->khr_external_fence_capabilities = true; } + if (strcmp(extension_list[i], VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME) == 0) { enables->khr_get_surface_capabilities2 = true; } + if (strcmp(extension_list[i], VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME) == 0) { enables->khr_get_display_properties2 = true; } + if (strcmp(extension_list[i], VK_KHR_SURFACE_PROTECTED_CAPABILITIES_EXTENSION_NAME) == 0) { enables->khr_surface_protected_capabilities = true; } + if (strcmp(extension_list[i], VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME) == 0) { enables->khr_portability_enumeration = true; } + if (strcmp(extension_list[i], VK_EXT_DEBUG_REPORT_EXTENSION_NAME) == 0) { enables->ext_debug_report = true; } +#if defined(VK_USE_PLATFORM_GGP) + if (strcmp(extension_list[i], VK_GGP_STREAM_DESCRIPTOR_SURFACE_EXTENSION_NAME) == 0) { enables->ggp_stream_descriptor_surface = true; } +#endif // defined(VK_USE_PLATFORM_GGP) + if (strcmp(extension_list[i], VK_NV_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME) == 0) { enables->nv_external_memory_capabilities = true; } + if (strcmp(extension_list[i], VK_EXT_VALIDATION_FLAGS_EXTENSION_NAME) == 0) { enables->ext_validation_flags = true; } +#if defined(VK_USE_PLATFORM_VI_NN) + if (strcmp(extension_list[i], VK_NN_VI_SURFACE_EXTENSION_NAME) == 0) { enables->nn_vi_surface = true; } +#endif // defined(VK_USE_PLATFORM_VI_NN) + if (strcmp(extension_list[i], VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME) == 0) { enables->ext_direct_mode_display = true; } #if defined(VK_USE_PLATFORM_XLIB_XRANDR_EXT) - } else if (0 == strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_ACQUIRE_XLIB_DISPLAY_EXTENSION_NAME)) { - ptr_instance->enabled_known_extensions.ext_acquire_xlib_display = 1; -#endif // VK_USE_PLATFORM_XLIB_XRANDR_EXT - - // ---- VK_EXT_display_surface_counter extension commands - } else if (0 == strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME)) { - ptr_instance->enabled_known_extensions.ext_display_surface_counter = 1; - - // ---- VK_EXT_debug_utils extension commands - } else if (0 == strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_DEBUG_UTILS_EXTENSION_NAME)) { - ptr_instance->enabled_known_extensions.ext_debug_utils = 1; - - // ---- VK_EXT_acquire_drm_display extension commands - } else if (0 == strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_ACQUIRE_DRM_DISPLAY_EXTENSION_NAME)) { - ptr_instance->enabled_known_extensions.ext_acquire_drm_display = 1; - } + if (strcmp(extension_list[i], VK_EXT_ACQUIRE_XLIB_DISPLAY_EXTENSION_NAME) == 0) { enables->ext_acquire_xlib_display = true; } +#endif // defined(VK_USE_PLATFORM_XLIB_XRANDR_EXT) + if (strcmp(extension_list[i], VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME) == 0) { enables->ext_display_surface_counter = true; } + if (strcmp(extension_list[i], VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME) == 0) { enables->ext_swapchain_colorspace = true; } +#if defined(VK_USE_PLATFORM_IOS_MVK) + if (strcmp(extension_list[i], VK_MVK_IOS_SURFACE_EXTENSION_NAME) == 0) { enables->mvk_ios_surface = true; } +#endif // defined(VK_USE_PLATFORM_IOS_MVK) +#if defined(VK_USE_PLATFORM_MACOS_MVK) + if (strcmp(extension_list[i], VK_MVK_MACOS_SURFACE_EXTENSION_NAME) == 0) { enables->mvk_macos_surface = true; } +#endif // defined(VK_USE_PLATFORM_MACOS_MVK) + if (strcmp(extension_list[i], VK_EXT_DEBUG_UTILS_EXTENSION_NAME) == 0) { enables->ext_debug_utils = true; } +#if defined(VK_USE_PLATFORM_FUCHSIA) + if (strcmp(extension_list[i], VK_FUCHSIA_IMAGEPIPE_SURFACE_EXTENSION_NAME) == 0) { enables->fuchsia_imagepipe_surface = true; } +#endif // defined(VK_USE_PLATFORM_FUCHSIA) +#if defined(VK_USE_PLATFORM_METAL_EXT) + if (strcmp(extension_list[i], VK_EXT_METAL_SURFACE_EXTENSION_NAME) == 0) { enables->ext_metal_surface = true; } +#endif // defined(VK_USE_PLATFORM_METAL_EXT) + if (strcmp(extension_list[i], VK_EXT_VALIDATION_FEATURES_EXTENSION_NAME) == 0) { enables->ext_validation_features = true; } + if (strcmp(extension_list[i], VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME) == 0) { enables->ext_headless_surface = true; } + if (strcmp(extension_list[i], VK_EXT_SURFACE_MAINTENANCE_1_EXTENSION_NAME) == 0) { enables->ext_surface_maintenance1 = true; } + if (strcmp(extension_list[i], VK_EXT_ACQUIRE_DRM_DISPLAY_EXTENSION_NAME) == 0) { enables->ext_acquire_drm_display = true; } +#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) + if (strcmp(extension_list[i], VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME) == 0) { enables->ext_directfb_surface = true; } +#endif // defined(VK_USE_PLATFORM_DIRECTFB_EXT) +#if defined(VK_USE_PLATFORM_SCREEN_QNX) + if (strcmp(extension_list[i], VK_QNX_SCREEN_SURFACE_EXTENSION_NAME) == 0) { enables->qnx_screen_surface = true; } +#endif // defined(VK_USE_PLATFORM_SCREEN_QNX) + if (strcmp(extension_list[i], VK_GOOGLE_SURFACELESS_QUERY_EXTENSION_NAME) == 0) { enables->google_surfaceless_query = true; } + if (strcmp(extension_list[i], VK_LUNARG_DIRECT_DRIVER_LOADING_EXTENSION_NAME) == 0) { enables->lunarg_direct_driver_loading = true; } + if (strcmp(extension_list[i], VK_EXT_LAYER_SETTINGS_EXTENSION_NAME) == 0) { enables->ext_layer_settings = true; } } -} +}; // Some device commands still need a terminator because the loader needs to unwrap something about them. // In many cases, the item needing unwrapping is a VkPhysicalDevice or VkSurfaceKHR object. But there may be other items @@ -12581,6 +12600,9 @@ const char *const LOADER_INSTANCE_EXTENSIONS[] = { #if defined(VK_USE_PLATFORM_WAYLAND_KHR) VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME, #endif // VK_USE_PLATFORM_WAYLAND_KHR +#if defined(VK_USE_PLATFORM_ANDROID_KHR) + VK_KHR_ANDROID_SURFACE_EXTENSION_NAME, +#endif // VK_USE_PLATFORM_ANDROID_KHR #if defined(VK_USE_PLATFORM_WIN32_KHR) VK_KHR_WIN32_SURFACE_EXTENSION_NAME, #endif // VK_USE_PLATFORM_WIN32_KHR diff --git a/loader/generated/vk_loader_extensions.h b/loader/generated/vk_loader_extensions.h index df59d91b8..4a15fc54a 100644 --- a/loader/generated/vk_loader_extensions.h +++ b/loader/generated/vk_loader_extensions.h @@ -46,10 +46,12 @@ VKAPI_ATTR VkResult VKAPI_CALL vkDevExtError(VkDevice dev); // the appropriate information for any instance extensions we know about. bool extension_instance_gpa(struct loader_instance *ptr_instance, const char *name, void **addr); +struct loader_instance_extension_enables; // Forward declaration // Extension interception for vkCreateInstance function, so we can properly // detect and enable any instance extension information for extensions we know // about. -void extensions_create_instance(struct loader_instance *ptr_instance, const VkInstanceCreateInfo *pCreateInfo); +void fill_out_enabled_instance_extensions(uint32_t extension_count, const char *const * extension_list, struct loader_instance_extension_enables* enables); + // Extension interception for vkGetDeviceProcAddr function, so we can return // an appropriate terminator if this is one of those few device commands requiring @@ -479,18 +481,73 @@ struct loader_icd_term_dispatch { }; struct loader_instance_extension_enables { + uint8_t khr_surface; + uint8_t khr_display; +#if defined(VK_USE_PLATFORM_XLIB_KHR) + uint8_t khr_xlib_surface; +#endif // defined(VK_USE_PLATFORM_XLIB_KHR) +#if defined(VK_USE_PLATFORM_XCB_KHR) + uint8_t khr_xcb_surface; +#endif // defined(VK_USE_PLATFORM_XCB_KHR) +#if defined(VK_USE_PLATFORM_WAYLAND_KHR) + uint8_t khr_wayland_surface; +#endif // defined(VK_USE_PLATFORM_WAYLAND_KHR) +#if defined(VK_USE_PLATFORM_ANDROID_KHR) + uint8_t khr_android_surface; +#endif // defined(VK_USE_PLATFORM_ANDROID_KHR) +#if defined(VK_USE_PLATFORM_WIN32_KHR) + uint8_t khr_win32_surface; +#endif // defined(VK_USE_PLATFORM_WIN32_KHR) uint8_t khr_get_physical_device_properties2; uint8_t khr_device_group_creation; uint8_t khr_external_memory_capabilities; uint8_t khr_external_semaphore_capabilities; uint8_t khr_external_fence_capabilities; + uint8_t khr_get_surface_capabilities2; + uint8_t khr_get_display_properties2; + uint8_t khr_surface_protected_capabilities; + uint8_t khr_portability_enumeration; uint8_t ext_debug_report; +#if defined(VK_USE_PLATFORM_GGP) + uint8_t ggp_stream_descriptor_surface; +#endif // defined(VK_USE_PLATFORM_GGP) uint8_t nv_external_memory_capabilities; + uint8_t ext_validation_flags; +#if defined(VK_USE_PLATFORM_VI_NN) + uint8_t nn_vi_surface; +#endif // defined(VK_USE_PLATFORM_VI_NN) uint8_t ext_direct_mode_display; +#if defined(VK_USE_PLATFORM_XLIB_XRANDR_EXT) uint8_t ext_acquire_xlib_display; +#endif // defined(VK_USE_PLATFORM_XLIB_XRANDR_EXT) uint8_t ext_display_surface_counter; + uint8_t ext_swapchain_colorspace; +#if defined(VK_USE_PLATFORM_IOS_MVK) + uint8_t mvk_ios_surface; +#endif // defined(VK_USE_PLATFORM_IOS_MVK) +#if defined(VK_USE_PLATFORM_MACOS_MVK) + uint8_t mvk_macos_surface; +#endif // defined(VK_USE_PLATFORM_MACOS_MVK) uint8_t ext_debug_utils; +#if defined(VK_USE_PLATFORM_FUCHSIA) + uint8_t fuchsia_imagepipe_surface; +#endif // defined(VK_USE_PLATFORM_FUCHSIA) +#if defined(VK_USE_PLATFORM_METAL_EXT) + uint8_t ext_metal_surface; +#endif // defined(VK_USE_PLATFORM_METAL_EXT) + uint8_t ext_validation_features; + uint8_t ext_headless_surface; + uint8_t ext_surface_maintenance1; uint8_t ext_acquire_drm_display; +#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) + uint8_t ext_directfb_surface; +#endif // defined(VK_USE_PLATFORM_DIRECTFB_EXT) +#if defined(VK_USE_PLATFORM_SCREEN_QNX) + uint8_t qnx_screen_surface; +#endif // defined(VK_USE_PLATFORM_SCREEN_QNX) + uint8_t google_surfaceless_query; + uint8_t lunarg_direct_driver_loading; + uint8_t ext_layer_settings; }; // Functions that required a terminator need to have a separate dispatch table which contains their corresponding diff --git a/loader/loader.c b/loader/loader.c index 82e5bca10..e51d03ffe 100644 --- a/loader/loader.c +++ b/loader/loader.c @@ -5471,18 +5471,10 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateInstance(const VkInstanceCreateI // Determine if vkGetPhysicalDeviceProperties2 is available to this Instance // Also determine if VK_EXT_surface_maintenance1 is available on the ICD if (icd_term->scanned_icd->api_version >= VK_API_VERSION_1_1) { - icd_term->supports_get_dev_prop_2 = true; - } - for (uint32_t j = 0; j < icd_create_info.enabledExtensionCount; j++) { - if (!strcmp(filtered_extension_names[j], VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { - icd_term->supports_get_dev_prop_2 = true; - continue; - } - if (!strcmp(filtered_extension_names[j], VK_EXT_SURFACE_MAINTENANCE_1_EXTENSION_NAME)) { - icd_term->supports_ext_surface_maintenance_1 = true; - continue; - } + icd_term->enabled_instance_extensions.khr_get_physical_device_properties2 = true; } + fill_out_enabled_instance_extensions(icd_create_info.enabledExtensionCount, (const char *const *)filtered_extension_names, + &icd_term->enabled_instance_extensions); loader_destroy_generic_list(ptr_instance, (struct loader_generic_list *)&icd_exts); @@ -5605,18 +5597,18 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateInstance(const VkInstanceCreateI // For vkGetPhysicalDeviceProperties2, at least one ICD needs to support the extension for the // instance to have it - if (ptr_instance->supports_get_dev_prop_2) { + if (ptr_instance->enabled_known_extensions.khr_get_physical_device_properties2) { bool at_least_one_supports = false; icd_term = ptr_instance->icd_terms; while (icd_term != NULL) { - if (icd_term->supports_get_dev_prop_2) { + if (icd_term->enabled_instance_extensions.khr_get_physical_device_properties2) { at_least_one_supports = true; break; } icd_term = icd_term->next; } if (!at_least_one_supports) { - ptr_instance->supports_get_dev_prop_2 = false; + ptr_instance->enabled_known_extensions.khr_get_physical_device_properties2 = false; } } @@ -5654,9 +5646,8 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateInstance(const VkInstanceCreateI // This is why we don't clear inside of these function calls. // The clearing should actually be handled by the overall memset of the pInstance structure in the // trampoline. - wsi_create_instance(ptr_instance, pCreateInfo); - check_for_enabled_debug_extensions(ptr_instance, pCreateInfo); - extensions_create_instance(ptr_instance, pCreateInfo); + fill_out_enabled_instance_extensions(pCreateInfo->enabledExtensionCount, pCreateInfo->ppEnabledExtensionNames, + &ptr_instance->enabled_known_extensions); } return res; diff --git a/loader/loader_common.h b/loader/loader_common.h index 37b7d23d6..5ccf3dcde 100644 --- a/loader/loader_common.h +++ b/loader/loader_common.h @@ -265,8 +265,8 @@ struct loader_icd_term { struct loader_icd_term *next; PFN_PhysDevExt phys_dev_ext[MAX_NUM_UNKNOWN_EXTS]; - bool supports_get_dev_prop_2; - bool supports_ext_surface_maintenance_1; + + struct loader_instance_extension_enables enabled_instance_extensions; uint32_t physical_device_count; @@ -371,49 +371,6 @@ struct loader_instance { bool portability_enumeration_flag_bit_set; bool portability_enumeration_extension_enabled; - bool wsi_surface_enabled; -#if defined(VK_USE_PLATFORM_WIN32_KHR) - bool wsi_win32_surface_enabled; -#endif -#if defined(VK_USE_PLATFORM_WAYLAND_KHR) - bool wsi_wayland_surface_enabled; -#endif -#if defined(VK_USE_PLATFORM_XCB_KHR) - bool wsi_xcb_surface_enabled; -#endif -#if defined(VK_USE_PLATFORM_XLIB_KHR) - bool wsi_xlib_surface_enabled; -#endif -#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) - bool wsi_directfb_surface_enabled; -#endif -#if defined(VK_USE_PLATFORM_ANDROID_KHR) - bool wsi_android_surface_enabled; -#endif -#if defined(VK_USE_PLATFORM_MACOS_MVK) - bool wsi_macos_surface_enabled; -#endif -#if defined(VK_USE_PLATFORM_IOS_MVK) - bool wsi_ios_surface_enabled; -#endif -#if defined(VK_USE_PLATFORM_GGP) - bool wsi_ggp_surface_enabled; -#endif - bool wsi_headless_surface_enabled; -#if defined(VK_USE_PLATFORM_METAL_EXT) - bool wsi_metal_surface_enabled; -#endif -#if defined(VK_USE_PLATFORM_FUCHSIA) - bool wsi_imagepipe_surface_enabled; -#endif -#if defined(VK_USE_PLATFORM_SCREEN_QNX) - bool wsi_screen_surface_enabled; -#endif -#if defined(VK_USE_PLATFORM_VI_NN) - bool wsi_vi_surface_enabled; -#endif - bool wsi_display_enabled; - bool wsi_display_props2_enabled; bool create_terminator_invalid_extension; bool supports_get_dev_prop_2; }; diff --git a/loader/trampoline.c b/loader/trampoline.c index 2df9248e3..8d7328b89 100644 --- a/loader/trampoline.c +++ b/loader/trampoline.c @@ -738,9 +738,8 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(const VkInstanceCr // are enabled than what's down in the terminator. // This is why we don't clear inside of these function calls. // The clearing should actually be handled by the overall memset of the pInstance structure above. - wsi_create_instance(ptr_instance, &ici); - check_for_enabled_debug_extensions(ptr_instance, &ici); - extensions_create_instance(ptr_instance, &ici); + fill_out_enabled_instance_extensions(ici.enabledExtensionCount, ici.ppEnabledExtensionNames, + &ptr_instance->enabled_known_extensions); *pInstance = (VkInstance)ptr_instance; diff --git a/loader/wsi.c b/loader/wsi.c index 9dd98acf5..0ac7320e8 100644 --- a/loader/wsi.c +++ b/loader/wsi.c @@ -39,105 +39,6 @@ // the ICDs. #define ICD_VER_SUPPORTS_ICD_SURFACE_KHR 3 -void wsi_create_instance(struct loader_instance *loader_inst, const VkInstanceCreateInfo *pCreateInfo) { - for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) { - if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SURFACE_EXTENSION_NAME) == 0) { - loader_inst->wsi_surface_enabled = true; - continue; - } -#if defined(VK_USE_PLATFORM_WIN32_KHR) - if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_WIN32_SURFACE_EXTENSION_NAME) == 0) { - loader_inst->wsi_win32_surface_enabled = true; - continue; - } -#endif // VK_USE_PLATFORM_WIN32_KHR -#if defined(VK_USE_PLATFORM_WAYLAND_KHR) - if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME) == 0) { - loader_inst->wsi_wayland_surface_enabled = true; - continue; - } -#endif // VK_USE_PLATFORM_WAYLAND_KHR -#if defined(VK_USE_PLATFORM_XCB_KHR) - if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_XCB_SURFACE_EXTENSION_NAME) == 0) { - loader_inst->wsi_xcb_surface_enabled = true; - continue; - } -#endif // VK_USE_PLATFORM_XCB_KHR -#if defined(VK_USE_PLATFORM_XLIB_KHR) - if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_XLIB_SURFACE_EXTENSION_NAME) == 0) { - loader_inst->wsi_xlib_surface_enabled = true; - continue; - } -#endif // VK_USE_PLATFORM_XLIB_KHR -#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) - if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME) == 0) { - loader_inst->wsi_directfb_surface_enabled = true; - continue; - } -#endif // VK_USE_PLATFORM_DIRECTFB_EXT -#if defined(VK_USE_PLATFORM_ANDROID_KHR) - if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_ANDROID_SURFACE_EXTENSION_NAME) == 0) { - loader_inst->wsi_android_surface_enabled = true; - continue; - } -#endif // VK_USE_PLATFORM_ANDROID_KHR -#if defined(VK_USE_PLATFORM_MACOS_MVK) - if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_MVK_MACOS_SURFACE_EXTENSION_NAME) == 0) { - loader_inst->wsi_macos_surface_enabled = true; - continue; - } -#endif // VK_USE_PLATFORM_MACOS_MVK -#if defined(VK_USE_PLATFORM_IOS_MVK) - if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_MVK_IOS_SURFACE_EXTENSION_NAME) == 0) { - loader_inst->wsi_ios_surface_enabled = true; - continue; - } -#endif // VK_USE_PLATFORM_IOS_MVK -#if defined(VK_USE_PLATFORM_GGP) - if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_GGP_STREAM_DESCRIPTOR_SURFACE_EXTENSION_NAME) == 0) { - loader_inst->wsi_ggp_surface_enabled = true; - continue; - } -#endif // VK_USE_PLATFORM_GGP -#if defined(VK_USE_PLATFORM_FUCHSIA) - if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_FUCHSIA_IMAGEPIPE_SURFACE_EXTENSION_NAME) == 0) { - loader_inst->wsi_imagepipe_surface_enabled = true; - continue; - } -#endif // VK_USE_PLATFORM_FUCHSIA - if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME) == 0) { - loader_inst->wsi_headless_surface_enabled = true; - continue; - } -#if defined(VK_USE_PLATFORM_METAL_EXT) - if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_METAL_SURFACE_EXTENSION_NAME) == 0) { - loader_inst->wsi_metal_surface_enabled = true; - continue; - } -#endif -#if defined(VK_USE_PLATFORM_SCREEN_QNX) - if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_QNX_SCREEN_SURFACE_EXTENSION_NAME) == 0) { - loader_inst->wsi_screen_surface_enabled = true; - continue; - } -#endif // VK_USE_PLATFORM_SCREEN_QNX -#if defined(VK_USE_PLATFORM_VI_NN) - if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_NN_VI_SURFACE_EXTENSION_NAME) == 0) { - loader_inst->wsi_vi_surface_enabled = true; - continue; - } -#endif // VK_USE_PLATFORM_VI_NN - if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_DISPLAY_EXTENSION_NAME) == 0) { - loader_inst->wsi_display_enabled = true; - continue; - } - if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME) == 0) { - loader_inst->wsi_display_props2_enabled = true; - continue; - } - } -} - // Linux WSI surface extensions are not always compiled into the loader. (Assume // for Windows the KHR_win32_surface is always compiled into loader). A given // Linux build environment might not have the headers required for building one @@ -232,7 +133,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceSupportKHR(VkP struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance; - if (!loader_inst->wsi_surface_enabled) { + if (!loader_inst->enabled_known_extensions.khr_surface) { loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "VK_KHR_surface extension not enabled. vkGetPhysicalDeviceSurfaceSupportKHR not executed!"); return VK_SUCCESS; @@ -288,7 +189,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceCapabilitiesKH struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance; - if (!loader_inst->wsi_surface_enabled) { + if (!loader_inst->enabled_known_extensions.khr_surface) { loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "VK_KHR_surface extension not enabled. vkGetPhysicalDeviceSurfaceCapabilitiesKHR not executed!"); return VK_SUCCESS; @@ -346,7 +247,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceFormatsKHR(VkP struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance; - if (!loader_inst->wsi_surface_enabled) { + if (!loader_inst->enabled_known_extensions.khr_surface) { loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "VK_KHR_surface extension not enabled. vkGetPhysicalDeviceSurfaceFormatsKHR not executed!"); return VK_SUCCESS; @@ -405,7 +306,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfacePresentModesKH struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance; - if (!loader_inst->wsi_surface_enabled) { + if (!loader_inst->enabled_known_extensions.khr_surface) { loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "VK_KHR_surface extension not enabled. vkGetPhysicalDeviceSurfacePresentModesKHR not executed!"); return VK_SUCCESS; @@ -645,7 +546,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateWin32SurfaceKHR(VkInstance insta *pSurface = VK_NULL_HANDLE; // First, check to ensure the appropriate extension was enabled: struct loader_instance *loader_inst = loader_get_instance(instance); - if (!loader_inst->wsi_win32_surface_enabled) { + if (!loader_inst->enabled_known_extensions.khr_win32_surface) { loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "VK_KHR_win32_surface extension not enabled. vkCreateWin32SurfaceKHR not executed!"); result = VK_ERROR_EXTENSION_NOT_PRESENT; @@ -703,7 +604,7 @@ VKAPI_ATTR VkBool32 VKAPI_CALL terminator_GetPhysicalDeviceWin32PresentationSupp struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance; - if (!loader_inst->wsi_win32_surface_enabled) { + if (!loader_inst->enabled_known_extensions.khr_win32_surface) { loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "VK_KHR_win32_surface extension not enabled. vkGetPhysicalDeviceWin32PresentationSupportKHR not executed!"); return VK_FALSE; @@ -746,7 +647,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateWaylandSurfaceKHR(VkInstance ins // First, check to ensure the appropriate extension was enabled: struct loader_instance *loader_inst = loader_get_instance(instance); - if (!loader_inst->wsi_wayland_surface_enabled) { + if (!loader_inst->enabled_known_extensions.khr_wayland_surface) { loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "VK_KHR_wayland_surface extension not enabled. vkCreateWaylandSurfaceKHR not executed!"); result = VK_ERROR_EXTENSION_NOT_PRESENT; @@ -807,7 +708,7 @@ VKAPI_ATTR VkBool32 VKAPI_CALL terminator_GetPhysicalDeviceWaylandPresentationSu struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance; - if (!loader_inst->wsi_wayland_surface_enabled) { + if (!loader_inst->enabled_known_extensions.khr_wayland_surface) { loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "VK_KHR_wayland_surface extension not enabled. vkGetPhysicalDeviceWaylandPresentationSupportKHR not executed!"); return VK_FALSE; @@ -851,7 +752,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateXcbSurfaceKHR(VkInstance instanc // First, check to ensure the appropriate extension was enabled: struct loader_instance *loader_inst = loader_get_instance(instance); - if (!loader_inst->wsi_xcb_surface_enabled) { + if (!loader_inst->enabled_known_extensions.khr_xcb_surface) { loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "VK_KHR_xcb_surface extension not enabled. vkCreateXcbSurfaceKHR not executed!"); result = VK_ERROR_EXTENSION_NOT_PRESENT; @@ -914,7 +815,7 @@ VKAPI_ATTR VkBool32 VKAPI_CALL terminator_GetPhysicalDeviceXcbPresentationSuppor struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance; - if (!loader_inst->wsi_xcb_surface_enabled) { + if (!loader_inst->enabled_known_extensions.khr_xcb_surface) { loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "VK_KHR_xcb_surface extension not enabled. vkGetPhysicalDeviceXcbPresentationSupportKHR not executed!"); return VK_FALSE; @@ -959,7 +860,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateXlibSurfaceKHR(VkInstance instan // First, check to ensure the appropriate extension was enabled: struct loader_instance *loader_inst = loader_get_instance(instance); - if (!loader_inst->wsi_xlib_surface_enabled) { + if (!loader_inst->enabled_known_extensions.khr_xlib_surface) { loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "VK_KHR_xlib_surface extension not enabled. vkCreateXlibSurfaceKHR not executed!"); result = VK_ERROR_EXTENSION_NOT_PRESENT; @@ -1020,7 +921,7 @@ VKAPI_ATTR VkBool32 VKAPI_CALL terminator_GetPhysicalDeviceXlibPresentationSuppo struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance; - if (!loader_inst->wsi_xlib_surface_enabled) { + if (!loader_inst->enabled_known_extensions.khr_xlib_surface) { loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "VK_KHR_xlib_surface extension not enabled. vkGetPhysicalDeviceXlibPresentationSupportKHR not executed!"); return VK_FALSE; @@ -1066,7 +967,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDirectFBSurfaceEXT(VkInstance in // First, check to ensure the appropriate extension was enabled: struct loader_instance *loader_inst = loader_get_instance(instance); - if (!loader_inst->wsi_directfb_surface_enabled) { + if (!loader_inst->enabled_known_extensions.ext_directfb_surface) { loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "VK_EXT_directfb_surface extension not enabled. vkCreateDirectFBSurfaceEXT not executed!"); result = VK_ERROR_EXTENSION_NOT_PRESENT; @@ -1127,7 +1028,7 @@ VKAPI_ATTR VkBool32 VKAPI_CALL terminator_GetPhysicalDeviceDirectFBPresentationS struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance; - if (!loader_inst->wsi_directfb_surface_enabled) { + if (!loader_inst->enabled_known_extensions.ext_directfb_surface) { loader_log( loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "VK_EXT_directfb_surface extension not enabled. vkGetPhysicalDeviceDirectFBPresentationSupportKHR not executed!"); @@ -1170,7 +1071,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateAndroidSurfaceKHR(VkInstance ins const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { // First, check to ensure the appropriate extension was enabled: struct loader_instance *loader_inst = loader_get_instance(instance); - if (!loader_inst->wsi_display_enabled) { + if (!loader_inst->enabled_known_extensions.khr_display) { loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "VK_KHR_display extension not enabled. vkCreateAndroidSurfaceKHR not executed!"); return VK_ERROR_EXTENSION_NOT_PRESENT; @@ -1218,7 +1119,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateHeadlessSurfaceEXT(VkInstance in // First, check to ensure the appropriate extension was enabled: struct loader_instance *loader_inst = loader_get_instance(instance); - if (!loader_inst->wsi_headless_surface_enabled) { + if (!loader_inst->enabled_known_extensions.ext_headless_surface) { loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "VK_EXT_headless_surface extension not enabled. " "vkCreateHeadlessSurfaceEXT not executed!"); @@ -1307,7 +1208,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateMacOSSurfaceMVK(VkInstance insta // First, check to ensure the appropriate extension was enabled: struct loader_instance *loader_inst = loader_get_instance(instance); - if (!loader_inst->wsi_macos_surface_enabled) { + if (!loader_inst->enabled_known_extensions.mvk_macos_surface) { loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "VK_MVK_macos_surface extension not enabled. vkCreateMacOSSurfaceMVK not executed!"); result = VK_ERROR_EXTENSION_NOT_PRESENT; @@ -1369,7 +1270,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateIOSSurfaceMVK(VkInstance instanc // First, check to ensure the appropriate extension was enabled: struct loader_instance *loader_inst = loader_get_instance(instance); - if (!loader_inst->wsi_ios_surface_enabled) { + if (!loader_inst->enabled_known_extensions.mvk_ios_surface) { loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "VK_MVK_ios_surface extension not enabled. vkCreateIOSSurfaceMVK not executed!"); return VK_ERROR_EXTENSION_NOT_PRESENT; @@ -1421,7 +1322,7 @@ terminator_CreateStreamDescriptorSurfaceGGP(VkInstance instance, const VkStreamD // First, check to ensure the appropriate extension was enabled: struct loader_instance *loader_inst = loader_get_instance(instance); - if (!loader_inst->wsi_ggp_surface_enabled) { + if (!loader_inst->enabled_known_extensions.wsi_ggp_surface_enabled) { loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "VK_GGP_stream_descriptor_surface extension not enabled. vkCreateStreamDescriptorSurfaceGGP not executed!"); result = VK_ERROR_EXTENSION_NOT_PRESENT; @@ -1481,7 +1382,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateMetalSurfaceEXT(VkInstance insta // First, check to ensure the appropriate extension was enabled: struct loader_instance *loader_inst = loader_get_instance(instance); - if (!loader_inst->wsi_metal_surface_enabled) { + if (!loader_inst->enabled_known_extensions.ext_metal_surface) { loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "VK_EXT_metal_surface extension not enabled. vkCreateMetalSurfaceEXT will not be executed."); } @@ -1541,7 +1442,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateScreenSurfaceQNX(VkInstance inst // First, check to ensure the appropriate extension was enabled: struct loader_instance *loader_inst = loader_get_instance(instance); - if (!loader_inst->wsi_screen_surface_enabled) { + if (!loader_inst->enabled_known_extensions.qnx_screen_surface) { loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "VK_QNX_screen_surface extension not enabled. vkCreateScreenSurfaceQNX not executed!"); result = VK_ERROR_EXTENSION_NOT_PRESENT; @@ -1602,7 +1503,7 @@ VKAPI_ATTR VkBool32 VKAPI_CALL terminator_GetPhysicalDeviceScreenPresentationSup struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance; - if (!loader_inst->wsi_screen_surface_enabled) { + if (!loader_inst->enabled_known_extensions.qnx_screen_surface) { loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "VK_QNX_screen_surface extension not enabled. vkGetPhysicalDeviceScreenPresentationSupportQNX not executed!"); return VK_FALSE; @@ -1644,7 +1545,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateViSurfaceNN(VkInstance instance, // First, check to ensure the appropriate extension was enabled: struct loader_instance *loader_inst = loader_get_instance(instance); - if (!loader_inst->wsi_vi_surface_enabled) { + if (!loader_inst->enabled_known_extensions.nn_vi_surface) { loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "VK_NN_vi_surface extension not enabled. vkCreateViSurfaceNN not executed!"); result = VK_ERROR_EXTENSION_NOT_PRESENT; @@ -1705,7 +1606,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceDisplayPropertiesKHR( struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance; - if (!loader_inst->wsi_display_enabled) { + if (!loader_inst->enabled_known_extensions.khr_display) { loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "VK_KHR_display extension not enabled. vkGetPhysicalDeviceDisplayPropertiesKHR not executed!"); return VK_SUCCESS; @@ -1746,7 +1647,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceDisplayPlanePropertie struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance; - if (!loader_inst->wsi_display_enabled) { + if (!loader_inst->enabled_known_extensions.khr_display) { loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "VK_KHR_display extension not enabled. vkGetPhysicalDeviceDisplayPlanePropertiesKHR not executed!"); return VK_SUCCESS; @@ -1787,7 +1688,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDisplayPlaneSupportedDisplaysKHR(Vk struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance; - if (!loader_inst->wsi_display_enabled) { + if (!loader_inst->enabled_known_extensions.khr_display) { loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "VK_KHR_display extension not enabled. vkGetDisplayPlaneSupportedDisplaysKHR not executed!"); return VK_SUCCESS; @@ -1829,7 +1730,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDisplayModePropertiesKHR(VkPhysical struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance; - if (!loader_inst->wsi_display_enabled) { + if (!loader_inst->enabled_known_extensions.khr_display) { loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "VK_KHR_display extension not enabled. vkGetDisplayModePropertiesKHR not executed!"); return VK_SUCCESS; @@ -1872,7 +1773,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDisplayModeKHR(VkPhysicalDevice struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance; - if (!loader_inst->wsi_display_enabled) { + if (!loader_inst->enabled_known_extensions.khr_display) { loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "VK_KHR_display extension not enabled. vkCreateDisplayModeKHR not executed!"); return VK_ERROR_EXTENSION_NOT_PRESENT; @@ -1911,7 +1812,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDisplayPlaneCapabilitiesKHR(VkPhysi struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance; - if (!loader_inst->wsi_display_enabled) { + if (!loader_inst->enabled_known_extensions.khr_display) { loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "VK_KHR_display extension not enabled. vkGetDisplayPlaneCapabilitiesKHR not executed!"); return VK_SUCCESS; @@ -1954,7 +1855,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDisplayPlaneSurfaceKHR(VkInstanc // First, check to ensure the appropriate extension was enabled: struct loader_instance *loader_inst = loader_get_instance(instance); - if (!loader_inst->wsi_display_enabled) { + if (!loader_inst->enabled_known_extensions.khr_display) { loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "VK_KHR_surface extension not enabled. vkCreateDisplayPlaneSurfaceKHR not executed!"); result = VK_ERROR_EXTENSION_NOT_PRESENT; @@ -1971,10 +1872,10 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDisplayPlaneSurfaceKHR(VkInstanc for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) { if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) { if (NULL != icd_term->dispatch.CreateDisplayPlaneSurfaceKHR) { - result = icd_term->dispatch.CreateDisplayPlaneSurfaceKHR(icd_term->instance, pCreateInfo, pAllocator, - &icd_term->surface_list.list[icd_surface->surface_index]); - if (VK_SUCCESS != result) { - goto out; + result = icd_term->dispatch.CreateDisplayPlaneSurfaceKHR(icd_term->instance, pCreateInfo, pAllocator, + &icd_term->surface_list.list[icd_surface->surface_index]); + if (VK_SUCCESS != result) { + goto out; } } } @@ -2389,7 +2290,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateImagePipeSurfaceFUCHSIA(VkInstan *pSurface = VK_NULL_HANDLE; // First, check to ensure the appropriate extension was enabled: struct loader_instance *loader_inst = loader_get_instance(instance); - if (!loader_inst->wsi_imagepipe_surface_enabled) { + if (!loader_inst->enabled_known_extensions.fuchsia_imagepipe_surface) { loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "VK_FUCHSIA_imagepipe_surface extension not enabled. " "vkCreateImagePipeSurfaceFUCHSIA not executed!"); @@ -2444,7 +2345,7 @@ void emulate_VK_EXT_surface_maintenance1(struct loader_icd_term *icd_term, const VkSurfaceCapabilities2KHR *pSurfaceCapabilities) { // Because VK_EXT_surface_maintenance1 is an instance extension, applications will use it to query info on drivers which do // not support the extension. Thus we need to emulate the driver filling out the structs in that case. - if (!icd_term->supports_ext_surface_maintenance_1) { + if (!icd_term->enabled_instance_extensions.ext_surface_maintenance1) { VkPresentModeKHR present_mode = VK_PRESENT_MODE_MAX_ENUM_KHR; const void *void_pNext = pSurfaceInfo->pNext; while (void_pNext) { @@ -2507,7 +2408,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceCapabilities2K struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance; VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pSurfaceInfo->surface; - if (!loader_inst->wsi_surface_enabled) { + if (!loader_inst->enabled_known_extensions.khr_surface) { loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "VK_KHR_surface extension not enabled. vkGetPhysicalDeviceSurfaceCapabilities2KHR not executed!"); return VK_SUCCESS; @@ -2544,7 +2445,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceCapabilities2K // Because VK_EXT_surface_maintenance1 is an instance extension, applications will use it to query info on drivers which do // not support the extension. Thus we need to emulate the driver filling out the structs in that case. - if (!icd_term->supports_ext_surface_maintenance_1) { + if (!icd_term->enabled_instance_extensions.ext_surface_maintenance1) { emulate_VK_EXT_surface_maintenance1(icd_term, pSurfaceInfo, pSurfaceCapabilities); } @@ -2602,7 +2503,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceFormats2KHR(Vk struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance; - if (!loader_inst->wsi_surface_enabled) { + if (!loader_inst->enabled_known_extensions.khr_surface) { loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "VK_KHR_surface extension not enabled. vkGetPhysicalDeviceSurfaceFormats2KHR not executed!"); return VK_SUCCESS; @@ -2682,49 +2583,49 @@ bool wsi_swapchain_instance_gpa(struct loader_instance *loader_inst, const char // Functions for the VK_KHR_surface extension: if (!strcmp("vkDestroySurfaceKHR", name)) { - *addr = loader_inst->wsi_surface_enabled ? (void *)vkDestroySurfaceKHR : NULL; + *addr = loader_inst->enabled_known_extensions.khr_surface ? (void *)vkDestroySurfaceKHR : NULL; return true; } if (!strcmp("vkGetPhysicalDeviceSurfaceSupportKHR", name)) { - *addr = loader_inst->wsi_surface_enabled ? (void *)vkGetPhysicalDeviceSurfaceSupportKHR : NULL; + *addr = loader_inst->enabled_known_extensions.khr_surface ? (void *)vkGetPhysicalDeviceSurfaceSupportKHR : NULL; return true; } if (!strcmp("vkGetPhysicalDeviceSurfaceCapabilitiesKHR", name)) { - *addr = loader_inst->wsi_surface_enabled ? (void *)vkGetPhysicalDeviceSurfaceCapabilitiesKHR : NULL; + *addr = loader_inst->enabled_known_extensions.khr_surface ? (void *)vkGetPhysicalDeviceSurfaceCapabilitiesKHR : NULL; return true; } if (!strcmp("vkGetPhysicalDeviceSurfaceFormatsKHR", name)) { - *addr = loader_inst->wsi_surface_enabled ? (void *)vkGetPhysicalDeviceSurfaceFormatsKHR : NULL; + *addr = loader_inst->enabled_known_extensions.khr_surface ? (void *)vkGetPhysicalDeviceSurfaceFormatsKHR : NULL; return true; } if (!strcmp("vkGetPhysicalDeviceSurfacePresentModesKHR", name)) { - *addr = loader_inst->wsi_surface_enabled ? (void *)vkGetPhysicalDeviceSurfacePresentModesKHR : NULL; + *addr = loader_inst->enabled_known_extensions.khr_surface ? (void *)vkGetPhysicalDeviceSurfacePresentModesKHR : NULL; return true; } if (!strcmp("vkGetDeviceGroupPresentCapabilitiesKHR", name)) { - *addr = loader_inst->wsi_surface_enabled ? (void *)vkGetDeviceGroupPresentCapabilitiesKHR : NULL; + *addr = loader_inst->enabled_known_extensions.khr_surface ? (void *)vkGetDeviceGroupPresentCapabilitiesKHR : NULL; return true; } if (!strcmp("vkGetDeviceGroupSurfacePresentModesKHR", name)) { - *addr = loader_inst->wsi_surface_enabled ? (void *)vkGetDeviceGroupSurfacePresentModesKHR : NULL; + *addr = loader_inst->enabled_known_extensions.khr_surface ? (void *)vkGetDeviceGroupSurfacePresentModesKHR : NULL; return true; } if (!strcmp("vkGetPhysicalDevicePresentRectanglesKHR", name)) { - *addr = loader_inst->wsi_surface_enabled ? (void *)vkGetPhysicalDevicePresentRectanglesKHR : NULL; + *addr = loader_inst->enabled_known_extensions.khr_surface ? (void *)vkGetPhysicalDevicePresentRectanglesKHR : NULL; return true; } // Functions for VK_KHR_get_surface_capabilities2 extension: if (!strcmp("vkGetPhysicalDeviceSurfaceCapabilities2KHR", name)) { - *addr = loader_inst->wsi_surface_enabled ? (void *)vkGetPhysicalDeviceSurfaceCapabilities2KHR : NULL; + *addr = loader_inst->enabled_known_extensions.khr_surface ? (void *)vkGetPhysicalDeviceSurfaceCapabilities2KHR : NULL; return true; } if (!strcmp("vkGetPhysicalDeviceSurfaceFormats2KHR", name)) { - *addr = loader_inst->wsi_surface_enabled ? (void *)vkGetPhysicalDeviceSurfaceFormats2KHR : NULL; + *addr = loader_inst->enabled_known_extensions.khr_surface ? (void *)vkGetPhysicalDeviceSurfaceFormats2KHR : NULL; return true; } @@ -2763,11 +2664,12 @@ bool wsi_swapchain_instance_gpa(struct loader_instance *loader_inst, const char // Functions for the VK_KHR_win32_surface extension: if (!strcmp("vkCreateWin32SurfaceKHR", name)) { - *addr = loader_inst->wsi_win32_surface_enabled ? (void *)vkCreateWin32SurfaceKHR : NULL; + *addr = loader_inst->enabled_known_extensions.khr_win32_surface ? (void *)vkCreateWin32SurfaceKHR : NULL; return true; } if (!strcmp("vkGetPhysicalDeviceWin32PresentationSupportKHR", name)) { - *addr = loader_inst->wsi_win32_surface_enabled ? (void *)vkGetPhysicalDeviceWin32PresentationSupportKHR : NULL; + *addr = + loader_inst->enabled_known_extensions.khr_win32_surface ? (void *)vkGetPhysicalDeviceWin32PresentationSupportKHR : NULL; return true; } #endif // VK_USE_PLATFORM_WIN32_KHR @@ -2775,11 +2677,12 @@ bool wsi_swapchain_instance_gpa(struct loader_instance *loader_inst, const char // Functions for the VK_KHR_wayland_surface extension: if (!strcmp("vkCreateWaylandSurfaceKHR", name)) { - *addr = loader_inst->wsi_wayland_surface_enabled ? (void *)vkCreateWaylandSurfaceKHR : NULL; + *addr = loader_inst->enabled_known_extensions.khr_wayland_surface ? (void *)vkCreateWaylandSurfaceKHR : NULL; return true; } if (!strcmp("vkGetPhysicalDeviceWaylandPresentationSupportKHR", name)) { - *addr = loader_inst->wsi_wayland_surface_enabled ? (void *)vkGetPhysicalDeviceWaylandPresentationSupportKHR : NULL; + *addr = loader_inst->enabled_known_extensions.khr_wayland_surface ? (void *)vkGetPhysicalDeviceWaylandPresentationSupportKHR + : NULL; return true; } #endif // VK_USE_PLATFORM_WAYLAND_KHR @@ -2787,11 +2690,11 @@ bool wsi_swapchain_instance_gpa(struct loader_instance *loader_inst, const char // Functions for the VK_KHR_xcb_surface extension: if (!strcmp("vkCreateXcbSurfaceKHR", name)) { - *addr = loader_inst->wsi_xcb_surface_enabled ? (void *)vkCreateXcbSurfaceKHR : NULL; + *addr = loader_inst->enabled_known_extensions.khr_xcb_surface ? (void *)vkCreateXcbSurfaceKHR : NULL; return true; } if (!strcmp("vkGetPhysicalDeviceXcbPresentationSupportKHR", name)) { - *addr = loader_inst->wsi_xcb_surface_enabled ? (void *)vkGetPhysicalDeviceXcbPresentationSupportKHR : NULL; + *addr = loader_inst->enabled_known_extensions.khr_xcb_surface ? (void *)vkGetPhysicalDeviceXcbPresentationSupportKHR : NULL; return true; } #endif // VK_USE_PLATFORM_XCB_KHR @@ -2799,11 +2702,12 @@ bool wsi_swapchain_instance_gpa(struct loader_instance *loader_inst, const char // Functions for the VK_KHR_xlib_surface extension: if (!strcmp("vkCreateXlibSurfaceKHR", name)) { - *addr = loader_inst->wsi_xlib_surface_enabled ? (void *)vkCreateXlibSurfaceKHR : NULL; + *addr = loader_inst->enabled_known_extensions.khr_xlib_surface ? (void *)vkCreateXlibSurfaceKHR : NULL; return true; } if (!strcmp("vkGetPhysicalDeviceXlibPresentationSupportKHR", name)) { - *addr = loader_inst->wsi_xlib_surface_enabled ? (void *)vkGetPhysicalDeviceXlibPresentationSupportKHR : NULL; + *addr = + loader_inst->enabled_known_extensions.khr_xlib_surface ? (void *)vkGetPhysicalDeviceXlibPresentationSupportKHR : NULL; return true; } #endif // VK_USE_PLATFORM_XLIB_KHR @@ -2811,11 +2715,13 @@ bool wsi_swapchain_instance_gpa(struct loader_instance *loader_inst, const char // Functions for the VK_EXT_directfb_surface extension: if (!strcmp("vkCreateDirectFBSurfaceEXT", name)) { - *addr = loader_inst->wsi_directfb_surface_enabled ? (void *)vkCreateDirectFBSurfaceEXT : NULL; + *addr = loader_inst->enabled_known_extensions.ext_directfb_surface ? (void *)vkCreateDirectFBSurfaceEXT : NULL; return true; } if (!strcmp("vkGetPhysicalDeviceDirectFBPresentationSupportEXT", name)) { - *addr = loader_inst->wsi_directfb_surface_enabled ? (void *)vkGetPhysicalDeviceDirectFBPresentationSupportEXT : NULL; + *addr = loader_inst->enabled_known_extensions.ext_directfb_surface + ? (void *)vkGetPhysicalDeviceDirectFBPresentationSupportEXT + : NULL; return true; } #endif // VK_USE_PLATFORM_DIRECTFB_EXT @@ -2823,7 +2729,7 @@ bool wsi_swapchain_instance_gpa(struct loader_instance *loader_inst, const char // Functions for the VK_KHR_android_surface extension: if (!strcmp("vkCreateAndroidSurfaceKHR", name)) { - *addr = loader_inst->wsi_android_surface_enabled ? (void *)vkCreateAndroidSurfaceKHR : NULL; + *addr = loader_inst->enabled_known_extensions.khr_android_surface ? (void *)vkCreateAndroidSurfaceKHR : NULL; return true; } #endif // VK_USE_PLATFORM_ANDROID_KHR @@ -2832,7 +2738,7 @@ bool wsi_swapchain_instance_gpa(struct loader_instance *loader_inst, const char // Functions for the VK_MVK_macos_surface extension: if (!strcmp("vkCreateMacOSSurfaceMVK", name)) { - *addr = loader_inst->wsi_macos_surface_enabled ? (void *)vkCreateMacOSSurfaceMVK : NULL; + *addr = loader_inst->enabled_known_extensions.mvk_macos_surface ? (void *)vkCreateMacOSSurfaceMVK : NULL; return true; } #endif // VK_USE_PLATFORM_MACOS_MVK @@ -2840,7 +2746,7 @@ bool wsi_swapchain_instance_gpa(struct loader_instance *loader_inst, const char // Functions for the VK_MVK_ios_surface extension: if (!strcmp("vkCreateIOSSurfaceMVK", name)) { - *addr = loader_inst->wsi_ios_surface_enabled ? (void *)vkCreateIOSSurfaceMVK : NULL; + *addr = loader_inst->enabled_known_extensions.mvk_ios_surface ? (void *)vkCreateIOSSurfaceMVK : NULL; return true; } #endif // VK_USE_PLATFORM_IOS_MVK @@ -2848,7 +2754,7 @@ bool wsi_swapchain_instance_gpa(struct loader_instance *loader_inst, const char // Functions for the VK_GGP_stream_descriptor_surface extension: if (!strcmp("vkCreateStreamDescriptorSurfaceGGP", name)) { - *addr = loader_inst->wsi_ggp_surface_enabled ? (void *)vkCreateStreamDescriptorSurfaceGGP : NULL; + *addr = loader_inst->enabled_known_extensions.wsi_ggp_surface_enabled ? (void *)vkCreateStreamDescriptorSurfaceGGP : NULL; return true; } #endif // VK_USE_PLATFORM_GGP @@ -2856,7 +2762,7 @@ bool wsi_swapchain_instance_gpa(struct loader_instance *loader_inst, const char // Functions for the VK_FUCHSIA_imagepipe_surface extension: if (!strcmp("vkCreateImagePipeSurfaceFUCHSIA", name)) { - *addr = loader_inst->wsi_imagepipe_surface_enabled ? (void *)vkCreateImagePipeSurfaceFUCHSIA : NULL; + *addr = loader_inst->enabled_known_extensions.fuchsia_imagepipe_surface ? (void *)vkCreateImagePipeSurfaceFUCHSIA : NULL; return true; } @@ -2864,14 +2770,14 @@ bool wsi_swapchain_instance_gpa(struct loader_instance *loader_inst, const char // Functions for the VK_EXT_headless_surface extension: if (!strcmp("vkCreateHeadlessSurfaceEXT", name)) { - *addr = loader_inst->wsi_headless_surface_enabled ? (void *)vkCreateHeadlessSurfaceEXT : NULL; + *addr = loader_inst->enabled_known_extensions.ext_headless_surface ? (void *)vkCreateHeadlessSurfaceEXT : NULL; return true; } #if defined(VK_USE_PLATFORM_METAL_EXT) // Functions for the VK_MVK_macos_surface extension: if (!strcmp("vkCreateMetalSurfaceEXT", name)) { - *addr = loader_inst->wsi_metal_surface_enabled ? (void *)vkCreateMetalSurfaceEXT : NULL; + *addr = loader_inst->enabled_known_extensions.ext_metal_surface ? (void *)vkCreateMetalSurfaceEXT : NULL; return true; } #endif // VK_USE_PLATFORM_METAL_EXT @@ -2880,11 +2786,12 @@ bool wsi_swapchain_instance_gpa(struct loader_instance *loader_inst, const char // Functions for the VK_QNX_screen_surface extension: if (!strcmp("vkCreateScreenSurfaceQNX", name)) { - *addr = loader_inst->wsi_screen_surface_enabled ? (void *)vkCreateScreenSurfaceQNX : NULL; + *addr = loader_inst->enabled_known_extensions.qnx_screen_surface ? (void *)vkCreateScreenSurfaceQNX : NULL; return true; } if (!strcmp("vkGetPhysicalDeviceScreenPresentationSupportQNX", name)) { - *addr = loader_inst->wsi_screen_surface_enabled ? (void *)vkGetPhysicalDeviceScreenPresentationSupportQNX : NULL; + *addr = loader_inst->enabled_known_extensions.qnx_screen_surface ? (void *)vkGetPhysicalDeviceScreenPresentationSupportQNX + : NULL; return true; } #endif // VK_USE_PLATFORM_SCREEN_QNX @@ -2893,38 +2800,38 @@ bool wsi_swapchain_instance_gpa(struct loader_instance *loader_inst, const char // Functions for the VK_NN_vi_surface extension: if (!strcmp("vkCreateViSurfaceNN", name)) { - *addr = loader_inst->wsi_vi_surface_enabled ? (void *)vkCreateViSurfaceNN : NULL; + *addr = loader_inst->enabled_known_extensions.nn_vi_surface ? (void *)vkCreateViSurfaceNN : NULL; return true; } #endif // VK_USE_PLATFORM_VI_NN // Functions for VK_KHR_display extension: if (!strcmp("vkGetPhysicalDeviceDisplayPropertiesKHR", name)) { - *addr = loader_inst->wsi_display_enabled ? (void *)vkGetPhysicalDeviceDisplayPropertiesKHR : NULL; + *addr = loader_inst->enabled_known_extensions.khr_display ? (void *)vkGetPhysicalDeviceDisplayPropertiesKHR : NULL; return true; } if (!strcmp("vkGetPhysicalDeviceDisplayPlanePropertiesKHR", name)) { - *addr = loader_inst->wsi_display_enabled ? (void *)vkGetPhysicalDeviceDisplayPlanePropertiesKHR : NULL; + *addr = loader_inst->enabled_known_extensions.khr_display ? (void *)vkGetPhysicalDeviceDisplayPlanePropertiesKHR : NULL; return true; } if (!strcmp("vkGetDisplayPlaneSupportedDisplaysKHR", name)) { - *addr = loader_inst->wsi_display_enabled ? (void *)vkGetDisplayPlaneSupportedDisplaysKHR : NULL; + *addr = loader_inst->enabled_known_extensions.khr_display ? (void *)vkGetDisplayPlaneSupportedDisplaysKHR : NULL; return true; } if (!strcmp("vkGetDisplayModePropertiesKHR", name)) { - *addr = loader_inst->wsi_display_enabled ? (void *)vkGetDisplayModePropertiesKHR : NULL; + *addr = loader_inst->enabled_known_extensions.khr_display ? (void *)vkGetDisplayModePropertiesKHR : NULL; return true; } if (!strcmp("vkCreateDisplayModeKHR", name)) { - *addr = loader_inst->wsi_display_enabled ? (void *)vkCreateDisplayModeKHR : NULL; + *addr = loader_inst->enabled_known_extensions.khr_display ? (void *)vkCreateDisplayModeKHR : NULL; return true; } if (!strcmp("vkGetDisplayPlaneCapabilitiesKHR", name)) { - *addr = loader_inst->wsi_display_enabled ? (void *)vkGetDisplayPlaneCapabilitiesKHR : NULL; + *addr = loader_inst->enabled_known_extensions.khr_display ? (void *)vkGetDisplayPlaneCapabilitiesKHR : NULL; return true; } if (!strcmp("vkCreateDisplayPlaneSurfaceKHR", name)) { - *addr = loader_inst->wsi_display_enabled ? (void *)vkCreateDisplayPlaneSurfaceKHR : NULL; + *addr = loader_inst->enabled_known_extensions.khr_display ? (void *)vkCreateDisplayPlaneSurfaceKHR : NULL; return true; } @@ -2936,19 +2843,23 @@ bool wsi_swapchain_instance_gpa(struct loader_instance *loader_inst, const char // Functions for KHR_get_display_properties2 if (!strcmp("vkGetPhysicalDeviceDisplayProperties2KHR", name)) { - *addr = loader_inst->wsi_display_props2_enabled ? (void *)vkGetPhysicalDeviceDisplayProperties2KHR : NULL; + *addr = loader_inst->enabled_known_extensions.khr_get_display_properties2 ? (void *)vkGetPhysicalDeviceDisplayProperties2KHR + : NULL; return true; } if (!strcmp("vkGetPhysicalDeviceDisplayPlaneProperties2KHR", name)) { - *addr = loader_inst->wsi_display_props2_enabled ? (void *)vkGetPhysicalDeviceDisplayPlaneProperties2KHR : NULL; + *addr = loader_inst->enabled_known_extensions.khr_get_display_properties2 + ? (void *)vkGetPhysicalDeviceDisplayPlaneProperties2KHR + : NULL; return true; } if (!strcmp("vkGetDisplayModeProperties2KHR", name)) { - *addr = loader_inst->wsi_display_props2_enabled ? (void *)vkGetDisplayModeProperties2KHR : NULL; + *addr = loader_inst->enabled_known_extensions.khr_get_display_properties2 ? (void *)vkGetDisplayModeProperties2KHR : NULL; return true; } if (!strcmp("vkGetDisplayPlaneCapabilities2KHR", name)) { - *addr = loader_inst->wsi_display_props2_enabled ? (void *)vkGetDisplayPlaneCapabilities2KHR : NULL; + *addr = + loader_inst->enabled_known_extensions.khr_get_display_properties2 ? (void *)vkGetDisplayPlaneCapabilities2KHR : NULL; return true; } diff --git a/loader/wsi.h b/loader/wsi.h index c2ec9af6a..90de00123 100644 --- a/loader/wsi.h +++ b/loader/wsi.h @@ -30,7 +30,6 @@ typedef struct { bool wsi_swapchain_instance_gpa(struct loader_instance *ptr_instance, const char *name, void **addr); -void wsi_create_instance(struct loader_instance *ptr_instance, const VkInstanceCreateInfo *pCreateInfo); bool wsi_unsupported_instance_extension(const VkExtensionProperties *ext_prop); VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateHeadlessSurfaceEXT(VkInstance instance, diff --git a/scripts/loader_extension_generator.py b/scripts/loader_extension_generator.py index a0b9f69b5..8b9721d89 100644 --- a/scripts/loader_extension_generator.py +++ b/scripts/loader_extension_generator.py @@ -271,7 +271,7 @@ def endFile(self): file_data += self.OutputPrototypesInHeader() file_data += self.OutputLoaderTerminators() file_data += self.OutputIcdDispatchTable() - file_data += self.OutputIcdExtensionEnableUnion() + file_data += self.OutputInstanceExtensionEnableStructDeclaration() file_data += self.OutputDeviceFunctionTerminatorDispatchTable() elif self.genOpts.filename == 'vk_loader_extensions.c': @@ -283,7 +283,7 @@ def endFile(self): file_data += self.OutputLoaderLookupFunc() file_data += self.CreateTrampTermFuncs() file_data += self.InstExtensionGPA() - file_data += self.InstantExtensionCreate() + file_data += self.OutputInstanceExtensionEnableStructDefinition() file_data += self.DeviceExtensionGetTerminator() file_data += self.InitInstLoaderExtensionDispatchTable() file_data += self.OutputInstantExtensionWhitelistArray() @@ -334,8 +334,7 @@ def genCmd(self, cmdinfo, name, alias): def endFeature(self): - if 'android' not in self.currentExtension: - self.instanceExtensions.append(self.ExtensionData(name=self.currentExtension, + self.instanceExtensions.append(self.ExtensionData(name=self.currentExtension, type=self.type, protect=self.featureExtraProtect, define=self.name_definition, @@ -507,10 +506,11 @@ def OutputPrototypesInHeader(self): protos += '// the appropriate information for any instance extensions we know about.\n' protos += 'bool extension_instance_gpa(struct loader_instance *ptr_instance, const char *name, void **addr);\n' protos += '\n' + protos += 'struct loader_instance_extension_enables; // Forward declaration\n' protos += '// Extension interception for vkCreateInstance function, so we can properly\n' protos += '// detect and enable any instance extension information for extensions we know\n' protos += '// about.\n' - protos += 'void extensions_create_instance(struct loader_instance *ptr_instance, const VkInstanceCreateInfo *pCreateInfo);\n' + protos += 'void fill_out_enabled_instance_extensions(uint32_t extension_count, const char *const * extension_list, struct loader_instance_extension_enables* enables);\n\n' protos += '\n' protos += '// Extension interception for vkGetDeviceProcAddr function, so we can return\n' protos += '// an appropriate terminator if this is one of those few device commands requiring\n' @@ -785,22 +785,36 @@ def OutputIcdDispatchTableInit(self): table += '};\n\n' return table - # - # Create the extension enable union - def OutputIcdExtensionEnableUnion(self): - extensions = self.instanceExtensions - - union = '' - union += 'struct loader_instance_extension_enables {\n' - for ext in extensions: - if (self.getAPIVersion(ext.name) or ext.name in WSI_EXT_NAMES or - ext.type == 'device' or ext.num_commands == 0): + # Create a struct which holds bools for each enabled instance extension + def OutputInstanceExtensionEnableStructDeclaration(self): + out = 'struct loader_instance_extension_enables {\n' + for ext in self.instanceExtensions: + if self.getAPIVersion(ext.name) or ext.type == 'device': continue + if ext.protect is not None: + out += f'#if defined({ext.protect})\n' + out += f' uint8_t {ext.name[3:].lower()};\n' + if ext.protect is not None: + out += f'#endif // defined({ext.protect})\n' - union += f' uint8_t {ext.name[3:].lower()};\n' + out += '};\n\n' + return out - union += '};\n\n' - return union + def OutputInstanceExtensionEnableStructDefinition(self): + out = 'void fill_out_enabled_instance_extensions(uint32_t extension_count, const char *const * extension_list, struct loader_instance_extension_enables* enables) {\n' + out += ' for(uint32_t i = 0; i < extension_count; i++) {\n' + for ext in self.instanceExtensions: + if self.getAPIVersion(ext.name) or ext.type == 'device': + continue + if ext.protect is not None: + out += f'#if defined({ext.protect})\n' + out += f' if (strcmp(extension_list[i], {ext.define}) == 0) {{ enables->{ext.name[3:].lower()} = true; }}\n' + if ext.protect is not None: + out += f'#endif // defined({ext.protect})\n' + out += ' }\n' + out += '};\n\n' + + return out # # Creates the prototypes for the loader's core instance command terminators @@ -1500,49 +1514,6 @@ def InstExtensionGPA(self): return gpa_func - # - # Create the extension name init function - def InstantExtensionCreate(self): - entries = [] - entries = self.instanceExtensions - count = 0 - cur_extension_name = '' - - create_func = '' - create_func += '// A function that can be used to query enabled extensions during a vkCreateInstance call\n' - create_func += 'void extensions_create_instance(struct loader_instance *ptr_instance, const VkInstanceCreateInfo *pCreateInfo) {\n' - create_func += ' for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {\n' - for ext in entries: - if (self.getAPIVersion(ext.name) or ext.name in WSI_EXT_NAMES or - ext.name in AVOID_EXT_NAMES or ext.name in AVOID_CMD_NAMES or - ext.type == 'device' or ext.num_commands == 0): - continue - - if ext.name != cur_extension_name: - create_func += f'\n // ---- {ext.name} extension commands\n' - cur_extension_name = ext.name - - if ext.protect is not None: - create_func += f'#if defined({ext.protect})\n' - if count == 0: - create_func += ' if (0 == strcmp(pCreateInfo->ppEnabledExtensionNames[i], ' - else: - create_func += ' } else if (0 == strcmp(pCreateInfo->ppEnabledExtensionNames[i], ' - - create_func += ext.define + ')) {\n' - create_func += ' ptr_instance->enabled_known_extensions.' - create_func += ext.name[3:].lower() - create_func += ' = 1;\n' - - if ext.protect is not None: - create_func += f'#endif // {ext.protect}\n' - count += 1 - - create_func += ' }\n' - create_func += ' }\n' - create_func += '}\n\n' - return create_func - # # Create code to initialize a dispatch table from the appropriate list of # extension entrypoints and return it as a string From 0a8fa90eb4cabe9344c04cb89e6ada9d19491847 Mon Sep 17 00:00:00 2001 From: Charles Giessen Date: Wed, 23 Oct 2024 16:38:07 -0500 Subject: [PATCH 2/5] Only call surface creation functions on supported drivers Make sure that the surface extension is supported by a driver and enabled before calling down on each surface creation function. This fixes crashes where a driver on the system doesn't support a surface extension that the application is using but still exposes the function pointer. --- loader/wsi.c | 192 ++++++++++++++++++++++++++------------------------- 1 file changed, 97 insertions(+), 95 deletions(-) diff --git a/loader/wsi.c b/loader/wsi.c index 0ac7320e8..d60d56bf1 100644 --- a/loader/wsi.c +++ b/loader/wsi.c @@ -90,12 +90,13 @@ VKAPI_ATTR void VKAPI_CALL terminator_DestroySurfaceKHR(VkInstance instance, VkS VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)(surface); if (NULL != icd_surface) { for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) { - if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) { - if (NULL != icd_term->dispatch.DestroySurfaceKHR && icd_term->surface_list.list[icd_surface->surface_index]) { - icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, - icd_term->surface_list.list[icd_surface->surface_index], pAllocator); - icd_term->surface_list.list[icd_surface->surface_index] = (VkSurfaceKHR)(uintptr_t)NULL; - } + if (icd_term->enabled_instance_extensions.khr_surface && + icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR && + NULL != icd_term->dispatch.DestroySurfaceKHR && icd_term->surface_list.list[icd_surface->surface_index]) { + icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, icd_term->surface_list.list[icd_surface->surface_index], + pAllocator); + icd_term->surface_list.list[icd_surface->surface_index] = (VkSurfaceKHR)(uintptr_t)NULL; + } else { // The real_icd_surface for any ICD not supporting the // proper interface version should be NULL. If not, then @@ -470,7 +471,8 @@ VkResult allocate_icd_surface_struct(struct loader_instance *instance, const VkA icd_surface->surface_index = next_index; for (struct loader_icd_term *icd_term = instance->icd_terms; icd_term != NULL; icd_term = icd_term->next) { - if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) { + if (icd_term->enabled_instance_extensions.khr_surface && + icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) { if (icd_term->surface_list.list == NULL) { res = loader_init_generic_list(instance, (struct loader_generic_list *)&icd_term->surface_list, sizeof(VkSurfaceKHR)); @@ -499,7 +501,7 @@ void cleanup_surface_creation(struct loader_instance *loader_inst, VkResult resu const VkAllocationCallbacks *pAllocator) { if (VK_SUCCESS != result && NULL != icd_surface) { for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) { - if (NULL != icd_term->surface_list.list && + if (icd_term->enabled_instance_extensions.khr_surface && NULL != icd_term->surface_list.list && icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) && icd_term->surface_list.list[icd_surface->surface_index] && NULL != icd_term->dispatch.DestroySurfaceKHR) { icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, icd_term->surface_list.list[icd_surface->surface_index], @@ -561,13 +563,13 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateWin32SurfaceKHR(VkInstance insta // Loop through each ICD and determine if they need to create a surface for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) { - if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) { - if (NULL != icd_term->dispatch.CreateWin32SurfaceKHR) { - result = icd_term->dispatch.CreateWin32SurfaceKHR(icd_term->instance, pCreateInfo, pAllocator, - &icd_term->surface_list.list[icd_surface->surface_index]); - if (VK_SUCCESS != result) { - goto out; - } + if (icd_term->enabled_instance_extensions.khr_win32_surface && + icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR && + NULL != icd_term->dispatch.CreateWin32SurfaceKHR) { + result = icd_term->dispatch.CreateWin32SurfaceKHR(icd_term->instance, pCreateInfo, pAllocator, + &icd_term->surface_list.list[icd_surface->surface_index]); + if (VK_SUCCESS != result) { + goto out; } } } @@ -662,13 +664,13 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateWaylandSurfaceKHR(VkInstance ins // Loop through each ICD and determine if they need to create a surface for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) { - if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) { - if (NULL != icd_term->dispatch.CreateWaylandSurfaceKHR) { - result = icd_term->dispatch.CreateWaylandSurfaceKHR(icd_term->instance, pCreateInfo, pAllocator, - &icd_term->surface_list.list[icd_surface->surface_index]); - if (VK_SUCCESS != result) { - goto out; - } + if (icd_term->enabled_instance_extensions.khr_wayland_surface && + icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR && + NULL != icd_term->dispatch.CreateWaylandSurfaceKHR) { + result = icd_term->dispatch.CreateWaylandSurfaceKHR(icd_term->instance, pCreateInfo, pAllocator, + &icd_term->surface_list.list[icd_surface->surface_index]); + if (VK_SUCCESS != result) { + goto out; } } } @@ -767,13 +769,13 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateXcbSurfaceKHR(VkInstance instanc // Loop through each ICD and determine if they need to create a surface for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) { - if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) { - if (NULL != icd_term->dispatch.CreateXcbSurfaceKHR) { - result = icd_term->dispatch.CreateXcbSurfaceKHR(icd_term->instance, pCreateInfo, pAllocator, - &icd_term->surface_list.list[icd_surface->surface_index]); - if (VK_SUCCESS != result) { - goto out; - } + if (icd_term->enabled_instance_extensions.khr_xcb_surface && + icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR && + NULL != icd_term->dispatch.CreateXcbSurfaceKHR) { + result = icd_term->dispatch.CreateXcbSurfaceKHR(icd_term->instance, pCreateInfo, pAllocator, + &icd_term->surface_list.list[icd_surface->surface_index]); + if (VK_SUCCESS != result) { + goto out; } } } @@ -875,13 +877,13 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateXlibSurfaceKHR(VkInstance instan // Loop through each ICD and determine if they need to create a surface for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) { - if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) { - if (NULL != icd_term->dispatch.CreateXlibSurfaceKHR) { - result = icd_term->dispatch.CreateXlibSurfaceKHR(icd_term->instance, pCreateInfo, pAllocator, - &icd_term->surface_list.list[icd_surface->surface_index]); - if (VK_SUCCESS != result) { - goto out; - } + if (icd_term->enabled_instance_extensions.khr_xlib_surface && + icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR && + NULL != icd_term->dispatch.CreateXlibSurfaceKHR) { + result = icd_term->dispatch.CreateXlibSurfaceKHR(icd_term->instance, pCreateInfo, pAllocator, + &icd_term->surface_list.list[icd_surface->surface_index]); + if (VK_SUCCESS != result) { + goto out; } } } @@ -982,13 +984,13 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDirectFBSurfaceEXT(VkInstance in // Loop through each ICD and determine if they need to create a surface for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) { - if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) { - if (NULL != icd_term->dispatch.CreateDirectFBSurfaceEXT) { - result = icd_term->dispatch.CreateDirectFBSurfaceEXT(icd_term->instance, pCreateInfo, pAllocator, - &icd_term->surface_list.list[icd_surface->surface_index]); - if (VK_SUCCESS != result) { - goto out; - } + if (icd_term->enabled_instance_extensions.ext_directfb_surface && + icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR && + NULL != icd_term->dispatch.CreateDirectFBSurfaceEXT) { + result = icd_term->dispatch.CreateDirectFBSurfaceEXT(icd_term->instance, pCreateInfo, pAllocator, + &icd_term->surface_list.list[icd_surface->surface_index]); + if (VK_SUCCESS != result) { + goto out; } } } @@ -1134,13 +1136,13 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateHeadlessSurfaceEXT(VkInstance in // Loop through each ICD and determine if they need to create a surface for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) { - if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) { - if (NULL != icd_term->dispatch.CreateHeadlessSurfaceEXT) { - result = icd_term->dispatch.CreateHeadlessSurfaceEXT(icd_term->instance, pCreateInfo, pAllocator, - &icd_term->surface_list.list[icd_surface->surface_index]); - if (VK_SUCCESS != result) { - goto out; - } + if (icd_term->enabled_instance_extensions.ext_headless_surface && + icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR && + NULL != icd_term->dispatch.CreateHeadlessSurfaceEXT) { + result = icd_term->dispatch.CreateHeadlessSurfaceEXT(icd_term->instance, pCreateInfo, pAllocator, + &icd_term->surface_list.list[icd_surface->surface_index]); + if (VK_SUCCESS != result) { + goto out; } } } @@ -1223,13 +1225,13 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateMacOSSurfaceMVK(VkInstance insta // Loop through each ICD and determine if they need to create a surface for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) { - if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) { - if (NULL != icd_term->dispatch.CreateMacOSSurfaceMVK) { - result = icd_term->dispatch.CreateMacOSSurfaceMVK(icd_term->instance, pCreateInfo, pAllocator, - &icd_term->surface_list.list[icd_surface->surface_index]); - if (VK_SUCCESS != result) { - goto out; - } + if (icd_term->enabled_instance_extensions.mvk_macos_surface && + icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR && + NULL != icd_term->dispatch.CreateMacOSSurfaceMVK) { + result = icd_term->dispatch.CreateMacOSSurfaceMVK(icd_term->instance, pCreateInfo, pAllocator, + &icd_term->surface_list.list[icd_surface->surface_index]); + if (VK_SUCCESS != result) { + goto out; } } } @@ -1337,13 +1339,13 @@ terminator_CreateStreamDescriptorSurfaceGGP(VkInstance instance, const VkStreamD // Loop through each ICD and determine if they need to create a surface for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) { - if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) { - if (NULL != icd_term->dispatch.CreateStreamDescriptorSurfaceGGP) { - result = icd_term->dispatch.CreateStreamDescriptorSurfaceGGP( - icd_term->instance, pCreateInfo, pAllocator, &icd_term->surface_list.list[icd_surface->surface_index]); - if (VK_SUCCESS != result) { - goto out; - } + if (icd_term->enabled_instance_extensions.ggp_stream_descriptor_surface && + icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR && + NULL != icd_term->dispatch.CreateStreamDescriptorSurfaceGGP) { + result = icd_term->dispatch.CreateStreamDescriptorSurfaceGGP(icd_term->instance, pCreateInfo, pAllocator, + &icd_term->surface_list.list[icd_surface->surface_index]); + if (VK_SUCCESS != result) { + goto out; } } } @@ -1395,13 +1397,13 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateMetalSurfaceEXT(VkInstance insta // Loop through each ICD and determine if they need to create a surface for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) { - if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) { - if (NULL != icd_term->dispatch.CreateMetalSurfaceEXT) { - result = icd_term->dispatch.CreateMetalSurfaceEXT(icd_term->instance, pCreateInfo, pAllocator, - &icd_term->surface_list.list[icd_surface->surface_index]); - if (VK_SUCCESS != result) { - goto out; - } + if (icd_term->enabled_instance_extensions.ext_metal_surface && + icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR && + NULL != icd_term->dispatch.CreateMetalSurfaceEXT) { + result = icd_term->dispatch.CreateMetalSurfaceEXT(icd_term->instance, pCreateInfo, pAllocator, + &icd_term->surface_list.list[icd_surface->surface_index]); + if (VK_SUCCESS != result) { + goto out; } } } @@ -1457,13 +1459,13 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateScreenSurfaceQNX(VkInstance inst // Loop through each ICD and determine if they need to create a surface for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) { - if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) { - if (NULL != icd_term->dispatch.CreateScreenSurfaceQNX) { - result = icd_term->dispatch.CreateScreenSurfaceQNX(icd_term->instance, pCreateInfo, pAllocator, - &icd_term->surface_list.list[icd_surface->surface_index]); - if (VK_SUCCESS != result) { - goto out; - } + if (icd_term->enabled_instance_extensions.qnx_screen_surface && + icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR && + NULL != icd_term->dispatch.CreateScreenSurfaceQNX) { + result = icd_term->dispatch.CreateScreenSurfaceQNX(icd_term->instance, pCreateInfo, pAllocator, + &icd_term->surface_list.list[icd_surface->surface_index]); + if (VK_SUCCESS != result) { + goto out; } } } @@ -1560,13 +1562,13 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateViSurfaceNN(VkInstance instance, // Loop through each ICD and determine if they need to create a surface for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) { - if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) { - if (NULL != icd_term->dispatch.CreateViSurfaceNN) { - result = icd_term->dispatch.CreateViSurfaceNN(icd_term->instance, pCreateInfo, pAllocator, - &icd_term->surface_list.list[icd_surface->surface_index]); - if (VK_SUCCESS != result) { - goto out; - } + if (icd_term->enabled_instance_extensions.nn_vi_surface && + icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR && + NULL != icd_term->dispatch.CreateViSurfaceNN) { + result = icd_term->dispatch.CreateViSurfaceNN(icd_term->instance, pCreateInfo, pAllocator, + &icd_term->surface_list.list[icd_surface->surface_index]); + if (VK_SUCCESS != result) { + goto out; } } } @@ -1870,13 +1872,13 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDisplayPlaneSurfaceKHR(VkInstanc // Loop through each ICD and determine if they need to create a surface for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) { - if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) { - if (NULL != icd_term->dispatch.CreateDisplayPlaneSurfaceKHR) { + if (icd_term->enabled_instance_extensions.khr_display && + icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR && + icd_term->dispatch.CreateDisplayPlaneSurfaceKHR) { result = icd_term->dispatch.CreateDisplayPlaneSurfaceKHR(icd_term->instance, pCreateInfo, pAllocator, &icd_term->surface_list.list[icd_surface->surface_index]); if (VK_SUCCESS != result) { goto out; - } } } } @@ -2306,13 +2308,13 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateImagePipeSurfaceFUCHSIA(VkInstan // Loop through each ICD and determine if they need to create a surface for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) { - if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) { - if (NULL != icd_term->dispatch.CreateImagePipeSurfaceFUCHSIA) { - result = icd_term->dispatch.CreateImagePipeSurfaceFUCHSIA(icd_term->instance, pCreateInfo, pAllocator, - &icd_term->surface_list.list[icd_surface->surface_index]); - if (VK_SUCCESS != result) { - goto out; - } + if (icd_term->enabled_instance_extensions.fuchsia_imagepipe_surface && + icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR && + NULL != icd_term->dispatch.CreateImagePipeSurfaceFUCHSIA) { + result = icd_term->dispatch.CreateImagePipeSurfaceFUCHSIA(icd_term->instance, pCreateInfo, pAllocator, + &icd_term->surface_list.list[icd_surface->surface_index]); + if (VK_SUCCESS != result) { + goto out; } } } From d79f3188f295793abc4f1df096feadcd7d53fe9b Mon Sep 17 00:00:00 2001 From: Charles Giessen Date: Tue, 29 Oct 2024 12:45:56 -0500 Subject: [PATCH 3/5] Fix wrong extension in log message --- loader/wsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/loader/wsi.c b/loader/wsi.c index d60d56bf1..693640cb0 100644 --- a/loader/wsi.c +++ b/loader/wsi.c @@ -1859,7 +1859,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDisplayPlaneSurfaceKHR(VkInstanc struct loader_instance *loader_inst = loader_get_instance(instance); if (!loader_inst->enabled_known_extensions.khr_display) { loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, - "VK_KHR_surface extension not enabled. vkCreateDisplayPlaneSurfaceKHR not executed!"); + "VK_KHR_display extension not enabled. vkCreateDisplayPlaneSurfaceKHR not executed!"); result = VK_ERROR_EXTENSION_NOT_PRESENT; goto out; } From b3b62dc1c835417779556fd68c74e3f1b7202205 Mon Sep 17 00:00:00 2001 From: Charles Giessen Date: Tue, 29 Oct 2024 12:48:42 -0500 Subject: [PATCH 4/5] Small refactor of codegen Renames `instanceExtensions` to extensions to reflect that it is all extensions, not just instance. Uses self.extensions instead of creating local variables. --- scripts/loader_extension_generator.py | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/scripts/loader_extension_generator.py b/scripts/loader_extension_generator.py index 8b9721d89..e9b513c01 100644 --- a/scripts/loader_extension_generator.py +++ b/scripts/loader_extension_generator.py @@ -181,10 +181,10 @@ def __init__(self, self.ext_device_dispatch_list = [] # List of extension entries for device dispatch list self.core_commands = [] # List of CommandData records for core Vulkan commands self.ext_commands = [] # List of CommandData records for extension Vulkan commands + self.extensions = [] # List of ExtensionData records self.CommandParam = namedtuple('CommandParam', ['type', 'name', 'cdecl']) self.CommandData = namedtuple('CommandData', ['name', 'ext_name', 'ext_type', 'require', 'protect', 'return_type', 'handle_type', 'params', 'cdecl']) - self.instanceExtensions = [] - self.ExtensionData = namedtuple('ExtensionData', ['name', 'type', 'protect', 'define', 'num_commands']) + self.ExtensionData = namedtuple('ExtensionData', ['name', 'type', 'protect', 'define']) # # Called once at the beginning of each run @@ -314,7 +314,6 @@ def beginFeature(self, interface, emit): self.name_definition = name_definition self.type = interface.get('type') - self.num_commands = 0 name = interface.get('name') self.currentExtension = name @@ -327,18 +326,15 @@ def genCmd(self, cmdinfo, name, alias): params = cmdinfo.elem.findall('param') info = self.getTypeNameTuple(params[0]) - self.num_commands += 1 - if 'android' not in name: self.AddCommandToDispatchList(self.currentExtension, self.type, name, cmdinfo, info[0]) def endFeature(self): - self.instanceExtensions.append(self.ExtensionData(name=self.currentExtension, + self.extensions.append(self.ExtensionData(name=self.currentExtension, type=self.type, protect=self.featureExtraProtect, - define=self.name_definition, - num_commands=self.num_commands)) + define=self.name_definition)) # Finish processing in superclass OutputGenerator.endFeature(self) @@ -788,7 +784,7 @@ def OutputIcdDispatchTableInit(self): # Create a struct which holds bools for each enabled instance extension def OutputInstanceExtensionEnableStructDeclaration(self): out = 'struct loader_instance_extension_enables {\n' - for ext in self.instanceExtensions: + for ext in self.extensions: if self.getAPIVersion(ext.name) or ext.type == 'device': continue if ext.protect is not None: @@ -803,7 +799,7 @@ def OutputInstanceExtensionEnableStructDeclaration(self): def OutputInstanceExtensionEnableStructDefinition(self): out = 'void fill_out_enabled_instance_extensions(uint32_t extension_count, const char *const * extension_list, struct loader_instance_extension_enables* enables) {\n' out += ' for(uint32_t i = 0; i < extension_count; i++) {\n' - for ext in self.instanceExtensions: + for ext in self.extensions: if self.getAPIVersion(ext.name) or ext.type == 'device': continue if ext.protect is not None: @@ -1719,15 +1715,13 @@ def InitInstLoaderExtensionDispatchTable(self): # # Create the extension name whitelist array def OutputInstantExtensionWhitelistArray(self): - extensions = self.instanceExtensions - table = '' table += '// A null-terminated list of all of the instance extensions supported by the loader.\n' table += '// If an instance extension name is not in this list, but it is exported by one or more of the\n' table += '// ICDs detected by the loader, then the extension name not in the list will be filtered out\n' table += '// before passing the list of extensions to the application.\n' table += 'const char *const LOADER_INSTANCE_EXTENSIONS[] = {\n' - for ext in extensions: + for ext in self.extensions: if ext.type == 'device' or self.getAPIVersion(ext.name): continue From d34e39292be0e355bd00f731303dd100f224c9b6 Mon Sep 17 00:00:00 2001 From: Charles Giessen Date: Tue, 29 Oct 2024 12:52:26 -0500 Subject: [PATCH 5/5] Track the extension used to create each VkSurfaceKHR The Vulkan-Loader now doesn't call into drivers if they do not support the extension that was used to create the VkSurfaceKHR handle. This prevents crashes from occuring where a driver is called using a surface that it does not know about, due to the driver not supporting the surface extension. Because the specification requires that VkSurfaceKHR must be a valid handle, the loader should not allow calls down into drivers which cannot know about the surface. Instead it should "emulate" the call as appropriate, returning 0 for counts and setting to 0 any structures that were passed in. --- loader/generated/vk_loader_extensions.c | 71 +++++++++++ loader/generated/vk_loader_extensions.h | 2 + loader/wsi.c | 150 +++++++++++++++++++++++- loader/wsi.h | 3 + scripts/loader_extension_generator.py | 18 +++ 5 files changed, 242 insertions(+), 2 deletions(-) diff --git a/loader/generated/vk_loader_extensions.c b/loader/generated/vk_loader_extensions.c index a10c91079..a155a484c 100644 --- a/loader/generated/vk_loader_extensions.c +++ b/loader/generated/vk_loader_extensions.c @@ -12241,6 +12241,77 @@ void fill_out_enabled_instance_extensions(uint32_t extension_count, const char * } }; +bool check_if_instance_extension_is_available(const struct loader_instance_extension_enables* enabled, const struct loader_instance_extension_enables* desired) { + if (desired->khr_surface && !enabled->khr_surface) return false; + if (desired->khr_display && !enabled->khr_display) return false; +#if defined(VK_USE_PLATFORM_XLIB_KHR) + if (desired->khr_xlib_surface && !enabled->khr_xlib_surface) return false; +#endif // defined(VK_USE_PLATFORM_XLIB_KHR) +#if defined(VK_USE_PLATFORM_XCB_KHR) + if (desired->khr_xcb_surface && !enabled->khr_xcb_surface) return false; +#endif // defined(VK_USE_PLATFORM_XCB_KHR) +#if defined(VK_USE_PLATFORM_WAYLAND_KHR) + if (desired->khr_wayland_surface && !enabled->khr_wayland_surface) return false; +#endif // defined(VK_USE_PLATFORM_WAYLAND_KHR) +#if defined(VK_USE_PLATFORM_ANDROID_KHR) + if (desired->khr_android_surface && !enabled->khr_android_surface) return false; +#endif // defined(VK_USE_PLATFORM_ANDROID_KHR) +#if defined(VK_USE_PLATFORM_WIN32_KHR) + if (desired->khr_win32_surface && !enabled->khr_win32_surface) return false; +#endif // defined(VK_USE_PLATFORM_WIN32_KHR) + if (desired->khr_get_physical_device_properties2 && !enabled->khr_get_physical_device_properties2) return false; + if (desired->khr_device_group_creation && !enabled->khr_device_group_creation) return false; + if (desired->khr_external_memory_capabilities && !enabled->khr_external_memory_capabilities) return false; + if (desired->khr_external_semaphore_capabilities && !enabled->khr_external_semaphore_capabilities) return false; + if (desired->khr_external_fence_capabilities && !enabled->khr_external_fence_capabilities) return false; + if (desired->khr_get_surface_capabilities2 && !enabled->khr_get_surface_capabilities2) return false; + if (desired->khr_get_display_properties2 && !enabled->khr_get_display_properties2) return false; + if (desired->khr_surface_protected_capabilities && !enabled->khr_surface_protected_capabilities) return false; + if (desired->khr_portability_enumeration && !enabled->khr_portability_enumeration) return false; + if (desired->ext_debug_report && !enabled->ext_debug_report) return false; +#if defined(VK_USE_PLATFORM_GGP) + if (desired->ggp_stream_descriptor_surface && !enabled->ggp_stream_descriptor_surface) return false; +#endif // defined(VK_USE_PLATFORM_GGP) + if (desired->nv_external_memory_capabilities && !enabled->nv_external_memory_capabilities) return false; + if (desired->ext_validation_flags && !enabled->ext_validation_flags) return false; +#if defined(VK_USE_PLATFORM_VI_NN) + if (desired->nn_vi_surface && !enabled->nn_vi_surface) return false; +#endif // defined(VK_USE_PLATFORM_VI_NN) + if (desired->ext_direct_mode_display && !enabled->ext_direct_mode_display) return false; +#if defined(VK_USE_PLATFORM_XLIB_XRANDR_EXT) + if (desired->ext_acquire_xlib_display && !enabled->ext_acquire_xlib_display) return false; +#endif // defined(VK_USE_PLATFORM_XLIB_XRANDR_EXT) + if (desired->ext_display_surface_counter && !enabled->ext_display_surface_counter) return false; + if (desired->ext_swapchain_colorspace && !enabled->ext_swapchain_colorspace) return false; +#if defined(VK_USE_PLATFORM_IOS_MVK) + if (desired->mvk_ios_surface && !enabled->mvk_ios_surface) return false; +#endif // defined(VK_USE_PLATFORM_IOS_MVK) +#if defined(VK_USE_PLATFORM_MACOS_MVK) + if (desired->mvk_macos_surface && !enabled->mvk_macos_surface) return false; +#endif // defined(VK_USE_PLATFORM_MACOS_MVK) + if (desired->ext_debug_utils && !enabled->ext_debug_utils) return false; +#if defined(VK_USE_PLATFORM_FUCHSIA) + if (desired->fuchsia_imagepipe_surface && !enabled->fuchsia_imagepipe_surface) return false; +#endif // defined(VK_USE_PLATFORM_FUCHSIA) +#if defined(VK_USE_PLATFORM_METAL_EXT) + if (desired->ext_metal_surface && !enabled->ext_metal_surface) return false; +#endif // defined(VK_USE_PLATFORM_METAL_EXT) + if (desired->ext_validation_features && !enabled->ext_validation_features) return false; + if (desired->ext_headless_surface && !enabled->ext_headless_surface) return false; + if (desired->ext_surface_maintenance1 && !enabled->ext_surface_maintenance1) return false; + if (desired->ext_acquire_drm_display && !enabled->ext_acquire_drm_display) return false; +#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) + if (desired->ext_directfb_surface && !enabled->ext_directfb_surface) return false; +#endif // defined(VK_USE_PLATFORM_DIRECTFB_EXT) +#if defined(VK_USE_PLATFORM_SCREEN_QNX) + if (desired->qnx_screen_surface && !enabled->qnx_screen_surface) return false; +#endif // defined(VK_USE_PLATFORM_SCREEN_QNX) + if (desired->google_surfaceless_query && !enabled->google_surfaceless_query) return false; + if (desired->lunarg_direct_driver_loading && !enabled->lunarg_direct_driver_loading) return false; + if (desired->ext_layer_settings && !enabled->ext_layer_settings) return false; + return true; +}; + // Some device commands still need a terminator because the loader needs to unwrap something about them. // In many cases, the item needing unwrapping is a VkPhysicalDevice or VkSurfaceKHR object. But there may be other items // in the future. diff --git a/loader/generated/vk_loader_extensions.h b/loader/generated/vk_loader_extensions.h index 4a15fc54a..7b601d1a6 100644 --- a/loader/generated/vk_loader_extensions.h +++ b/loader/generated/vk_loader_extensions.h @@ -53,6 +53,8 @@ struct loader_instance_extension_enables; // Forward declaration void fill_out_enabled_instance_extensions(uint32_t extension_count, const char *const * extension_list, struct loader_instance_extension_enables* enables); +bool check_if_instance_extension_is_available(const struct loader_instance_extension_enables* enabled, const struct loader_instance_extension_enables* desired); + // Extension interception for vkGetDeviceProcAddr function, so we can return // an appropriate terminator if this is one of those few device commands requiring // a terminator. diff --git a/loader/wsi.c b/loader/wsi.c index 693640cb0..27b4b8ac7 100644 --- a/loader/wsi.c +++ b/loader/wsi.c @@ -156,6 +156,13 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceSupportKHR(VkP } VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)surface; + + // Set pSupported to false if the instance extension used to create the VkSurfaceKHR isn't supported by the ICD + if (!check_if_instance_extension_is_available(&icd_term->enabled_instance_extensions, &icd_surface->wsi_extension_used)) { + *pSupported = VK_FALSE; + return VK_SUCCESS; + } + if (NULL != icd_term->surface_list.list && icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) && icd_term->surface_list.list[icd_surface->surface_index]) { @@ -211,6 +218,14 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceCapabilitiesKH } VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)surface; + + // Return if the instance extension used to create the VkSurfaceKHR isn't supported by the ICD + if (!check_if_instance_extension_is_available(&icd_term->enabled_instance_extensions, &icd_surface->wsi_extension_used)) { + // Application shouldn't query the surface capabilities if the VkPhysicalDevice doesn't support the VkSurfaceKHR + memset(pSurfaceCapabilities, 0, sizeof(VkSurfaceCapabilitiesKHR)); + return VK_SUCCESS; + } + if (NULL != phys_dev_term->this_icd_term->surface_list.list && phys_dev_term->this_icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) && phys_dev_term->this_icd_term->surface_list.list[icd_surface->surface_index]) { @@ -269,6 +284,14 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceFormatsKHR(VkP } VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)surface; + + // Return if the instance extension used to create the VkSurfaceKHR isn't supported by the ICD + if (!check_if_instance_extension_is_available(&icd_term->enabled_instance_extensions, &icd_surface->wsi_extension_used)) { + // Application shouldn't query the surface formats if the VkPhysicalDevice doesn't support the VkSurfaceKHR + *pSurfaceFormatCount = 0; + return VK_SUCCESS; + } + if (NULL != phys_dev_term->this_icd_term->surface_list.list && phys_dev_term->this_icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) && phys_dev_term->this_icd_term->surface_list.list[icd_surface->surface_index]) { @@ -328,6 +351,14 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfacePresentModesKH } VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)surface; + + // Return if the instance extension used to create the VkSurfaceKHR isn't supported by the ICD + if (!check_if_instance_extension_is_available(&icd_term->enabled_instance_extensions, &icd_surface->wsi_extension_used)) { + // Application shouldn't query the surface present modes if the VkPhysicalDevice doesn't support the VkSurfaceKHR + *pPresentModeCount = 0; + return VK_SUCCESS; + } + if (NULL != phys_dev_term->this_icd_term->surface_list.list && phys_dev_term->this_icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) && phys_dev_term->this_icd_term->surface_list.list[icd_surface->surface_index]) { @@ -386,7 +417,19 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateSwapchainKHR(VkDevice device, co "extension enabled?"); return VK_SUCCESS; } + VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pCreateInfo->surface; + + // Return if the instance extension used to create the VkSurfaceKHR isn't supported by the ICD + if (!check_if_instance_extension_is_available(&icd_term->enabled_instance_extensions, &icd_surface->wsi_extension_used)) { + // Application shouldn't try to create a swapchain if the VkPhysicalDevice doesn't support the VkSurfaceKHR + // Return VK_ERROR_INITIALIZATION_FAILED to indicate that the swapchain is not valid and zero out the swapchain handle + if (pSwapchain) { + *pSwapchain = VK_NULL_HANDLE; + } + return VK_ERROR_INITIALIZATION_FAILED; + } + if (NULL != icd_term->surface_list.list && icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) && icd_term->surface_list.list[icd_surface->surface_index]) { @@ -461,7 +504,7 @@ VkResult allocate_icd_surface_struct(struct loader_instance *instance, const VkA } // Next, if so, proceed with the implementation of this function: - icd_surface = loader_instance_heap_alloc(instance, sizeof(VkIcdSurface), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + icd_surface = loader_instance_heap_calloc(instance, sizeof(VkIcdSurface), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); if (icd_surface == NULL) { res = VK_ERROR_OUT_OF_HOST_MEMORY; goto out; @@ -503,7 +546,9 @@ void cleanup_surface_creation(struct loader_instance *loader_inst, VkResult resu for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) { if (icd_term->enabled_instance_extensions.khr_surface && NULL != icd_term->surface_list.list && icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) && - icd_term->surface_list.list[icd_surface->surface_index] && NULL != icd_term->dispatch.DestroySurfaceKHR) { + icd_term->surface_list.list[icd_surface->surface_index] && NULL != icd_term->dispatch.DestroySurfaceKHR && + check_if_instance_extension_is_available(&icd_term->enabled_instance_extensions, + &icd_surface->wsi_extension_used)) { icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, icd_term->surface_list.list[icd_surface->surface_index], pAllocator); } @@ -560,6 +605,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateWin32SurfaceKHR(VkInstance insta if (VK_SUCCESS != result) { goto out; } + icd_surface->wsi_extension_used.khr_win32_surface = 1; // Loop through each ICD and determine if they need to create a surface for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) { @@ -661,6 +707,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateWaylandSurfaceKHR(VkInstance ins if (VK_SUCCESS != result) { goto out; } + icd_surface->wsi_extension_used.khr_wayland_surface = 1; // Loop through each ICD and determine if they need to create a surface for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) { @@ -766,6 +813,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateXcbSurfaceKHR(VkInstance instanc if (VK_SUCCESS != result) { goto out; } + icd_surface->wsi_extension_used.khr_xcb_surface = 1; // Loop through each ICD and determine if they need to create a surface for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) { @@ -874,6 +922,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateXlibSurfaceKHR(VkInstance instan if (VK_SUCCESS != result) { goto out; } + icd_surface->wsi_extension_used.khr_xlib_surface = 1; // Loop through each ICD and determine if they need to create a surface for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) { @@ -981,6 +1030,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDirectFBSurfaceEXT(VkInstance in if (VK_SUCCESS != result) { goto out; } + icd_surface->wsi_extension_used.ext_directfb_surface = 1; // Loop through each ICD and determine if they need to create a surface for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) { @@ -1133,6 +1183,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateHeadlessSurfaceEXT(VkInstance in if (VK_SUCCESS != result) { goto out; } + icd_surface->wsi_extension_used.ext_headless_surface = 1; // Loop through each ICD and determine if they need to create a surface for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) { @@ -1222,6 +1273,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateMacOSSurfaceMVK(VkInstance insta if (VK_SUCCESS != result) { goto out; } + icd_surface->wsi_extension_used.mvk_macos_surface = 1; // Loop through each ICD and determine if they need to create a surface for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) { @@ -1336,6 +1388,7 @@ terminator_CreateStreamDescriptorSurfaceGGP(VkInstance instance, const VkStreamD if (VK_SUCCESS != result) { goto out; } + icd_surface->wsi_extension_used.ggp_stream_descriptor_surface = 1; // Loop through each ICD and determine if they need to create a surface for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) { @@ -1394,6 +1447,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateMetalSurfaceEXT(VkInstance insta if (VK_SUCCESS != result) { goto out; } + icd_surface->wsi_extension_used.ext_metal_surface = 1; // Loop through each ICD and determine if they need to create a surface for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) { @@ -1456,6 +1510,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateScreenSurfaceQNX(VkInstance inst if (VK_SUCCESS != result) { goto out; } + icd_surface->wsi_extension_used.qnx_screen_surface = 1; // Loop through each ICD and determine if they need to create a surface for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) { @@ -1559,6 +1614,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateViSurfaceNN(VkInstance instance, if (VK_SUCCESS != result) { goto out; } + icd_surface->wsi_extension_used.nn_vi_surface = 1; // Loop through each ICD and determine if they need to create a surface for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) { @@ -1655,6 +1711,18 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceDisplayPlanePropertie return VK_SUCCESS; } + struct loader_instance_extension_enables display_enabled = {0}; + display_enabled.khr_display = 1; + + if (!check_if_instance_extension_is_available(&icd_term->enabled_instance_extensions, &display_enabled)) { + // return 0 for property count as this driver doesn't support WSI functionality + if (pPropertyCount) { + *pPropertyCount = 0; + } + loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "ICD for selected physical device does not support VK_KHR_display!"); + return VK_SUCCESS; + } + if (NULL == icd_term->dispatch.GetPhysicalDeviceDisplayPlanePropertiesKHR) { loader_log(loader_inst, VULKAN_LOADER_WARN_BIT, 0, "ICD for selected physical device does not export vkGetPhysicalDeviceDisplayPlanePropertiesKHR!"); @@ -1696,6 +1764,18 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDisplayPlaneSupportedDisplaysKHR(Vk return VK_SUCCESS; } + struct loader_instance_extension_enables display_enabled = {0}; + display_enabled.khr_display = 1; + + if (!check_if_instance_extension_is_available(&icd_term->enabled_instance_extensions, &display_enabled)) { + // return 0 for property count as this driver doesn't support WSI functionality + if (pDisplayCount) { + *pDisplayCount = 0; + } + loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "ICD for selected physical device does not support VK_KHR_display!"); + return VK_SUCCESS; + } + if (NULL == icd_term->dispatch.GetDisplayPlaneSupportedDisplaysKHR) { loader_log(loader_inst, VULKAN_LOADER_WARN_BIT, 0, "ICD for selected physical device does not export vkGetDisplayPlaneSupportedDisplaysKHR!"); @@ -1738,6 +1818,18 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDisplayModePropertiesKHR(VkPhysical return VK_SUCCESS; } + struct loader_instance_extension_enables display_enabled = {0}; + display_enabled.khr_display = 1; + + if (!check_if_instance_extension_is_available(&icd_term->enabled_instance_extensions, &display_enabled)) { + // return 0 for property count as this driver doesn't support WSI functionality + if (pPropertyCount) { + *pPropertyCount = 0; + } + loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "ICD for selected physical device does not support VK_KHR_display!"); + return VK_SUCCESS; + } + if (NULL == icd_term->dispatch.GetDisplayModePropertiesKHR) { loader_log(loader_inst, VULKAN_LOADER_WARN_BIT, 0, "ICD for selected physical device does not export vkGetDisplayModePropertiesKHR!"); @@ -1781,6 +1873,15 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDisplayModeKHR(VkPhysicalDevice return VK_ERROR_EXTENSION_NOT_PRESENT; } + struct loader_instance_extension_enables display_enabled = {0}; + display_enabled.khr_display = 1; + + if (!check_if_instance_extension_is_available(&icd_term->enabled_instance_extensions, &display_enabled)) { + // Can't emulate, so return an appropriate error + loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "ICD for selected physical device does not support VK_KHR_display!"); + return VK_ERROR_INITIALIZATION_FAILED; + } + if (NULL == icd_term->dispatch.CreateDisplayModeKHR) { // Can't emulate, so return an appropriate error loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, @@ -1820,6 +1921,18 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDisplayPlaneCapabilitiesKHR(VkPhysi return VK_SUCCESS; } + struct loader_instance_extension_enables display_enabled = {0}; + display_enabled.khr_display = 1; + + if (!check_if_instance_extension_is_available(&icd_term->enabled_instance_extensions, &display_enabled)) { + // Emulate support + if (pCapabilities) { + memset(pCapabilities, 0, sizeof(VkDisplayPlaneCapabilitiesKHR)); + } + loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "ICD for selected physical device does not support VK_KHR_display!"); + return VK_SUCCESS; + } + if (NULL == icd_term->dispatch.GetDisplayPlaneCapabilitiesKHR) { // Emulate support loader_log(loader_inst, VULKAN_LOADER_WARN_BIT, 0, @@ -1869,6 +1982,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDisplayPlaneSurfaceKHR(VkInstanc if (VK_SUCCESS != result) { goto out; } + icd_surface->wsi_extension_used.khr_display = 1; // Loop through each ICD and determine if they need to create a surface for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) { @@ -2030,6 +2144,15 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDevicePresentRectanglesKHR( return VK_SUCCESS; } VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)(surface); + + if (!check_if_instance_extension_is_available(&icd_term->enabled_instance_extensions, &icd_surface->wsi_extension_used)) { + // return as this driver doesn't support WSI functionality + if (pRectCount) { + *pRectCount = 0; + } + return VK_SUCCESS; + } + if (NULL != icd_term->surface_list.list && icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) && icd_term->surface_list.list[icd_surface->surface_index]) { @@ -2305,6 +2428,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateImagePipeSurfaceFUCHSIA(VkInstan if (VK_SUCCESS != result) { goto out; } + icd_surface->wsi_extension_used.fuchsia_imagepipe_surface = 1; // Loop through each ICD and determine if they need to create a surface for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) { @@ -2474,6 +2598,13 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceCapabilities2K } return VK_SUCCESS; } + // If the ICD doesn't support the surface extension used to create the VkSurfaceKHR, then there are no capabilities + if (!check_if_instance_extension_is_available(&icd_term->enabled_instance_extensions, &icd_surface->wsi_extension_used)) { + if (pSurfaceCapabilities) { + memset(&pSurfaceCapabilities->surfaceCapabilities, 0, sizeof(VkSurfaceCapabilitiesKHR)); + } + return VK_SUCCESS; + } VkResult res = icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilitiesKHR(phys_dev_term->phys_dev, surface, &pSurfaceCapabilities->surfaceCapabilities); @@ -2514,6 +2645,14 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceFormats2KHR(Vk VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)(pSurfaceInfo->surface); if (icd_term->dispatch.GetPhysicalDeviceSurfaceFormats2KHR != NULL) { + // If the ICD doesn't support the surface extension used to create the VkSurfaceKHR, then there are no formats + if (!check_if_instance_extension_is_available(&icd_term->enabled_instance_extensions, &icd_surface->wsi_extension_used)) { + if (pSurfaceFormatCount) { + *pSurfaceFormatCount = 0; + } + return VK_SUCCESS; + } + // Pass the call to the driver, possibly unwrapping the ICD surface if (NULL != icd_term->surface_list.list && icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) && @@ -2552,6 +2691,13 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceFormats2KHR(Vk } return VK_SUCCESS; } + // If the ICD doesn't support the surface extension used to create the VkSurfaceKHR, then there are no formats + if (!check_if_instance_extension_is_available(&icd_term->enabled_instance_extensions, &icd_surface->wsi_extension_used)) { + if (pSurfaceFormatCount) { + *pSurfaceFormatCount = 0; + } + return VK_SUCCESS; + } if (*pSurfaceFormatCount == 0 || pSurfaceFormats == NULL) { // Write to pSurfaceFormatCount diff --git a/loader/wsi.h b/loader/wsi.h index 90de00123..ddbc1a4a1 100644 --- a/loader/wsi.h +++ b/loader/wsi.h @@ -26,6 +26,9 @@ typedef struct { uint32_t surface_index; // This surface's index into each drivers list of created surfaces + + // Defines the 'active' WSI extension used - only one member should be true + struct loader_instance_extension_enables wsi_extension_used; } VkIcdSurface; bool wsi_swapchain_instance_gpa(struct loader_instance *ptr_instance, const char *name, void **addr); diff --git a/scripts/loader_extension_generator.py b/scripts/loader_extension_generator.py index e9b513c01..a9706b99f 100644 --- a/scripts/loader_extension_generator.py +++ b/scripts/loader_extension_generator.py @@ -284,6 +284,7 @@ def endFile(self): file_data += self.CreateTrampTermFuncs() file_data += self.InstExtensionGPA() file_data += self.OutputInstanceExtensionEnableStructDefinition() + file_data += self.OutputCheckInstanceExtensionIsEnabledFunc() file_data += self.DeviceExtensionGetTerminator() file_data += self.InitInstLoaderExtensionDispatchTable() file_data += self.OutputInstantExtensionWhitelistArray() @@ -508,6 +509,8 @@ def OutputPrototypesInHeader(self): protos += '// about.\n' protos += 'void fill_out_enabled_instance_extensions(uint32_t extension_count, const char *const * extension_list, struct loader_instance_extension_enables* enables);\n\n' protos += '\n' + protos += 'bool check_if_instance_extension_is_available(const struct loader_instance_extension_enables* enabled, const struct loader_instance_extension_enables* desired);\n' + protos += '\n' protos += '// Extension interception for vkGetDeviceProcAddr function, so we can return\n' protos += '// an appropriate terminator if this is one of those few device commands requiring\n' protos += '// a terminator.\n' @@ -812,6 +815,21 @@ def OutputInstanceExtensionEnableStructDefinition(self): return out + def OutputCheckInstanceExtensionIsEnabledFunc(self): + out = 'bool check_if_instance_extension_is_available(const struct loader_instance_extension_enables* enabled, const struct loader_instance_extension_enables* desired) {\n' + for ext in self.extensions: + if self.getAPIVersion(ext.name) or ext.type == 'device': + continue + if ext.protect is not None: + out += f'#if defined({ext.protect})\n' + out += f' if (desired->{ext.name[3:].lower()} && !enabled->{ext.name[3:].lower()}) return false;\n' + if ext.protect is not None: + out += f'#endif // defined({ext.protect})\n' + out += ' return true;\n' + out += '};\n\n' + + return out + # # Creates the prototypes for the loader's core instance command terminators def OutputLoaderTerminators(self):