Home | History | Annotate | Download | only in loader
      1 /*
      2  * Copyright (c) 2015-2016 The Khronos Group Inc.
      3  * Copyright (c) 2015-2016 Valve Corporation
      4  * Copyright (c) 2015-2016 LunarG, Inc.
      5  *
      6  * Licensed under the Apache License, Version 2.0 (the "License");
      7  * you may not use this file except in compliance with the License.
      8  * You may obtain a copy of the License at
      9  *
     10  *     http://www.apache.org/licenses/LICENSE-2.0
     11  *
     12  * Unless required by applicable law or agreed to in writing, software
     13  * distributed under the License is distributed on an "AS IS" BASIS,
     14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     15  * See the License for the specific language governing permissions and
     16  * limitations under the License.
     17  *
     18  * Author: Ian Elliott <ian (at) lunarg.com>
     19  * Author: Jon Ashburn <jon (at) lunarg.com>
     20  * Author: Ian Elliott <ianelliott (at) google.com>
     21  * Author: Mark Lobodzinski <mark (at) lunarg.com>
     22  */
     23 
     24 #define _GNU_SOURCE
     25 #include <stdio.h>
     26 #include <stdlib.h>
     27 #include <string.h>
     28 #include "vk_loader_platform.h"
     29 #include "loader.h"
     30 #include "wsi.h"
     31 #include <vulkan/vk_icd.h>
     32 
     33 // The first ICD/Loader interface that support querying the SurfaceKHR from
     34 // the ICDs.
     35 #define ICD_VER_SUPPORTS_ICD_SURFACE_KHR 3
     36 
     37 void wsi_create_instance(struct loader_instance *ptr_instance, const VkInstanceCreateInfo *pCreateInfo) {
     38     ptr_instance->wsi_surface_enabled = false;
     39 
     40 #ifdef VK_USE_PLATFORM_WIN32_KHR
     41     ptr_instance->wsi_win32_surface_enabled = false;
     42 #endif  // VK_USE_PLATFORM_WIN32_KHR
     43 #ifdef VK_USE_PLATFORM_MIR_KHR
     44     ptr_instance->wsi_mir_surface_enabled = false;
     45 #endif  // VK_USE_PLATFORM_MIR_KHR
     46 #ifdef VK_USE_PLATFORM_WAYLAND_KHR
     47     ptr_instance->wsi_wayland_surface_enabled = false;
     48 #endif  // VK_USE_PLATFORM_WAYLAND_KHR
     49 #ifdef VK_USE_PLATFORM_XCB_KHR
     50     ptr_instance->wsi_xcb_surface_enabled = false;
     51 #endif  // VK_USE_PLATFORM_XCB_KHR
     52 #ifdef VK_USE_PLATFORM_XLIB_KHR
     53     ptr_instance->wsi_xlib_surface_enabled = false;
     54 #endif  // VK_USE_PLATFORM_XLIB_KHR
     55 #ifdef VK_USE_PLATFORM_ANDROID_KHR
     56     ptr_instance->wsi_android_surface_enabled = false;
     57 #endif  // VK_USE_PLATFORM_ANDROID_KHR
     58 
     59     ptr_instance->wsi_display_enabled = false;
     60 
     61     for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
     62         if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SURFACE_EXTENSION_NAME) == 0) {
     63             ptr_instance->wsi_surface_enabled = true;
     64             continue;
     65         }
     66 #ifdef VK_USE_PLATFORM_WIN32_KHR
     67         if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_WIN32_SURFACE_EXTENSION_NAME) == 0) {
     68             ptr_instance->wsi_win32_surface_enabled = true;
     69             continue;
     70         }
     71 #endif  // VK_USE_PLATFORM_WIN32_KHR
     72 #ifdef VK_USE_PLATFORM_MIR_KHR
     73         if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_MIR_SURFACE_EXTENSION_NAME) == 0) {
     74             ptr_instance->wsi_mir_surface_enabled = true;
     75             continue;
     76         }
     77 #endif  // VK_USE_PLATFORM_MIR_KHR
     78 #ifdef VK_USE_PLATFORM_WAYLAND_KHR
     79         if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME) == 0) {
     80             ptr_instance->wsi_wayland_surface_enabled = true;
     81             continue;
     82         }
     83 #endif  // VK_USE_PLATFORM_WAYLAND_KHR
     84 #ifdef VK_USE_PLATFORM_XCB_KHR
     85         if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_XCB_SURFACE_EXTENSION_NAME) == 0) {
     86             ptr_instance->wsi_xcb_surface_enabled = true;
     87             continue;
     88         }
     89 #endif  // VK_USE_PLATFORM_XCB_KHR
     90 #ifdef VK_USE_PLATFORM_XLIB_KHR
     91         if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_XLIB_SURFACE_EXTENSION_NAME) == 0) {
     92             ptr_instance->wsi_xlib_surface_enabled = true;
     93             continue;
     94         }
     95 #endif  // VK_USE_PLATFORM_XLIB_KHR
     96 #ifdef VK_USE_PLATFORM_ANDROID_KHR
     97         if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_ANDROID_SURFACE_EXTENSION_NAME) == 0) {
     98             ptr_instance->wsi_android_surface_enabled = true;
     99             continue;
    100         }
    101 #endif  // VK_USE_PLATFORM_ANDROID_KHR
    102         if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_DISPLAY_EXTENSION_NAME) == 0) {
    103             ptr_instance->wsi_display_enabled = true;
    104             continue;
    105         }
    106     }
    107 }
    108 
    109 // Linux WSI surface extensions are not always compiled into the loader. (Assume
    110 // for Windows the KHR_win32_surface is always compiled into loader). A given
    111 // Linux build environment might not have the headers required for building one
    112 // of the four extensions  (Xlib, Xcb, Mir, Wayland).  Thus, need to check if
    113 // the built loader actually supports the particular Linux surface extension.
    114 // If not supported by the built loader it will not be included in the list of
    115 // enumerated instance extensions.  This solves the issue where an ICD or layer
    116 // advertises support for a given Linux surface extension but the loader was not
    117 // built to support the extension.
    118 bool wsi_unsupported_instance_extension(const VkExtensionProperties *ext_prop) {
    119 #ifndef VK_USE_PLATFORM_MIR_KHR
    120     if (!strcmp(ext_prop->extensionName, "VK_KHR_mir_surface")) return true;
    121 #endif  // VK_USE_PLATFORM_MIR_KHR
    122 #ifndef VK_USE_PLATFORM_WAYLAND_KHR
    123     if (!strcmp(ext_prop->extensionName, "VK_KHR_wayland_surface")) return true;
    124 #endif  // VK_USE_PLATFORM_WAYLAND_KHR
    125 #ifndef VK_USE_PLATFORM_XCB_KHR
    126     if (!strcmp(ext_prop->extensionName, "VK_KHR_xcb_surface")) return true;
    127 #endif  // VK_USE_PLATFORM_XCB_KHR
    128 #ifndef VK_USE_PLATFORM_XLIB_KHR
    129     if (!strcmp(ext_prop->extensionName, "VK_KHR_xlib_surface")) return true;
    130 #endif  // VK_USE_PLATFORM_XLIB_KHR
    131 
    132     return false;
    133 }
    134 
    135 // Functions for the VK_KHR_surface extension:
    136 
    137 // This is the trampoline entrypoint for DestroySurfaceKHR
    138 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface,
    139                                                              const VkAllocationCallbacks *pAllocator) {
    140     const VkLayerInstanceDispatchTable *disp;
    141     disp = loader_get_instance_layer_dispatch(instance);
    142     disp->DestroySurfaceKHR(instance, surface, pAllocator);
    143 }
    144 
    145 // TODO probably need to lock around all the loader_get_instance() calls.
    146 
    147 // This is the instance chain terminator function for DestroySurfaceKHR
    148 VKAPI_ATTR void VKAPI_CALL terminator_DestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface,
    149                                                         const VkAllocationCallbacks *pAllocator) {
    150     struct loader_instance *ptr_instance = loader_get_instance(instance);
    151 
    152     VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)surface;
    153     if (NULL != icd_surface) {
    154         if (NULL != icd_surface->real_icd_surfaces) {
    155             uint32_t i = 0;
    156             for (struct loader_icd_term *icd_term = ptr_instance->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
    157                 if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
    158                     if (NULL != icd_term->dispatch.DestroySurfaceKHR && (VkSurfaceKHR)NULL != icd_surface->real_icd_surfaces[i]) {
    159                         icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, icd_surface->real_icd_surfaces[i], pAllocator);
    160                         icd_surface->real_icd_surfaces[i] = (VkSurfaceKHR)NULL;
    161                     }
    162                 } else {
    163                     // The real_icd_surface for any ICD not supporting the
    164                     // proper interface version should be NULL.  If not, then
    165                     // we have a problem.
    166                     assert((VkSurfaceKHR)NULL == icd_surface->real_icd_surfaces[i]);
    167                 }
    168             }
    169             loader_instance_heap_free(ptr_instance, icd_surface->real_icd_surfaces);
    170         }
    171 
    172         loader_instance_heap_free(ptr_instance, (void *)(uintptr_t)surface);
    173     }
    174 }
    175 
    176 // This is the trampoline entrypoint for GetPhysicalDeviceSurfaceSupportKHR
    177 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice,
    178                                                                                   uint32_t queueFamilyIndex, VkSurfaceKHR surface,
    179                                                                                   VkBool32 *pSupported) {
    180     const VkLayerInstanceDispatchTable *disp;
    181     VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
    182     disp = loader_get_instance_layer_dispatch(physicalDevice);
    183     VkResult res = disp->GetPhysicalDeviceSurfaceSupportKHR(unwrapped_phys_dev, queueFamilyIndex, surface, pSupported);
    184     return res;
    185 }
    186 
    187 // This is the instance chain terminator function for
    188 // GetPhysicalDeviceSurfaceSupportKHR
    189 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice,
    190                                                                              uint32_t queueFamilyIndex, VkSurfaceKHR surface,
    191                                                                              VkBool32 *pSupported) {
    192     // First, check to ensure the appropriate extension was enabled:
    193     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
    194     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
    195     struct loader_instance *ptr_instance = (struct loader_instance *)icd_term->this_instance;
    196     if (!ptr_instance->wsi_surface_enabled) {
    197         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
    198                    "VK_KHR_surface extension not enabled.  vkGetPhysicalDeviceSurfaceSupportKHR not executed!\n");
    199         return VK_SUCCESS;
    200     }
    201 
    202     if (NULL == pSupported) {
    203         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
    204                    "NULL pointer passed into vkGetPhysicalDeviceSurfaceSupportKHR for pSupported!\n");
    205         assert(false && "GetPhysicalDeviceSurfaceSupportKHR: Error, null pSupported");
    206     }
    207     *pSupported = false;
    208 
    209     if (NULL == icd_term->dispatch.GetPhysicalDeviceSurfaceSupportKHR) {
    210         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
    211                    "ICD for selected physical device is not exporting vkGetPhysicalDeviceSurfaceSupportKHR!\n");
    212         assert(false && "loader: null GetPhysicalDeviceSurfaceSupportKHR ICD pointer");
    213     }
    214 
    215     VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)surface;
    216     if (NULL != icd_surface->real_icd_surfaces && (VkSurfaceKHR)NULL != icd_surface->real_icd_surfaces[phys_dev_term->icd_index]) {
    217         return icd_term->dispatch.GetPhysicalDeviceSurfaceSupportKHR(
    218             phys_dev_term->phys_dev, queueFamilyIndex, icd_surface->real_icd_surfaces[phys_dev_term->icd_index], pSupported);
    219     }
    220 
    221     return icd_term->dispatch.GetPhysicalDeviceSurfaceSupportKHR(phys_dev_term->phys_dev, queueFamilyIndex, surface, pSupported);
    222 }
    223 
    224 // This is the trampoline entrypoint for GetPhysicalDeviceSurfaceCapabilitiesKHR
    225 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceCapabilitiesKHR(
    226     VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) {
    227     const VkLayerInstanceDispatchTable *disp;
    228     VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
    229     disp = loader_get_instance_layer_dispatch(physicalDevice);
    230     VkResult res = disp->GetPhysicalDeviceSurfaceCapabilitiesKHR(unwrapped_phys_dev, surface, pSurfaceCapabilities);
    231     return res;
    232 }
    233 
    234 // This is the instance chain terminator function for
    235 // GetPhysicalDeviceSurfaceCapabilitiesKHR
    236 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice,
    237                                                                                   VkSurfaceKHR surface,
    238                                                                                   VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) {
    239     // First, check to ensure the appropriate extension was enabled:
    240     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
    241     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
    242     struct loader_instance *ptr_instance = (struct loader_instance *)icd_term->this_instance;
    243     if (!ptr_instance->wsi_surface_enabled) {
    244         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
    245                    "VK_KHR_surface extension not enabled.  vkGetPhysicalDeviceSurfaceCapabilitiesKHR not executed!\n");
    246         return VK_SUCCESS;
    247     }
    248 
    249     if (NULL == pSurfaceCapabilities) {
    250         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
    251                    "NULL pointer passed into vkGetPhysicalDeviceSurfaceCapabilitiesKHR for pSurfaceCapabilities!\n");
    252         assert(false && "GetPhysicalDeviceSurfaceCapabilitiesKHR: Error, null pSurfaceCapabilities");
    253     }
    254 
    255     if (NULL == icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilitiesKHR) {
    256         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
    257                    "ICD for selected physical device is not exporting vkGetPhysicalDeviceSurfaceCapabilitiesKHR!\n");
    258         assert(false && "loader: null GetPhysicalDeviceSurfaceCapabilitiesKHR ICD pointer");
    259     }
    260 
    261     VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)surface;
    262     if (NULL != icd_surface->real_icd_surfaces && (VkSurfaceKHR)NULL != icd_surface->real_icd_surfaces[phys_dev_term->icd_index]) {
    263         return icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilitiesKHR(
    264             phys_dev_term->phys_dev, icd_surface->real_icd_surfaces[phys_dev_term->icd_index], pSurfaceCapabilities);
    265     }
    266 
    267     return icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilitiesKHR(phys_dev_term->phys_dev, surface, pSurfaceCapabilities);
    268 }
    269 
    270 // This is the trampoline entrypoint for GetPhysicalDeviceSurfaceFormatsKHR
    271 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice,
    272                                                                                   VkSurfaceKHR surface,
    273                                                                                   uint32_t *pSurfaceFormatCount,
    274                                                                                   VkSurfaceFormatKHR *pSurfaceFormats) {
    275     VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
    276     const VkLayerInstanceDispatchTable *disp;
    277     disp = loader_get_instance_layer_dispatch(physicalDevice);
    278     VkResult res = disp->GetPhysicalDeviceSurfaceFormatsKHR(unwrapped_phys_dev, surface, pSurfaceFormatCount, pSurfaceFormats);
    279     return res;
    280 }
    281 
    282 // This is the instance chain terminator function for
    283 // GetPhysicalDeviceSurfaceFormatsKHR
    284 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
    285                                                                              uint32_t *pSurfaceFormatCount,
    286                                                                              VkSurfaceFormatKHR *pSurfaceFormats) {
    287     // First, check to ensure the appropriate extension was enabled:
    288     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
    289     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
    290     struct loader_instance *ptr_instance = (struct loader_instance *)icd_term->this_instance;
    291     if (!ptr_instance->wsi_surface_enabled) {
    292         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
    293                    "VK_KHR_surface extension not enabled.  vkGetPhysicalDeviceSurfaceFormatsKHR not executed!\n");
    294         return VK_SUCCESS;
    295     }
    296 
    297     if (NULL == pSurfaceFormatCount) {
    298         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
    299                    "NULL pointer passed into vkGetPhysicalDeviceSurfaceFormatsKHR for pSurfaceFormatCount!\n");
    300         assert(false && "GetPhysicalDeviceSurfaceFormatsKHR(: Error, null pSurfaceFormatCount");
    301     }
    302 
    303     if (NULL == icd_term->dispatch.GetPhysicalDeviceSurfaceFormatsKHR) {
    304         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
    305                    "ICD for selected physical device is not exporting vkGetPhysicalDeviceSurfaceCapabilitiesKHR!\n");
    306         assert(false && "loader: null GetPhysicalDeviceSurfaceFormatsKHR ICD pointer");
    307     }
    308 
    309     VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)surface;
    310     if (NULL != icd_surface->real_icd_surfaces && (VkSurfaceKHR)NULL != icd_surface->real_icd_surfaces[phys_dev_term->icd_index]) {
    311         return icd_term->dispatch.GetPhysicalDeviceSurfaceFormatsKHR(phys_dev_term->phys_dev,
    312                                                                      icd_surface->real_icd_surfaces[phys_dev_term->icd_index],
    313                                                                      pSurfaceFormatCount, pSurfaceFormats);
    314     }
    315 
    316     return icd_term->dispatch.GetPhysicalDeviceSurfaceFormatsKHR(phys_dev_term->phys_dev, surface, pSurfaceFormatCount,
    317                                                                  pSurfaceFormats);
    318 }
    319 
    320 // This is the trampoline entrypoint for GetPhysicalDeviceSurfacePresentModesKHR
    321 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice,
    322                                                                                        VkSurfaceKHR surface,
    323                                                                                        uint32_t *pPresentModeCount,
    324                                                                                        VkPresentModeKHR *pPresentModes) {
    325     VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
    326     const VkLayerInstanceDispatchTable *disp;
    327     disp = loader_get_instance_layer_dispatch(physicalDevice);
    328     VkResult res = disp->GetPhysicalDeviceSurfacePresentModesKHR(unwrapped_phys_dev, surface, pPresentModeCount, pPresentModes);
    329     return res;
    330 }
    331 
    332 // This is the instance chain terminator function for
    333 // GetPhysicalDeviceSurfacePresentModesKHR
    334 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice,
    335                                                                                   VkSurfaceKHR surface, uint32_t *pPresentModeCount,
    336                                                                                   VkPresentModeKHR *pPresentModes) {
    337     // First, check to ensure the appropriate extension was enabled:
    338     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
    339     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
    340     struct loader_instance *ptr_instance = (struct loader_instance *)icd_term->this_instance;
    341     if (!ptr_instance->wsi_surface_enabled) {
    342         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
    343                    "VK_KHR_surface extension not enabled.  vkGetPhysicalDeviceSurfacePresentModesKHR not executed!\n");
    344         return VK_SUCCESS;
    345     }
    346 
    347     if (NULL == pPresentModeCount) {
    348         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
    349                    "NULL pointer passed into vkGetPhysicalDeviceSurfacePresentModesKHR for pPresentModeCount!\n");
    350         assert(false && "GetPhysicalDeviceSurfacePresentModesKHR(: Error, null pPresentModeCount");
    351     }
    352 
    353     if (NULL == icd_term->dispatch.GetPhysicalDeviceSurfacePresentModesKHR) {
    354         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
    355                    "ICD for selected physical device is not exporting vkGetPhysicalDeviceSurfacePresentModesKHR!\n");
    356         assert(false && "loader: null GetPhysicalDeviceSurfacePresentModesKHR ICD pointer");
    357     }
    358 
    359     VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)surface;
    360     if (NULL != icd_surface->real_icd_surfaces && (VkSurfaceKHR)NULL != icd_surface->real_icd_surfaces[phys_dev_term->icd_index]) {
    361         return icd_term->dispatch.GetPhysicalDeviceSurfacePresentModesKHR(
    362             phys_dev_term->phys_dev, icd_surface->real_icd_surfaces[phys_dev_term->icd_index], pPresentModeCount, pPresentModes);
    363     }
    364 
    365     return icd_term->dispatch.GetPhysicalDeviceSurfacePresentModesKHR(phys_dev_term->phys_dev, surface, pPresentModeCount,
    366                                                                       pPresentModes);
    367 }
    368 
    369 // Functions for the VK_KHR_swapchain extension:
    370 
    371 // This is the trampoline entrypoint for CreateSwapchainKHR
    372 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo,
    373                                                                   const VkAllocationCallbacks *pAllocator,
    374                                                                   VkSwapchainKHR *pSwapchain) {
    375     const VkLayerDispatchTable *disp;
    376     disp = loader_get_dispatch(device);
    377     return disp->CreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain);
    378 }
    379 
    380 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo,
    381                                                              const VkAllocationCallbacks *pAllocator,
    382                                                              VkSwapchainKHR *pSwapchain) {
    383     uint32_t icd_index = 0;
    384     struct loader_device *dev;
    385     struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, &icd_index);
    386     if (NULL != icd_term && NULL != icd_term->dispatch.CreateSwapchainKHR) {
    387         VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pCreateInfo->surface;
    388         if (NULL != icd_surface->real_icd_surfaces) {
    389             if ((VkSurfaceKHR)NULL != icd_surface->real_icd_surfaces[icd_index]) {
    390                 // We found the ICD, and there is an ICD KHR surface
    391                 // associated with it, so copy the CreateInfo struct
    392                 // and point it at the ICD's surface.
    393                 VkSwapchainCreateInfoKHR *pCreateCopy = loader_stack_alloc(sizeof(VkSwapchainCreateInfoKHR));
    394                 if (NULL == pCreateCopy) {
    395                     return VK_ERROR_OUT_OF_HOST_MEMORY;
    396                 }
    397                 memcpy(pCreateCopy, pCreateInfo, sizeof(VkSwapchainCreateInfoKHR));
    398                 pCreateCopy->surface = icd_surface->real_icd_surfaces[icd_index];
    399                 return icd_term->dispatch.CreateSwapchainKHR(device, pCreateCopy, pAllocator, pSwapchain);
    400             }
    401         }
    402         return icd_term->dispatch.CreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain);
    403     }
    404     return VK_SUCCESS;
    405 }
    406 
    407 // This is the trampoline entrypoint for DestroySwapchainKHR
    408 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain,
    409                                                                const VkAllocationCallbacks *pAllocator) {
    410     const VkLayerDispatchTable *disp;
    411     disp = loader_get_dispatch(device);
    412     disp->DestroySwapchainKHR(device, swapchain, pAllocator);
    413 }
    414 
    415 // This is the trampoline entrypoint for GetSwapchainImagesKHR
    416 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain,
    417                                                                      uint32_t *pSwapchainImageCount, VkImage *pSwapchainImages) {
    418     const VkLayerDispatchTable *disp;
    419     disp = loader_get_dispatch(device);
    420     return disp->GetSwapchainImagesKHR(device, swapchain, pSwapchainImageCount, pSwapchainImages);
    421 }
    422 
    423 // This is the trampoline entrypoint for AcquireNextImageKHR
    424 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout,
    425                                                                    VkSemaphore semaphore, VkFence fence, uint32_t *pImageIndex) {
    426     const VkLayerDispatchTable *disp;
    427     disp = loader_get_dispatch(device);
    428     return disp->AcquireNextImageKHR(device, swapchain, timeout, semaphore, fence, pImageIndex);
    429 }
    430 
    431 // This is the trampoline entrypoint for QueuePresentKHR
    432 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo) {
    433     const VkLayerDispatchTable *disp;
    434     disp = loader_get_dispatch(queue);
    435     return disp->QueuePresentKHR(queue, pPresentInfo);
    436 }
    437 
    438 static VkIcdSurface *AllocateIcdSurfaceStruct(struct loader_instance *instance, size_t base_size, size_t platform_size) {
    439     // Next, if so, proceed with the implementation of this function:
    440     VkIcdSurface *pIcdSurface = loader_instance_heap_alloc(instance, sizeof(VkIcdSurface), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
    441     if (pIcdSurface != NULL) {
    442         // Setup the new sizes and offsets so we can grow the structures in the
    443         // future without having problems
    444         pIcdSurface->base_size = (uint32_t)base_size;
    445         pIcdSurface->platform_size = (uint32_t)platform_size;
    446         pIcdSurface->non_platform_offset = (uint32_t)((uint8_t *)(&pIcdSurface->base_size) - (uint8_t *)pIcdSurface);
    447         pIcdSurface->entire_size = sizeof(VkIcdSurface);
    448 
    449         pIcdSurface->real_icd_surfaces = loader_instance_heap_alloc(instance, sizeof(VkSurfaceKHR) * instance->total_icd_count,
    450                                                                     VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
    451         if (pIcdSurface->real_icd_surfaces == NULL) {
    452             loader_instance_heap_free(instance, pIcdSurface);
    453             pIcdSurface = NULL;
    454         } else {
    455             memset(pIcdSurface->real_icd_surfaces, 0, sizeof(VkSurfaceKHR) * instance->total_icd_count);
    456         }
    457     }
    458     return pIcdSurface;
    459 }
    460 
    461 #ifdef VK_USE_PLATFORM_WIN32_KHR
    462 
    463 // Functions for the VK_KHR_win32_surface extension:
    464 
    465 // This is the trampoline entrypoint for CreateWin32SurfaceKHR
    466 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateWin32SurfaceKHR(VkInstance instance,
    467                                                                      const VkWin32SurfaceCreateInfoKHR *pCreateInfo,
    468                                                                      const VkAllocationCallbacks *pAllocator,
    469                                                                      VkSurfaceKHR *pSurface) {
    470     const VkLayerInstanceDispatchTable *disp;
    471     disp = loader_get_instance_layer_dispatch(instance);
    472     VkResult res;
    473 
    474     res = disp->CreateWin32SurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
    475     return res;
    476 }
    477 
    478 // This is the instance chain terminator function for CreateWin32SurfaceKHR
    479 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateWin32SurfaceKHR(VkInstance instance, const VkWin32SurfaceCreateInfoKHR *pCreateInfo,
    480                                                                 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
    481     VkResult vkRes = VK_SUCCESS;
    482     VkIcdSurface *pIcdSurface = NULL;
    483     uint32_t i = 0;
    484 
    485     // Initialize pSurface to NULL just to be safe.
    486     *pSurface = VK_NULL_HANDLE;
    487     // First, check to ensure the appropriate extension was enabled:
    488     struct loader_instance *ptr_instance = loader_get_instance(instance);
    489     if (!ptr_instance->wsi_win32_surface_enabled) {
    490         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
    491                    "VK_KHR_win32_surface extension not enabled.  vkCreateWin32SurfaceKHR not executed!\n");
    492         vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
    493         goto out;
    494     }
    495 
    496     // Next, if so, proceed with the implementation of this function:
    497     pIcdSurface = AllocateIcdSurfaceStruct(ptr_instance, sizeof(pIcdSurface->win_surf.base), sizeof(pIcdSurface->win_surf));
    498     if (pIcdSurface == NULL) {
    499         vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
    500         goto out;
    501     }
    502 
    503     pIcdSurface->win_surf.base.platform = VK_ICD_WSI_PLATFORM_WIN32;
    504     pIcdSurface->win_surf.hinstance = pCreateInfo->hinstance;
    505     pIcdSurface->win_surf.hwnd = pCreateInfo->hwnd;
    506 
    507     // Loop through each ICD and determine if they need to create a surface
    508     for (struct loader_icd_term *icd_term = ptr_instance->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
    509         if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
    510             if (NULL != icd_term->dispatch.CreateWin32SurfaceKHR) {
    511                 vkRes = icd_term->dispatch.CreateWin32SurfaceKHR(icd_term->instance, pCreateInfo, pAllocator,
    512                                                                  &pIcdSurface->real_icd_surfaces[i]);
    513                 if (VK_SUCCESS != vkRes) {
    514                     goto out;
    515                 }
    516             }
    517         }
    518     }
    519 
    520     *pSurface = (VkSurfaceKHR)(pIcdSurface);
    521 
    522 out:
    523 
    524     if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
    525         if (NULL != pIcdSurface->real_icd_surfaces) {
    526             i = 0;
    527             for (struct loader_icd_term *icd_term = ptr_instance->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
    528                 if ((VkSurfaceKHR)NULL != pIcdSurface->real_icd_surfaces[i] && NULL != icd_term->dispatch.DestroySurfaceKHR) {
    529                     icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
    530                 }
    531             }
    532             loader_instance_heap_free(ptr_instance, pIcdSurface->real_icd_surfaces);
    533         }
    534         loader_instance_heap_free(ptr_instance, pIcdSurface);
    535     }
    536 
    537     return vkRes;
    538 }
    539 
    540 // This is the trampoline entrypoint for
    541 // GetPhysicalDeviceWin32PresentationSupportKHR
    542 LOADER_EXPORT VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice physicalDevice,
    543                                                                                             uint32_t queueFamilyIndex) {
    544     VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
    545     const VkLayerInstanceDispatchTable *disp;
    546     disp = loader_get_instance_layer_dispatch(physicalDevice);
    547     VkBool32 res = disp->GetPhysicalDeviceWin32PresentationSupportKHR(unwrapped_phys_dev, queueFamilyIndex);
    548     return res;
    549 }
    550 
    551 // This is the instance chain terminator function for
    552 // GetPhysicalDeviceWin32PresentationSupportKHR
    553 VKAPI_ATTR VkBool32 VKAPI_CALL terminator_GetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice physicalDevice,
    554                                                                                        uint32_t queueFamilyIndex) {
    555     // First, check to ensure the appropriate extension was enabled:
    556     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
    557     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
    558     struct loader_instance *ptr_instance = (struct loader_instance *)icd_term->this_instance;
    559     if (!ptr_instance->wsi_win32_surface_enabled) {
    560         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
    561                    "VK_KHR_win32_surface extension not enabled.  vkGetPhysicalDeviceWin32PresentationSupportKHR not executed!\n");
    562         return VK_SUCCESS;
    563     }
    564 
    565     if (NULL == icd_term->dispatch.GetPhysicalDeviceWin32PresentationSupportKHR) {
    566         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
    567                    "ICD for selected physical device is not exporting vkGetPhysicalDeviceWin32PresentationSupportKHR!\n");
    568         assert(false && "loader: null GetPhysicalDeviceWin32PresentationSupportKHR ICD pointer");
    569     }
    570 
    571     return icd_term->dispatch.GetPhysicalDeviceWin32PresentationSupportKHR(phys_dev_term->phys_dev, queueFamilyIndex);
    572 }
    573 #endif  // VK_USE_PLATFORM_WIN32_KHR
    574 
    575 #ifdef VK_USE_PLATFORM_MIR_KHR
    576 
    577 // Functions for the VK_KHR_mir_surface extension:
    578 
    579 // This is the trampoline entrypoint for CreateMirSurfaceKHR
    580 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateMirSurfaceKHR(VkInstance instance,
    581                                                                    const VkMirSurfaceCreateInfoKHR *pCreateInfo,
    582                                                                    const VkAllocationCallbacks *pAllocator,
    583                                                                    VkSurfaceKHR *pSurface) {
    584     const VkLayerInstanceDispatchTable *disp;
    585     disp = loader_get_instance_layer_dispatch(instance);
    586     VkResult res;
    587 
    588     res = disp->CreateMirSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
    589     return res;
    590 }
    591 
    592 // This is the instance chain terminator function for CreateMirSurfaceKHR
    593 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateMirSurfaceKHR(VkInstance instance, const VkMirSurfaceCreateInfoKHR *pCreateInfo,
    594                                                               const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
    595     VkResult vkRes = VK_SUCCESS;
    596     VkIcdSurface *pIcdSurface = NULL;
    597     uint32_t i = 0;
    598 
    599     // First, check to ensure the appropriate extension was enabled:
    600     struct loader_instance *ptr_instance = loader_get_instance(instance);
    601     if (!ptr_instance->wsi_mir_surface_enabled) {
    602         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
    603                    "VK_KHR_mir_surface extension not enabled.  vkCreateMirSurfaceKHR not executed!\n");
    604         vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
    605         goto out;
    606     }
    607 
    608     // Next, if so, proceed with the implementation of this function:
    609     pIcdSurface = AllocateIcdSurfaceStruct(ptr_instance, sizeof(pIcdSurface->mir_surf.base), sizeof(pIcdSurface->mir_surf));
    610     if (pIcdSurface == NULL) {
    611         vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
    612         goto out;
    613     }
    614 
    615     pIcdSurface->mir_surf.base.platform = VK_ICD_WSI_PLATFORM_MIR;
    616     pIcdSurface->mir_surf.connection = pCreateInfo->connection;
    617     pIcdSurface->mir_surf.mirSurface = pCreateInfo->mirSurface;
    618 
    619     // Loop through each ICD and determine if they need to create a surface
    620     for (struct loader_icd_term *icd_term = ptr_instance->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
    621         if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
    622             if (NULL != icd_term->dispatch.CreateMirSurfaceKHR) {
    623                 vkRes = icd_term->dispatch.CreateMirSurfaceKHR(icd_term->instance, pCreateInfo, pAllocator,
    624                                                                &pIcdSurface->real_icd_surfaces[i]);
    625                 if (VK_SUCCESS != vkRes) {
    626                     goto out;
    627                 }
    628             }
    629         }
    630     }
    631 
    632     *pSurface = (VkSurfaceKHR)pIcdSurface;
    633 
    634 out:
    635 
    636     if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
    637         if (NULL != pIcdSurface->real_icd_surfaces) {
    638             i = 0;
    639             for (struct loader_icd_term *icd_term = ptr_instance->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
    640                 if ((VkSurfaceKHR)NULL != pIcdSurface->real_icd_surfaces[i] && NULL != icd_term->dispatch.DestroySurfaceKHR) {
    641                     icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
    642                 }
    643             }
    644             loader_instance_heap_free(ptr_instance, pIcdSurface->real_icd_surfaces);
    645         }
    646         loader_instance_heap_free(ptr_instance, pIcdSurface);
    647     }
    648 
    649     return vkRes;
    650 }
    651 
    652 // This is the trampoline entrypoint for
    653 // GetPhysicalDeviceMirPresentationSupportKHR
    654 LOADER_EXPORT VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceMirPresentationSupportKHR(VkPhysicalDevice physicalDevice,
    655                                                                                           uint32_t queueFamilyIndex,
    656                                                                                           MirConnection *connection) {
    657     VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
    658     const VkLayerInstanceDispatchTable *disp;
    659     disp = loader_get_instance_layer_dispatch(physicalDevice);
    660     VkBool32 res = disp->GetPhysicalDeviceMirPresentationSupportKHR(unwrapped_phys_dev, queueFamilyIndex, connection);
    661     return res;
    662 }
    663 
    664 // This is the instance chain terminator function for
    665 // GetPhysicalDeviceMirPresentationSupportKHR
    666 VKAPI_ATTR VkBool32 VKAPI_CALL terminator_GetPhysicalDeviceMirPresentationSupportKHR(VkPhysicalDevice physicalDevice,
    667                                                                                      uint32_t queueFamilyIndex,
    668                                                                                      MirConnection *connection) {
    669     // First, check to ensure the appropriate extension was enabled:
    670     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
    671     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
    672     struct loader_instance *ptr_instance = (struct loader_instance *)icd_term->this_instance;
    673     if (!ptr_instance->wsi_mir_surface_enabled) {
    674         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
    675                    "VK_KHR_mir_surface extension not enabled.  vkGetPhysicalDeviceMirPresentationSupportKHR not executed!\n");
    676         return VK_SUCCESS;
    677     }
    678 
    679     if (NULL == icd_term->dispatch.GetPhysicalDeviceMirPresentationSupportKHR) {
    680         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
    681                    "ICD for selected physical device is not exporting vkGetPhysicalDeviceMirPresentationSupportKHR!\n");
    682         assert(false && "loader: null GetPhysicalDeviceMirPresentationSupportKHR ICD pointer");
    683     }
    684 
    685     return icd_term->dispatch.GetPhysicalDeviceMirPresentationSupportKHR(phys_dev_term->phys_dev, queueFamilyIndex, connection);
    686 }
    687 #endif  // VK_USE_PLATFORM_MIR_KHR
    688 
    689 #ifdef VK_USE_PLATFORM_WAYLAND_KHR
    690 
    691 // This is the trampoline entrypoint for CreateWaylandSurfaceKHR
    692 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateWaylandSurfaceKHR(VkInstance instance,
    693                                                                        const VkWaylandSurfaceCreateInfoKHR *pCreateInfo,
    694                                                                        const VkAllocationCallbacks *pAllocator,
    695                                                                        VkSurfaceKHR *pSurface) {
    696     const VkLayerInstanceDispatchTable *disp;
    697     disp = loader_get_instance_layer_dispatch(instance);
    698     VkResult res;
    699 
    700     res = disp->CreateWaylandSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
    701     return res;
    702 }
    703 
    704 // This is the instance chain terminator function for CreateWaylandSurfaceKHR
    705 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateWaylandSurfaceKHR(VkInstance instance,
    706                                                                   const VkWaylandSurfaceCreateInfoKHR *pCreateInfo,
    707                                                                   const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
    708     VkResult vkRes = VK_SUCCESS;
    709     VkIcdSurface *pIcdSurface = NULL;
    710     uint32_t i = 0;
    711 
    712     // First, check to ensure the appropriate extension was enabled:
    713     struct loader_instance *ptr_instance = loader_get_instance(instance);
    714     if (!ptr_instance->wsi_wayland_surface_enabled) {
    715         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
    716                    "VK_KHR_wayland_surface extension not enabled.  vkCreateWaylandSurfaceKHR not executed!\n");
    717         vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
    718         goto out;
    719     }
    720 
    721     // Next, if so, proceed with the implementation of this function:
    722     pIcdSurface = AllocateIcdSurfaceStruct(ptr_instance, sizeof(pIcdSurface->wayland_surf.base), sizeof(pIcdSurface->wayland_surf));
    723     if (pIcdSurface == NULL) {
    724         vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
    725         goto out;
    726     }
    727 
    728     pIcdSurface->wayland_surf.base.platform = VK_ICD_WSI_PLATFORM_WAYLAND;
    729     pIcdSurface->wayland_surf.display = pCreateInfo->display;
    730     pIcdSurface->wayland_surf.surface = pCreateInfo->surface;
    731 
    732     // Loop through each ICD and determine if they need to create a surface
    733     for (struct loader_icd_term *icd_term = ptr_instance->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
    734         if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
    735             if (NULL != icd_term->dispatch.CreateWaylandSurfaceKHR) {
    736                 vkRes = icd_term->dispatch.CreateWaylandSurfaceKHR(icd_term->instance, pCreateInfo, pAllocator,
    737                                                                    &pIcdSurface->real_icd_surfaces[i]);
    738                 if (VK_SUCCESS != vkRes) {
    739                     goto out;
    740                 }
    741             }
    742         }
    743     }
    744 
    745     *pSurface = (VkSurfaceKHR)pIcdSurface;
    746 
    747 out:
    748 
    749     if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
    750         if (NULL != pIcdSurface->real_icd_surfaces) {
    751             i = 0;
    752             for (struct loader_icd_term *icd_term = ptr_instance->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
    753                 if ((VkSurfaceKHR)NULL != pIcdSurface->real_icd_surfaces[i] && NULL != icd_term->dispatch.DestroySurfaceKHR) {
    754                     icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
    755                 }
    756             }
    757             loader_instance_heap_free(ptr_instance, pIcdSurface->real_icd_surfaces);
    758         }
    759         loader_instance_heap_free(ptr_instance, pIcdSurface);
    760     }
    761 
    762     return vkRes;
    763 }
    764 
    765 // This is the trampoline entrypoint for
    766 // GetPhysicalDeviceWaylandPresentationSupportKHR
    767 LOADER_EXPORT VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWaylandPresentationSupportKHR(VkPhysicalDevice physicalDevice,
    768                                                                                               uint32_t queueFamilyIndex,
    769                                                                                               struct wl_display *display) {
    770     VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
    771     const VkLayerInstanceDispatchTable *disp;
    772     disp = loader_get_instance_layer_dispatch(physicalDevice);
    773     VkBool32 res = disp->GetPhysicalDeviceWaylandPresentationSupportKHR(unwrapped_phys_dev, queueFamilyIndex, display);
    774     return res;
    775 }
    776 
    777 // This is the instance chain terminator function for
    778 // GetPhysicalDeviceWaylandPresentationSupportKHR
    779 VKAPI_ATTR VkBool32 VKAPI_CALL terminator_GetPhysicalDeviceWaylandPresentationSupportKHR(VkPhysicalDevice physicalDevice,
    780                                                                                          uint32_t queueFamilyIndex,
    781                                                                                          struct wl_display *display) {
    782     // First, check to ensure the appropriate extension was enabled:
    783     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
    784     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
    785     struct loader_instance *ptr_instance = (struct loader_instance *)icd_term->this_instance;
    786     if (!ptr_instance->wsi_wayland_surface_enabled) {
    787         loader_log(
    788             ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
    789             "VK_KHR_wayland_surface extension not enabled.  vkGetPhysicalDeviceWaylandPresentationSupportKHR not executed!\n");
    790         return VK_SUCCESS;
    791     }
    792 
    793     if (NULL == icd_term->dispatch.GetPhysicalDeviceWaylandPresentationSupportKHR) {
    794         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
    795                    "ICD for selected physical device is not exporting vkGetPhysicalDeviceWaylandPresentationSupportKHR!\n");
    796         assert(false && "loader: null GetPhysicalDeviceWaylandPresentationSupportKHR ICD pointer");
    797     }
    798 
    799     return icd_term->dispatch.GetPhysicalDeviceWaylandPresentationSupportKHR(phys_dev_term->phys_dev, queueFamilyIndex, display);
    800 }
    801 #endif  // VK_USE_PLATFORM_WAYLAND_KHR
    802 
    803 #ifdef VK_USE_PLATFORM_XCB_KHR
    804 
    805 // Functions for the VK_KHR_xcb_surface extension:
    806 
    807 // This is the trampoline entrypoint for CreateXcbSurfaceKHR
    808 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateXcbSurfaceKHR(VkInstance instance,
    809                                                                    const VkXcbSurfaceCreateInfoKHR *pCreateInfo,
    810                                                                    const VkAllocationCallbacks *pAllocator,
    811                                                                    VkSurfaceKHR *pSurface) {
    812     const VkLayerInstanceDispatchTable *disp;
    813     disp = loader_get_instance_layer_dispatch(instance);
    814     VkResult res;
    815 
    816     res = disp->CreateXcbSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
    817     return res;
    818 }
    819 
    820 // This is the instance chain terminator function for CreateXcbSurfaceKHR
    821 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateXcbSurfaceKHR(VkInstance instance, const VkXcbSurfaceCreateInfoKHR *pCreateInfo,
    822                                                               const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
    823     VkResult vkRes = VK_SUCCESS;
    824     VkIcdSurface *pIcdSurface = NULL;
    825     uint32_t i = 0;
    826 
    827     // First, check to ensure the appropriate extension was enabled:
    828     struct loader_instance *ptr_instance = loader_get_instance(instance);
    829     if (!ptr_instance->wsi_xcb_surface_enabled) {
    830         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
    831                    "VK_KHR_xcb_surface extension not enabled.  vkCreateXcbSurfaceKHR not executed!\n");
    832         vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
    833         goto out;
    834     }
    835 
    836     // Next, if so, proceed with the implementation of this function:
    837     pIcdSurface = AllocateIcdSurfaceStruct(ptr_instance, sizeof(pIcdSurface->xcb_surf.base), sizeof(pIcdSurface->xcb_surf));
    838     if (pIcdSurface == NULL) {
    839         vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
    840         goto out;
    841     }
    842 
    843     pIcdSurface->xcb_surf.base.platform = VK_ICD_WSI_PLATFORM_XCB;
    844     pIcdSurface->xcb_surf.connection = pCreateInfo->connection;
    845     pIcdSurface->xcb_surf.window = pCreateInfo->window;
    846 
    847     // Loop through each ICD and determine if they need to create a surface
    848     for (struct loader_icd_term *icd_term = ptr_instance->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
    849         if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
    850             if (NULL != icd_term->dispatch.CreateXcbSurfaceKHR) {
    851                 vkRes = icd_term->dispatch.CreateXcbSurfaceKHR(icd_term->instance, pCreateInfo, pAllocator,
    852                                                                &pIcdSurface->real_icd_surfaces[i]);
    853                 if (VK_SUCCESS != vkRes) {
    854                     goto out;
    855                 }
    856             }
    857         }
    858     }
    859 
    860     *pSurface = (VkSurfaceKHR)pIcdSurface;
    861 
    862 out:
    863 
    864     if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
    865         if (NULL != pIcdSurface->real_icd_surfaces) {
    866             i = 0;
    867             for (struct loader_icd_term *icd_term = ptr_instance->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
    868                 if ((VkSurfaceKHR)NULL != pIcdSurface->real_icd_surfaces[i] && NULL != icd_term->dispatch.DestroySurfaceKHR) {
    869                     icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
    870                 }
    871             }
    872             loader_instance_heap_free(ptr_instance, pIcdSurface->real_icd_surfaces);
    873         }
    874         loader_instance_heap_free(ptr_instance, pIcdSurface);
    875     }
    876 
    877     return vkRes;
    878 }
    879 
    880 // This is the trampoline entrypoint for
    881 // GetPhysicalDeviceXcbPresentationSupportKHR
    882 LOADER_EXPORT VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceXcbPresentationSupportKHR(VkPhysicalDevice physicalDevice,
    883                                                                                           uint32_t queueFamilyIndex,
    884                                                                                           xcb_connection_t *connection,
    885                                                                                           xcb_visualid_t visual_id) {
    886     VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
    887     const VkLayerInstanceDispatchTable *disp;
    888     disp = loader_get_instance_layer_dispatch(physicalDevice);
    889     VkBool32 res = disp->GetPhysicalDeviceXcbPresentationSupportKHR(unwrapped_phys_dev, queueFamilyIndex, connection, visual_id);
    890     return res;
    891 }
    892 
    893 // This is the instance chain terminator function for
    894 // GetPhysicalDeviceXcbPresentationSupportKHR
    895 VKAPI_ATTR VkBool32 VKAPI_CALL terminator_GetPhysicalDeviceXcbPresentationSupportKHR(VkPhysicalDevice physicalDevice,
    896                                                                                      uint32_t queueFamilyIndex,
    897                                                                                      xcb_connection_t *connection,
    898                                                                                      xcb_visualid_t visual_id) {
    899     // First, check to ensure the appropriate extension was enabled:
    900     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
    901     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
    902     struct loader_instance *ptr_instance = (struct loader_instance *)icd_term->this_instance;
    903     if (!ptr_instance->wsi_xcb_surface_enabled) {
    904         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
    905                    "VK_KHR_xcb_surface extension not enabled.  vkGetPhysicalDeviceXcbPresentationSupportKHR not executed!\n");
    906         return VK_SUCCESS;
    907     }
    908 
    909     if (NULL == icd_term->dispatch.GetPhysicalDeviceXcbPresentationSupportKHR) {
    910         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
    911                    "ICD for selected physical device is not exporting vkGetPhysicalDeviceXcbPresentationSupportKHR!\n");
    912         assert(false && "loader: null GetPhysicalDeviceXcbPresentationSupportKHR ICD pointer");
    913     }
    914 
    915     return icd_term->dispatch.GetPhysicalDeviceXcbPresentationSupportKHR(phys_dev_term->phys_dev, queueFamilyIndex, connection,
    916                                                                          visual_id);
    917 }
    918 #endif  // VK_USE_PLATFORM_XCB_KHR
    919 
    920 #ifdef VK_USE_PLATFORM_XLIB_KHR
    921 
    922 // Functions for the VK_KHR_xlib_surface extension:
    923 
    924 // This is the trampoline entrypoint for CreateXlibSurfaceKHR
    925 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateXlibSurfaceKHR(VkInstance instance,
    926                                                                     const VkXlibSurfaceCreateInfoKHR *pCreateInfo,
    927                                                                     const VkAllocationCallbacks *pAllocator,
    928                                                                     VkSurfaceKHR *pSurface) {
    929     const VkLayerInstanceDispatchTable *disp;
    930     disp = loader_get_instance_layer_dispatch(instance);
    931     VkResult res;
    932 
    933     res = disp->CreateXlibSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
    934     return res;
    935 }
    936 
    937 // This is the instance chain terminator function for CreateXlibSurfaceKHR
    938 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateXlibSurfaceKHR(VkInstance instance, const VkXlibSurfaceCreateInfoKHR *pCreateInfo,
    939                                                                const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
    940     VkResult vkRes = VK_SUCCESS;
    941     VkIcdSurface *pIcdSurface = NULL;
    942     uint32_t i = 0;
    943 
    944     // First, check to ensure the appropriate extension was enabled:
    945     struct loader_instance *ptr_instance = loader_get_instance(instance);
    946     if (!ptr_instance->wsi_xlib_surface_enabled) {
    947         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
    948                    "VK_KHR_xlib_surface extension not enabled.  vkCreateXlibSurfaceKHR not executed!\n");
    949         vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
    950         goto out;
    951     }
    952 
    953     // Next, if so, proceed with the implementation of this function:
    954     pIcdSurface = AllocateIcdSurfaceStruct(ptr_instance, sizeof(pIcdSurface->xlib_surf.base), sizeof(pIcdSurface->xlib_surf));
    955     if (pIcdSurface == NULL) {
    956         vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
    957         goto out;
    958     }
    959 
    960     pIcdSurface->xlib_surf.base.platform = VK_ICD_WSI_PLATFORM_XLIB;
    961     pIcdSurface->xlib_surf.dpy = pCreateInfo->dpy;
    962     pIcdSurface->xlib_surf.window = pCreateInfo->window;
    963 
    964     // Loop through each ICD and determine if they need to create a surface
    965     for (struct loader_icd_term *icd_term = ptr_instance->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
    966         if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
    967             if (NULL != icd_term->dispatch.CreateXlibSurfaceKHR) {
    968                 vkRes = icd_term->dispatch.CreateXlibSurfaceKHR(icd_term->instance, pCreateInfo, pAllocator,
    969                                                                 &pIcdSurface->real_icd_surfaces[i]);
    970                 if (VK_SUCCESS != vkRes) {
    971                     goto out;
    972                 }
    973             }
    974         }
    975     }
    976 
    977     *pSurface = (VkSurfaceKHR)pIcdSurface;
    978 
    979 out:
    980 
    981     if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
    982         if (NULL != pIcdSurface->real_icd_surfaces) {
    983             i = 0;
    984             for (struct loader_icd_term *icd_term = ptr_instance->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
    985                 if ((VkSurfaceKHR)NULL != pIcdSurface->real_icd_surfaces[i] && NULL != icd_term->dispatch.DestroySurfaceKHR) {
    986                     icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
    987                 }
    988             }
    989             loader_instance_heap_free(ptr_instance, pIcdSurface->real_icd_surfaces);
    990         }
    991         loader_instance_heap_free(ptr_instance, pIcdSurface);
    992     }
    993 
    994     return vkRes;
    995 }
    996 
    997 // This is the trampoline entrypoint for
    998 // GetPhysicalDeviceXlibPresentationSupportKHR
    999 LOADER_EXPORT VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceXlibPresentationSupportKHR(VkPhysicalDevice physicalDevice,
   1000                                                                                            uint32_t queueFamilyIndex, Display *dpy,
   1001                                                                                            VisualID visualID) {
   1002     VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
   1003     const VkLayerInstanceDispatchTable *disp;
   1004     disp = loader_get_instance_layer_dispatch(physicalDevice);
   1005     VkBool32 res = disp->GetPhysicalDeviceXlibPresentationSupportKHR(unwrapped_phys_dev, queueFamilyIndex, dpy, visualID);
   1006     return res;
   1007 }
   1008 
   1009 // This is the instance chain terminator function for
   1010 // GetPhysicalDeviceXlibPresentationSupportKHR
   1011 VKAPI_ATTR VkBool32 VKAPI_CALL terminator_GetPhysicalDeviceXlibPresentationSupportKHR(VkPhysicalDevice physicalDevice,
   1012                                                                                       uint32_t queueFamilyIndex, Display *dpy,
   1013                                                                                       VisualID visualID) {
   1014     // First, check to ensure the appropriate extension was enabled:
   1015     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
   1016     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
   1017     struct loader_instance *ptr_instance = (struct loader_instance *)icd_term->this_instance;
   1018     if (!ptr_instance->wsi_xlib_surface_enabled) {
   1019         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
   1020                    "VK_KHR_xlib_surface extension not enabled.  vkGetPhysicalDeviceXlibPresentationSupportKHR not executed!\n");
   1021         return VK_SUCCESS;
   1022     }
   1023 
   1024     if (NULL == icd_term->dispatch.GetPhysicalDeviceXlibPresentationSupportKHR) {
   1025         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
   1026                    "ICD for selected physical device is not exporting vkGetPhysicalDeviceXlibPresentationSupportKHR!\n");
   1027         assert(false && "loader: null GetPhysicalDeviceXlibPresentationSupportKHR ICD pointer");
   1028     }
   1029 
   1030     return icd_term->dispatch.GetPhysicalDeviceXlibPresentationSupportKHR(phys_dev_term->phys_dev, queueFamilyIndex, dpy, visualID);
   1031 }
   1032 #endif  // VK_USE_PLATFORM_XLIB_KHR
   1033 
   1034 #ifdef VK_USE_PLATFORM_ANDROID_KHR
   1035 
   1036 // Functions for the VK_KHR_android_surface extension:
   1037 
   1038 // This is the trampoline entrypoint for CreateAndroidSurfaceKHR
   1039 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateAndroidSurfaceKHR(VkInstance instance, ANativeWindow *window,
   1040                                                                        const VkAllocationCallbacks *pAllocator,
   1041                                                                        VkSurfaceKHR *pSurface) {
   1042     const VkLayerInstanceDispatchTable *disp;
   1043     disp = loader_get_instance_layer_dispatch(instance);
   1044     VkResult res;
   1045 
   1046     res = disp->CreateAndroidSurfaceKHR(instance, window, pAllocator, pSurface);
   1047     return res;
   1048 }
   1049 
   1050 // This is the instance chain terminator function for CreateAndroidSurfaceKHR
   1051 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateAndroidSurfaceKHR(VkInstance instance, Window window,
   1052                                                                   const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
   1053     // First, check to ensure the appropriate extension was enabled:
   1054     struct loader_instance *ptr_instance = loader_get_instance(instance);
   1055     if (!ptr_instance->wsi_display_enabled) {
   1056         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
   1057                    "VK_KHR_display extension not enabled.  vkCreateAndroidSurfaceKHR not executed!\n");
   1058         return VK_ERROR_EXTENSION_NOT_PRESENT;
   1059     }
   1060 
   1061     // Next, if so, proceed with the implementation of this function:
   1062     VkIcdSurfaceAndroid *pIcdSurface =
   1063         loader_instance_heap_alloc(ptr_instance, sizeof(VkIcdSurfaceAndroid), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
   1064     if (pIcdSurface == NULL) {
   1065         return VK_ERROR_OUT_OF_HOST_MEMORY;
   1066     }
   1067 
   1068     pIcdSurface->base.platform = VK_ICD_WSI_PLATFORM_ANDROID;
   1069     pIcdSurface->dpy = dpy;
   1070     pIcdSurface->window = window;
   1071 
   1072     *pSurface = (VkSurfaceKHR)pIcdSurface;
   1073 
   1074     return VK_SUCCESS;
   1075 }
   1076 
   1077 #endif  // VK_USE_PLATFORM_ANDROID_KHR
   1078 
   1079 // Functions for the VK_KHR_display instance extension:
   1080 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice,
   1081                                                                                      uint32_t *pPropertyCount,
   1082                                                                                      VkDisplayPropertiesKHR *pProperties) {
   1083     VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
   1084     const VkLayerInstanceDispatchTable *disp;
   1085     disp = loader_get_instance_layer_dispatch(physicalDevice);
   1086     VkResult res = disp->GetPhysicalDeviceDisplayPropertiesKHR(unwrapped_phys_dev, pPropertyCount, pProperties);
   1087     return res;
   1088 }
   1089 
   1090 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice,
   1091                                                                                 uint32_t *pPropertyCount,
   1092                                                                                 VkDisplayPropertiesKHR *pProperties) {
   1093     // First, check to ensure the appropriate extension was enabled:
   1094     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
   1095     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
   1096     struct loader_instance *ptr_instance = (struct loader_instance *)icd_term->this_instance;
   1097     if (!ptr_instance->wsi_display_enabled) {
   1098         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
   1099                    "VK_KHR_display extension not enabled.  vkGetPhysicalDeviceDisplayPropertiesKHR not executed!\n");
   1100         return VK_SUCCESS;
   1101     }
   1102 
   1103     if (NULL == icd_term->dispatch.GetPhysicalDeviceDisplayPropertiesKHR) {
   1104         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
   1105                    "ICD for selected physical device is not exporting vkGetPhysicalDeviceDisplayPropertiesKHR!\n");
   1106         assert(false && "loader: null GetPhysicalDeviceDisplayPropertiesKHR ICD pointer");
   1107     }
   1108 
   1109     return icd_term->dispatch.GetPhysicalDeviceDisplayPropertiesKHR(phys_dev_term->phys_dev, pPropertyCount, pProperties);
   1110 }
   1111 
   1112 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayPlanePropertiesKHR(
   1113     VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, VkDisplayPlanePropertiesKHR *pProperties) {
   1114     VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
   1115     const VkLayerInstanceDispatchTable *disp;
   1116     disp = loader_get_instance_layer_dispatch(physicalDevice);
   1117     VkResult res = disp->GetPhysicalDeviceDisplayPlanePropertiesKHR(unwrapped_phys_dev, pPropertyCount, pProperties);
   1118     return res;
   1119 }
   1120 
   1121 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceDisplayPlanePropertiesKHR(VkPhysicalDevice physicalDevice,
   1122                                                                                      uint32_t *pPropertyCount,
   1123                                                                                      VkDisplayPlanePropertiesKHR *pProperties) {
   1124     // First, check to ensure the appropriate extension was enabled:
   1125     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
   1126     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
   1127     struct loader_instance *ptr_instance = (struct loader_instance *)icd_term->this_instance;
   1128     if (!ptr_instance->wsi_display_enabled) {
   1129         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
   1130                    "VK_KHR_display extension not enabled.  vkGetPhysicalDeviceDisplayPlanePropertiesKHR not executed!\n");
   1131         return VK_SUCCESS;
   1132     }
   1133 
   1134     if (NULL == icd_term->dispatch.GetPhysicalDeviceDisplayPlanePropertiesKHR) {
   1135         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
   1136                    "ICD for selected physical device is not exporting vkGetPhysicalDeviceDisplayPlanePropertiesKHR!\n");
   1137         assert(false && "loader: null GetPhysicalDeviceDisplayPlanePropertiesKHR ICD pointer");
   1138     }
   1139 
   1140     return icd_term->dispatch.GetPhysicalDeviceDisplayPlanePropertiesKHR(phys_dev_term->phys_dev, pPropertyCount, pProperties);
   1141 }
   1142 
   1143 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice,
   1144                                                                                    uint32_t planeIndex, uint32_t *pDisplayCount,
   1145                                                                                    VkDisplayKHR *pDisplays) {
   1146     VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
   1147     const VkLayerInstanceDispatchTable *disp;
   1148     disp = loader_get_instance_layer_dispatch(physicalDevice);
   1149     VkResult res = disp->GetDisplayPlaneSupportedDisplaysKHR(unwrapped_phys_dev, planeIndex, pDisplayCount, pDisplays);
   1150     return res;
   1151 }
   1152 
   1153 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice, uint32_t planeIndex,
   1154                                                                               uint32_t *pDisplayCount, VkDisplayKHR *pDisplays) {
   1155     // First, check to ensure the appropriate extension was enabled:
   1156     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
   1157     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
   1158     struct loader_instance *ptr_instance = (struct loader_instance *)icd_term->this_instance;
   1159     if (!ptr_instance->wsi_display_enabled) {
   1160         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
   1161                    "VK_KHR_display extension not enabled.  vkGetDisplayPlaneSupportedDisplaysKHR not executed!\n");
   1162         return VK_SUCCESS;
   1163     }
   1164 
   1165     if (NULL == icd_term->dispatch.GetDisplayPlaneSupportedDisplaysKHR) {
   1166         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
   1167                    "ICD for selected physical device is not exporting vkGetDisplayPlaneSupportedDisplaysKHR!\n");
   1168         assert(false && "loader: null GetDisplayPlaneSupportedDisplaysKHR ICD pointer");
   1169     }
   1170 
   1171     return icd_term->dispatch.GetDisplayPlaneSupportedDisplaysKHR(phys_dev_term->phys_dev, planeIndex, pDisplayCount, pDisplays);
   1172 }
   1173 
   1174 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
   1175                                                                            uint32_t *pPropertyCount,
   1176                                                                            VkDisplayModePropertiesKHR *pProperties) {
   1177     VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
   1178     const VkLayerInstanceDispatchTable *disp;
   1179     disp = loader_get_instance_layer_dispatch(physicalDevice);
   1180     VkResult res = disp->GetDisplayModePropertiesKHR(unwrapped_phys_dev, display, pPropertyCount, pProperties);
   1181     return res;
   1182 }
   1183 
   1184 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
   1185                                                                       uint32_t *pPropertyCount,
   1186                                                                       VkDisplayModePropertiesKHR *pProperties) {
   1187     // First, check to ensure the appropriate extension was enabled:
   1188     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
   1189     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
   1190     struct loader_instance *ptr_instance = (struct loader_instance *)icd_term->this_instance;
   1191     if (!ptr_instance->wsi_display_enabled) {
   1192         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
   1193                    "VK_KHR_display extension not enabled.  vkGetDisplayModePropertiesKHR not executed!\n");
   1194         return VK_SUCCESS;
   1195     }
   1196 
   1197     if (NULL == icd_term->dispatch.GetDisplayModePropertiesKHR) {
   1198         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
   1199                    "ICD for selected physical device is not exporting vkGetDisplayModePropertiesKHR!\n");
   1200         assert(false && "loader: null GetDisplayModePropertiesKHR ICD pointer");
   1201     }
   1202 
   1203     return icd_term->dispatch.GetDisplayModePropertiesKHR(phys_dev_term->phys_dev, display, pPropertyCount, pProperties);
   1204 }
   1205 
   1206 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDisplayModeKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
   1207                                                                     const VkDisplayModeCreateInfoKHR *pCreateInfo,
   1208                                                                     const VkAllocationCallbacks *pAllocator,
   1209                                                                     VkDisplayModeKHR *pMode) {
   1210     VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
   1211     const VkLayerInstanceDispatchTable *disp;
   1212     disp = loader_get_instance_layer_dispatch(physicalDevice);
   1213     VkResult res = disp->CreateDisplayModeKHR(unwrapped_phys_dev, display, pCreateInfo, pAllocator, pMode);
   1214     return res;
   1215 }
   1216 
   1217 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDisplayModeKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
   1218                                                                const VkDisplayModeCreateInfoKHR *pCreateInfo,
   1219                                                                const VkAllocationCallbacks *pAllocator, VkDisplayModeKHR *pMode) {
   1220     // First, check to ensure the appropriate extension was enabled:
   1221     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
   1222     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
   1223     struct loader_instance *ptr_instance = (struct loader_instance *)icd_term->this_instance;
   1224     if (!ptr_instance->wsi_display_enabled) {
   1225         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
   1226                    "VK_KHR_display extension not enabled.  vkCreateDisplayModeKHR not executed!\n");
   1227         return VK_ERROR_EXTENSION_NOT_PRESENT;
   1228     }
   1229 
   1230     if (NULL == icd_term->dispatch.CreateDisplayModeKHR) {
   1231         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
   1232                    "ICD for selected physical device is not exporting vkCreateDisplayModeKHR!\n");
   1233         assert(false && "loader: null CreateDisplayModeKHR ICD pointer");
   1234     }
   1235 
   1236     return icd_term->dispatch.CreateDisplayModeKHR(phys_dev_term->phys_dev, display, pCreateInfo, pAllocator, pMode);
   1237 }
   1238 
   1239 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayPlaneCapabilitiesKHR(VkPhysicalDevice physicalDevice,
   1240                                                                               VkDisplayModeKHR mode, uint32_t planeIndex,
   1241                                                                               VkDisplayPlaneCapabilitiesKHR *pCapabilities) {
   1242     VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
   1243     const VkLayerInstanceDispatchTable *disp;
   1244     disp = loader_get_instance_layer_dispatch(physicalDevice);
   1245     VkResult res = disp->GetDisplayPlaneCapabilitiesKHR(unwrapped_phys_dev, mode, planeIndex, pCapabilities);
   1246     return res;
   1247 }
   1248 
   1249 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDisplayPlaneCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkDisplayModeKHR mode,
   1250                                                                          uint32_t planeIndex,
   1251                                                                          VkDisplayPlaneCapabilitiesKHR *pCapabilities) {
   1252     // First, check to ensure the appropriate extension was enabled:
   1253     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
   1254     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
   1255     struct loader_instance *ptr_instance = (struct loader_instance *)icd_term->this_instance;
   1256     if (!ptr_instance->wsi_display_enabled) {
   1257         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
   1258                    "VK_KHR_display extension not enabled.  vkGetDisplayPlaneCapabilitiesKHR not executed!\n");
   1259         return VK_SUCCESS;
   1260     }
   1261 
   1262     if (NULL == icd_term->dispatch.GetDisplayPlaneCapabilitiesKHR) {
   1263         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
   1264                    "ICD for selected physical device is not exporting vkGetDisplayPlaneCapabilitiesKHR!\n");
   1265         assert(false && "loader: null GetDisplayPlaneCapabilitiesKHR ICD pointer");
   1266     }
   1267 
   1268     return icd_term->dispatch.GetDisplayPlaneCapabilitiesKHR(phys_dev_term->phys_dev, mode, planeIndex, pCapabilities);
   1269 }
   1270 
   1271 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDisplayPlaneSurfaceKHR(VkInstance instance,
   1272                                                                             const VkDisplaySurfaceCreateInfoKHR *pCreateInfo,
   1273                                                                             const VkAllocationCallbacks *pAllocator,
   1274                                                                             VkSurfaceKHR *pSurface) {
   1275     const VkLayerInstanceDispatchTable *disp;
   1276     disp = loader_get_instance_layer_dispatch(instance);
   1277     VkResult res;
   1278 
   1279     res = disp->CreateDisplayPlaneSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
   1280     return res;
   1281 }
   1282 
   1283 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDisplayPlaneSurfaceKHR(VkInstance instance,
   1284                                                                        const VkDisplaySurfaceCreateInfoKHR *pCreateInfo,
   1285                                                                        const VkAllocationCallbacks *pAllocator,
   1286                                                                        VkSurfaceKHR *pSurface) {
   1287     struct loader_instance *inst = loader_get_instance(instance);
   1288     VkIcdSurface *pIcdSurface = NULL;
   1289     VkResult vkRes = VK_SUCCESS;
   1290     uint32_t i = 0;
   1291 
   1292     if (!inst->wsi_display_enabled) {
   1293         loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
   1294                    "VK_KHR_surface extension not enabled.  vkCreateDisplayPlaneSurfaceKHR not executed!\n");
   1295         vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
   1296         goto out;
   1297     }
   1298 
   1299     // Next, if so, proceed with the implementation of this function:
   1300     pIcdSurface = AllocateIcdSurfaceStruct(inst, sizeof(pIcdSurface->display_surf.base), sizeof(pIcdSurface->display_surf));
   1301     if (pIcdSurface == NULL) {
   1302         vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
   1303         goto out;
   1304     }
   1305 
   1306     pIcdSurface->display_surf.base.platform = VK_ICD_WSI_PLATFORM_DISPLAY;
   1307     pIcdSurface->display_surf.displayMode = pCreateInfo->displayMode;
   1308     pIcdSurface->display_surf.planeIndex = pCreateInfo->planeIndex;
   1309     pIcdSurface->display_surf.planeStackIndex = pCreateInfo->planeStackIndex;
   1310     pIcdSurface->display_surf.transform = pCreateInfo->transform;
   1311     pIcdSurface->display_surf.globalAlpha = pCreateInfo->globalAlpha;
   1312     pIcdSurface->display_surf.alphaMode = pCreateInfo->alphaMode;
   1313     pIcdSurface->display_surf.imageExtent = pCreateInfo->imageExtent;
   1314 
   1315     // Loop through each ICD and determine if they need to create a surface
   1316     for (struct loader_icd_term *icd_term = inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
   1317         if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
   1318             if (NULL != icd_term->dispatch.CreateDisplayPlaneSurfaceKHR) {
   1319                 vkRes = icd_term->dispatch.CreateDisplayPlaneSurfaceKHR(icd_term->instance, pCreateInfo, pAllocator,
   1320                                                                         &pIcdSurface->real_icd_surfaces[i]);
   1321                 if (VK_SUCCESS != vkRes) {
   1322                     goto out;
   1323                 }
   1324             }
   1325         }
   1326     }
   1327 
   1328     *pSurface = (VkSurfaceKHR)pIcdSurface;
   1329 
   1330 out:
   1331 
   1332     if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
   1333         if (NULL != pIcdSurface->real_icd_surfaces) {
   1334             i = 0;
   1335             for (struct loader_icd_term *icd_term = inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
   1336                 if ((VkSurfaceKHR)NULL != pIcdSurface->real_icd_surfaces[i] && NULL != icd_term->dispatch.DestroySurfaceKHR) {
   1337                     icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
   1338                 }
   1339             }
   1340             loader_instance_heap_free(inst, pIcdSurface->real_icd_surfaces);
   1341         }
   1342         loader_instance_heap_free(inst, pIcdSurface);
   1343     }
   1344 
   1345     return vkRes;
   1346 }
   1347 
   1348 // EXT_display_swapchain Extension command
   1349 
   1350 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateSharedSwapchainsKHR(VkDevice device, uint32_t swapchainCount,
   1351                                                                          const VkSwapchainCreateInfoKHR *pCreateInfos,
   1352                                                                          const VkAllocationCallbacks *pAllocator,
   1353                                                                          VkSwapchainKHR *pSwapchains) {
   1354     const VkLayerDispatchTable *disp;
   1355     disp = loader_get_dispatch(device);
   1356     return disp->CreateSharedSwapchainsKHR(device, swapchainCount, pCreateInfos, pAllocator, pSwapchains);
   1357 }
   1358 
   1359 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateSharedSwapchainsKHR(VkDevice device, uint32_t swapchainCount,
   1360                                                                     const VkSwapchainCreateInfoKHR *pCreateInfos,
   1361                                                                     const VkAllocationCallbacks *pAllocator,
   1362                                                                     VkSwapchainKHR *pSwapchains) {
   1363     uint32_t icd_index = 0;
   1364     struct loader_device *dev;
   1365     struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, &icd_index);
   1366     if (NULL != icd_term && NULL != icd_term->dispatch.CreateSharedSwapchainsKHR) {
   1367         VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pCreateInfos->surface;
   1368         if (NULL != icd_surface->real_icd_surfaces) {
   1369             if ((VkSurfaceKHR)NULL != icd_surface->real_icd_surfaces[icd_index]) {
   1370                 // We found the ICD, and there is an ICD KHR surface
   1371                 // associated with it, so copy the CreateInfo struct
   1372                 // and point it at the ICD's surface.
   1373                 VkSwapchainCreateInfoKHR *pCreateCopy = loader_stack_alloc(sizeof(VkSwapchainCreateInfoKHR) * swapchainCount);
   1374                 if (NULL == pCreateCopy) {
   1375                     return VK_ERROR_OUT_OF_HOST_MEMORY;
   1376                 }
   1377                 memcpy(pCreateCopy, pCreateInfos, sizeof(VkSwapchainCreateInfoKHR) * swapchainCount);
   1378                 for (uint32_t sc = 0; sc < swapchainCount; sc++) {
   1379                     pCreateCopy[sc].surface = icd_surface->real_icd_surfaces[icd_index];
   1380                 }
   1381                 return icd_term->dispatch.CreateSharedSwapchainsKHR(device, swapchainCount, pCreateCopy, pAllocator, pSwapchains);
   1382             }
   1383         }
   1384         return icd_term->dispatch.CreateSharedSwapchainsKHR(device, swapchainCount, pCreateInfos, pAllocator, pSwapchains);
   1385     }
   1386     return VK_SUCCESS;
   1387 }
   1388 
   1389 bool wsi_swapchain_instance_gpa(struct loader_instance *ptr_instance, const char *name, void **addr) {
   1390     *addr = NULL;
   1391 
   1392     // Functions for the VK_KHR_surface extension:
   1393     if (!strcmp("vkDestroySurfaceKHR", name)) {
   1394         *addr = ptr_instance->wsi_surface_enabled ? (void *)vkDestroySurfaceKHR : NULL;
   1395         return true;
   1396     }
   1397     if (!strcmp("vkGetPhysicalDeviceSurfaceSupportKHR", name)) {
   1398         *addr = ptr_instance->wsi_surface_enabled ? (void *)vkGetPhysicalDeviceSurfaceSupportKHR : NULL;
   1399         return true;
   1400     }
   1401     if (!strcmp("vkGetPhysicalDeviceSurfaceCapabilitiesKHR", name)) {
   1402         *addr = ptr_instance->wsi_surface_enabled ? (void *)vkGetPhysicalDeviceSurfaceCapabilitiesKHR : NULL;
   1403         return true;
   1404     }
   1405     if (!strcmp("vkGetPhysicalDeviceSurfaceFormatsKHR", name)) {
   1406         *addr = ptr_instance->wsi_surface_enabled ? (void *)vkGetPhysicalDeviceSurfaceFormatsKHR : NULL;
   1407         return true;
   1408     }
   1409     if (!strcmp("vkGetPhysicalDeviceSurfacePresentModesKHR", name)) {
   1410         *addr = ptr_instance->wsi_surface_enabled ? (void *)vkGetPhysicalDeviceSurfacePresentModesKHR : NULL;
   1411         return true;
   1412     }
   1413 
   1414     // Functions for the VK_KHR_swapchain extension:
   1415 
   1416     // Note: This is a device extension, and its functions are statically
   1417     // exported from the loader.  Per Khronos decisions, the loader's GIPA
   1418     // function will return the trampoline function for such device-extension
   1419     // functions, regardless of whether the extension has been enabled.
   1420     if (!strcmp("vkCreateSwapchainKHR", name)) {
   1421         *addr = (void *)vkCreateSwapchainKHR;
   1422         return true;
   1423     }
   1424     if (!strcmp("vkDestroySwapchainKHR", name)) {
   1425         *addr = (void *)vkDestroySwapchainKHR;
   1426         return true;
   1427     }
   1428     if (!strcmp("vkGetSwapchainImagesKHR", name)) {
   1429         *addr = (void *)vkGetSwapchainImagesKHR;
   1430         return true;
   1431     }
   1432     if (!strcmp("vkAcquireNextImageKHR", name)) {
   1433         *addr = (void *)vkAcquireNextImageKHR;
   1434         return true;
   1435     }
   1436     if (!strcmp("vkQueuePresentKHR", name)) {
   1437         *addr = (void *)vkQueuePresentKHR;
   1438         return true;
   1439     }
   1440 
   1441 #ifdef VK_USE_PLATFORM_WIN32_KHR
   1442 
   1443     // Functions for the VK_KHR_win32_surface extension:
   1444     if (!strcmp("vkCreateWin32SurfaceKHR", name)) {
   1445         *addr = ptr_instance->wsi_win32_surface_enabled ? (void *)vkCreateWin32SurfaceKHR : NULL;
   1446         return true;
   1447     }
   1448     if (!strcmp("vkGetPhysicalDeviceWin32PresentationSupportKHR", name)) {
   1449         *addr = ptr_instance->wsi_win32_surface_enabled ? (void *)vkGetPhysicalDeviceWin32PresentationSupportKHR : NULL;
   1450         return true;
   1451     }
   1452 #endif  // VK_USE_PLATFORM_WIN32_KHR
   1453 #ifdef VK_USE_PLATFORM_MIR_KHR
   1454 
   1455     // Functions for the VK_KHR_mir_surface extension:
   1456     if (!strcmp("vkCreateMirSurfaceKHR", name)) {
   1457         *addr = ptr_instance->wsi_mir_surface_enabled ? (void *)vkCreateMirSurfaceKHR : NULL;
   1458         return true;
   1459     }
   1460     if (!strcmp("vkGetPhysicalDeviceMirPresentationSupportKHR", name)) {
   1461         *addr = ptr_instance->wsi_mir_surface_enabled ? (void *)vkGetPhysicalDeviceMirPresentationSupportKHR : NULL;
   1462         return true;
   1463     }
   1464 #endif  // VK_USE_PLATFORM_MIR_KHR
   1465 #ifdef VK_USE_PLATFORM_WAYLAND_KHR
   1466 
   1467     // Functions for the VK_KHR_wayland_surface extension:
   1468     if (!strcmp("vkCreateWaylandSurfaceKHR", name)) {
   1469         *addr = ptr_instance->wsi_wayland_surface_enabled ? (void *)vkCreateWaylandSurfaceKHR : NULL;
   1470         return true;
   1471     }
   1472     if (!strcmp("vkGetPhysicalDeviceWaylandPresentationSupportKHR", name)) {
   1473         *addr = ptr_instance->wsi_wayland_surface_enabled ? (void *)vkGetPhysicalDeviceWaylandPresentationSupportKHR : NULL;
   1474         return true;
   1475     }
   1476 #endif  // VK_USE_PLATFORM_WAYLAND_KHR
   1477 #ifdef VK_USE_PLATFORM_XCB_KHR
   1478 
   1479     // Functions for the VK_KHR_xcb_surface extension:
   1480     if (!strcmp("vkCreateXcbSurfaceKHR", name)) {
   1481         *addr = ptr_instance->wsi_xcb_surface_enabled ? (void *)vkCreateXcbSurfaceKHR : NULL;
   1482         return true;
   1483     }
   1484     if (!strcmp("vkGetPhysicalDeviceXcbPresentationSupportKHR", name)) {
   1485         *addr = ptr_instance->wsi_xcb_surface_enabled ? (void *)vkGetPhysicalDeviceXcbPresentationSupportKHR : NULL;
   1486         return true;
   1487     }
   1488 #endif  // VK_USE_PLATFORM_XCB_KHR
   1489 #ifdef VK_USE_PLATFORM_XLIB_KHR
   1490 
   1491     // Functions for the VK_KHR_xlib_surface extension:
   1492     if (!strcmp("vkCreateXlibSurfaceKHR", name)) {
   1493         *addr = ptr_instance->wsi_xlib_surface_enabled ? (void *)vkCreateXlibSurfaceKHR : NULL;
   1494         return true;
   1495     }
   1496     if (!strcmp("vkGetPhysicalDeviceXlibPresentationSupportKHR", name)) {
   1497         *addr = ptr_instance->wsi_xlib_surface_enabled ? (void *)vkGetPhysicalDeviceXlibPresentationSupportKHR : NULL;
   1498         return true;
   1499     }
   1500 #endif  // VK_USE_PLATFORM_XLIB_KHR
   1501 #ifdef VK_USE_PLATFORM_ANDROID_KHR
   1502 
   1503     // Functions for the VK_KHR_android_surface extension:
   1504     if (!strcmp("vkCreateAndroidSurfaceKHR", name)) {
   1505         *addr = ptr_instance->wsi_xlib_surface_enabled ? (void *)vkCreateAndroidSurfaceKHR : NULL;
   1506         return true;
   1507     }
   1508 #endif  // VK_USE_PLATFORM_ANDROID_KHR
   1509 
   1510     // Functions for VK_KHR_display extension:
   1511     if (!strcmp("vkGetPhysicalDeviceDisplayPropertiesKHR", name)) {
   1512         *addr = ptr_instance->wsi_display_enabled ? (void *)vkGetPhysicalDeviceDisplayPropertiesKHR : NULL;
   1513         return true;
   1514     }
   1515     if (!strcmp("vkGetPhysicalDeviceDisplayPlanePropertiesKHR", name)) {
   1516         *addr = ptr_instance->wsi_display_enabled ? (void *)vkGetPhysicalDeviceDisplayPlanePropertiesKHR : NULL;
   1517         return true;
   1518     }
   1519     if (!strcmp("vkGetDisplayPlaneSupportedDisplaysKHR", name)) {
   1520         *addr = ptr_instance->wsi_display_enabled ? (void *)vkGetDisplayPlaneSupportedDisplaysKHR : NULL;
   1521         return true;
   1522     }
   1523     if (!strcmp("vkGetDisplayModePropertiesKHR", name)) {
   1524         *addr = ptr_instance->wsi_display_enabled ? (void *)vkGetDisplayModePropertiesKHR : NULL;
   1525         return true;
   1526     }
   1527     if (!strcmp("vkCreateDisplayModeKHR", name)) {
   1528         *addr = ptr_instance->wsi_display_enabled ? (void *)vkCreateDisplayModeKHR : NULL;
   1529         return true;
   1530     }
   1531     if (!strcmp("vkGetDisplayPlaneCapabilitiesKHR", name)) {
   1532         *addr = ptr_instance->wsi_display_enabled ? (void *)vkGetDisplayPlaneCapabilitiesKHR : NULL;
   1533         return true;
   1534     }
   1535     if (!strcmp("vkCreateDisplayPlaneSurfaceKHR", name)) {
   1536         *addr = ptr_instance->wsi_display_enabled ? (void *)vkCreateDisplayPlaneSurfaceKHR : NULL;
   1537         return true;
   1538     }
   1539 
   1540     // Functions for KHR_display_swapchain extension:
   1541     if (!strcmp("vkCreateSharedSwapchainsKHR", name)) {
   1542         *addr = (void *)vkCreateSharedSwapchainsKHR;
   1543         return true;
   1544     }
   1545 
   1546     return false;
   1547 }
   1548