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