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