loader: Call ICD for CreateDisplayPlaneSurfaceKHR
[platform/upstream/Vulkan-LoaderAndValidationLayers.git] / loader / wsi.c
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@lunarg.com>
19  * Author: Jon Ashburn <jon@lunarg.com>
20  * Author: Ian Elliott <ianelliott@google.com>
21  * Author: Mark Lobodzinski <mark@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     VkResult vkRes = VK_SUCCESS;
1489
1490     if (!inst->wsi_display_enabled) {
1491         loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
1492                    "VK_KHR_surface extension not enabled.  "
1493                    "vkCreateDisplayPlaneSurfaceKHR not executed!\n");
1494         vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
1495         goto out;
1496     }
1497
1498     // The VK_KHR_display path will continue to use the old path (hence the
1499     // false as the last parameter).
1500     pIcdSurface =
1501         AllocateIcdSurfaceStruct(inst, sizeof(pIcdSurface->display_surf.base),
1502                                  sizeof(pIcdSurface->display_surf), false);
1503     if (pIcdSurface == NULL) {
1504         vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
1505         goto out;
1506     }
1507
1508     pIcdSurface->display_surf.base.platform = VK_ICD_WSI_PLATFORM_DISPLAY;
1509     pIcdSurface->display_surf.displayMode = pCreateInfo->displayMode;
1510     pIcdSurface->display_surf.planeIndex = pCreateInfo->planeIndex;
1511     pIcdSurface->display_surf.planeStackIndex = pCreateInfo->planeStackIndex;
1512     pIcdSurface->display_surf.transform = pCreateInfo->transform;
1513     pIcdSurface->display_surf.globalAlpha = pCreateInfo->globalAlpha;
1514     pIcdSurface->display_surf.alphaMode = pCreateInfo->alphaMode;
1515     pIcdSurface->display_surf.imageExtent = pCreateInfo->imageExtent;
1516
1517     // Loop through each ICD and determine if they need to create a surface
1518     for (uint32_t i = 0; i < inst->total_icd_count; i++) {
1519         if (inst->icd_libs.list[i].interface_version >=
1520             ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
1521             struct loader_icd *icd = &inst->icds[i];
1522             if (NULL != icd->CreateDisplayPlaneSurfaceKHR) {
1523                 vkRes = icd->CreateDisplayPlaneSurfaceKHR(
1524                     icd->instance, pCreateInfo, pAllocator,
1525                     &pIcdSurface->real_icd_surfaces[i]);
1526                 if (VK_SUCCESS != vkRes) {
1527                     goto out;
1528                 }
1529             }
1530         }
1531     }
1532
1533     *pSurface = (VkSurfaceKHR)pIcdSurface;
1534
1535 out:
1536
1537     if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
1538         if (NULL != pIcdSurface->real_icd_surfaces) {
1539             for (uint32_t i = 0; i < inst->total_icd_count; i++) {
1540                 struct loader_icd *icd = &inst->icds[i];
1541                 if (NULL != (void *)pIcdSurface->real_icd_surfaces[i] &&
1542                     NULL != icd->DestroySurfaceKHR) {
1543                     icd->DestroySurfaceKHR(icd->instance,
1544                                            pIcdSurface->real_icd_surfaces[i],
1545                                            pAllocator);
1546                 }
1547             }
1548             loader_instance_heap_free(inst, pIcdSurface->real_icd_surfaces);
1549         }
1550         loader_instance_heap_free(inst, pIcdSurface);
1551     }
1552
1553     return vkRes;
1554 }
1555
1556 // This is the trampoline entrypoint
1557 // for CreateSharedSwapchainsKHR
1558 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateSharedSwapchainsKHR(
1559     VkDevice device, uint32_t swapchainCount,
1560     const VkSwapchainCreateInfoKHR *pCreateInfos,
1561     const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchains) {
1562     const VkLayerDispatchTable *disp;
1563     disp = loader_get_dispatch(device);
1564     return disp->CreateSharedSwapchainsKHR(device, swapchainCount, pCreateInfos, pAllocator, pSwapchains);
1565 }
1566
1567 bool wsi_swapchain_instance_gpa(struct loader_instance *ptr_instance,
1568                                 const char *name, void **addr) {
1569     *addr = NULL;
1570
1571     // Functions for the VK_KHR_surface extension:
1572     if (!strcmp("vkDestroySurfaceKHR", name)) {
1573         *addr = ptr_instance->wsi_surface_enabled ? (void *)vkDestroySurfaceKHR
1574                                                   : NULL;
1575         return true;
1576     }
1577     if (!strcmp("vkGetPhysicalDeviceSurfaceSupportKHR", name)) {
1578         *addr = ptr_instance->wsi_surface_enabled
1579                     ? (void *)vkGetPhysicalDeviceSurfaceSupportKHR
1580                     : NULL;
1581         return true;
1582     }
1583     if (!strcmp("vkGetPhysicalDeviceSurfaceCapabilitiesKHR", name)) {
1584         *addr = ptr_instance->wsi_surface_enabled
1585                     ? (void *)vkGetPhysicalDeviceSurfaceCapabilitiesKHR
1586                     : NULL;
1587         return true;
1588     }
1589     if (!strcmp("vkGetPhysicalDeviceSurfaceFormatsKHR", name)) {
1590         *addr = ptr_instance->wsi_surface_enabled
1591                     ? (void *)vkGetPhysicalDeviceSurfaceFormatsKHR
1592                     : NULL;
1593         return true;
1594     }
1595     if (!strcmp("vkGetPhysicalDeviceSurfacePresentModesKHR", name)) {
1596         *addr = ptr_instance->wsi_surface_enabled
1597                     ? (void *)vkGetPhysicalDeviceSurfacePresentModesKHR
1598                     : NULL;
1599         return true;
1600     }
1601
1602     // Functions for the VK_KHR_swapchain extension:
1603
1604     // Note: This is a device extension, and its functions are statically
1605     // exported from the loader.  Per Khronos decisions, the loader's GIPA
1606     // function will return the trampoline function for such device-extension
1607     // functions, regardless of whether the extension has been enabled.
1608     if (!strcmp("vkCreateSwapchainKHR", name)) {
1609         *addr = (void *)vkCreateSwapchainKHR;
1610         return true;
1611     }
1612     if (!strcmp("vkDestroySwapchainKHR", name)) {
1613         *addr = (void *)vkDestroySwapchainKHR;
1614         return true;
1615     }
1616     if (!strcmp("vkGetSwapchainImagesKHR", name)) {
1617         *addr = (void *)vkGetSwapchainImagesKHR;
1618         return true;
1619     }
1620     if (!strcmp("vkAcquireNextImageKHR", name)) {
1621         *addr = (void *)vkAcquireNextImageKHR;
1622         return true;
1623     }
1624     if (!strcmp("vkQueuePresentKHR", name)) {
1625         *addr = (void *)vkQueuePresentKHR;
1626         return true;
1627     }
1628
1629 #ifdef VK_USE_PLATFORM_WIN32_KHR
1630
1631     // Functions for the VK_KHR_win32_surface extension:
1632     if (!strcmp("vkCreateWin32SurfaceKHR", name)) {
1633         *addr = ptr_instance->wsi_win32_surface_enabled
1634                     ? (void *)vkCreateWin32SurfaceKHR
1635                     : NULL;
1636         return true;
1637     }
1638     if (!strcmp("vkGetPhysicalDeviceWin32PresentationSupportKHR", name)) {
1639         *addr = ptr_instance->wsi_win32_surface_enabled
1640                     ? (void *)vkGetPhysicalDeviceWin32PresentationSupportKHR
1641                     : NULL;
1642         return true;
1643     }
1644 #endif // VK_USE_PLATFORM_WIN32_KHR
1645 #ifdef VK_USE_PLATFORM_MIR_KHR
1646
1647     // Functions for the VK_KHR_mir_surface extension:
1648     if (!strcmp("vkCreateMirSurfaceKHR", name)) {
1649         *addr = ptr_instance->wsi_mir_surface_enabled
1650                     ? (void *)vkCreateMirSurfaceKHR
1651                     : NULL;
1652         return true;
1653     }
1654     if (!strcmp("vkGetPhysicalDeviceMirPresentationSupportKHR", name)) {
1655         *addr = ptr_instance->wsi_mir_surface_enabled
1656                     ? (void *)vkGetPhysicalDeviceMirPresentationSupportKHR
1657                     : NULL;
1658         return true;
1659     }
1660 #endif // VK_USE_PLATFORM_MIR_KHR
1661 #ifdef VK_USE_PLATFORM_WAYLAND_KHR
1662
1663     // Functions for the VK_KHR_wayland_surface extension:
1664     if (!strcmp("vkCreateWaylandSurfaceKHR", name)) {
1665         *addr = ptr_instance->wsi_wayland_surface_enabled
1666                     ? (void *)vkCreateWaylandSurfaceKHR
1667                     : NULL;
1668         return true;
1669     }
1670     if (!strcmp("vkGetPhysicalDeviceWaylandPresentationSupportKHR", name)) {
1671         *addr = ptr_instance->wsi_wayland_surface_enabled
1672                     ? (void *)vkGetPhysicalDeviceWaylandPresentationSupportKHR
1673                     : NULL;
1674         return true;
1675     }
1676 #endif // VK_USE_PLATFORM_WAYLAND_KHR
1677 #ifdef VK_USE_PLATFORM_XCB_KHR
1678
1679     // Functions for the VK_KHR_xcb_surface extension:
1680     if (!strcmp("vkCreateXcbSurfaceKHR", name)) {
1681         *addr = ptr_instance->wsi_xcb_surface_enabled
1682                     ? (void *)vkCreateXcbSurfaceKHR
1683                     : NULL;
1684         return true;
1685     }
1686     if (!strcmp("vkGetPhysicalDeviceXcbPresentationSupportKHR", name)) {
1687         *addr = ptr_instance->wsi_xcb_surface_enabled
1688                     ? (void *)vkGetPhysicalDeviceXcbPresentationSupportKHR
1689                     : NULL;
1690         return true;
1691     }
1692 #endif // VK_USE_PLATFORM_XCB_KHR
1693 #ifdef VK_USE_PLATFORM_XLIB_KHR
1694
1695     // Functions for the VK_KHR_xlib_surface extension:
1696     if (!strcmp("vkCreateXlibSurfaceKHR", name)) {
1697         *addr = ptr_instance->wsi_xlib_surface_enabled
1698                     ? (void *)vkCreateXlibSurfaceKHR
1699                     : NULL;
1700         return true;
1701     }
1702     if (!strcmp("vkGetPhysicalDeviceXlibPresentationSupportKHR", name)) {
1703         *addr = ptr_instance->wsi_xlib_surface_enabled
1704                     ? (void *)vkGetPhysicalDeviceXlibPresentationSupportKHR
1705                     : NULL;
1706         return true;
1707     }
1708 #endif // VK_USE_PLATFORM_XLIB_KHR
1709 #ifdef VK_USE_PLATFORM_ANDROID_KHR
1710
1711     // Functions for the VK_KHR_android_surface extension:
1712     if (!strcmp("vkCreateAndroidSurfaceKHR", name)) {
1713         *addr = ptr_instance->wsi_xlib_surface_enabled
1714                     ? (void *)vkCreateAndroidSurfaceKHR
1715                     : NULL;
1716         return true;
1717     }
1718 #endif // VK_USE_PLATFORM_ANDROID_KHR
1719
1720     // Functions for VK_KHR_display extension:
1721     if (!strcmp("vkGetPhysicalDeviceDisplayPropertiesKHR", name)) {
1722         *addr = ptr_instance->wsi_display_enabled
1723                     ? (void *)vkGetPhysicalDeviceDisplayPropertiesKHR
1724                     : NULL;
1725         return true;
1726     }
1727     if (!strcmp("vkGetPhysicalDeviceDisplayPlanePropertiesKHR", name)) {
1728         *addr = ptr_instance->wsi_display_enabled
1729                     ? (void *)vkGetPhysicalDeviceDisplayPlanePropertiesKHR
1730                     : NULL;
1731         return true;
1732     }
1733     if (!strcmp("vkGetDisplayPlaneSupportedDisplaysKHR", name)) {
1734         *addr = ptr_instance->wsi_display_enabled
1735                     ? (void *)vkGetDisplayPlaneSupportedDisplaysKHR
1736                     : NULL;
1737         return true;
1738     }
1739     if (!strcmp("vkGetDisplayModePropertiesKHR", name)) {
1740         *addr = ptr_instance->wsi_display_enabled
1741                     ? (void *)vkGetDisplayModePropertiesKHR
1742                     : NULL;
1743         return true;
1744     }
1745     if (!strcmp("vkCreateDisplayModeKHR", name)) {
1746         *addr = ptr_instance->wsi_display_enabled
1747                     ? (void *)vkCreateDisplayModeKHR
1748                     : NULL;
1749         return true;
1750     }
1751     if (!strcmp("vkGetDisplayPlaneCapabilitiesKHR", name)) {
1752         *addr = ptr_instance->wsi_display_enabled
1753                     ? (void *)vkGetDisplayPlaneCapabilitiesKHR
1754                     : NULL;
1755         return true;
1756     }
1757     if (!strcmp("vkCreateDisplayPlaneSurfaceKHR", name)) {
1758         *addr = ptr_instance->wsi_display_enabled
1759                     ? (void *)vkCreateDisplayPlaneSurfaceKHR
1760                     : NULL;
1761         return true;
1762     }
1763
1764     // Functions for KHR_display_swapchain extension:
1765     if (!strcmp("vkCreateSharedSwapchainsKHR", name)) {
1766         *addr = (void *)vkCreateSharedSwapchainsKHR;
1767         return true;
1768     }
1769
1770     return false;
1771 }