1 /*
2  * Copyright (c) 2015-2022 The Khronos Group Inc.
3  * Copyright (c) 2015-2022 Valve Corporation
4  * Copyright (c) 2015-2022 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  * Author: Lenny Komow <lenny@lunarg.com>
23  * Author: Charles Giessen <charles@lunarg.com>
24  */
25 
26 #include <stdio.h>
27 #include <stdlib.h>
28 
29 #include <vulkan/vk_icd.h>
30 
31 #include "allocation.h"
32 #include "loader.h"
33 #include "log.h"
34 #include "vk_loader_platform.h"
35 #include "wsi.h"
36 
37 // The first ICD/Loader interface that support querying the SurfaceKHR from
38 // the ICDs.
39 #define ICD_VER_SUPPORTS_ICD_SURFACE_KHR 3
40 
wsi_create_instance(struct loader_instance *loader_inst, const VkInstanceCreateInfo *pCreateInfo)41 void wsi_create_instance(struct loader_instance *loader_inst, const VkInstanceCreateInfo *pCreateInfo) {
42     for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
43         if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SURFACE_EXTENSION_NAME) == 0) {
44             loader_inst->wsi_surface_enabled = true;
45             continue;
46         }
47 #if defined(VK_USE_PLATFORM_WIN32_KHR)
48         if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_WIN32_SURFACE_EXTENSION_NAME) == 0) {
49             loader_inst->wsi_win32_surface_enabled = true;
50             continue;
51         }
52 #endif  // VK_USE_PLATFORM_WIN32_KHR
53 #if defined(VK_USE_PLATFORM_WAYLAND_KHR)
54         if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME) == 0) {
55             loader_inst->wsi_wayland_surface_enabled = true;
56             continue;
57         }
58 #endif  // VK_USE_PLATFORM_WAYLAND_KHR
59 #if defined(VK_USE_PLATFORM_XCB_KHR)
60         if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_XCB_SURFACE_EXTENSION_NAME) == 0) {
61             loader_inst->wsi_xcb_surface_enabled = true;
62             continue;
63         }
64 #endif  // VK_USE_PLATFORM_XCB_KHR
65 #if defined(VK_USE_PLATFORM_XLIB_KHR)
66         if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_XLIB_SURFACE_EXTENSION_NAME) == 0) {
67             loader_inst->wsi_xlib_surface_enabled = true;
68             continue;
69         }
70 #endif  // VK_USE_PLATFORM_XLIB_KHR
71 #if defined(VK_USE_PLATFORM_DIRECTFB_EXT)
72         if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME) == 0) {
73             loader_inst->wsi_directfb_surface_enabled = true;
74             continue;
75         }
76 #endif  // VK_USE_PLATFORM_DIRECTFB_EXT
77 #if defined(VK_USE_PLATFORM_ANDROID_KHR)
78         if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_ANDROID_SURFACE_EXTENSION_NAME) == 0) {
79             loader_inst->wsi_android_surface_enabled = true;
80             continue;
81         }
82 #endif  // VK_USE_PLATFORM_ANDROID_KHR
83 #if defined(VK_USE_PLATFORM_OHOS)
84         if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_OHOS_SURFACE_EXTENSION_NAME) == 0) {
85             loader_inst->wsi_ohos_surface_enabled = true;
86             continue;
87         }
88 #endif  // VK_USE_PLATFORM_OHOS
89 #if defined(VK_USE_PLATFORM_MACOS_MVK)
90         if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_MVK_MACOS_SURFACE_EXTENSION_NAME) == 0) {
91             loader_inst->wsi_macos_surface_enabled = true;
92             continue;
93         }
94 #endif  // VK_USE_PLATFORM_MACOS_MVK
95 #if defined(VK_USE_PLATFORM_IOS_MVK)
96         if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_MVK_IOS_SURFACE_EXTENSION_NAME) == 0) {
97             loader_inst->wsi_ios_surface_enabled = true;
98             continue;
99         }
100 #endif  // VK_USE_PLATFORM_IOS_MVK
101 #if defined(VK_USE_PLATFORM_GGP)
102         if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_GGP_STREAM_DESCRIPTOR_SURFACE_EXTENSION_NAME) == 0) {
103             loader_inst->wsi_ggp_surface_enabled = true;
104             continue;
105         }
106 #endif  // VK_USE_PLATFORM_GGP
107 #if defined(VK_USE_PLATFORM_FUCHSIA)
108         if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_FUCHSIA_IMAGEPIPE_SURFACE_EXTENSION_NAME) == 0) {
109             loader_inst->wsi_imagepipe_surface_enabled = true;
110             continue;
111         }
112 #endif  // VK_USE_PLATFORM_FUCHSIA
113         if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME) == 0) {
114             loader_inst->wsi_headless_surface_enabled = true;
115             continue;
116         }
117 #if defined(VK_USE_PLATFORM_METAL_EXT)
118         if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_METAL_SURFACE_EXTENSION_NAME) == 0) {
119             loader_inst->wsi_metal_surface_enabled = true;
120             continue;
121         }
122 #endif
123 #if defined(VK_USE_PLATFORM_SCREEN_QNX)
124         if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_QNX_SCREEN_SURFACE_EXTENSION_NAME) == 0) {
125             loader_inst->wsi_screen_surface_enabled = true;
126             continue;
127         }
128 #endif  // VK_USE_PLATFORM_SCREEN_QNX
129 #if defined(VK_USE_PLATFORM_VI_NN)
130         if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_NN_VI_SURFACE_EXTENSION_NAME) == 0) {
131             loader_inst->wsi_vi_surface_enabled = true;
132             continue;
133         }
134 #endif  // VK_USE_PLATFORM_VI_NN
135         if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_DISPLAY_EXTENSION_NAME) == 0) {
136             loader_inst->wsi_display_enabled = true;
137             continue;
138         }
139         if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME) == 0) {
140             loader_inst->wsi_display_props2_enabled = true;
141             continue;
142         }
143     }
144 }
145 
146 // Linux WSI surface extensions are not always compiled into the loader. (Assume
147 // for Windows the KHR_win32_surface is always compiled into loader). A given
148 // Linux build environment might not have the headers required for building one
149 // of the three extensions  (Xlib, Xcb, Wayland).  Thus, need to check if
150 // the built loader actually supports the particular Linux surface extension.
151 // If not supported by the built loader it will not be included in the list of
152 // enumerated instance extensions.  This solves the issue where an ICD or layer
153 // advertises support for a given Linux surface extension but the loader was not
154 // built to support the extension.
wsi_unsupported_instance_extension(const VkExtensionProperties *ext_prop)155 bool wsi_unsupported_instance_extension(const VkExtensionProperties *ext_prop) {
156 #if !defined(VK_USE_PLATFORM_WAYLAND_KHR)
157     if (!strcmp(ext_prop->extensionName, "VK_KHR_wayland_surface")) return true;
158 #endif  // VK_USE_PLATFORM_WAYLAND_KHR
159 #if !defined(VK_USE_PLATFORM_XCB_KHR)
160     if (!strcmp(ext_prop->extensionName, "VK_KHR_xcb_surface")) return true;
161 #endif  // VK_USE_PLATFORM_XCB_KHR
162 #if !defined(VK_USE_PLATFORM_XLIB_KHR)
163     if (!strcmp(ext_prop->extensionName, "VK_KHR_xlib_surface")) return true;
164 #endif  // VK_USE_PLATFORM_XLIB_KHR
165 #if !defined(VK_USE_PLATFORM_DIRECTFB_EXT)
166     if (!strcmp(ext_prop->extensionName, "VK_EXT_directfb_surface")) return true;
167 #endif  // VK_USE_PLATFORM_DIRECTFB_EXT
168 #if !defined(VK_USE_PLATFORM_SCREEN_QNX)
169     if (!strcmp(ext_prop->extensionName, "VK_QNX_screen_surface")) return true;
170 #endif  // VK_USE_PLATFORM_SCREEN_QNX
171 
172     return false;
173 }
174 
175 // Functions for the VK_KHR_surface extension:
176 
177 // This is the trampoline entrypoint for DestroySurfaceKHR
vkDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks *pAllocator)178 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface,
179                                                              const VkAllocationCallbacks *pAllocator) {
180     struct loader_instance *loader_inst = loader_get_instance(instance);
181     if (NULL == loader_inst) {
182         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
183                    "vkDestroySurfaceKHR: Invalid instance [VUID-vkDestroySurfaceKHR-instance-parameter]");
184         abort(); /* Intentionally fail so user can correct issue. */
185     }
186     loader_inst->disp->layer_inst_disp.DestroySurfaceKHR(loader_inst->instance, surface, pAllocator);
187 }
188 
189 // TODO probably need to lock around all the loader_get_instance() calls.
190 
191 // This is the instance chain terminator function for DestroySurfaceKHR
terminator_DestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks *pAllocator)192 VKAPI_ATTR void VKAPI_CALL terminator_DestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface,
193                                                         const VkAllocationCallbacks *pAllocator) {
194     struct loader_instance *loader_inst = loader_get_instance(instance);
195 
196     VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)(surface);
197     if (NULL != icd_surface) {
198         if (NULL != icd_surface->real_icd_surfaces) {
199             uint32_t i = 0;
200             for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
201                 if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
202                     if (NULL != icd_term->dispatch.DestroySurfaceKHR &&
203                         (VkSurfaceKHR)(uintptr_t)NULL != icd_surface->real_icd_surfaces[i]) {
204                         icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, icd_surface->real_icd_surfaces[i], pAllocator);
205                         icd_surface->real_icd_surfaces[i] = (VkSurfaceKHR)(uintptr_t)NULL;
206                     }
207                 } else {
208                     // The real_icd_surface for any ICD not supporting the
209                     // proper interface version should be NULL.  If not, then
210                     // we have a problem.
211                     assert((VkSurfaceKHR)(uintptr_t)NULL == icd_surface->real_icd_surfaces[i]);
212                 }
213             }
214             loader_instance_heap_free(loader_inst, icd_surface->real_icd_surfaces);
215         }
216 
217         loader_instance_heap_free(loader_inst, (void *)(uintptr_t)surface);
218     }
219 }
220 
221 // This is the trampoline entrypoint for GetPhysicalDeviceSurfaceSupportKHR
vkGetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, VkSurfaceKHR surface, VkBool32 *pSupported)222 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice,
223                                                                                   uint32_t queueFamilyIndex, VkSurfaceKHR surface,
224                                                                                   VkBool32 *pSupported) {
225     const VkLayerInstanceDispatchTable *disp;
226     VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
227     if (VK_NULL_HANDLE == unwrapped_phys_dev) {
228         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
229                    "vkGetPhysicalDeviceSurfaceSupportKHR: Invalid physicalDevice "
230                    "[VUID-vkGetPhysicalDeviceSurfaceSupportKHR-physicalDevice-parameter]");
231         abort(); /* Intentionally fail so user can correct issue. */
232     }
233     disp = loader_get_instance_layer_dispatch(physicalDevice);
234     return disp->GetPhysicalDeviceSurfaceSupportKHR(unwrapped_phys_dev, queueFamilyIndex, surface, pSupported);
235 }
236 
237 // This is the instance chain terminator function for
238 // GetPhysicalDeviceSurfaceSupportKHR
terminator_GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, VkSurfaceKHR surface, VkBool32 *pSupported)239 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice,
240                                                                              uint32_t queueFamilyIndex, VkSurfaceKHR surface,
241                                                                              VkBool32 *pSupported) {
242     // First, check to ensure the appropriate extension was enabled:
243     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
244     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
245     struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
246     if (!loader_inst->wsi_surface_enabled) {
247         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
248                    "VK_KHR_surface extension not enabled. vkGetPhysicalDeviceSurfaceSupportKHR not executed!");
249         return VK_SUCCESS;
250     }
251 
252     if (NULL == pSupported) {
253         loader_log(loader_inst, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT, 0,
254                    "NULL pointer passed into vkGetPhysicalDeviceSurfaceSupportKHR for pSupported!");
255         abort();
256     }
257     *pSupported = false;
258 
259     if (NULL == icd_term->dispatch.GetPhysicalDeviceSurfaceSupportKHR) {
260         // set pSupported to false as this driver doesn't support WSI functionality
261         *pSupported = false;
262         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
263                    "ICD for selected physical device does not export vkGetPhysicalDeviceSurfaceSupportKHR!");
264         return VK_SUCCESS;
265     }
266 
267     VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)surface;
268     if (NULL != icd_surface->real_icd_surfaces &&
269         (VkSurfaceKHR)(uintptr_t)NULL != icd_surface->real_icd_surfaces[phys_dev_term->icd_index]) {
270         return icd_term->dispatch.GetPhysicalDeviceSurfaceSupportKHR(
271             phys_dev_term->phys_dev, queueFamilyIndex, icd_surface->real_icd_surfaces[phys_dev_term->icd_index], pSupported);
272     }
273 
274     return icd_term->dispatch.GetPhysicalDeviceSurfaceSupportKHR(phys_dev_term->phys_dev, queueFamilyIndex, surface, pSupported);
275 }
276 
277 // This is the trampoline entrypoint for GetPhysicalDeviceSurfaceCapabilitiesKHR
vkGetPhysicalDeviceSurfaceCapabilitiesKHR( VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR *pSurfaceCapabilities)278 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceCapabilitiesKHR(
279     VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) {
280     const VkLayerInstanceDispatchTable *disp;
281     VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
282     if (VK_NULL_HANDLE == unwrapped_phys_dev) {
283         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
284                    "vkGetPhysicalDeviceSurfaceCapabilitiesKHR: Invalid physicalDevice "
285                    "[VUID-vkGetPhysicalDeviceSurfaceCapabilitiesKHR-physicalDevice-parameter]");
286         abort(); /* Intentionally fail so user can correct issue. */
287     }
288     disp = loader_get_instance_layer_dispatch(physicalDevice);
289     return disp->GetPhysicalDeviceSurfaceCapabilitiesKHR(unwrapped_phys_dev, surface, pSurfaceCapabilities);
290 }
291 
292 // This is the instance chain terminator function for
293 // GetPhysicalDeviceSurfaceCapabilitiesKHR
terminator_GetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR *pSurfaceCapabilities)294 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice,
295                                                                                   VkSurfaceKHR surface,
296                                                                                   VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) {
297     // First, check to ensure the appropriate extension was enabled:
298     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
299     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
300     struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
301     if (!loader_inst->wsi_surface_enabled) {
302         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
303                    "VK_KHR_surface extension not enabled. vkGetPhysicalDeviceSurfaceCapabilitiesKHR not executed!");
304         return VK_SUCCESS;
305     }
306 
307     if (NULL == pSurfaceCapabilities) {
308         loader_log(loader_inst, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT, 0,
309                    "NULL pointer passed into vkGetPhysicalDeviceSurfaceCapabilitiesKHR for pSurfaceCapabilities!");
310         abort();
311     }
312 
313     if (NULL == icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilitiesKHR) {
314         // Zero out the capabilities as this driver doesn't support WSI functionality
315         memset(pSurfaceCapabilities, 0, sizeof(VkSurfaceCapabilitiesKHR));
316         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
317                    "ICD for selected physical device does not export vkGetPhysicalDeviceSurfaceCapabilitiesKHR!");
318         return VK_SUCCESS;
319     }
320 
321     VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)surface;
322     if (NULL != icd_surface->real_icd_surfaces &&
323         (VkSurfaceKHR)(uintptr_t)NULL != icd_surface->real_icd_surfaces[phys_dev_term->icd_index]) {
324         return icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilitiesKHR(
325             phys_dev_term->phys_dev, icd_surface->real_icd_surfaces[phys_dev_term->icd_index], pSurfaceCapabilities);
326     }
327 
328     return icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilitiesKHR(phys_dev_term->phys_dev, surface, pSurfaceCapabilities);
329 }
330 
331 // This is the trampoline entrypoint for GetPhysicalDeviceSurfaceFormatsKHR
vkGetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t *pSurfaceFormatCount, VkSurfaceFormatKHR *pSurfaceFormats)332 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice,
333                                                                                   VkSurfaceKHR surface,
334                                                                                   uint32_t *pSurfaceFormatCount,
335                                                                                   VkSurfaceFormatKHR *pSurfaceFormats) {
336     const VkLayerInstanceDispatchTable *disp;
337     VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
338     if (VK_NULL_HANDLE == unwrapped_phys_dev) {
339         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
340                    "vkGetPhysicalDeviceSurfaceFormatsKHR: Invalid physicalDevice "
341                    "[VUID-vkGetPhysicalDeviceSurfaceFormatsKHR-physicalDevice-parameter]");
342         abort(); /* Intentionally fail so user can correct issue. */
343     }
344     disp = loader_get_instance_layer_dispatch(physicalDevice);
345     return disp->GetPhysicalDeviceSurfaceFormatsKHR(unwrapped_phys_dev, surface, pSurfaceFormatCount, pSurfaceFormats);
346 }
347 
348 // This is the instance chain terminator function for
349 // GetPhysicalDeviceSurfaceFormatsKHR
terminator_GetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t *pSurfaceFormatCount, VkSurfaceFormatKHR *pSurfaceFormats)350 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
351                                                                              uint32_t *pSurfaceFormatCount,
352                                                                              VkSurfaceFormatKHR *pSurfaceFormats) {
353     // First, check to ensure the appropriate extension was enabled:
354     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
355     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
356     struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
357     if (!loader_inst->wsi_surface_enabled) {
358         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
359                    "VK_KHR_surface extension not enabled. vkGetPhysicalDeviceSurfaceFormatsKHR not executed!");
360         return VK_SUCCESS;
361     }
362 
363     if (NULL == pSurfaceFormatCount) {
364         loader_log(loader_inst, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT, 0,
365                    "NULL pointer passed into vkGetPhysicalDeviceSurfaceFormatsKHR for pSurfaceFormatCount!");
366         abort();
367     }
368 
369     if (NULL == icd_term->dispatch.GetPhysicalDeviceSurfaceFormatsKHR) {
370         // Zero out the format count as this driver doesn't support WSI functionality
371         *pSurfaceFormatCount = 0;
372         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
373                    "ICD for selected physical device does not export vkGetPhysicalDeviceSurfaceCapabilitiesKHR!");
374         return VK_SUCCESS;
375     }
376 
377     VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)surface;
378     if (NULL != icd_surface->real_icd_surfaces &&
379         (VkSurfaceKHR)(uintptr_t)NULL != icd_surface->real_icd_surfaces[phys_dev_term->icd_index]) {
380         return icd_term->dispatch.GetPhysicalDeviceSurfaceFormatsKHR(phys_dev_term->phys_dev,
381                                                                      icd_surface->real_icd_surfaces[phys_dev_term->icd_index],
382                                                                      pSurfaceFormatCount, pSurfaceFormats);
383     }
384 
385     return icd_term->dispatch.GetPhysicalDeviceSurfaceFormatsKHR(phys_dev_term->phys_dev, surface, pSurfaceFormatCount,
386                                                                  pSurfaceFormats);
387 }
388 
389 // This is the trampoline entrypoint for GetPhysicalDeviceSurfacePresentModesKHR
vkGetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t *pPresentModeCount, VkPresentModeKHR *pPresentModes)390 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice,
391                                                                                        VkSurfaceKHR surface,
392                                                                                        uint32_t *pPresentModeCount,
393                                                                                        VkPresentModeKHR *pPresentModes) {
394     const VkLayerInstanceDispatchTable *disp;
395     VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
396     if (VK_NULL_HANDLE == unwrapped_phys_dev) {
397         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
398                    "vkGetPhysicalDeviceSurfacePresentModesKHR: Invalid physicalDevice "
399                    "[VUID-vkGetPhysicalDeviceSurfacePresentModesKHR-physicalDevice-parameter]");
400         abort(); /* Intentionally fail so user can correct issue. */
401     }
402     disp = loader_get_instance_layer_dispatch(physicalDevice);
403     return disp->GetPhysicalDeviceSurfacePresentModesKHR(unwrapped_phys_dev, surface, pPresentModeCount, pPresentModes);
404 }
405 
406 // This is the instance chain terminator function for
407 // GetPhysicalDeviceSurfacePresentModesKHR
terminator_GetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t *pPresentModeCount, VkPresentModeKHR *pPresentModes)408 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice,
409                                                                                   VkSurfaceKHR surface, uint32_t *pPresentModeCount,
410                                                                                   VkPresentModeKHR *pPresentModes) {
411     // First, check to ensure the appropriate extension was enabled:
412     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
413     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
414     struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
415     if (!loader_inst->wsi_surface_enabled) {
416         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
417                    "VK_KHR_surface extension not enabled. vkGetPhysicalDeviceSurfacePresentModesKHR not executed!");
418         return VK_SUCCESS;
419     }
420 
421     if (NULL == pPresentModeCount) {
422         loader_log(loader_inst, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT, 0,
423                    "NULL pointer passed into vkGetPhysicalDeviceSurfacePresentModesKHR for pPresentModeCount!");
424         abort();
425     }
426 
427     if (NULL == icd_term->dispatch.GetPhysicalDeviceSurfacePresentModesKHR) {
428         // Zero out the present mode count as this driver doesn't support WSI functionality
429         *pPresentModeCount = 0;
430         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
431                    "ICD for selected physical device does not export vkGetPhysicalDeviceSurfacePresentModesKHR!");
432         return VK_SUCCESS;
433     }
434 
435     VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)surface;
436     if (NULL != icd_surface->real_icd_surfaces &&
437         (VkSurfaceKHR)(uintptr_t)NULL != icd_surface->real_icd_surfaces[phys_dev_term->icd_index]) {
438         return icd_term->dispatch.GetPhysicalDeviceSurfacePresentModesKHR(
439             phys_dev_term->phys_dev, icd_surface->real_icd_surfaces[phys_dev_term->icd_index], pPresentModeCount, pPresentModes);
440     }
441 
442     return icd_term->dispatch.GetPhysicalDeviceSurfacePresentModesKHR(phys_dev_term->phys_dev, surface, pPresentModeCount,
443                                                                       pPresentModes);
444 }
445 
446 // Functions for the VK_KHR_swapchain extension:
447 
448 // This is the trampoline entrypoint for CreateSwapchainKHR
vkCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchain)449 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo,
450                                                                   const VkAllocationCallbacks *pAllocator,
451                                                                   VkSwapchainKHR *pSwapchain) {
452     const VkLayerDispatchTable *disp = loader_get_dispatch(device);
453     if (NULL == disp) {
454         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
455                    "vkCreateSwapchainKHR: Invalid device [VUID-vkCreateSwapchainKHR-device-parameter]");
456         abort(); /* Intentionally fail so user can correct issue. */
457     }
458     if (NULL == disp->CreateSwapchainKHR) {
459         struct loader_device *dev = *((struct loader_device **)device);
460         loader_log(NULL != dev ? dev->phys_dev_term->this_icd_term->this_instance : NULL,
461                    VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
462                    "vkCreateSwapchainKHR: Driver's function pointer was NULL, returning VK_SUCCESS. Was the VK_KHR_swapchain "
463                    "extension enabled?");
464         abort();
465     }
466     return disp->CreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain);
467 }
468 
terminator_CreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchain)469 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo,
470                                                              const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchain) {
471     uint32_t icd_index = 0;
472     struct loader_device *dev;
473     struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, &icd_index);
474     if (NULL == icd_term || NULL == dev) {
475         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
476                    "vkCreateSwapchainKHR Terminator: device handle. This is likely the result of a "
477                    "layer wrapping device handles and failing to unwrap them in all functions. "
478                    "[VUID-vkCreateSwapchainKHR-device-parameter]");
479         abort(); /* Intentionally fail so user can correct issue. */
480     }
481     if (NULL == pCreateInfo) {
482         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
483                    "vkCreateSwapchainKHR: Invalid pCreateInfo pointer [VUID-vkCreateSwapchainKHR-pCreateInfo-parameter]");
484         abort(); /* Intentionally fail so user can correct issue. */
485     }
486     // Need to gracefully handle the function pointer not being found.
487     if (NULL == dev->loader_dispatch.extension_terminator_dispatch.CreateSwapchainKHR) {
488         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
489                    "vkCreateSwapchainKHR: Driver's function pointer was NULL, returning VK_SUCCESS. Was the VK_KHR_swapchain "
490                    "extension enabled?");
491         return VK_SUCCESS;
492     }
493     VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pCreateInfo->surface;
494     if (NULL != icd_surface->real_icd_surfaces) {
495         if ((VkSurfaceKHR)(uintptr_t)NULL != icd_surface->real_icd_surfaces[icd_index]) {
496             // We found the ICD, and there is an ICD KHR surface
497             // associated with it, so copy the CreateInfo struct
498             // and point it at the ICD's surface.
499             VkSwapchainCreateInfoKHR *pCreateCopy = loader_stack_alloc(sizeof(VkSwapchainCreateInfoKHR));
500             if (NULL == pCreateCopy) {
501                 return VK_ERROR_OUT_OF_HOST_MEMORY;
502             }
503             memcpy(pCreateCopy, pCreateInfo, sizeof(VkSwapchainCreateInfoKHR));
504             pCreateCopy->surface = icd_surface->real_icd_surfaces[icd_index];
505             return dev->loader_dispatch.extension_terminator_dispatch.CreateSwapchainKHR(device, pCreateCopy, pAllocator,
506                                                                                          pSwapchain);
507         }
508     }
509     return dev->loader_dispatch.extension_terminator_dispatch.CreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain);
510 }
511 
512 // This is the trampoline entrypoint for DestroySwapchainKHR
vkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks *pAllocator)513 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain,
514                                                                const VkAllocationCallbacks *pAllocator) {
515     const VkLayerDispatchTable *disp = loader_get_dispatch(device);
516     if (NULL == disp) {
517         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
518                    "vkDestroySwapchainKHR: Invalid device [VUID-vkDestroySwapchainKHR-device-parameter]");
519         abort(); /* Intentionally fail so user can correct issue. */
520     }
521     disp->DestroySwapchainKHR(device, swapchain, pAllocator);
522 }
523 
524 // This is the trampoline entrypoint for GetSwapchainImagesKHR
vkGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint32_t *pSwapchainImageCount, VkImage *pSwapchainImages)525 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain,
526                                                                      uint32_t *pSwapchainImageCount, VkImage *pSwapchainImages) {
527     const VkLayerDispatchTable *disp = loader_get_dispatch(device);
528     if (NULL == disp) {
529         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
530                    "vkGetSwapchainImagesKHR: Invalid device [VUID-vkGetSwapchainImagesKHR-device-parameter]");
531         abort(); /* Intentionally fail so user can correct issue. */
532     }
533     return disp->GetSwapchainImagesKHR(device, swapchain, pSwapchainImageCount, pSwapchainImages);
534 }
535 
536 // This is the trampoline entrypoint for AcquireNextImageKHR
vkAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t *pImageIndex)537 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout,
538                                                                    VkSemaphore semaphore, VkFence fence, uint32_t *pImageIndex) {
539     const VkLayerDispatchTable *disp = loader_get_dispatch(device);
540     if (NULL == disp) {
541         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
542                    "vkAcquireNextImageKHR: Invalid device [VUID-vkAcquireNextImageKHR-device-parameter]");
543         abort(); /* Intentionally fail so user can correct issue. */
544     }
545     return disp->AcquireNextImageKHR(device, swapchain, timeout, semaphore, fence, pImageIndex);
546 }
547 
548 // This is the trampoline entrypoint for QueuePresentKHR
vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo)549 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo) {
550     const VkLayerDispatchTable *disp = loader_get_dispatch(queue);
551     if (NULL == disp) {
552         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
553                    "vkQueuePresentKHR: Invalid queue [VUID-vkQueuePresentKHR-queue-parameter]");
554         abort(); /* Intentionally fail so user can correct issue. */
555     }
556     return disp->QueuePresentKHR(queue, pPresentInfo);
557 }
558 
AllocateIcdSurfaceStruct(struct loader_instance *instance, size_t base_size, size_t platform_size)559 VkIcdSurface *AllocateIcdSurfaceStruct(struct loader_instance *instance, size_t base_size, size_t platform_size) {
560     // Next, if so, proceed with the implementation of this function:
561     VkIcdSurface *pIcdSurface = loader_instance_heap_alloc(instance, sizeof(VkIcdSurface), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
562     if (pIcdSurface != NULL) {
563         // Setup the new sizes and offsets so we can grow the structures in the
564         // future without having problems
565         pIcdSurface->base_size = (uint32_t)base_size;
566         pIcdSurface->platform_size = (uint32_t)platform_size;
567         pIcdSurface->non_platform_offset = (uint32_t)((uint8_t *)(&pIcdSurface->base_size) - (uint8_t *)pIcdSurface);
568         pIcdSurface->entire_size = sizeof(VkIcdSurface);
569 
570         pIcdSurface->real_icd_surfaces = loader_instance_heap_calloc(instance, sizeof(VkSurfaceKHR) * instance->total_icd_count,
571                                                                      VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
572         if (pIcdSurface->real_icd_surfaces == NULL) {
573             loader_instance_heap_free(instance, pIcdSurface);
574             pIcdSurface = NULL;
575         }
576     }
577     return pIcdSurface;
578 }
579 
580 #if defined(VK_USE_PLATFORM_WIN32_KHR)
581 
582 // Functions for the VK_KHR_win32_surface extension:
583 
584 // This is the trampoline entrypoint for CreateWin32SurfaceKHR
vkCreateWin32SurfaceKHR(VkInstance instance, const VkWin32SurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)585 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateWin32SurfaceKHR(VkInstance instance,
586                                                                      const VkWin32SurfaceCreateInfoKHR *pCreateInfo,
587                                                                      const VkAllocationCallbacks *pAllocator,
588                                                                      VkSurfaceKHR *pSurface) {
589     struct loader_instance *loader_inst = loader_get_instance(instance);
590     if (NULL == loader_inst) {
591         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
592                    "vkCreateWin32SurfaceKHR: Invalid instance [VUID-vkCreateWin32SurfaceKHR-instance-parameter]");
593         abort(); /* Intentionally fail so user can correct issue. */
594     }
595     return loader_inst->disp->layer_inst_disp.CreateWin32SurfaceKHR(loader_inst->instance, pCreateInfo, pAllocator, pSurface);
596 }
597 
598 // This is the instance chain terminator function for CreateWin32SurfaceKHR
terminator_CreateWin32SurfaceKHR(VkInstance instance, const VkWin32SurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)599 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateWin32SurfaceKHR(VkInstance instance, const VkWin32SurfaceCreateInfoKHR *pCreateInfo,
600                                                                 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
601     VkResult vkRes = VK_SUCCESS;
602     VkIcdSurface *pIcdSurface = NULL;
603     uint32_t i = 0;
604 
605     // Initialize pSurface to NULL just to be safe.
606     *pSurface = VK_NULL_HANDLE;
607     // First, check to ensure the appropriate extension was enabled:
608     struct loader_instance *loader_inst = loader_get_instance(instance);
609     if (!loader_inst->wsi_win32_surface_enabled) {
610         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
611                    "VK_KHR_win32_surface extension not enabled. vkCreateWin32SurfaceKHR not executed!");
612         vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
613         goto out;
614     }
615 
616     // Next, if so, proceed with the implementation of this function:
617     pIcdSurface = AllocateIcdSurfaceStruct(loader_inst, sizeof(pIcdSurface->win_surf.base), sizeof(pIcdSurface->win_surf));
618     if (pIcdSurface == NULL) {
619         vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
620         goto out;
621     }
622 
623     pIcdSurface->win_surf.base.platform = VK_ICD_WSI_PLATFORM_WIN32;
624     pIcdSurface->win_surf.hinstance = pCreateInfo->hinstance;
625     pIcdSurface->win_surf.hwnd = pCreateInfo->hwnd;
626 
627     // Loop through each ICD and determine if they need to create a surface
628     for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
629         if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
630             if (NULL != icd_term->dispatch.CreateWin32SurfaceKHR) {
631                 vkRes = icd_term->dispatch.CreateWin32SurfaceKHR(icd_term->instance, pCreateInfo, pAllocator,
632                                                                  &pIcdSurface->real_icd_surfaces[i]);
633                 if (VK_SUCCESS != vkRes) {
634                     goto out;
635                 }
636             }
637         }
638     }
639 
640     *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface;
641 
642 out:
643 
644     if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
645         if (NULL != pIcdSurface->real_icd_surfaces) {
646             i = 0;
647             for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
648                 if ((VkSurfaceKHR)(uintptr_t)NULL != pIcdSurface->real_icd_surfaces[i] &&
649                     NULL != icd_term->dispatch.DestroySurfaceKHR) {
650                     icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
651                 }
652             }
653             loader_instance_heap_free(loader_inst, pIcdSurface->real_icd_surfaces);
654         }
655         loader_instance_heap_free(loader_inst, pIcdSurface);
656     }
657 
658     return vkRes;
659 }
660 
661 // This is the trampoline entrypoint for
662 // GetPhysicalDeviceWin32PresentationSupportKHR
vkGetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex)663 LOADER_EXPORT VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice physicalDevice,
664                                                                                             uint32_t queueFamilyIndex) {
665     const VkLayerInstanceDispatchTable *disp;
666     VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
667     if (VK_NULL_HANDLE == unwrapped_phys_dev) {
668         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
669                    "vkGetPhysicalDeviceWin32PresentationSupportKHR: Invalid physicalDevice "
670                    "[VUID-vkGetPhysicalDeviceWin32PresentationSupportKHR-physicalDevice-parameter]");
671         abort(); /* Intentionally fail so user can correct issue. */
672     }
673     disp = loader_get_instance_layer_dispatch(physicalDevice);
674     return disp->GetPhysicalDeviceWin32PresentationSupportKHR(unwrapped_phys_dev, queueFamilyIndex);
675 }
676 
677 // This is the instance chain terminator function for
678 // GetPhysicalDeviceWin32PresentationSupportKHR
terminator_GetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex)679 VKAPI_ATTR VkBool32 VKAPI_CALL terminator_GetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice physicalDevice,
680                                                                                        uint32_t queueFamilyIndex) {
681     // First, check to ensure the appropriate extension was enabled:
682     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
683     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
684     struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
685     if (!loader_inst->wsi_win32_surface_enabled) {
686         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
687                    "VK_KHR_win32_surface extension not enabled. vkGetPhysicalDeviceWin32PresentationSupportKHR not executed!");
688         return VK_FALSE;
689     }
690 
691     if (NULL == icd_term->dispatch.GetPhysicalDeviceWin32PresentationSupportKHR) {
692         // return VK_FALSE as this driver doesn't support WSI functionality
693         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
694                    "ICD for selected physical device does not export vkGetPhysicalDeviceWin32PresentationSupportKHR!");
695         return VK_FALSE;
696     }
697 
698     return icd_term->dispatch.GetPhysicalDeviceWin32PresentationSupportKHR(phys_dev_term->phys_dev, queueFamilyIndex);
699 }
700 #endif  // VK_USE_PLATFORM_WIN32_KHR
701 
702 #if defined(VK_USE_PLATFORM_WAYLAND_KHR)
703 
704 // This is the trampoline entrypoint for CreateWaylandSurfaceKHR
vkCreateWaylandSurfaceKHR(VkInstance instance, const VkWaylandSurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)705 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateWaylandSurfaceKHR(VkInstance instance,
706                                                                        const VkWaylandSurfaceCreateInfoKHR *pCreateInfo,
707                                                                        const VkAllocationCallbacks *pAllocator,
708                                                                        VkSurfaceKHR *pSurface) {
709     struct loader_instance *loader_inst = loader_get_instance(instance);
710     if (NULL == loader_inst) {
711         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
712                    "vkCreateWaylandSurfaceKHR: Invalid instance [VUID-vkCreateWaylandSurfaceKHR-instance-parameter]");
713         abort(); /* Intentionally fail so user can correct issue. */
714     }
715     return loader_inst->disp->layer_inst_disp.CreateWaylandSurfaceKHR(loader_inst->instance, pCreateInfo, pAllocator, pSurface);
716 }
717 
718 // This is the instance chain terminator function for CreateWaylandSurfaceKHR
terminator_CreateWaylandSurfaceKHR(VkInstance instance, const VkWaylandSurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)719 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateWaylandSurfaceKHR(VkInstance instance,
720                                                                   const VkWaylandSurfaceCreateInfoKHR *pCreateInfo,
721                                                                   const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
722     VkResult vkRes = VK_SUCCESS;
723     VkIcdSurface *pIcdSurface = NULL;
724     uint32_t i = 0;
725 
726     // First, check to ensure the appropriate extension was enabled:
727     struct loader_instance *loader_inst = loader_get_instance(instance);
728     if (!loader_inst->wsi_wayland_surface_enabled) {
729         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
730                    "VK_KHR_wayland_surface extension not enabled. vkCreateWaylandSurfaceKHR not executed!");
731         vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
732         goto out;
733     }
734 
735     // Next, if so, proceed with the implementation of this function:
736     pIcdSurface = AllocateIcdSurfaceStruct(loader_inst, sizeof(pIcdSurface->wayland_surf.base), sizeof(pIcdSurface->wayland_surf));
737     if (pIcdSurface == NULL) {
738         vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
739         goto out;
740     }
741 
742     pIcdSurface->wayland_surf.base.platform = VK_ICD_WSI_PLATFORM_WAYLAND;
743     pIcdSurface->wayland_surf.display = pCreateInfo->display;
744     pIcdSurface->wayland_surf.surface = pCreateInfo->surface;
745 
746     // Loop through each ICD and determine if they need to create a surface
747     for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
748         if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
749             if (NULL != icd_term->dispatch.CreateWaylandSurfaceKHR) {
750                 vkRes = icd_term->dispatch.CreateWaylandSurfaceKHR(icd_term->instance, pCreateInfo, pAllocator,
751                                                                    &pIcdSurface->real_icd_surfaces[i]);
752                 if (VK_SUCCESS != vkRes) {
753                     goto out;
754                 }
755             }
756         }
757     }
758 
759     *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface;
760 
761 out:
762 
763     if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
764         if (NULL != pIcdSurface->real_icd_surfaces) {
765             i = 0;
766             for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
767                 if ((VkSurfaceKHR)(uintptr_t)NULL != pIcdSurface->real_icd_surfaces[i] &&
768                     NULL != icd_term->dispatch.DestroySurfaceKHR) {
769                     icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
770                 }
771             }
772             loader_instance_heap_free(loader_inst, pIcdSurface->real_icd_surfaces);
773         }
774         loader_instance_heap_free(loader_inst, pIcdSurface);
775     }
776 
777     return vkRes;
778 }
779 
780 // This is the trampoline entrypoint for
781 // GetPhysicalDeviceWaylandPresentationSupportKHR
vkGetPhysicalDeviceWaylandPresentationSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, struct wl_display *display)782 LOADER_EXPORT VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWaylandPresentationSupportKHR(VkPhysicalDevice physicalDevice,
783                                                                                               uint32_t queueFamilyIndex,
784                                                                                               struct wl_display *display) {
785     const VkLayerInstanceDispatchTable *disp;
786     VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
787     if (VK_NULL_HANDLE == unwrapped_phys_dev) {
788         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
789                    "vkGetPhysicalDeviceWaylandPresentationSupportKHR: Invalid physicalDevice "
790                    "[VUID-vkGetPhysicalDeviceWaylandPresentationSupportKHR-physicalDevice-parameter]");
791         abort(); /* Intentionally fail so user can correct issue. */
792     }
793     disp = loader_get_instance_layer_dispatch(physicalDevice);
794     return disp->GetPhysicalDeviceWaylandPresentationSupportKHR(unwrapped_phys_dev, queueFamilyIndex, display);
795 }
796 
797 // This is the instance chain terminator function for
798 // GetPhysicalDeviceWaylandPresentationSupportKHR
terminator_GetPhysicalDeviceWaylandPresentationSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, struct wl_display *display)799 VKAPI_ATTR VkBool32 VKAPI_CALL terminator_GetPhysicalDeviceWaylandPresentationSupportKHR(VkPhysicalDevice physicalDevice,
800                                                                                          uint32_t queueFamilyIndex,
801                                                                                          struct wl_display *display) {
802     // First, check to ensure the appropriate extension was enabled:
803     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
804     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
805     struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
806     if (!loader_inst->wsi_wayland_surface_enabled) {
807         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
808                    "VK_KHR_wayland_surface extension not enabled. vkGetPhysicalDeviceWaylandPresentationSupportKHR not executed!");
809         return VK_FALSE;
810     }
811 
812     if (NULL == icd_term->dispatch.GetPhysicalDeviceWaylandPresentationSupportKHR) {
813         // return VK_FALSE as this driver doesn't support WSI functionality
814         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
815                    "ICD for selected physical device does not export vkGetPhysicalDeviceWaylandPresentationSupportKHR!");
816         return VK_FALSE;
817     }
818 
819     return icd_term->dispatch.GetPhysicalDeviceWaylandPresentationSupportKHR(phys_dev_term->phys_dev, queueFamilyIndex, display);
820 }
821 #endif  // VK_USE_PLATFORM_WAYLAND_KHR
822 
823 #if defined(VK_USE_PLATFORM_XCB_KHR)
824 
825 // Functions for the VK_KHR_xcb_surface extension:
826 
827 // This is the trampoline entrypoint for CreateXcbSurfaceKHR
vkCreateXcbSurfaceKHR(VkInstance instance, const VkXcbSurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)828 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateXcbSurfaceKHR(VkInstance instance,
829                                                                    const VkXcbSurfaceCreateInfoKHR *pCreateInfo,
830                                                                    const VkAllocationCallbacks *pAllocator,
831                                                                    VkSurfaceKHR *pSurface) {
832     struct loader_instance *loader_inst = loader_get_instance(instance);
833     if (NULL == loader_inst) {
834         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
835                    "vkCreateXcbSurfaceKHR: Invalid instance [VUID-vkCreateXcbSurfaceKHR-instance-parameter]");
836         abort(); /* Intentionally fail so user can correct issue. */
837     }
838     return loader_inst->disp->layer_inst_disp.CreateXcbSurfaceKHR(loader_inst->instance, pCreateInfo, pAllocator, pSurface);
839 }
840 
841 // This is the instance chain terminator function for CreateXcbSurfaceKHR
terminator_CreateXcbSurfaceKHR(VkInstance instance, const VkXcbSurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)842 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateXcbSurfaceKHR(VkInstance instance, const VkXcbSurfaceCreateInfoKHR *pCreateInfo,
843                                                               const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
844     VkResult vkRes = VK_SUCCESS;
845     VkIcdSurface *pIcdSurface = NULL;
846     uint32_t i = 0;
847 
848     // First, check to ensure the appropriate extension was enabled:
849     struct loader_instance *loader_inst = loader_get_instance(instance);
850     if (!loader_inst->wsi_xcb_surface_enabled) {
851         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
852                    "VK_KHR_xcb_surface extension not enabled. vkCreateXcbSurfaceKHR not executed!");
853         vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
854         goto out;
855     }
856 
857     // Next, if so, proceed with the implementation of this function:
858     pIcdSurface = AllocateIcdSurfaceStruct(loader_inst, sizeof(pIcdSurface->xcb_surf.base), sizeof(pIcdSurface->xcb_surf));
859     if (pIcdSurface == NULL) {
860         vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
861         goto out;
862     }
863 
864     pIcdSurface->xcb_surf.base.platform = VK_ICD_WSI_PLATFORM_XCB;
865     pIcdSurface->xcb_surf.connection = pCreateInfo->connection;
866     pIcdSurface->xcb_surf.window = pCreateInfo->window;
867 
868     // Loop through each ICD and determine if they need to create a surface
869     for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
870         if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
871             if (NULL != icd_term->dispatch.CreateXcbSurfaceKHR) {
872                 vkRes = icd_term->dispatch.CreateXcbSurfaceKHR(icd_term->instance, pCreateInfo, pAllocator,
873                                                                &pIcdSurface->real_icd_surfaces[i]);
874                 if (VK_SUCCESS != vkRes) {
875                     goto out;
876                 }
877             }
878         }
879     }
880 
881     *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface;
882 
883 out:
884 
885     if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
886         if (NULL != pIcdSurface->real_icd_surfaces) {
887             i = 0;
888             for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
889                 if ((VkSurfaceKHR)(uintptr_t)NULL != pIcdSurface->real_icd_surfaces[i] &&
890                     NULL != icd_term->dispatch.DestroySurfaceKHR) {
891                     icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
892                 }
893             }
894             loader_instance_heap_free(loader_inst, pIcdSurface->real_icd_surfaces);
895         }
896         loader_instance_heap_free(loader_inst, pIcdSurface);
897     }
898 
899     return vkRes;
900 }
901 
902 // This is the trampoline entrypoint for
903 // GetPhysicalDeviceXcbPresentationSupportKHR
vkGetPhysicalDeviceXcbPresentationSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, xcb_connection_t *connection, xcb_visualid_t visual_id)904 LOADER_EXPORT VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceXcbPresentationSupportKHR(VkPhysicalDevice physicalDevice,
905                                                                                           uint32_t queueFamilyIndex,
906                                                                                           xcb_connection_t *connection,
907                                                                                           xcb_visualid_t visual_id) {
908     const VkLayerInstanceDispatchTable *disp;
909     VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
910     if (VK_NULL_HANDLE == unwrapped_phys_dev) {
911         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
912                    "vkGetPhysicalDeviceXcbPresentationSupportKHR: Invalid physicalDevice "
913                    "[VUID-vkGetPhysicalDeviceXcbPresentationSupportKHR-physicalDevice-parameter]");
914         abort(); /* Intentionally fail so user can correct issue. */
915     }
916     disp = loader_get_instance_layer_dispatch(physicalDevice);
917     return disp->GetPhysicalDeviceXcbPresentationSupportKHR(unwrapped_phys_dev, queueFamilyIndex, connection, visual_id);
918 }
919 
920 // This is the instance chain terminator function for
921 // GetPhysicalDeviceXcbPresentationSupportKHR
terminator_GetPhysicalDeviceXcbPresentationSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, xcb_connection_t *connection, xcb_visualid_t visual_id)922 VKAPI_ATTR VkBool32 VKAPI_CALL terminator_GetPhysicalDeviceXcbPresentationSupportKHR(VkPhysicalDevice physicalDevice,
923                                                                                      uint32_t queueFamilyIndex,
924                                                                                      xcb_connection_t *connection,
925                                                                                      xcb_visualid_t visual_id) {
926     // First, check to ensure the appropriate extension was enabled:
927     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
928     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
929     struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
930     if (!loader_inst->wsi_xcb_surface_enabled) {
931         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
932                    "VK_KHR_xcb_surface extension not enabled. vkGetPhysicalDeviceXcbPresentationSupportKHR not executed!");
933         return VK_FALSE;
934     }
935 
936     if (NULL == icd_term->dispatch.GetPhysicalDeviceXcbPresentationSupportKHR) {
937         // return VK_FALSE as this driver doesn't support WSI functionality
938         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
939                    "ICD for selected physical device does not export vkGetPhysicalDeviceXcbPresentationSupportKHR!");
940         return VK_FALSE;
941     }
942 
943     return icd_term->dispatch.GetPhysicalDeviceXcbPresentationSupportKHR(phys_dev_term->phys_dev, queueFamilyIndex, connection,
944                                                                          visual_id);
945 }
946 #endif  // VK_USE_PLATFORM_XCB_KHR
947 
948 #if defined(VK_USE_PLATFORM_XLIB_KHR)
949 
950 // Functions for the VK_KHR_xlib_surface extension:
951 
952 // This is the trampoline entrypoint for CreateXlibSurfaceKHR
vkCreateXlibSurfaceKHR(VkInstance instance, const VkXlibSurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)953 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateXlibSurfaceKHR(VkInstance instance,
954                                                                     const VkXlibSurfaceCreateInfoKHR *pCreateInfo,
955                                                                     const VkAllocationCallbacks *pAllocator,
956                                                                     VkSurfaceKHR *pSurface) {
957     struct loader_instance *loader_inst = loader_get_instance(instance);
958     if (NULL == loader_inst) {
959         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
960                    "vkCreateXlibSurfaceKHR: Invalid instance [VUID-vkCreateXlibSurfaceKHR-instance-parameter]");
961         abort(); /* Intentionally fail so user can correct issue. */
962     }
963     return loader_inst->disp->layer_inst_disp.CreateXlibSurfaceKHR(loader_inst->instance, pCreateInfo, pAllocator, pSurface);
964 }
965 
966 // This is the instance chain terminator function for CreateXlibSurfaceKHR
terminator_CreateXlibSurfaceKHR(VkInstance instance, const VkXlibSurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)967 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateXlibSurfaceKHR(VkInstance instance, const VkXlibSurfaceCreateInfoKHR *pCreateInfo,
968                                                                const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
969     VkResult vkRes = VK_SUCCESS;
970     VkIcdSurface *pIcdSurface = NULL;
971     uint32_t i = 0;
972 
973     // First, check to ensure the appropriate extension was enabled:
974     struct loader_instance *loader_inst = loader_get_instance(instance);
975     if (!loader_inst->wsi_xlib_surface_enabled) {
976         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
977                    "VK_KHR_xlib_surface extension not enabled. vkCreateXlibSurfaceKHR not executed!");
978         vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
979         goto out;
980     }
981 
982     // Next, if so, proceed with the implementation of this function:
983     pIcdSurface = AllocateIcdSurfaceStruct(loader_inst, sizeof(pIcdSurface->xlib_surf.base), sizeof(pIcdSurface->xlib_surf));
984     if (pIcdSurface == NULL) {
985         vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
986         goto out;
987     }
988 
989     pIcdSurface->xlib_surf.base.platform = VK_ICD_WSI_PLATFORM_XLIB;
990     pIcdSurface->xlib_surf.dpy = pCreateInfo->dpy;
991     pIcdSurface->xlib_surf.window = pCreateInfo->window;
992 
993     // Loop through each ICD and determine if they need to create a surface
994     for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
995         if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
996             if (NULL != icd_term->dispatch.CreateXlibSurfaceKHR) {
997                 vkRes = icd_term->dispatch.CreateXlibSurfaceKHR(icd_term->instance, pCreateInfo, pAllocator,
998                                                                 &pIcdSurface->real_icd_surfaces[i]);
999                 if (VK_SUCCESS != vkRes) {
1000                     goto out;
1001                 }
1002             }
1003         }
1004     }
1005 
1006     *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface;
1007 
1008 out:
1009 
1010     if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
1011         if (NULL != pIcdSurface->real_icd_surfaces) {
1012             i = 0;
1013             for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
1014                 if ((VkSurfaceKHR)(uintptr_t)NULL != pIcdSurface->real_icd_surfaces[i] &&
1015                     NULL != icd_term->dispatch.DestroySurfaceKHR) {
1016                     icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
1017                 }
1018             }
1019             loader_instance_heap_free(loader_inst, pIcdSurface->real_icd_surfaces);
1020         }
1021         loader_instance_heap_free(loader_inst, pIcdSurface);
1022     }
1023 
1024     return vkRes;
1025 }
1026 
1027 // This is the trampoline entrypoint for
1028 // GetPhysicalDeviceXlibPresentationSupportKHR
vkGetPhysicalDeviceXlibPresentationSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, Display *dpy, VisualID visualID)1029 LOADER_EXPORT VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceXlibPresentationSupportKHR(VkPhysicalDevice physicalDevice,
1030                                                                                            uint32_t queueFamilyIndex, Display *dpy,
1031                                                                                            VisualID visualID) {
1032     const VkLayerInstanceDispatchTable *disp;
1033     VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
1034     if (VK_NULL_HANDLE == unwrapped_phys_dev) {
1035         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1036                    "vkGetPhysicalDeviceXlibPresentationSupportKHR: Invalid physicalDevice "
1037                    "[VUID-vkGetPhysicalDeviceXlibPresentationSupportKHR-physicalDevice-parameter]");
1038         abort(); /* Intentionally fail so user can correct issue. */
1039     }
1040     disp = loader_get_instance_layer_dispatch(physicalDevice);
1041     return disp->GetPhysicalDeviceXlibPresentationSupportKHR(unwrapped_phys_dev, queueFamilyIndex, dpy, visualID);
1042 }
1043 
1044 // This is the instance chain terminator function for
1045 // GetPhysicalDeviceXlibPresentationSupportKHR
terminator_GetPhysicalDeviceXlibPresentationSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, Display *dpy, VisualID visualID)1046 VKAPI_ATTR VkBool32 VKAPI_CALL terminator_GetPhysicalDeviceXlibPresentationSupportKHR(VkPhysicalDevice physicalDevice,
1047                                                                                       uint32_t queueFamilyIndex, Display *dpy,
1048                                                                                       VisualID visualID) {
1049     // First, check to ensure the appropriate extension was enabled:
1050     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
1051     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
1052     struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
1053     if (!loader_inst->wsi_xlib_surface_enabled) {
1054         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
1055                    "VK_KHR_xlib_surface extension not enabled. vkGetPhysicalDeviceXlibPresentationSupportKHR not executed!");
1056         return VK_FALSE;
1057     }
1058 
1059     if (NULL == icd_term->dispatch.GetPhysicalDeviceXlibPresentationSupportKHR) {
1060         // return VK_FALSE as this driver doesn't support WSI functionality
1061         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
1062                    "ICD for selected physical device does not export vkGetPhysicalDeviceXlibPresentationSupportKHR!");
1063         return VK_FALSE;
1064     }
1065 
1066     return icd_term->dispatch.GetPhysicalDeviceXlibPresentationSupportKHR(phys_dev_term->phys_dev, queueFamilyIndex, dpy, visualID);
1067 }
1068 #endif  // VK_USE_PLATFORM_XLIB_KHR
1069 
1070 #if defined(VK_USE_PLATFORM_DIRECTFB_EXT)
1071 
1072 // Functions for the VK_EXT_directfb_surface extension:
1073 
1074 // This is the trampoline entrypoint for CreateDirectFBSurfaceEXT
vkCreateDirectFBSurfaceEXT(VkInstance instance, const VkDirectFBSurfaceCreateInfoEXT *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)1075 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDirectFBSurfaceEXT(VkInstance instance,
1076                                                                         const VkDirectFBSurfaceCreateInfoEXT *pCreateInfo,
1077                                                                         const VkAllocationCallbacks *pAllocator,
1078                                                                         VkSurfaceKHR *pSurface) {
1079     struct loader_instance *loader_inst = loader_get_instance(instance);
1080     if (NULL == loader_inst) {
1081         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1082                    "vkCreateDirectFBSurfaceEXT: Invalid instance [VUID-vkCreateDirectFBSurfaceEXT-instance-parameter]");
1083         abort(); /* Intentionally fail so user can correct issue. */
1084     }
1085     return loader_inst->disp->layer_inst_disp.CreateDirectFBSurfaceEXT(loader_inst->instance, pCreateInfo, pAllocator, pSurface);
1086 }
1087 
1088 // This is the instance chain terminator function for CreateDirectFBSurfaceEXT
terminator_CreateDirectFBSurfaceEXT(VkInstance instance, const VkDirectFBSurfaceCreateInfoEXT *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)1089 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDirectFBSurfaceEXT(VkInstance instance,
1090                                                                    const VkDirectFBSurfaceCreateInfoEXT *pCreateInfo,
1091                                                                    const VkAllocationCallbacks *pAllocator,
1092                                                                    VkSurfaceKHR *pSurface) {
1093     VkResult vkRes = VK_SUCCESS;
1094     VkIcdSurface *pIcdSurface = NULL;
1095     uint32_t i = 0;
1096 
1097     // First, check to ensure the appropriate extension was enabled:
1098     struct loader_instance *loader_inst = loader_get_instance(instance);
1099     if (!loader_inst->wsi_directfb_surface_enabled) {
1100         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
1101                    "VK_EXT_directfb_surface extension not enabled. vkCreateDirectFBSurfaceEXT not executed!");
1102         vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
1103         goto out;
1104     }
1105 
1106     // Next, if so, proceed with the implementation of this function:
1107     pIcdSurface =
1108         AllocateIcdSurfaceStruct(loader_inst, sizeof(pIcdSurface->directfb_surf.base), sizeof(pIcdSurface->directfb_surf));
1109     if (pIcdSurface == NULL) {
1110         vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
1111         goto out;
1112     }
1113 
1114     pIcdSurface->directfb_surf.base.platform = VK_ICD_WSI_PLATFORM_DIRECTFB;
1115     pIcdSurface->directfb_surf.dfb = pCreateInfo->dfb;
1116     pIcdSurface->directfb_surf.surface = pCreateInfo->surface;
1117 
1118     // Loop through each ICD and determine if they need to create a surface
1119     for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
1120         if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
1121             if (NULL != icd_term->dispatch.CreateDirectFBSurfaceEXT) {
1122                 vkRes = icd_term->dispatch.CreateDirectFBSurfaceEXT(icd_term->instance, pCreateInfo, pAllocator,
1123                                                                     &pIcdSurface->real_icd_surfaces[i]);
1124                 if (VK_SUCCESS != vkRes) {
1125                     goto out;
1126                 }
1127             }
1128         }
1129     }
1130 
1131     *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface;
1132 
1133 out:
1134 
1135     if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
1136         if (NULL != pIcdSurface->real_icd_surfaces) {
1137             i = 0;
1138             for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
1139                 if ((VkSurfaceKHR)(uintptr_t)NULL != pIcdSurface->real_icd_surfaces[i] &&
1140                     NULL != icd_term->dispatch.DestroySurfaceKHR) {
1141                     icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
1142                 }
1143             }
1144             loader_instance_heap_free(loader_inst, pIcdSurface->real_icd_surfaces);
1145         }
1146         loader_instance_heap_free(loader_inst, pIcdSurface);
1147     }
1148 
1149     return vkRes;
1150 }
1151 
1152 // This is the trampoline entrypoint for
1153 // GetPhysicalDeviceDirectFBPresentationSupportEXT
vkGetPhysicalDeviceDirectFBPresentationSupportEXT(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, IDirectFB *dfb)1154 LOADER_EXPORT VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceDirectFBPresentationSupportEXT(VkPhysicalDevice physicalDevice,
1155                                                                                                uint32_t queueFamilyIndex,
1156                                                                                                IDirectFB *dfb) {
1157     const VkLayerInstanceDispatchTable *disp;
1158     VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
1159     if (VK_NULL_HANDLE == unwrapped_phys_dev) {
1160         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1161                    "vkGetPhysicalDeviceDirectFBPresentationSupportEXT: Invalid physicalDevice "
1162                    "[VUID-vkGetPhysicalDeviceDirectFBPresentationSupportEXT-physicalDevice-parameter]");
1163         abort(); /* Intentionally fail so user can correct issue. */
1164     }
1165     disp = loader_get_instance_layer_dispatch(physicalDevice);
1166     return disp->GetPhysicalDeviceDirectFBPresentationSupportEXT(unwrapped_phys_dev, queueFamilyIndex, dfb);
1167 }
1168 
1169 // This is the instance chain terminator function for
1170 // GetPhysicalDeviceDirectFBPresentationSupportEXT
terminator_GetPhysicalDeviceDirectFBPresentationSupportEXT(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, IDirectFB *dfb)1171 VKAPI_ATTR VkBool32 VKAPI_CALL terminator_GetPhysicalDeviceDirectFBPresentationSupportEXT(VkPhysicalDevice physicalDevice,
1172                                                                                           uint32_t queueFamilyIndex,
1173                                                                                           IDirectFB *dfb) {
1174     // First, check to ensure the appropriate extension was enabled:
1175     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
1176     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
1177     struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
1178     if (!loader_inst->wsi_directfb_surface_enabled) {
1179         loader_log(
1180             loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
1181             "VK_EXT_directfb_surface extension not enabled. vkGetPhysicalDeviceDirectFBPresentationSupportKHR not executed!");
1182         return VK_FALSE;
1183     }
1184 
1185     if (NULL == icd_term->dispatch.GetPhysicalDeviceDirectFBPresentationSupportEXT) {
1186         // return VK_FALSE as this driver doesn't support WSI functionality
1187         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
1188                    "ICD for selected physical device does not export vkGetPhysicalDeviceDirectFBPresentationSupportEXT!");
1189         return VK_FALSE;
1190     }
1191 
1192     return icd_term->dispatch.GetPhysicalDeviceDirectFBPresentationSupportEXT(phys_dev_term->phys_dev, queueFamilyIndex, dfb);
1193 }
1194 
1195 #endif  // VK_USE_PLATFORM_DIRECTFB_EXT
1196 
1197 #if defined(VK_USE_PLATFORM_ANDROID_KHR)
1198 
1199 // Functions for the VK_KHR_android_surface extension:
1200 
1201 // This is the trampoline entrypoint for CreateAndroidSurfaceKHR
vkCreateAndroidSurfaceKHR(VkInstance instance, const VkAndroidSurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)1202 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateAndroidSurfaceKHR(VkInstance instance,
1203                                                                        const VkAndroidSurfaceCreateInfoKHR *pCreateInfo,
1204                                                                        const VkAllocationCallbacks *pAllocator,
1205                                                                        VkSurfaceKHR *pSurface) {
1206     struct loader_instance *loader_inst = loader_get_instance(instance);
1207     if (NULL == loader_inst) {
1208         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1209                    "vkCreateAndroidSurfaceKHR: Invalid instance [VUID-vkCreateAndroidSurfaceKHR-instance-parameter]");
1210         abort(); /* Intentionally fail so user can correct issue. */
1211     }
1212     return loader_inst->disp->layer_inst_disp.CreateAndroidSurfaceKHR(loader_inst->instance, pCreateInfo, pAllocator, pSurface);
1213 }
1214 
1215 // This is the instance chain terminator function for CreateAndroidSurfaceKHR
terminator_CreateAndroidSurfaceKHR(VkInstance instance, const VkAndroidSurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)1216 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateAndroidSurfaceKHR(VkInstance instance,
1217                                                                   const VkAndroidSurfaceCreateInfoKHR *pCreateInfo,
1218                                                                   const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
1219     // First, check to ensure the appropriate extension was enabled:
1220     struct loader_instance *loader_inst = loader_get_instance(instance);
1221     if (!loader_inst->wsi_display_enabled) {
1222         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
1223                    "VK_KHR_display extension not enabled. vkCreateAndroidSurfaceKHR not executed!");
1224         return VK_ERROR_EXTENSION_NOT_PRESENT;
1225     }
1226 
1227     // Next, if so, proceed with the implementation of this function:
1228     VkIcdSurfaceAndroid *pIcdSurface =
1229         loader_instance_heap_alloc(loader_inst, sizeof(VkIcdSurfaceAndroid), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1230     if (pIcdSurface == NULL) {
1231         return VK_ERROR_OUT_OF_HOST_MEMORY;
1232     }
1233 
1234     pIcdSurface->base.platform = VK_ICD_WSI_PLATFORM_ANDROID;
1235     pIcdSurface->window = pCreateInfo->window;
1236 
1237     *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface;
1238 
1239     return VK_SUCCESS;
1240 }
1241 
1242 #endif  // VK_USE_PLATFORM_ANDROID_KHR
1243 
1244 #if defined(VK_USE_PLATFORM_OHOS)
1245 
1246 // Functions for the VK_OHOS_surface extension:
1247 
1248 // This is the trampoline entrypoint for CreateSurfaceOHOS
1249 
vkCreateSurfaceOHOS(VkInstance instance, const VkSurfaceCreateInfoOHOS *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)1250 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateSurfaceOHOS(VkInstance instance,
1251 																 const VkSurfaceCreateInfoOHOS *pCreateInfo,
1252                                                                  const VkAllocationCallbacks *pAllocator,
1253                                                                  VkSurfaceKHR *pSurface) {
1254     struct loader_instance *loader_inst = loader_get_instance(instance);
1255     if (NULL == loader_inst) {
1256         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1257                    "vkCreateSurfaceOHOS: Invalid instance [VUID-vkCreateSurfaceOHOS-instance-parameter]");
1258         abort(); /* Intentionally fail so user can correct issue. */
1259     }
1260     return loader_inst->disp->layer_inst_disp.CreateSurfaceOHOS(loader_inst->instance, pCreateInfo, pAllocator, pSurface);
1261 }
1262 
1263 // This is the instance chain terminator function for CreateSurfaceOHOS
terminator_CreateSurfaceOHOS(VkInstance instance, const VkSurfaceCreateInfoOHOS *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)1264 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateSurfaceOHOS(VkInstance instance,
1265                                                             const VkSurfaceCreateInfoOHOS *pCreateInfo,
1266                                                             const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
1267     // First, check to ensure the appropriate extension was enabled:
1268     struct loader_instance *loader_inst = loader_get_instance(instance);
1269     if (!loader_inst->wsi_ohos_surface_enabled) {
1270         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
1271                    "VK_OHOS_surface extension not enabled. vkCreateSurfaceOHOS not executed!\n");
1272         return VK_ERROR_EXTENSION_NOT_PRESENT;
1273     }
1274 
1275     // Next, if so, proceed with the implementation of this function:
1276     VkIcdSurfaceOHOS *pIcdSurface =
1277         loader_instance_heap_alloc(loader_inst, sizeof(VkIcdSurfaceOHOS), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1278     if (pIcdSurface == NULL) {
1279         return VK_ERROR_OUT_OF_HOST_MEMORY;
1280     }
1281 
1282     pIcdSurface->base.platform = VK_ICD_WSI_PLATFORM_OHOS;
1283     pIcdSurface->window = pCreateInfo->window;
1284 
1285     *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface;
1286 
1287     return VK_SUCCESS;
1288 }
1289 
1290 #endif  // VK_USE_PLATFORM_OHOS
1291 
1292 
1293 // Functions for the VK_EXT_headless_surface extension:
1294 
vkCreateHeadlessSurfaceEXT(VkInstance instance, const VkHeadlessSurfaceCreateInfoEXT *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)1295 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateHeadlessSurfaceEXT(VkInstance instance,
1296                                                                         const VkHeadlessSurfaceCreateInfoEXT *pCreateInfo,
1297                                                                         const VkAllocationCallbacks *pAllocator,
1298                                                                         VkSurfaceKHR *pSurface) {
1299     struct loader_instance *loader_inst = loader_get_instance(instance);
1300     if (NULL == loader_inst) {
1301         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1302                    "vkCreateHeadlessSurfaceEXT: Invalid instance [VUID-vkCreateHeadlessSurfaceEXT-instance-parameter]");
1303         abort(); /* Intentionally fail so user can correct issue. */
1304     }
1305     return loader_inst->disp->layer_inst_disp.CreateHeadlessSurfaceEXT(loader_inst->instance, pCreateInfo, pAllocator, pSurface);
1306 }
1307 
terminator_CreateHeadlessSurfaceEXT(VkInstance instance, const VkHeadlessSurfaceCreateInfoEXT *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)1308 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateHeadlessSurfaceEXT(VkInstance instance,
1309                                                                    const VkHeadlessSurfaceCreateInfoEXT *pCreateInfo,
1310                                                                    const VkAllocationCallbacks *pAllocator,
1311                                                                    VkSurfaceKHR *pSurface) {
1312     struct loader_instance *inst = loader_get_instance(instance);
1313     VkIcdSurface *pIcdSurface = NULL;
1314     VkResult vkRes = VK_SUCCESS;
1315     uint32_t i = 0;
1316 
1317     if (!inst->wsi_headless_surface_enabled) {
1318         loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0,
1319                    "VK_EXT_headless_surface extension not enabled.  "
1320                    "vkCreateHeadlessSurfaceEXT not executed!");
1321         return VK_SUCCESS;
1322     }
1323 
1324     // Next, if so, proceed with the implementation of this function:
1325     pIcdSurface = AllocateIcdSurfaceStruct(inst, sizeof(pIcdSurface->headless_surf.base), sizeof(pIcdSurface->headless_surf));
1326     if (pIcdSurface == NULL) {
1327         vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
1328         goto out;
1329     }
1330 
1331     pIcdSurface->headless_surf.base.platform = VK_ICD_WSI_PLATFORM_HEADLESS;
1332     // Loop through each ICD and determine if they need to create a surface
1333     for (struct loader_icd_term *icd_term = inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
1334         if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
1335             if (NULL != icd_term->dispatch.CreateHeadlessSurfaceEXT) {
1336                 vkRes = icd_term->dispatch.CreateHeadlessSurfaceEXT(icd_term->instance, pCreateInfo, pAllocator,
1337                                                                     &pIcdSurface->real_icd_surfaces[i]);
1338                 if (VK_SUCCESS != vkRes) {
1339                     goto out;
1340                 }
1341             }
1342         }
1343     }
1344 
1345     *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface;
1346 
1347 out:
1348 
1349     if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
1350         if (NULL != pIcdSurface->real_icd_surfaces) {
1351             i = 0;
1352             for (struct loader_icd_term *icd_term = inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
1353                 if ((VkSurfaceKHR)(uintptr_t)NULL != pIcdSurface->real_icd_surfaces[i] &&
1354                     NULL != icd_term->dispatch.DestroySurfaceKHR) {
1355                     icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
1356                 }
1357             }
1358             loader_instance_heap_free(inst, pIcdSurface->real_icd_surfaces);
1359         }
1360         loader_instance_heap_free(inst, pIcdSurface);
1361     }
1362 
1363     return vkRes;
1364 }
1365 
1366 // Ensure we are properly setting VK_USE_PLATFORM_METAL_EXT, VK_USE_PLATFORM_IOS_MVK, and VK_USE_PLATFORM_MACOS_MVK.
1367 #if __APPLE__
1368 
1369 #ifndef VK_USE_PLATFORM_METAL_EXT
1370 #error "VK_USE_PLATFORM_METAL_EXT not defined!"
1371 #endif
1372 
1373 #include <TargetConditionals.h>
1374 
1375 #if TARGET_OS_IOS
1376 
1377 #ifndef VK_USE_PLATFORM_IOS_MVK
1378 #error "VK_USE_PLATFORM_IOS_MVK not defined!"
1379 #endif
1380 
1381 #endif  //  TARGET_OS_IOS
1382 
1383 #if TARGET_OS_OSX
1384 
1385 #ifndef VK_USE_PLATFORM_MACOS_MVK
1386 #error "VK_USE_PLATFORM_MACOS_MVK not defined!"
1387 #endif
1388 
1389 #endif  // TARGET_OS_OSX
1390 
1391 #endif  // __APPLE__
1392 
1393 #if defined(VK_USE_PLATFORM_MACOS_MVK)
1394 
1395 // Functions for the VK_MVK_macos_surface extension:
1396 
1397 // This is the trampoline entrypoint for CreateMacOSSurfaceMVK
vkCreateMacOSSurfaceMVK(VkInstance instance, const VkMacOSSurfaceCreateInfoMVK *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)1398 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateMacOSSurfaceMVK(VkInstance instance,
1399                                                                      const VkMacOSSurfaceCreateInfoMVK *pCreateInfo,
1400                                                                      const VkAllocationCallbacks *pAllocator,
1401                                                                      VkSurfaceKHR *pSurface) {
1402     struct loader_instance *loader_inst = loader_get_instance(instance);
1403     if (NULL == loader_inst) {
1404         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1405                    "vkCreateMacOSSurfaceMVK: Invalid instance [VUID-vkCreateMacOSSurfaceMVK-instance-parameter]");
1406         abort(); /* Intentionally fail so user can correct issue. */
1407     }
1408     return loader_inst->disp->layer_inst_disp.CreateMacOSSurfaceMVK(loader_inst->instance, pCreateInfo, pAllocator, pSurface);
1409 }
1410 
1411 // This is the instance chain terminator function for CreateMacOSSurfaceKHR
terminator_CreateMacOSSurfaceMVK(VkInstance instance, const VkMacOSSurfaceCreateInfoMVK *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)1412 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateMacOSSurfaceMVK(VkInstance instance, const VkMacOSSurfaceCreateInfoMVK *pCreateInfo,
1413                                                                 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
1414     VkResult vkRes = VK_SUCCESS;
1415     VkIcdSurface *pIcdSurface = NULL;
1416     uint32_t i = 0;
1417 
1418     // First, check to ensure the appropriate extension was enabled:
1419     struct loader_instance *loader_inst = loader_get_instance(instance);
1420     if (!loader_inst->wsi_macos_surface_enabled) {
1421         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
1422                    "VK_MVK_macos_surface extension not enabled. vkCreateMacOSSurfaceMVK not executed!");
1423         vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
1424         goto out;
1425     }
1426 
1427     // Next, if so, proceed with the implementation of this function:
1428     pIcdSurface = AllocateIcdSurfaceStruct(loader_inst, sizeof(pIcdSurface->macos_surf.base), sizeof(pIcdSurface->macos_surf));
1429     if (pIcdSurface == NULL) {
1430         vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
1431         goto out;
1432     }
1433 
1434     pIcdSurface->macos_surf.base.platform = VK_ICD_WSI_PLATFORM_MACOS;
1435     pIcdSurface->macos_surf.pView = pCreateInfo->pView;
1436 
1437     // Loop through each ICD and determine if they need to create a surface
1438     for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
1439         if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
1440             if (NULL != icd_term->dispatch.CreateMacOSSurfaceMVK) {
1441                 vkRes = icd_term->dispatch.CreateMacOSSurfaceMVK(icd_term->instance, pCreateInfo, pAllocator,
1442                                                                  &pIcdSurface->real_icd_surfaces[i]);
1443                 if (VK_SUCCESS != vkRes) {
1444                     goto out;
1445                 }
1446             }
1447         }
1448     }
1449 
1450     *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface;
1451 
1452 out:
1453 
1454     if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
1455         if (NULL != pIcdSurface->real_icd_surfaces) {
1456             i = 0;
1457             for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
1458                 if ((VkSurfaceKHR)(uintptr_t)NULL != pIcdSurface->real_icd_surfaces[i] &&
1459                     NULL != icd_term->dispatch.DestroySurfaceKHR) {
1460                     icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
1461                 }
1462             }
1463             loader_instance_heap_free(loader_inst, pIcdSurface->real_icd_surfaces);
1464         }
1465         loader_instance_heap_free(loader_inst, pIcdSurface);
1466     }
1467 
1468     return vkRes;
1469 }
1470 
1471 #endif  // VK_USE_PLATFORM_MACOS_MVK
1472 
1473 #if defined(VK_USE_PLATFORM_IOS_MVK)
1474 
1475 // Functions for the VK_MVK_ios_surface extension:
1476 
1477 // This is the trampoline entrypoint for CreateIOSSurfaceMVK
vkCreateIOSSurfaceMVK(VkInstance instance, const VkIOSSurfaceCreateInfoMVK *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)1478 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateIOSSurfaceMVK(VkInstance instance,
1479                                                                    const VkIOSSurfaceCreateInfoMVK *pCreateInfo,
1480                                                                    const VkAllocationCallbacks *pAllocator,
1481                                                                    VkSurfaceKHR *pSurface) {
1482     struct loader_instance *loader_inst = loader_get_instance(instance);
1483     if (NULL == loader_inst) {
1484         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1485                    "vkCreateIOSSurfaceMVK: Invalid instance [VUID-vkCreateIOSSurfaceMVK-instance-parameter]");
1486         abort(); /* Intentionally fail so user can correct issue. */
1487     }
1488     return loader_inst->disp->layer_inst_disp.CreateIOSSurfaceMVK(loader_inst->instance, pCreateInfo, pAllocator, pSurface);
1489 }
1490 
1491 // This is the instance chain terminator function for CreateIOSSurfaceKHR
terminator_CreateIOSSurfaceMVK(VkInstance instance, const VkIOSSurfaceCreateInfoMVK *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)1492 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateIOSSurfaceMVK(VkInstance instance, const VkIOSSurfaceCreateInfoMVK *pCreateInfo,
1493                                                               const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
1494     (void)pAllocator;
1495 
1496     // First, check to ensure the appropriate extension was enabled:
1497     struct loader_instance *loader_inst = loader_get_instance(instance);
1498     if (!loader_inst->wsi_ios_surface_enabled) {
1499         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
1500                    "VK_MVK_ios_surface extension not enabled. vkCreateIOSSurfaceMVK not executed!");
1501         return VK_ERROR_EXTENSION_NOT_PRESENT;
1502     }
1503 
1504     // Next, if so, proceed with the implementation of this function:
1505     VkIcdSurfaceIOS *pIcdSurface =
1506         loader_instance_heap_alloc(loader_inst, sizeof(VkIcdSurfaceIOS), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1507     if (pIcdSurface == NULL) {
1508         return VK_ERROR_OUT_OF_HOST_MEMORY;
1509     }
1510 
1511     pIcdSurface->base.platform = VK_ICD_WSI_PLATFORM_IOS;
1512     pIcdSurface->pView = pCreateInfo->pView;
1513 
1514     *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface;
1515 
1516     return VK_SUCCESS;
1517 }
1518 
1519 #endif  // VK_USE_PLATFORM_IOS_MVK
1520 
1521 #if defined(VK_USE_PLATFORM_GGP)
1522 
1523 // Functions for the VK_GGP_stream_descriptor_surface extension:
1524 
1525 // This is the trampoline entrypoint for CreateStreamDescriptorSurfaceGGP
1526 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
vkCreateStreamDescriptorSurfaceGGP(VkInstance instance, const VkStreamDescriptorSurfaceCreateInfoGGP *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)1527 vkCreateStreamDescriptorSurfaceGGP(VkInstance instance, const VkStreamDescriptorSurfaceCreateInfoGGP *pCreateInfo,
1528                                    const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
1529     struct loader_instance *loader_inst = loader_get_instance(instance);
1530     if (NULL == loader_inst) {
1531         loader_log(
1532             NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1533             "vkCreateStreamDescriptorSurfaceGGP: Invalid instance [VUID-vkCreateStreamDescriptorSurfaceGGP-instance-parameter]");
1534         abort(); /* Intentionally fail so user can correct issue. */
1535     }
1536     return loader_inst->disp->layer_inst_disp.CreateStreamDescriptorSurfaceGGP(loader_inst->instance, pCreateInfo, pAllocator,
1537                                                                                pSurface);
1538 }
1539 
1540 // This is the instance chain terminator function for CreateStreamDescriptorSurfaceGGP
1541 VKAPI_ATTR VkResult VKAPI_CALL
terminator_CreateStreamDescriptorSurfaceGGP(VkInstance instance, const VkStreamDescriptorSurfaceCreateInfoGGP *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)1542 terminator_CreateStreamDescriptorSurfaceGGP(VkInstance instance, const VkStreamDescriptorSurfaceCreateInfoGGP *pCreateInfo,
1543                                             const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
1544     VkResult vkRes = VK_SUCCESS;
1545     VkIcdSurface *pIcdSurface = NULL;
1546     uint32_t i = 0;
1547 
1548     // First, check to ensure the appropriate extension was enabled:
1549     struct loader_instance *loader_inst = loader_get_instance(instance);
1550     if (!loader_inst->wsi_ggp_surface_enabled) {
1551         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
1552                    "VK_GGP_stream_descriptor_surface extension not enabled. vkCreateStreamDescriptorSurfaceGGP not executed!");
1553         vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
1554         goto out;
1555     }
1556 
1557     // Next, if so, proceed with the implementation of this function:
1558     pIcdSurface = AllocateIcdSurfaceStruct(loader_inst, sizeof(pIcdSurface->ggp_surf.base), sizeof(pIcdSurface->ggp_surf));
1559     if (pIcdSurface == NULL) {
1560         vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
1561         goto out;
1562     }
1563 
1564     pIcdSurface->ggp_surf.base.platform = VK_ICD_WSI_PLATFORM_GGP;
1565     pIcdSurface->ggp_surf.streamDescriptor = pCreateInfo->streamDescriptor;
1566 
1567     // Loop through each ICD and determine if they need to create a surface
1568     for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
1569         if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
1570             if (NULL != icd_term->dispatch.CreateStreamDescriptorSurfaceGGP) {
1571                 vkRes = icd_term->dispatch.CreateStreamDescriptorSurfaceGGP(icd_term->instance, pCreateInfo, pAllocator,
1572                                                                             &pIcdSurface->real_icd_surfaces[i]);
1573                 if (VK_SUCCESS != vkRes) {
1574                     goto out;
1575                 }
1576             }
1577         }
1578     }
1579 
1580     *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface;
1581 
1582 out:
1583 
1584     if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
1585         if (NULL != pIcdSurface->real_icd_surfaces) {
1586             i = 0;
1587             for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
1588                 if ((VkSurfaceKHR)(uintptr_t)NULL != pIcdSurface->real_icd_surfaces[i] &&
1589                     NULL != icd_term->dispatch.DestroySurfaceKHR) {
1590                     icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
1591                 }
1592             }
1593             loader_instance_heap_free(loader_inst, pIcdSurface->real_icd_surfaces);
1594         }
1595         loader_instance_heap_free(loader_inst, pIcdSurface);
1596     }
1597     return vkRes;
1598 }
1599 
1600 #endif  // VK_USE_PLATFORM_GGP
1601 
1602 #if defined(VK_USE_PLATFORM_METAL_EXT)
1603 
vkCreateMetalSurfaceEXT(VkInstance instance, const VkMetalSurfaceCreateInfoEXT *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)1604 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateMetalSurfaceEXT(VkInstance instance,
1605                                                                      const VkMetalSurfaceCreateInfoEXT *pCreateInfo,
1606                                                                      const VkAllocationCallbacks *pAllocator,
1607                                                                      VkSurfaceKHR *pSurface) {
1608     struct loader_instance *loader_inst = loader_get_instance(instance);
1609     if (NULL == loader_inst) {
1610         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1611                    "vkCreateMetalSurfaceEXT: Invalid instance [VUID-vkCreateMetalSurfaceEXT-instance-parameter]");
1612         abort(); /* Intentionally fail so user can correct issue. */
1613     }
1614     return loader_inst->disp->layer_inst_disp.CreateMetalSurfaceEXT(loader_inst->instance, pCreateInfo, pAllocator, pSurface);
1615 }
1616 
terminator_CreateMetalSurfaceEXT(VkInstance instance, const VkMetalSurfaceCreateInfoEXT *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)1617 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateMetalSurfaceEXT(VkInstance instance, const VkMetalSurfaceCreateInfoEXT *pCreateInfo,
1618                                                                 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
1619     VkResult result = VK_SUCCESS;
1620     VkIcdSurface *icd_surface = NULL;
1621     uint32_t i;
1622 
1623     // First, check to ensure the appropriate extension was enabled:
1624     struct loader_instance *loader_inst = loader_get_instance(instance);
1625     if (!loader_inst->wsi_metal_surface_enabled) {
1626         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
1627                    "VK_EXT_metal_surface extension not enabled. vkCreateMetalSurfaceEXT will not be executed.");
1628     }
1629 
1630     // Next, if so, proceed with the implementation of this function:
1631     icd_surface = AllocateIcdSurfaceStruct(loader_inst, sizeof(icd_surface->metal_surf.base), sizeof(icd_surface->metal_surf));
1632     if (icd_surface == NULL) {
1633         result = VK_ERROR_OUT_OF_HOST_MEMORY;
1634         goto out;
1635     }
1636 
1637     icd_surface->metal_surf.base.platform = VK_ICD_WSI_PLATFORM_METAL;
1638     icd_surface->metal_surf.pLayer = pCreateInfo->pLayer;
1639 
1640     // Loop through each ICD and determine if they need to create a surface
1641     i = 0;
1642     for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, ++i) {
1643         if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
1644             if (icd_term->dispatch.CreateMetalSurfaceEXT != NULL) {
1645                 result = icd_term->dispatch.CreateMetalSurfaceEXT(icd_term->instance, pCreateInfo, pAllocator,
1646                                                                   &icd_surface->real_icd_surfaces[i]);
1647                 if (result != VK_SUCCESS) {
1648                     goto out;
1649                 }
1650             }
1651         }
1652     }
1653     *pSurface = (VkSurfaceKHR)(uintptr_t)icd_surface;
1654 
1655 out:
1656     if (result != VK_SUCCESS && icd_surface != NULL) {
1657         if (icd_surface->real_icd_surfaces != NULL) {
1658             i = 0;
1659             for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, ++i) {
1660                 if (icd_surface->real_icd_surfaces[i] == VK_NULL_HANDLE && icd_term->dispatch.DestroySurfaceKHR != NULL) {
1661                     icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, icd_surface->real_icd_surfaces[i], pAllocator);
1662                 }
1663             }
1664             loader_instance_heap_free(loader_inst, icd_surface->real_icd_surfaces);
1665         }
1666         loader_instance_heap_free(loader_inst, icd_surface);
1667     }
1668     return result;
1669 }
1670 
1671 #endif  // VK_USE_PLATFORM_METAL_EXT
1672 
1673 #if defined(VK_USE_PLATFORM_SCREEN_QNX)
1674 
1675 // This is the trampoline entrypoint for CreateScreenSurfaceQNX
vkCreateScreenSurfaceQNX(VkInstance instance, const VkScreenSurfaceCreateInfoQNX *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)1676 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateScreenSurfaceQNX(VkInstance instance,
1677                                                                       const VkScreenSurfaceCreateInfoQNX *pCreateInfo,
1678                                                                       const VkAllocationCallbacks *pAllocator,
1679                                                                       VkSurfaceKHR *pSurface) {
1680     struct loader_instance *loader_inst = loader_get_instance(instance);
1681     if (NULL == loader_inst) {
1682         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1683                    "vkCreateScreenSurfaceQNX: Invalid instance [VUID-vkCreateScreenSurfaceQNX-instance-parameter]");
1684         abort(); /* Intentionally fail so user can correct issue. */
1685     }
1686     return loader_inst->disp->layer_inst_disp.CreateScreenSurfaceQNX(loader_inst->instance, pCreateInfo, pAllocator, pSurface);
1687 }
1688 
1689 // This is the instance chain terminator function for CreateScreenSurfaceQNX
terminator_CreateScreenSurfaceQNX(VkInstance instance, const VkScreenSurfaceCreateInfoQNX *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)1690 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateScreenSurfaceQNX(VkInstance instance,
1691                                                                  const VkScreenSurfaceCreateInfoQNX *pCreateInfo,
1692                                                                  const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
1693     VkResult vkRes = VK_SUCCESS;
1694     VkIcdSurface *pIcdSurface = NULL;
1695     uint32_t i = 0;
1696 
1697     // First, check to ensure the appropriate extension was enabled:
1698     struct loader_instance *loader_inst = loader_get_instance(instance);
1699     if (!loader_inst->wsi_screen_surface_enabled) {
1700         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
1701                    "VK_QNX_screen_surface extension not enabled. vkCreateScreenSurfaceQNX not executed!");
1702         vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
1703         goto out;
1704     }
1705 
1706     // Next, if so, proceed with the implementation of this function:
1707     pIcdSurface = AllocateIcdSurfaceStruct(loader_inst, sizeof(pIcdSurface->screen_surf.base), sizeof(pIcdSurface->screen_surf));
1708     if (pIcdSurface == NULL) {
1709         vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
1710         goto out;
1711     }
1712 
1713     pIcdSurface->screen_surf.base.platform = VK_ICD_WSI_PLATFORM_SCREEN;
1714     pIcdSurface->screen_surf.context = pCreateInfo->context;
1715     pIcdSurface->screen_surf.window = pCreateInfo->window;
1716 
1717     // Loop through each ICD and determine if they need to create a surface
1718     for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
1719         if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
1720             if (NULL != icd_term->dispatch.CreateScreenSurfaceQNX) {
1721                 vkRes = icd_term->dispatch.CreateScreenSurfaceQNX(icd_term->instance, pCreateInfo, pAllocator,
1722                                                                   &pIcdSurface->real_icd_surfaces[i]);
1723                 if (VK_SUCCESS != vkRes) {
1724                     goto out;
1725                 }
1726             }
1727         }
1728     }
1729 
1730     *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface;
1731 
1732 out:
1733 
1734     if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
1735         if (NULL != pIcdSurface->real_icd_surfaces) {
1736             i = 0;
1737             for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
1738                 if ((VkSurfaceKHR)(uintptr_t)NULL != pIcdSurface->real_icd_surfaces[i] &&
1739                     NULL != icd_term->dispatch.DestroySurfaceKHR) {
1740                     icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
1741                 }
1742             }
1743             loader_instance_heap_free(loader_inst, pIcdSurface->real_icd_surfaces);
1744         }
1745         loader_instance_heap_free(loader_inst, pIcdSurface);
1746     }
1747 
1748     return vkRes;
1749 }
1750 
1751 // This is the trampoline entrypoint for
1752 // GetPhysicalDeviceScreenPresentationSupportQNX
vkGetPhysicalDeviceScreenPresentationSupportQNX(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, struct _screen_window *window)1753 LOADER_EXPORT VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceScreenPresentationSupportQNX(VkPhysicalDevice physicalDevice,
1754                                                                                              uint32_t queueFamilyIndex,
1755                                                                                              struct _screen_window *window) {
1756     VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
1757     if (VK_NULL_HANDLE == unwrapped_phys_dev) {
1758         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1759                    "vkGetPhysicalDeviceScreenPresentationSupportQNX: Invalid physicalDevice "
1760                    "[VUID-vkGetPhysicalDeviceScreenPresentationSupportQNX-physicalDevice-parameter]");
1761         abort(); /* Intentionally fail so user can correct issue. */
1762     }
1763     const VkLayerInstanceDispatchTable *disp = loader_get_instance_layer_dispatch(physicalDevice);
1764     VkBool32 res = disp->GetPhysicalDeviceScreenPresentationSupportQNX(unwrapped_phys_dev, queueFamilyIndex, window);
1765     return res;
1766 }
1767 
1768 // This is the instance chain terminator function for
1769 // GetPhysicalDeviceScreenPresentationSupportQNX
terminator_GetPhysicalDeviceScreenPresentationSupportQNX(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, struct _screen_window *window)1770 VKAPI_ATTR VkBool32 VKAPI_CALL terminator_GetPhysicalDeviceScreenPresentationSupportQNX(VkPhysicalDevice physicalDevice,
1771                                                                                         uint32_t queueFamilyIndex,
1772                                                                                         struct _screen_window *window) {
1773     // First, check to ensure the appropriate extension was enabled:
1774     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
1775     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
1776     struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
1777     if (!loader_inst->wsi_screen_surface_enabled) {
1778         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
1779                    "VK_QNX_screen_surface extension not enabled. vkGetPhysicalDeviceScreenPresentationSupportQNX not executed!");
1780         return VK_FALSE;
1781     }
1782 
1783     if (NULL == icd_term->dispatch.GetPhysicalDeviceScreenPresentationSupportQNX) {
1784         // return VK_FALSE as this driver doesn't support WSI functionality
1785         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
1786                    "ICD for selected physical device does not export vkGetPhysicalDeviceScreenPresentationSupportQNX!");
1787         return VK_FALSE;
1788     }
1789 
1790     return icd_term->dispatch.GetPhysicalDeviceScreenPresentationSupportQNX(phys_dev_term->phys_dev, queueFamilyIndex, window);
1791 }
1792 #endif  // VK_USE_PLATFORM_SCREEN_QNX
1793 
1794 #if defined(VK_USE_PLATFORM_VI_NN)
1795 
1796 // Functions for the VK_NN_vi_surface extension:
1797 
1798 // This is the trampoline entrypoint for CreateViSurfaceNN
vkCreateViSurfaceNN(VkInstance instance, const VkViSurfaceCreateInfoNN *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)1799 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateViSurfaceNN(VkInstance instance, const VkViSurfaceCreateInfoNN *pCreateInfo,
1800                                                                  const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
1801     struct loader_instance *loader_inst = loader_get_instance(instance);
1802     if (NULL == loader_inst) {
1803         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1804                    "vkCreateViSurfaceNN: Invalid instance [VUID-vkCreateViSurfaceNN-instance-parameter]");
1805         abort(); /* Intentionally fail so user can correct issue. */
1806     }
1807     return loader_inst->disp->layer_inst_disp.CreateViSurfaceNN(loader_inst->instance, pCreateInfo, pAllocator, pSurface);
1808 }
1809 
1810 // This is the instance chain terminator function for CreateViSurfaceNN
terminator_CreateViSurfaceNN(VkInstance instance, const VkViSurfaceCreateInfoNN *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)1811 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateViSurfaceNN(VkInstance instance, const VkViSurfaceCreateInfoNN *pCreateInfo,
1812                                                             const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
1813     VkResult vkRes = VK_SUCCESS;
1814     VkIcdSurface *pIcdSurface = NULL;
1815     uint32_t i = 0;
1816 
1817     // First, check to ensure the appropriate extension was enabled:
1818     struct loader_instance *loader_inst = loader_get_instance(instance);
1819     if (!loader_inst->wsi_vi_surface_enabled) {
1820         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
1821                    "VK_NN_vi_surface extension not enabled. vkCreateViSurfaceNN not executed!");
1822         vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
1823         goto out;
1824     }
1825 
1826     // Next, if so, proceed with the implementation of this function:
1827     pIcdSurface = AllocateIcdSurfaceStruct(loader_inst, sizeof(pIcdSurface->vi_surf.base), sizeof(pIcdSurface->vi_surf));
1828     if (pIcdSurface == NULL) {
1829         vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
1830         goto out;
1831     }
1832 
1833     pIcdSurface->vi_surf.base.platform = VK_ICD_WSI_PLATFORM_VI;
1834     pIcdSurface->vi_surf.window = pCreateInfo->window;
1835 
1836     // Loop through each ICD and determine if they need to create a surface
1837     for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
1838         if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
1839             if (NULL != icd_term->dispatch.CreateViSurfaceNN) {
1840                 vkRes = icd_term->dispatch.CreateViSurfaceNN(icd_term->instance, pCreateInfo, pAllocator,
1841                                                              &pIcdSurface->real_icd_surfaces[i]);
1842                 if (VK_SUCCESS != vkRes) {
1843                     goto out;
1844                 }
1845             }
1846         }
1847     }
1848 
1849     *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface;
1850 
1851 out:
1852 
1853     if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
1854         if (NULL != pIcdSurface->real_icd_surfaces) {
1855             i = 0;
1856             for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
1857                 if ((VkSurfaceKHR)(uintptr_t)NULL != pIcdSurface->real_icd_surfaces[i] &&
1858                     NULL != icd_term->dispatch.DestroySurfaceKHR) {
1859                     icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
1860                 }
1861             }
1862             loader_instance_heap_free(loader_inst, pIcdSurface->real_icd_surfaces);
1863         }
1864         loader_instance_heap_free(loader_inst, pIcdSurface);
1865     }
1866 
1867     return vkRes;
1868 }
1869 
1870 #endif  // VK_USE_PLATFORM_VI_NN
1871 
1872 // Functions for the VK_KHR_display instance extension:
vkGetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, VkDisplayPropertiesKHR *pProperties)1873 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice,
1874                                                                                      uint32_t *pPropertyCount,
1875                                                                                      VkDisplayPropertiesKHR *pProperties) {
1876     const VkLayerInstanceDispatchTable *disp;
1877     VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
1878     if (VK_NULL_HANDLE == unwrapped_phys_dev) {
1879         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1880                    "vkGetPhysicalDeviceDisplayPropertiesKHR: Invalid physicalDevice "
1881                    "[VUID-vkGetPhysicalDeviceDisplayPropertiesKHR-physicalDevice-parameter]");
1882         abort(); /* Intentionally fail so user can correct issue. */
1883     }
1884     disp = loader_get_instance_layer_dispatch(physicalDevice);
1885     VkResult res = disp->GetPhysicalDeviceDisplayPropertiesKHR(unwrapped_phys_dev, pPropertyCount, pProperties);
1886     return res;
1887 }
1888 
terminator_GetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, VkDisplayPropertiesKHR *pProperties)1889 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice,
1890                                                                                 uint32_t *pPropertyCount,
1891                                                                                 VkDisplayPropertiesKHR *pProperties) {
1892     // First, check to ensure the appropriate extension was enabled:
1893     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
1894     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
1895     struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
1896     if (!loader_inst->wsi_display_enabled) {
1897         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
1898                    "VK_KHR_display extension not enabled. vkGetPhysicalDeviceDisplayPropertiesKHR not executed!");
1899         return VK_SUCCESS;
1900     }
1901 
1902     if (NULL == icd_term->dispatch.GetPhysicalDeviceDisplayPropertiesKHR) {
1903         loader_log(loader_inst, VULKAN_LOADER_WARN_BIT, 0,
1904                    "ICD for selected physical device does not export vkGetPhysicalDeviceDisplayPropertiesKHR!");
1905         // return 0 for property count as this driver doesn't support WSI functionality
1906         if (pPropertyCount) {
1907             *pPropertyCount = 0;
1908         }
1909         return VK_SUCCESS;
1910     }
1911 
1912     return icd_term->dispatch.GetPhysicalDeviceDisplayPropertiesKHR(phys_dev_term->phys_dev, pPropertyCount, pProperties);
1913 }
1914 
vkGetPhysicalDeviceDisplayPlanePropertiesKHR( VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, VkDisplayPlanePropertiesKHR *pProperties)1915 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayPlanePropertiesKHR(
1916     VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, VkDisplayPlanePropertiesKHR *pProperties) {
1917     const VkLayerInstanceDispatchTable *disp;
1918     VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
1919     if (VK_NULL_HANDLE == unwrapped_phys_dev) {
1920         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1921                    "vkGetPhysicalDeviceDisplayPlanePropertiesKHR: Invalid physicalDevice "
1922                    "[VUID-vkGetPhysicalDeviceDisplayPlanePropertiesKHR-physicalDevice-parameter]");
1923         abort(); /* Intentionally fail so user can correct issue. */
1924     }
1925     disp = loader_get_instance_layer_dispatch(physicalDevice);
1926     VkResult res = disp->GetPhysicalDeviceDisplayPlanePropertiesKHR(unwrapped_phys_dev, pPropertyCount, pProperties);
1927     return res;
1928 }
1929 
terminator_GetPhysicalDeviceDisplayPlanePropertiesKHR(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, VkDisplayPlanePropertiesKHR *pProperties)1930 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceDisplayPlanePropertiesKHR(VkPhysicalDevice physicalDevice,
1931                                                                                      uint32_t *pPropertyCount,
1932                                                                                      VkDisplayPlanePropertiesKHR *pProperties) {
1933     // First, check to ensure the appropriate extension was enabled:
1934     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
1935     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
1936     struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
1937     if (!loader_inst->wsi_display_enabled) {
1938         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
1939                    "VK_KHR_display extension not enabled. vkGetPhysicalDeviceDisplayPlanePropertiesKHR not executed!");
1940         return VK_SUCCESS;
1941     }
1942 
1943     if (NULL == icd_term->dispatch.GetPhysicalDeviceDisplayPlanePropertiesKHR) {
1944         loader_log(loader_inst, VULKAN_LOADER_WARN_BIT, 0,
1945                    "ICD for selected physical device does not export vkGetPhysicalDeviceDisplayPlanePropertiesKHR!");
1946         // return 0 for property count as this driver doesn't support WSI functionality
1947         if (pPropertyCount) {
1948             *pPropertyCount = 0;
1949         }
1950         return VK_SUCCESS;
1951     }
1952 
1953     return icd_term->dispatch.GetPhysicalDeviceDisplayPlanePropertiesKHR(phys_dev_term->phys_dev, pPropertyCount, pProperties);
1954 }
1955 
vkGetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice, uint32_t planeIndex, uint32_t *pDisplayCount, VkDisplayKHR *pDisplays)1956 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice,
1957                                                                                    uint32_t planeIndex, uint32_t *pDisplayCount,
1958                                                                                    VkDisplayKHR *pDisplays) {
1959     const VkLayerInstanceDispatchTable *disp;
1960     VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
1961     if (VK_NULL_HANDLE == unwrapped_phys_dev) {
1962         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1963                    "vkGetDisplayPlaneSupportedDisplaysKHR: Invalid physicalDevice "
1964                    "[VUID-vkGetDisplayPlaneSupportedDisplaysKHR-physicalDevice-parameter]");
1965         abort(); /* Intentionally fail so user can correct issue. */
1966     }
1967     disp = loader_get_instance_layer_dispatch(physicalDevice);
1968     VkResult res = disp->GetDisplayPlaneSupportedDisplaysKHR(unwrapped_phys_dev, planeIndex, pDisplayCount, pDisplays);
1969     return res;
1970 }
1971 
terminator_GetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice, uint32_t planeIndex, uint32_t *pDisplayCount, VkDisplayKHR *pDisplays)1972 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice, uint32_t planeIndex,
1973                                                                               uint32_t *pDisplayCount, VkDisplayKHR *pDisplays) {
1974     // First, check to ensure the appropriate extension was enabled:
1975     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
1976     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
1977     struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
1978     if (!loader_inst->wsi_display_enabled) {
1979         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
1980                    "VK_KHR_display extension not enabled. vkGetDisplayPlaneSupportedDisplaysKHR not executed!");
1981         return VK_SUCCESS;
1982     }
1983 
1984     if (NULL == icd_term->dispatch.GetDisplayPlaneSupportedDisplaysKHR) {
1985         loader_log(loader_inst, VULKAN_LOADER_WARN_BIT, 0,
1986                    "ICD for selected physical device does not export vkGetDisplayPlaneSupportedDisplaysKHR!");
1987         // return 0 for property count as this driver doesn't support WSI functionality
1988         if (pDisplayCount) {
1989             *pDisplayCount = 0;
1990         }
1991         return VK_SUCCESS;
1992     }
1993 
1994     return icd_term->dispatch.GetDisplayPlaneSupportedDisplaysKHR(phys_dev_term->phys_dev, planeIndex, pDisplayCount, pDisplays);
1995 }
1996 
vkGetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display, uint32_t *pPropertyCount, VkDisplayModePropertiesKHR *pProperties)1997 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
1998                                                                            uint32_t *pPropertyCount,
1999                                                                            VkDisplayModePropertiesKHR *pProperties) {
2000     const VkLayerInstanceDispatchTable *disp;
2001     VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
2002     if (VK_NULL_HANDLE == unwrapped_phys_dev) {
2003         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2004                    "vkGetDisplayModePropertiesKHR: Invalid physicalDevice "
2005                    "[VUID-vkGetDisplayModePropertiesKHR-physicalDevice-parameter]");
2006         abort(); /* Intentionally fail so user can correct issue. */
2007     }
2008     disp = loader_get_instance_layer_dispatch(physicalDevice);
2009     VkResult res = disp->GetDisplayModePropertiesKHR(unwrapped_phys_dev, display, pPropertyCount, pProperties);
2010     return res;
2011 }
2012 
terminator_GetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display, uint32_t *pPropertyCount, VkDisplayModePropertiesKHR *pProperties)2013 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
2014                                                                       uint32_t *pPropertyCount,
2015                                                                       VkDisplayModePropertiesKHR *pProperties) {
2016     // First, check to ensure the appropriate extension was enabled:
2017     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
2018     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
2019     struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
2020     if (!loader_inst->wsi_display_enabled) {
2021         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
2022                    "VK_KHR_display extension not enabled. vkGetDisplayModePropertiesKHR not executed!");
2023         return VK_SUCCESS;
2024     }
2025 
2026     if (NULL == icd_term->dispatch.GetDisplayModePropertiesKHR) {
2027         loader_log(loader_inst, VULKAN_LOADER_WARN_BIT, 0,
2028                    "ICD for selected physical device does not export vkGetDisplayModePropertiesKHR!");
2029         // return 0 for property count as this driver doesn't support WSI functionality
2030         if (pPropertyCount) {
2031             *pPropertyCount = 0;
2032         }
2033         return VK_SUCCESS;
2034     }
2035 
2036     return icd_term->dispatch.GetDisplayModePropertiesKHR(phys_dev_term->phys_dev, display, pPropertyCount, pProperties);
2037 }
2038 
vkCreateDisplayModeKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display, const VkDisplayModeCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDisplayModeKHR *pMode)2039 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDisplayModeKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
2040                                                                     const VkDisplayModeCreateInfoKHR *pCreateInfo,
2041                                                                     const VkAllocationCallbacks *pAllocator,
2042                                                                     VkDisplayModeKHR *pMode) {
2043     const VkLayerInstanceDispatchTable *disp;
2044     VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
2045     if (VK_NULL_HANDLE == unwrapped_phys_dev) {
2046         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2047                    "vkCreateDisplayModeKHR: Invalid physicalDevice "
2048                    "[VUID-vkCreateDisplayModeKHR-physicalDevice-parameter]");
2049         abort(); /* Intentionally fail so user can correct issue. */
2050     }
2051     disp = loader_get_instance_layer_dispatch(physicalDevice);
2052     VkResult res = disp->CreateDisplayModeKHR(unwrapped_phys_dev, display, pCreateInfo, pAllocator, pMode);
2053     return res;
2054 }
2055 
terminator_CreateDisplayModeKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display, const VkDisplayModeCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDisplayModeKHR *pMode)2056 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDisplayModeKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
2057                                                                const VkDisplayModeCreateInfoKHR *pCreateInfo,
2058                                                                const VkAllocationCallbacks *pAllocator, VkDisplayModeKHR *pMode) {
2059     // First, check to ensure the appropriate extension was enabled:
2060     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
2061     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
2062     struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
2063     if (!loader_inst->wsi_display_enabled) {
2064         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
2065                    "VK_KHR_display extension not enabled. vkCreateDisplayModeKHR not executed!");
2066         return VK_ERROR_EXTENSION_NOT_PRESENT;
2067     }
2068 
2069     if (NULL == icd_term->dispatch.CreateDisplayModeKHR) {
2070         // Can't emulate, so return an appropriate error
2071         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
2072                    "ICD for selected physical device does not export vkCreateDisplayModeKHR!");
2073         return VK_ERROR_INITIALIZATION_FAILED;
2074     }
2075 
2076     return icd_term->dispatch.CreateDisplayModeKHR(phys_dev_term->phys_dev, display, pCreateInfo, pAllocator, pMode);
2077 }
2078 
vkGetDisplayPlaneCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkDisplayModeKHR mode, uint32_t planeIndex, VkDisplayPlaneCapabilitiesKHR *pCapabilities)2079 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayPlaneCapabilitiesKHR(VkPhysicalDevice physicalDevice,
2080                                                                               VkDisplayModeKHR mode, uint32_t planeIndex,
2081                                                                               VkDisplayPlaneCapabilitiesKHR *pCapabilities) {
2082     const VkLayerInstanceDispatchTable *disp;
2083     VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
2084     if (VK_NULL_HANDLE == unwrapped_phys_dev) {
2085         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2086                    "vkGetDisplayPlaneCapabilitiesKHR: Invalid physicalDevice "
2087                    "[VUID-vkGetDisplayPlaneCapabilitiesKHR-physicalDevice-parameter]");
2088         abort(); /* Intentionally fail so user can correct issue. */
2089     }
2090     disp = loader_get_instance_layer_dispatch(physicalDevice);
2091     VkResult res = disp->GetDisplayPlaneCapabilitiesKHR(unwrapped_phys_dev, mode, planeIndex, pCapabilities);
2092     return res;
2093 }
2094 
terminator_GetDisplayPlaneCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkDisplayModeKHR mode, uint32_t planeIndex, VkDisplayPlaneCapabilitiesKHR *pCapabilities)2095 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDisplayPlaneCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkDisplayModeKHR mode,
2096                                                                          uint32_t planeIndex,
2097                                                                          VkDisplayPlaneCapabilitiesKHR *pCapabilities) {
2098     // First, check to ensure the appropriate extension was enabled:
2099     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
2100     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
2101     struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
2102     if (!loader_inst->wsi_display_enabled) {
2103         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
2104                    "VK_KHR_display extension not enabled. vkGetDisplayPlaneCapabilitiesKHR not executed!");
2105         return VK_SUCCESS;
2106     }
2107 
2108     if (NULL == icd_term->dispatch.GetDisplayPlaneCapabilitiesKHR) {
2109         // Emulate support
2110         loader_log(loader_inst, VULKAN_LOADER_WARN_BIT, 0,
2111                    "ICD for selected physical device does not export vkGetDisplayPlaneCapabilitiesKHR!");
2112         if (pCapabilities) {
2113             memset(pCapabilities, 0, sizeof(VkDisplayPlaneCapabilitiesKHR));
2114         }
2115         return VK_SUCCESS;
2116     }
2117 
2118     return icd_term->dispatch.GetDisplayPlaneCapabilitiesKHR(phys_dev_term->phys_dev, mode, planeIndex, pCapabilities);
2119 }
2120 
vkCreateDisplayPlaneSurfaceKHR(VkInstance instance, const VkDisplaySurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)2121 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDisplayPlaneSurfaceKHR(VkInstance instance,
2122                                                                             const VkDisplaySurfaceCreateInfoKHR *pCreateInfo,
2123                                                                             const VkAllocationCallbacks *pAllocator,
2124                                                                             VkSurfaceKHR *pSurface) {
2125     struct loader_instance *loader_inst = loader_get_instance(instance);
2126     if (NULL == loader_inst) {
2127         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2128                    "vkCreateDisplayPlaneSurfaceKHR: Invalid instance [VUID-vkCreateDisplayPlaneSurfaceKHR-instance-parameter]");
2129         abort(); /* Intentionally fail so user can correct issue. */
2130     }
2131     return loader_inst->disp->layer_inst_disp.CreateDisplayPlaneSurfaceKHR(loader_inst->instance, pCreateInfo, pAllocator,
2132                                                                            pSurface);
2133 }
2134 
terminator_CreateDisplayPlaneSurfaceKHR(VkInstance instance, const VkDisplaySurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)2135 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDisplayPlaneSurfaceKHR(VkInstance instance,
2136                                                                        const VkDisplaySurfaceCreateInfoKHR *pCreateInfo,
2137                                                                        const VkAllocationCallbacks *pAllocator,
2138                                                                        VkSurfaceKHR *pSurface) {
2139     struct loader_instance *inst = loader_get_instance(instance);
2140     VkIcdSurface *pIcdSurface = NULL;
2141     VkResult vkRes = VK_SUCCESS;
2142     uint32_t i = 0;
2143 
2144     if (!inst->wsi_display_enabled) {
2145         loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0,
2146                    "VK_KHR_surface extension not enabled. vkCreateDisplayPlaneSurfaceKHR not executed!");
2147         vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
2148         goto out;
2149     }
2150 
2151     // Next, if so, proceed with the implementation of this function:
2152     pIcdSurface = AllocateIcdSurfaceStruct(inst, sizeof(pIcdSurface->display_surf.base), sizeof(pIcdSurface->display_surf));
2153     if (pIcdSurface == NULL) {
2154         vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
2155         goto out;
2156     }
2157 
2158     pIcdSurface->display_surf.base.platform = VK_ICD_WSI_PLATFORM_DISPLAY;
2159     pIcdSurface->display_surf.displayMode = pCreateInfo->displayMode;
2160     pIcdSurface->display_surf.planeIndex = pCreateInfo->planeIndex;
2161     pIcdSurface->display_surf.planeStackIndex = pCreateInfo->planeStackIndex;
2162     pIcdSurface->display_surf.transform = pCreateInfo->transform;
2163     pIcdSurface->display_surf.globalAlpha = pCreateInfo->globalAlpha;
2164     pIcdSurface->display_surf.alphaMode = pCreateInfo->alphaMode;
2165     pIcdSurface->display_surf.imageExtent = pCreateInfo->imageExtent;
2166 
2167     // Loop through each ICD and determine if they need to create a surface
2168     for (struct loader_icd_term *icd_term = inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
2169         if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
2170             if (NULL != icd_term->dispatch.CreateDisplayPlaneSurfaceKHR) {
2171                 vkRes = icd_term->dispatch.CreateDisplayPlaneSurfaceKHR(icd_term->instance, pCreateInfo, pAllocator,
2172                                                                         &pIcdSurface->real_icd_surfaces[i]);
2173                 if (VK_SUCCESS != vkRes) {
2174                     goto out;
2175                 }
2176             }
2177         }
2178     }
2179 
2180     *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface;
2181 
2182 out:
2183 
2184     if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
2185         if (NULL != pIcdSurface->real_icd_surfaces) {
2186             i = 0;
2187             for (struct loader_icd_term *icd_term = inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
2188                 if ((VkSurfaceKHR)(uintptr_t)NULL != pIcdSurface->real_icd_surfaces[i] &&
2189                     NULL != icd_term->dispatch.DestroySurfaceKHR) {
2190                     icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
2191                 }
2192             }
2193             loader_instance_heap_free(inst, pIcdSurface->real_icd_surfaces);
2194         }
2195         loader_instance_heap_free(inst, pIcdSurface);
2196     }
2197 
2198     return vkRes;
2199 }
2200 
2201 // EXT_display_swapchain Extension command
2202 
vkCreateSharedSwapchainsKHR(VkDevice device, uint32_t swapchainCount, const VkSwapchainCreateInfoKHR *pCreateInfos, const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchains)2203 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateSharedSwapchainsKHR(VkDevice device, uint32_t swapchainCount,
2204                                                                          const VkSwapchainCreateInfoKHR *pCreateInfos,
2205                                                                          const VkAllocationCallbacks *pAllocator,
2206                                                                          VkSwapchainKHR *pSwapchains) {
2207     const VkLayerDispatchTable *disp = loader_get_dispatch(device);
2208     if (NULL == disp) {
2209         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2210                    "vkCreateSharedSwapchainsKHR: Invalid device [VUID-vkCreateSharedSwapchainsKHR-device-parameter]");
2211         abort(); /* Intentionally fail so user can correct issue. */
2212     }
2213     return disp->CreateSharedSwapchainsKHR(device, swapchainCount, pCreateInfos, pAllocator, pSwapchains);
2214 }
2215 
terminator_CreateSharedSwapchainsKHR(VkDevice device, uint32_t swapchainCount, const VkSwapchainCreateInfoKHR *pCreateInfos, const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchains)2216 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateSharedSwapchainsKHR(VkDevice device, uint32_t swapchainCount,
2217                                                                     const VkSwapchainCreateInfoKHR *pCreateInfos,
2218                                                                     const VkAllocationCallbacks *pAllocator,
2219                                                                     VkSwapchainKHR *pSwapchains) {
2220     uint32_t icd_index = 0;
2221     struct loader_device *dev;
2222     struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, &icd_index);
2223     if (NULL == icd_term || NULL == dev) {
2224         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2225                    "vkCreateSharedSwapchainsKHR Terminator: Invalid device handle. This is likely the result of a "
2226                    "layer wrapping device handles and failing to unwrap them in all functions. "
2227                    "[VUID-vkCreateSharedSwapchainsKHR-device-parameter]");
2228         abort(); /* Intentionally fail so user can correct issue. */
2229     }
2230     if (NULL == dev->loader_dispatch.extension_terminator_dispatch.CreateSharedSwapchainsKHR) {
2231         loader_log(NULL, VULKAN_LOADER_ERROR_BIT, 0,
2232                    "vkCreateSharedSwapchainsKHR: Driver's function pointer was NULL, returning VK_SUCCESS. Was the "
2233                    "VK_KHR_display_swapchain extension enabled?");
2234         return VK_SUCCESS;
2235     }
2236     VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pCreateInfos->surface;
2237     if ((VkSurfaceKHR)(uintptr_t)NULL != icd_surface->real_icd_surfaces[icd_index]) {
2238         // We found the ICD, and there is an ICD KHR surface
2239         // associated with it, so copy the CreateInfo struct
2240         // and point it at the ICD's surface.
2241         VkSwapchainCreateInfoKHR *pCreateCopy = loader_stack_alloc(sizeof(VkSwapchainCreateInfoKHR) * swapchainCount);
2242         if (NULL == pCreateCopy) {
2243             return VK_ERROR_OUT_OF_HOST_MEMORY;
2244         }
2245         memcpy(pCreateCopy, pCreateInfos, sizeof(VkSwapchainCreateInfoKHR) * swapchainCount);
2246         for (uint32_t sc = 0; sc < swapchainCount; sc++) {
2247             pCreateCopy[sc].surface = icd_surface->real_icd_surfaces[icd_index];
2248         }
2249         return dev->loader_dispatch.extension_terminator_dispatch.CreateSharedSwapchainsKHR(device, swapchainCount, pCreateCopy,
2250                                                                                             pAllocator, pSwapchains);
2251     }
2252     return dev->loader_dispatch.extension_terminator_dispatch.CreateSharedSwapchainsKHR(device, swapchainCount, pCreateInfos,
2253                                                                                         pAllocator, pSwapchains);
2254 }
2255 
2256 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
vkGetDeviceGroupPresentCapabilitiesKHR(VkDevice device, VkDeviceGroupPresentCapabilitiesKHR *pDeviceGroupPresentCapabilities)2257 vkGetDeviceGroupPresentCapabilitiesKHR(VkDevice device, VkDeviceGroupPresentCapabilitiesKHR *pDeviceGroupPresentCapabilities) {
2258     const VkLayerDispatchTable *disp = loader_get_dispatch(device);
2259     if (NULL == disp) {
2260         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2261                    "vkGetDeviceGroupPresentCapabilitiesKHR: Invalid device "
2262                    "[VUID-vkGetDeviceGroupPresentCapabilitiesKHR-device-parameter]");
2263         abort(); /* Intentionally fail so user can correct issue. */
2264     }
2265     return disp->GetDeviceGroupPresentCapabilitiesKHR(device, pDeviceGroupPresentCapabilities);
2266 }
2267 
vkGetDeviceGroupSurfacePresentModesKHR(VkDevice device, VkSurfaceKHR surface, VkDeviceGroupPresentModeFlagsKHR *pModes)2268 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetDeviceGroupSurfacePresentModesKHR(VkDevice device, VkSurfaceKHR surface,
2269                                                                                     VkDeviceGroupPresentModeFlagsKHR *pModes) {
2270     const VkLayerDispatchTable *disp = loader_get_dispatch(device);
2271     if (NULL == disp) {
2272         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2273                    "vkGetDeviceGroupSurfacePresentModesKHR: Invalid device "
2274                    "[VUID-vkGetDeviceGroupSurfacePresentModesKHR-device-parameter]");
2275         abort(); /* Intentionally fail so user can correct issue. */
2276     }
2277     return disp->GetDeviceGroupSurfacePresentModesKHR(device, surface, pModes);
2278 }
2279 
terminator_GetDeviceGroupSurfacePresentModesKHR(VkDevice device, VkSurfaceKHR surface, VkDeviceGroupPresentModeFlagsKHR *pModes)2280 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDeviceGroupSurfacePresentModesKHR(VkDevice device, VkSurfaceKHR surface,
2281                                                                                VkDeviceGroupPresentModeFlagsKHR *pModes) {
2282     uint32_t icd_index = 0;
2283     struct loader_device *dev;
2284     struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, &icd_index);
2285     if (NULL == icd_term || NULL == dev) {
2286         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2287                    "vkGetDeviceGroupSurfacePresentModesKHR: Invalid device "
2288                    "[VUID-vkGetDeviceGroupSurfacePresentModesKHR-device-parameter]");
2289         abort(); /* Intentionally fail so user can correct issue. */
2290     }
2291     if (NULL == dev->loader_dispatch.extension_terminator_dispatch.GetDeviceGroupSurfacePresentModesKHR) {
2292         loader_log(NULL, VULKAN_LOADER_ERROR_BIT, 0,
2293                    "vkGetDeviceGroupSurfacePresentModesKHR: Driver's function pointer was NULL, returning VK_SUCCESS. Was either "
2294                    "Vulkan 1.1 and VK_KHR_swapchain enabled or both the VK_KHR_device_group and VK_KHR_surface "
2295                    "extensions enabled when using Vulkan 1.0?");
2296         return VK_SUCCESS;
2297     }
2298     VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)surface;
2299     if (NULL != icd_surface->real_icd_surfaces && (VkSurfaceKHR)(uintptr_t)NULL != icd_surface->real_icd_surfaces[icd_index]) {
2300         return dev->loader_dispatch.extension_terminator_dispatch.GetDeviceGroupSurfacePresentModesKHR(
2301             device, icd_surface->real_icd_surfaces[icd_index], pModes);
2302     }
2303     return dev->loader_dispatch.extension_terminator_dispatch.GetDeviceGroupSurfacePresentModesKHR(device, surface, pModes);
2304 }
2305 
vkGetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t *pRectCount, VkRect2D *pRects)2306 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice physicalDevice,
2307                                                                                      VkSurfaceKHR surface, uint32_t *pRectCount,
2308                                                                                      VkRect2D *pRects) {
2309     const VkLayerInstanceDispatchTable *disp;
2310     VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
2311     if (VK_NULL_HANDLE == unwrapped_phys_dev) {
2312         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2313                    "vkGetPhysicalDevicePresentRectanglesKHR: Invalid physicalDevice "
2314                    "[VUID-vkGetPhysicalDevicePresentRectanglesKHR-physicalDevice-parameter]");
2315         abort(); /* Intentionally fail so user can correct issue. */
2316     }
2317     disp = loader_get_instance_layer_dispatch(physicalDevice);
2318     return disp->GetPhysicalDevicePresentRectanglesKHR(unwrapped_phys_dev, surface, pRectCount, pRects);
2319 }
2320 
terminator_GetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t *pRectCount, VkRect2D *pRects)2321 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice physicalDevice,
2322                                                                                 VkSurfaceKHR surface, uint32_t *pRectCount,
2323                                                                                 VkRect2D *pRects) {
2324     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
2325     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
2326     if (NULL == icd_term->dispatch.GetPhysicalDevicePresentRectanglesKHR) {
2327         loader_log(icd_term->this_instance, VULKAN_LOADER_ERROR_BIT, 0,
2328                    "ICD associated with VkPhysicalDevice does not support GetPhysicalDevicePresentRectanglesKHX");
2329         // return as this driver doesn't support WSI functionality
2330         if (pRectCount) {
2331             *pRectCount = 0;
2332         }
2333         return VK_SUCCESS;
2334     }
2335     VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)(surface);
2336     uint8_t icd_index = phys_dev_term->icd_index;
2337     if (NULL != icd_surface->real_icd_surfaces && NULL != (void *)(uintptr_t)(icd_surface->real_icd_surfaces[icd_index])) {
2338         return icd_term->dispatch.GetPhysicalDevicePresentRectanglesKHR(
2339             phys_dev_term->phys_dev, icd_surface->real_icd_surfaces[icd_index], pRectCount, pRects);
2340     }
2341     return icd_term->dispatch.GetPhysicalDevicePresentRectanglesKHR(phys_dev_term->phys_dev, surface, pRectCount, pRects);
2342 }
2343 
vkAcquireNextImage2KHR(VkDevice device, const VkAcquireNextImageInfoKHR *pAcquireInfo, uint32_t *pImageIndex)2344 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkAcquireNextImage2KHR(VkDevice device, const VkAcquireNextImageInfoKHR *pAcquireInfo,
2345                                                                     uint32_t *pImageIndex) {
2346     const VkLayerDispatchTable *disp = loader_get_dispatch(device);
2347     if (NULL == disp) {
2348         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2349                    "vkAcquireNextImage2KHR: Invalid device [VUID-vkAcquireNextImage2KHR-device-parameter]");
2350         abort(); /* Intentionally fail so user can correct issue. */
2351     }
2352     return disp->AcquireNextImage2KHR(device, pAcquireInfo, pImageIndex);
2353 }
2354 
2355 // ---- VK_KHR_get_display_properties2 extension trampoline/terminators
2356 
vkGetPhysicalDeviceDisplayProperties2KHR(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, VkDisplayProperties2KHR *pProperties)2357 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayProperties2KHR(VkPhysicalDevice physicalDevice,
2358                                                                                       uint32_t *pPropertyCount,
2359                                                                                       VkDisplayProperties2KHR *pProperties) {
2360     const VkLayerInstanceDispatchTable *disp;
2361     VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
2362     if (VK_NULL_HANDLE == unwrapped_phys_dev) {
2363         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2364                    "vkGetPhysicalDeviceDisplayProperties2KHR: Invalid physicalDevice "
2365                    "[VUID-vkGetPhysicalDeviceDisplayProperties2KHR-physicalDevice-parameter]");
2366         abort(); /* Intentionally fail so user can correct issue. */
2367     }
2368     disp = loader_get_instance_layer_dispatch(physicalDevice);
2369     return disp->GetPhysicalDeviceDisplayProperties2KHR(unwrapped_phys_dev, pPropertyCount, pProperties);
2370 }
2371 
terminator_GetPhysicalDeviceDisplayProperties2KHR(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, VkDisplayProperties2KHR *pProperties)2372 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceDisplayProperties2KHR(VkPhysicalDevice physicalDevice,
2373                                                                                  uint32_t *pPropertyCount,
2374                                                                                  VkDisplayProperties2KHR *pProperties) {
2375     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
2376     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
2377 
2378     // If the function is available in the driver, just call into it
2379     if (icd_term->dispatch.GetPhysicalDeviceDisplayProperties2KHR != NULL) {
2380         return icd_term->dispatch.GetPhysicalDeviceDisplayProperties2KHR(phys_dev_term->phys_dev, pPropertyCount, pProperties);
2381     }
2382 
2383     // We have to emulate the function.
2384     loader_log(icd_term->this_instance, VULKAN_LOADER_INFO_BIT, 0,
2385                "vkGetPhysicalDeviceDisplayProperties2KHR: Emulating call in ICD \"%s\"", icd_term->scanned_icd->lib_name);
2386 
2387     // If the icd doesn't support VK_KHR_display, then no properties are available
2388     if (icd_term->dispatch.GetPhysicalDeviceDisplayPropertiesKHR == NULL) {
2389         *pPropertyCount = 0;
2390         return VK_SUCCESS;
2391     }
2392 
2393     // If we aren't writing to pProperties, then emulation is straightforward
2394     if (pProperties == NULL || *pPropertyCount == 0) {
2395         return icd_term->dispatch.GetPhysicalDeviceDisplayPropertiesKHR(phys_dev_term->phys_dev, pPropertyCount, NULL);
2396     }
2397 
2398     // If we do have to write to pProperties, then we need to write to a temporary array of VkDisplayPropertiesKHR and copy it
2399     VkDisplayPropertiesKHR *properties = loader_stack_alloc(*pPropertyCount * sizeof(VkDisplayPropertiesKHR));
2400     if (properties == NULL) {
2401         return VK_ERROR_OUT_OF_HOST_MEMORY;
2402     }
2403     VkResult res = icd_term->dispatch.GetPhysicalDeviceDisplayPropertiesKHR(phys_dev_term->phys_dev, pPropertyCount, properties);
2404     if (res < 0) {
2405         return res;
2406     }
2407     for (uint32_t i = 0; i < *pPropertyCount; ++i) {
2408         memcpy(&pProperties[i].displayProperties, &properties[i], sizeof(VkDisplayPropertiesKHR));
2409     }
2410     return res;
2411 }
2412 
vkGetPhysicalDeviceDisplayPlaneProperties2KHR( VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, VkDisplayPlaneProperties2KHR *pProperties)2413 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayPlaneProperties2KHR(
2414     VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, VkDisplayPlaneProperties2KHR *pProperties) {
2415     const VkLayerInstanceDispatchTable *disp;
2416     VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
2417     if (VK_NULL_HANDLE == unwrapped_phys_dev) {
2418         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2419                    "vkGetPhysicalDeviceDisplayPlaneProperties2KHR: Invalid physicalDevice "
2420                    "[VUID-vkGetPhysicalDeviceDisplayPlaneProperties2KHR-physicalDevice-parameter]");
2421         abort(); /* Intentionally fail so user can correct issue. */
2422     }
2423     disp = loader_get_instance_layer_dispatch(physicalDevice);
2424     return disp->GetPhysicalDeviceDisplayPlaneProperties2KHR(unwrapped_phys_dev, pPropertyCount, pProperties);
2425 }
2426 
terminator_GetPhysicalDeviceDisplayPlaneProperties2KHR(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, VkDisplayPlaneProperties2KHR *pProperties)2427 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceDisplayPlaneProperties2KHR(VkPhysicalDevice physicalDevice,
2428                                                                                       uint32_t *pPropertyCount,
2429                                                                                       VkDisplayPlaneProperties2KHR *pProperties) {
2430     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
2431     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
2432 
2433     // If the function is available in the driver, just call into it
2434     if (icd_term->dispatch.GetPhysicalDeviceDisplayPlaneProperties2KHR != NULL) {
2435         return icd_term->dispatch.GetPhysicalDeviceDisplayPlaneProperties2KHR(phys_dev_term->phys_dev, pPropertyCount, pProperties);
2436     }
2437 
2438     // We have to emulate the function.
2439     loader_log(icd_term->this_instance, VULKAN_LOADER_INFO_BIT, 0,
2440                "vkGetPhysicalDeviceDisplayPlaneProperties2KHR: Emulating call in ICD \"%s\"", icd_term->scanned_icd->lib_name);
2441 
2442     // If the icd doesn't support VK_KHR_display, then no properties are available
2443     if (icd_term->dispatch.GetPhysicalDeviceDisplayPlanePropertiesKHR == NULL) {
2444         *pPropertyCount = 0;
2445         return VK_SUCCESS;
2446     }
2447 
2448     // If we aren't writing to pProperties, then emulation is straightforward
2449     if (pProperties == NULL || *pPropertyCount == 0) {
2450         return icd_term->dispatch.GetPhysicalDeviceDisplayPlanePropertiesKHR(phys_dev_term->phys_dev, pPropertyCount, NULL);
2451     }
2452 
2453     // If we do have to write to pProperties, then we need to write to a temporary array of VkDisplayPlanePropertiesKHR and copy it
2454     VkDisplayPlanePropertiesKHR *properties = loader_stack_alloc(*pPropertyCount * sizeof(VkDisplayPlanePropertiesKHR));
2455     if (properties == NULL) {
2456         return VK_ERROR_OUT_OF_HOST_MEMORY;
2457     }
2458     VkResult res =
2459         icd_term->dispatch.GetPhysicalDeviceDisplayPlanePropertiesKHR(phys_dev_term->phys_dev, pPropertyCount, properties);
2460     if (res < 0) {
2461         return res;
2462     }
2463     for (uint32_t i = 0; i < *pPropertyCount; ++i) {
2464         memcpy(&pProperties[i].displayPlaneProperties, &properties[i], sizeof(VkDisplayPlanePropertiesKHR));
2465     }
2466     return res;
2467 }
2468 
vkGetDisplayModeProperties2KHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display, uint32_t *pPropertyCount, VkDisplayModeProperties2KHR *pProperties)2469 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayModeProperties2KHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
2470                                                                             uint32_t *pPropertyCount,
2471                                                                             VkDisplayModeProperties2KHR *pProperties) {
2472     const VkLayerInstanceDispatchTable *disp;
2473     VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
2474     if (VK_NULL_HANDLE == unwrapped_phys_dev) {
2475         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2476                    "vkGetDisplayModeProperties2KHR: Invalid physicalDevice "
2477                    "[VUID-vkGetDisplayModeProperties2KHR-physicalDevice-parameter]");
2478         abort(); /* Intentionally fail so user can correct issue. */
2479     }
2480     disp = loader_get_instance_layer_dispatch(physicalDevice);
2481     return disp->GetDisplayModeProperties2KHR(unwrapped_phys_dev, display, pPropertyCount, pProperties);
2482 }
2483 
terminator_GetDisplayModeProperties2KHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display, uint32_t *pPropertyCount, VkDisplayModeProperties2KHR *pProperties)2484 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDisplayModeProperties2KHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
2485                                                                        uint32_t *pPropertyCount,
2486                                                                        VkDisplayModeProperties2KHR *pProperties) {
2487     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
2488     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
2489 
2490     // If the function is available in the driver, just call into it
2491     if (icd_term->dispatch.GetDisplayModeProperties2KHR != NULL) {
2492         return icd_term->dispatch.GetDisplayModeProperties2KHR(phys_dev_term->phys_dev, display, pPropertyCount, pProperties);
2493     }
2494 
2495     // We have to emulate the function.
2496     loader_log(icd_term->this_instance, VULKAN_LOADER_INFO_BIT, 0, "vkGetDisplayModeProperties2KHR: Emulating call in ICD \"%s\"",
2497                icd_term->scanned_icd->lib_name);
2498 
2499     // If the icd doesn't support VK_KHR_display, then no properties are available
2500     if (icd_term->dispatch.GetDisplayModePropertiesKHR == NULL) {
2501         *pPropertyCount = 0;
2502         return VK_SUCCESS;
2503     }
2504 
2505     // If we aren't writing to pProperties, then emulation is straightforward
2506     if (pProperties == NULL || *pPropertyCount == 0) {
2507         return icd_term->dispatch.GetDisplayModePropertiesKHR(phys_dev_term->phys_dev, display, pPropertyCount, NULL);
2508     }
2509 
2510     // If we do have to write to pProperties, then we need to write to a temporary array of VkDisplayModePropertiesKHR and copy it
2511     VkDisplayModePropertiesKHR *properties = loader_stack_alloc(*pPropertyCount * sizeof(VkDisplayModePropertiesKHR));
2512     if (properties == NULL) {
2513         return VK_ERROR_OUT_OF_HOST_MEMORY;
2514     }
2515     VkResult res = icd_term->dispatch.GetDisplayModePropertiesKHR(phys_dev_term->phys_dev, display, pPropertyCount, properties);
2516     if (res < 0) {
2517         return res;
2518     }
2519     for (uint32_t i = 0; i < *pPropertyCount; ++i) {
2520         memcpy(&pProperties[i].displayModeProperties, &properties[i], sizeof(VkDisplayModePropertiesKHR));
2521     }
2522     return res;
2523 }
2524 
vkGetDisplayPlaneCapabilities2KHR(VkPhysicalDevice physicalDevice, const VkDisplayPlaneInfo2KHR *pDisplayPlaneInfo, VkDisplayPlaneCapabilities2KHR *pCapabilities)2525 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayPlaneCapabilities2KHR(VkPhysicalDevice physicalDevice,
2526                                                                                const VkDisplayPlaneInfo2KHR *pDisplayPlaneInfo,
2527                                                                                VkDisplayPlaneCapabilities2KHR *pCapabilities) {
2528     const VkLayerInstanceDispatchTable *disp;
2529     VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
2530     if (VK_NULL_HANDLE == unwrapped_phys_dev) {
2531         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2532                    "vkGetDisplayPlaneCapabilities2KHR: Invalid physicalDevice "
2533                    "[VUID-vkGetDisplayPlaneCapabilities2KHR-physicalDevice-parameter]");
2534         abort(); /* Intentionally fail so user can correct issue. */
2535     }
2536     disp = loader_get_instance_layer_dispatch(physicalDevice);
2537     return disp->GetDisplayPlaneCapabilities2KHR(unwrapped_phys_dev, pDisplayPlaneInfo, pCapabilities);
2538 }
2539 
terminator_GetDisplayPlaneCapabilities2KHR(VkPhysicalDevice physicalDevice, const VkDisplayPlaneInfo2KHR *pDisplayPlaneInfo, VkDisplayPlaneCapabilities2KHR *pCapabilities)2540 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDisplayPlaneCapabilities2KHR(VkPhysicalDevice physicalDevice,
2541                                                                           const VkDisplayPlaneInfo2KHR *pDisplayPlaneInfo,
2542                                                                           VkDisplayPlaneCapabilities2KHR *pCapabilities) {
2543     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
2544     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
2545 
2546     // If the function is available in the driver, just call into it
2547     if (icd_term->dispatch.GetDisplayPlaneCapabilities2KHR != NULL) {
2548         return icd_term->dispatch.GetDisplayPlaneCapabilities2KHR(phys_dev_term->phys_dev, pDisplayPlaneInfo, pCapabilities);
2549     }
2550 
2551     // We have to emulate the function.
2552     loader_log(icd_term->this_instance, VULKAN_LOADER_INFO_BIT, 0,
2553                "vkGetDisplayPlaneCapabilities2KHR: Emulating call in ICD \"%s\"", icd_term->scanned_icd->lib_name);
2554 
2555     // If the icd doesn't support VK_KHR_display, then there are no capabilities
2556     if (NULL == icd_term->dispatch.GetDisplayPlaneCapabilitiesKHR) {
2557         if (pCapabilities) {
2558             memset(&pCapabilities->capabilities, 0, sizeof(VkDisplayPlaneCapabilitiesKHR));
2559         }
2560         return VK_SUCCESS;
2561     }
2562 
2563     // Just call into the old version of the function.
2564     return icd_term->dispatch.GetDisplayPlaneCapabilitiesKHR(phys_dev_term->phys_dev, pDisplayPlaneInfo->mode,
2565                                                              pDisplayPlaneInfo->planeIndex, &pCapabilities->capabilities);
2566 }
2567 
2568 #if defined(VK_USE_PLATFORM_FUCHSIA)
2569 
2570 // This is the trampoline entrypoint for CreateImagePipeSurfaceFUCHSIA
vkCreateImagePipeSurfaceFUCHSIA(VkInstance instance, const VkImagePipeSurfaceCreateInfoFUCHSIA *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)2571 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateImagePipeSurfaceFUCHSIA(VkInstance instance,
2572                                                                              const VkImagePipeSurfaceCreateInfoFUCHSIA *pCreateInfo,
2573                                                                              const VkAllocationCallbacks *pAllocator,
2574                                                                              VkSurfaceKHR *pSurface) {
2575     struct loader_instance *loader_inst = loader_get_instance(instance);
2576     if (NULL == loader_inst) {
2577         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2578                    "vkCreateImagePipeSurfaceFUCHSIA: Invalid instance [VUID-vkCreateImagePipeSurfaceFUCHSIA-instance-parameter]");
2579         abort(); /* Intentionally fail so user can correct issue. */
2580     }
2581     return loader_inst->disp->layer_inst_disp.CreateImagePipeSurfaceFUCHSIA(loader_inst->instance, pCreateInfo, pAllocator,
2582                                                                             pSurface);
2583 }
2584 
2585 // This is the instance chain terminator function for CreateImagePipeSurfaceFUCHSIA
terminator_CreateImagePipeSurfaceFUCHSIA(VkInstance instance, const VkImagePipeSurfaceCreateInfoFUCHSIA *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)2586 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateImagePipeSurfaceFUCHSIA(VkInstance instance,
2587                                                                         const VkImagePipeSurfaceCreateInfoFUCHSIA *pCreateInfo,
2588                                                                         const VkAllocationCallbacks *pAllocator,
2589                                                                         VkSurfaceKHR *pSurface) {
2590     VkResult vkRes = VK_SUCCESS;
2591     VkIcdSurface *pIcdSurface = NULL;
2592     uint32_t i = 0;
2593 
2594     // Initialize pSurface to NULL just to be safe.
2595     *pSurface = VK_NULL_HANDLE;
2596     // First, check to ensure the appropriate extension was enabled:
2597     struct loader_instance *loader_inst = loader_get_instance(instance);
2598     if (!loader_inst->wsi_imagepipe_surface_enabled) {
2599         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
2600                    "VK_FUCHSIA_imagepipe_surface extension not enabled.  "
2601                    "vkCreateImagePipeSurfaceFUCHSIA not executed!");
2602         vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
2603         goto out;
2604     }
2605 
2606     // Next, if so, proceed with the implementation of this function:
2607     pIcdSurface =
2608         AllocateIcdSurfaceStruct(loader_inst, sizeof(pIcdSurface->imagepipe_surf.base), sizeof(pIcdSurface->imagepipe_surf));
2609     if (pIcdSurface == NULL) {
2610         vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
2611         goto out;
2612     }
2613 
2614     pIcdSurface->imagepipe_surf.base.platform = VK_ICD_WSI_PLATFORM_FUCHSIA;
2615 
2616     // Loop through each ICD and determine if they need to create a surface
2617     for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
2618         if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
2619             if (NULL != icd_term->dispatch.CreateImagePipeSurfaceFUCHSIA) {
2620                 vkRes = icd_term->dispatch.CreateImagePipeSurfaceFUCHSIA(icd_term->instance, pCreateInfo, pAllocator,
2621                                                                          &pIcdSurface->real_icd_surfaces[i]);
2622                 if (VK_SUCCESS != vkRes) {
2623                     goto out;
2624                 }
2625             }
2626         }
2627     }
2628 
2629     *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface;
2630 
2631 out:
2632 
2633     if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
2634         if (NULL != pIcdSurface->real_icd_surfaces) {
2635             i = 0;
2636             for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
2637                 if ((VkSurfaceKHR)(uintptr_t)NULL != pIcdSurface->real_icd_surfaces[i] &&
2638                     NULL != icd_term->dispatch.DestroySurfaceKHR) {
2639                     icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
2640                 }
2641             }
2642             loader_instance_heap_free(loader_inst, pIcdSurface->real_icd_surfaces);
2643         }
2644         loader_instance_heap_free(loader_inst, pIcdSurface);
2645     }
2646 
2647     return vkRes;
2648 }
2649 #endif  // VK_USE_PLATFORM_FUCHSIA
2650 
2651 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
vkGetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo, VkSurfaceCapabilities2KHR *pSurfaceCapabilities)2652 vkGetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
2653                                            VkSurfaceCapabilities2KHR *pSurfaceCapabilities) {
2654     const VkLayerInstanceDispatchTable *disp;
2655     VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
2656     if (VK_NULL_HANDLE == unwrapped_phys_dev) {
2657         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2658                    "vkGetPhysicalDeviceSurfaceCapabilities2KHR: Invalid physicalDevice "
2659                    "[VUID-vkGetPhysicalDeviceSurfaceCapabilities2KHR-physicalDevice-parameter]");
2660         abort(); /* Intentionally fail so user can correct issue. */
2661     }
2662     disp = loader_get_instance_layer_dispatch(physicalDevice);
2663     return disp->GetPhysicalDeviceSurfaceCapabilities2KHR(unwrapped_phys_dev, pSurfaceInfo, pSurfaceCapabilities);
2664 }
2665 
terminator_GetPhysicalDeviceSurfaceCapabilities2KHR( VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo, VkSurfaceCapabilities2KHR *pSurfaceCapabilities)2666 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceCapabilities2KHR(
2667     VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
2668     VkSurfaceCapabilities2KHR *pSurfaceCapabilities) {
2669     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
2670     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
2671     struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
2672 
2673     if (!loader_inst->wsi_surface_enabled) {
2674         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
2675                    "VK_KHR_surface extension not enabled. vkGetPhysicalDeviceSurfaceCapabilities2KHR not executed!");
2676         return VK_SUCCESS;
2677     }
2678 
2679     VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)(pSurfaceInfo->surface);
2680     uint8_t icd_index = phys_dev_term->icd_index;
2681 
2682     if (icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2KHR != NULL) {
2683         VkBaseOutStructure *pNext = (VkBaseOutStructure *)pSurfaceCapabilities->pNext;
2684         while (pNext != NULL) {
2685             if ((int)pNext->sType == VK_STRUCTURE_TYPE_SURFACE_PROTECTED_CAPABILITIES_KHR) {
2686                 // Not all ICDs may be supporting VK_KHR_surface_protected_capabilities
2687                 // Initialize VkSurfaceProtectedCapabilitiesKHR.supportsProtected to false and
2688                 // if an ICD supports protected surfaces, it will reset it to true accordingly.
2689                 ((VkSurfaceProtectedCapabilitiesKHR *)pNext)->supportsProtected = VK_FALSE;
2690             }
2691             pNext = (VkBaseOutStructure *)pNext->pNext;
2692         }
2693 
2694         // Pass the call to the driver, possibly unwrapping the ICD surface
2695         if (NULL != icd_surface->real_icd_surfaces && NULL != (void *)(uintptr_t)icd_surface->real_icd_surfaces[icd_index]) {
2696             VkPhysicalDeviceSurfaceInfo2KHR info_copy = *pSurfaceInfo;
2697             info_copy.surface = icd_surface->real_icd_surfaces[icd_index];
2698             return icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2KHR(phys_dev_term->phys_dev, &info_copy,
2699                                                                                pSurfaceCapabilities);
2700         } else {
2701             return icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2KHR(phys_dev_term->phys_dev, pSurfaceInfo,
2702                                                                                pSurfaceCapabilities);
2703         }
2704     } else {
2705         // Emulate the call
2706         loader_log(icd_term->this_instance, VULKAN_LOADER_INFO_BIT, 0,
2707                    "vkGetPhysicalDeviceSurfaceCapabilities2KHR: Emulating call in ICD \"%s\" using "
2708                    "vkGetPhysicalDeviceSurfaceCapabilitiesKHR",
2709                    icd_term->scanned_icd->lib_name);
2710 
2711         if (pSurfaceInfo->pNext != NULL) {
2712             loader_log(icd_term->this_instance, VULKAN_LOADER_WARN_BIT, 0,
2713                        "vkGetPhysicalDeviceSurfaceCapabilities2KHR: Emulation found unrecognized structure type in "
2714                        "pSurfaceInfo->pNext - this struct will be ignored");
2715         }
2716 
2717         // Write to the VkSurfaceCapabilities2KHR struct
2718         VkSurfaceKHR surface = pSurfaceInfo->surface;
2719         if (NULL != icd_surface->real_icd_surfaces && NULL != (void *)(uintptr_t)(icd_surface->real_icd_surfaces[icd_index])) {
2720             surface = icd_surface->real_icd_surfaces[icd_index];
2721         }
2722 
2723         // If the icd doesn't support VK_KHR_surface, then there are no capabilities
2724         if (NULL == icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilitiesKHR) {
2725             if (pSurfaceCapabilities) {
2726                 memset(&pSurfaceCapabilities->surfaceCapabilities, 0, sizeof(VkSurfaceCapabilitiesKHR));
2727             }
2728             return VK_SUCCESS;
2729         }
2730         VkResult res = icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilitiesKHR(phys_dev_term->phys_dev, surface,
2731                                                                                   &pSurfaceCapabilities->surfaceCapabilities);
2732 
2733         if (pSurfaceCapabilities->pNext != NULL) {
2734             loader_log(icd_term->this_instance, VULKAN_LOADER_WARN_BIT, 0,
2735                        "vkGetPhysicalDeviceSurfaceCapabilities2KHR: Emulation found unrecognized structure type in "
2736                        "pSurfaceCapabilities->pNext - this struct will be ignored");
2737         }
2738         return res;
2739     }
2740 }
2741 
2742 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
vkGetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo, uint32_t *pSurfaceFormatCount, VkSurfaceFormat2KHR *pSurfaceFormats)2743 vkGetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
2744                                       uint32_t *pSurfaceFormatCount, VkSurfaceFormat2KHR *pSurfaceFormats) {
2745     const VkLayerInstanceDispatchTable *disp;
2746     VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
2747     if (VK_NULL_HANDLE == unwrapped_phys_dev) {
2748         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2749                    "vkGetPhysicalDeviceSurfaceFormats2KHR: Invalid physicalDevice "
2750                    "[VUID-vkGetPhysicalDeviceSurfaceFormats2KHR-physicalDevice-parameter]");
2751         abort(); /* Intentionally fail so user can correct issue. */
2752     }
2753     disp = loader_get_instance_layer_dispatch(physicalDevice);
2754     return disp->GetPhysicalDeviceSurfaceFormats2KHR(unwrapped_phys_dev, pSurfaceInfo, pSurfaceFormatCount, pSurfaceFormats);
2755 }
2756 
terminator_GetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo, uint32_t *pSurfaceFormatCount, VkSurfaceFormat2KHR *pSurfaceFormats)2757 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice,
2758                                                                               const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
2759                                                                               uint32_t *pSurfaceFormatCount,
2760                                                                               VkSurfaceFormat2KHR *pSurfaceFormats) {
2761     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
2762     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
2763     struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
2764 
2765     if (!loader_inst->wsi_surface_enabled) {
2766         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
2767                    "VK_KHR_surface extension not enabled. vkGetPhysicalDeviceSurfaceFormats2KHR not executed!");
2768         return VK_SUCCESS;
2769     }
2770 
2771     VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)(pSurfaceInfo->surface);
2772     uint8_t icd_index = phys_dev_term->icd_index;
2773 
2774     if (icd_term->dispatch.GetPhysicalDeviceSurfaceFormats2KHR != NULL) {
2775         // Pass the call to the driver, possibly unwrapping the ICD surface
2776         if (NULL != icd_surface->real_icd_surfaces && NULL != (void *)(uintptr_t)(icd_surface->real_icd_surfaces[icd_index])) {
2777             VkPhysicalDeviceSurfaceInfo2KHR info_copy = *pSurfaceInfo;
2778             info_copy.surface = icd_surface->real_icd_surfaces[icd_index];
2779             return icd_term->dispatch.GetPhysicalDeviceSurfaceFormats2KHR(phys_dev_term->phys_dev, &info_copy, pSurfaceFormatCount,
2780                                                                           pSurfaceFormats);
2781         } else {
2782             return icd_term->dispatch.GetPhysicalDeviceSurfaceFormats2KHR(phys_dev_term->phys_dev, pSurfaceInfo,
2783                                                                           pSurfaceFormatCount, pSurfaceFormats);
2784         }
2785     } else {
2786         // Emulate the call
2787         loader_log(icd_term->this_instance, VULKAN_LOADER_INFO_BIT, 0,
2788                    "vkGetPhysicalDeviceSurfaceFormats2KHR: Emulating call in ICD \"%s\" using vkGetPhysicalDeviceSurfaceFormatsKHR",
2789                    icd_term->scanned_icd->lib_name);
2790 
2791         if (pSurfaceInfo->pNext != NULL) {
2792             loader_log(icd_term->this_instance, VULKAN_LOADER_WARN_BIT, 0,
2793                        "vkGetPhysicalDeviceSurfaceFormats2KHR: Emulation found unrecognized structure type in pSurfaceInfo->pNext "
2794                        "- this struct will be ignored");
2795         }
2796 
2797         VkSurfaceKHR surface = pSurfaceInfo->surface;
2798         if (NULL != icd_surface->real_icd_surfaces && NULL != (void *)(uintptr_t)(icd_surface->real_icd_surfaces[icd_index])) {
2799             surface = icd_surface->real_icd_surfaces[icd_index];
2800         }
2801 
2802         // If the icd doesn't support VK_KHR_surface, then there are no formats
2803         if (NULL == icd_term->dispatch.GetPhysicalDeviceSurfaceFormatsKHR) {
2804             if (pSurfaceFormatCount) {
2805                 *pSurfaceFormatCount = 0;
2806             }
2807             return VK_SUCCESS;
2808         }
2809 
2810         if (*pSurfaceFormatCount == 0 || pSurfaceFormats == NULL) {
2811             // Write to pSurfaceFormatCount
2812             return icd_term->dispatch.GetPhysicalDeviceSurfaceFormatsKHR(phys_dev_term->phys_dev, surface, pSurfaceFormatCount,
2813                                                                          NULL);
2814         } else {
2815             // Allocate a temporary array for the output of the old function
2816             VkSurfaceFormatKHR *formats = loader_stack_alloc(*pSurfaceFormatCount * sizeof(VkSurfaceFormatKHR));
2817             if (formats == NULL) {
2818                 return VK_ERROR_OUT_OF_HOST_MEMORY;
2819             }
2820 
2821             VkResult res = icd_term->dispatch.GetPhysicalDeviceSurfaceFormatsKHR(phys_dev_term->phys_dev, surface,
2822                                                                                  pSurfaceFormatCount, formats);
2823             for (uint32_t i = 0; i < *pSurfaceFormatCount; ++i) {
2824                 pSurfaceFormats[i].surfaceFormat = formats[i];
2825                 if (pSurfaceFormats[i].pNext != NULL) {
2826                     loader_log(icd_term->this_instance, VULKAN_LOADER_WARN_BIT, 0,
2827                                "vkGetPhysicalDeviceSurfaceFormats2KHR: Emulation found unrecognized structure type in "
2828                                "pSurfaceFormats[%d].pNext - this struct will be ignored",
2829                                i);
2830                 }
2831             }
2832             return res;
2833         }
2834     }
2835 }
2836 
wsi_swapchain_instance_gpa(struct loader_instance *loader_inst, const char *name, void **addr)2837 bool wsi_swapchain_instance_gpa(struct loader_instance *loader_inst, const char *name, void **addr) {
2838     *addr = NULL;
2839 
2840     // Functions for the VK_KHR_surface extension:
2841     if (!strcmp("vkDestroySurfaceKHR", name)) {
2842         *addr = loader_inst->wsi_surface_enabled ? (void *)vkDestroySurfaceKHR : NULL;
2843         return true;
2844     }
2845     if (!strcmp("vkGetPhysicalDeviceSurfaceSupportKHR", name)) {
2846         *addr = loader_inst->wsi_surface_enabled ? (void *)vkGetPhysicalDeviceSurfaceSupportKHR : NULL;
2847         return true;
2848     }
2849     if (!strcmp("vkGetPhysicalDeviceSurfaceCapabilitiesKHR", name)) {
2850         *addr = loader_inst->wsi_surface_enabled ? (void *)vkGetPhysicalDeviceSurfaceCapabilitiesKHR : NULL;
2851         return true;
2852     }
2853     if (!strcmp("vkGetPhysicalDeviceSurfaceFormatsKHR", name)) {
2854         *addr = loader_inst->wsi_surface_enabled ? (void *)vkGetPhysicalDeviceSurfaceFormatsKHR : NULL;
2855         return true;
2856     }
2857     if (!strcmp("vkGetPhysicalDeviceSurfacePresentModesKHR", name)) {
2858         *addr = loader_inst->wsi_surface_enabled ? (void *)vkGetPhysicalDeviceSurfacePresentModesKHR : NULL;
2859         return true;
2860     }
2861 
2862     if (!strcmp("vkGetDeviceGroupPresentCapabilitiesKHR", name)) {
2863         *addr = loader_inst->wsi_surface_enabled ? (void *)vkGetDeviceGroupPresentCapabilitiesKHR : NULL;
2864         return true;
2865     }
2866 
2867     if (!strcmp("vkGetDeviceGroupSurfacePresentModesKHR", name)) {
2868         *addr = loader_inst->wsi_surface_enabled ? (void *)vkGetDeviceGroupSurfacePresentModesKHR : NULL;
2869         return true;
2870     }
2871 
2872     if (!strcmp("vkGetPhysicalDevicePresentRectanglesKHR", name)) {
2873         *addr = loader_inst->wsi_surface_enabled ? (void *)vkGetPhysicalDevicePresentRectanglesKHR : NULL;
2874         return true;
2875     }
2876 
2877     // Functions for VK_KHR_get_surface_capabilities2 extension:
2878     if (!strcmp("vkGetPhysicalDeviceSurfaceCapabilities2KHR", name)) {
2879         *addr = loader_inst->wsi_surface_enabled ? (void *)vkGetPhysicalDeviceSurfaceCapabilities2KHR : NULL;
2880         return true;
2881     }
2882 
2883     if (!strcmp("vkGetPhysicalDeviceSurfaceFormats2KHR", name)) {
2884         *addr = loader_inst->wsi_surface_enabled ? (void *)vkGetPhysicalDeviceSurfaceFormats2KHR : NULL;
2885         return true;
2886     }
2887 
2888     // Functions for the VK_KHR_swapchain extension:
2889 
2890     // Note: This is a device extension, and its functions are statically
2891     // exported from the loader.  Per Khronos decisions, the loader's GIPA
2892     // function will return the trampoline function for such device-extension
2893     // functions, regardless of whether the extension has been enabled.
2894     if (!strcmp("vkCreateSwapchainKHR", name)) {
2895         *addr = (void *)vkCreateSwapchainKHR;
2896         return true;
2897     }
2898     if (!strcmp("vkDestroySwapchainKHR", name)) {
2899         *addr = (void *)vkDestroySwapchainKHR;
2900         return true;
2901     }
2902     if (!strcmp("vkGetSwapchainImagesKHR", name)) {
2903         *addr = (void *)vkGetSwapchainImagesKHR;
2904         return true;
2905     }
2906     if (!strcmp("vkAcquireNextImageKHR", name)) {
2907         *addr = (void *)vkAcquireNextImageKHR;
2908         return true;
2909     }
2910     if (!strcmp("vkQueuePresentKHR", name)) {
2911         *addr = (void *)vkQueuePresentKHR;
2912         return true;
2913     }
2914     if (!strcmp("vkAcquireNextImage2KHR", name)) {
2915         *addr = (void *)vkAcquireNextImage2KHR;
2916         return true;
2917     }
2918 
2919 #if defined(VK_USE_PLATFORM_WIN32_KHR)
2920 
2921     // Functions for the VK_KHR_win32_surface extension:
2922     if (!strcmp("vkCreateWin32SurfaceKHR", name)) {
2923         *addr = loader_inst->wsi_win32_surface_enabled ? (void *)vkCreateWin32SurfaceKHR : NULL;
2924         return true;
2925     }
2926     if (!strcmp("vkGetPhysicalDeviceWin32PresentationSupportKHR", name)) {
2927         *addr = loader_inst->wsi_win32_surface_enabled ? (void *)vkGetPhysicalDeviceWin32PresentationSupportKHR : NULL;
2928         return true;
2929     }
2930 #endif  // VK_USE_PLATFORM_WIN32_KHR
2931 #if defined(VK_USE_PLATFORM_WAYLAND_KHR)
2932 
2933     // Functions for the VK_KHR_wayland_surface extension:
2934     if (!strcmp("vkCreateWaylandSurfaceKHR", name)) {
2935         *addr = loader_inst->wsi_wayland_surface_enabled ? (void *)vkCreateWaylandSurfaceKHR : NULL;
2936         return true;
2937     }
2938     if (!strcmp("vkGetPhysicalDeviceWaylandPresentationSupportKHR", name)) {
2939         *addr = loader_inst->wsi_wayland_surface_enabled ? (void *)vkGetPhysicalDeviceWaylandPresentationSupportKHR : NULL;
2940         return true;
2941     }
2942 #endif  // VK_USE_PLATFORM_WAYLAND_KHR
2943 #if defined(VK_USE_PLATFORM_XCB_KHR)
2944 
2945     // Functions for the VK_KHR_xcb_surface extension:
2946     if (!strcmp("vkCreateXcbSurfaceKHR", name)) {
2947         *addr = loader_inst->wsi_xcb_surface_enabled ? (void *)vkCreateXcbSurfaceKHR : NULL;
2948         return true;
2949     }
2950     if (!strcmp("vkGetPhysicalDeviceXcbPresentationSupportKHR", name)) {
2951         *addr = loader_inst->wsi_xcb_surface_enabled ? (void *)vkGetPhysicalDeviceXcbPresentationSupportKHR : NULL;
2952         return true;
2953     }
2954 #endif  // VK_USE_PLATFORM_XCB_KHR
2955 #if defined(VK_USE_PLATFORM_XLIB_KHR)
2956 
2957     // Functions for the VK_KHR_xlib_surface extension:
2958     if (!strcmp("vkCreateXlibSurfaceKHR", name)) {
2959         *addr = loader_inst->wsi_xlib_surface_enabled ? (void *)vkCreateXlibSurfaceKHR : NULL;
2960         return true;
2961     }
2962     if (!strcmp("vkGetPhysicalDeviceXlibPresentationSupportKHR", name)) {
2963         *addr = loader_inst->wsi_xlib_surface_enabled ? (void *)vkGetPhysicalDeviceXlibPresentationSupportKHR : NULL;
2964         return true;
2965     }
2966 #endif  // VK_USE_PLATFORM_XLIB_KHR
2967 #if defined(VK_USE_PLATFORM_DIRECTFB_EXT)
2968 
2969     // Functions for the VK_EXT_directfb_surface extension:
2970     if (!strcmp("vkCreateDirectFBSurfaceEXT", name)) {
2971         *addr = loader_inst->wsi_directfb_surface_enabled ? (void *)vkCreateDirectFBSurfaceEXT : NULL;
2972         return true;
2973     }
2974     if (!strcmp("vkGetPhysicalDeviceDirectFBPresentationSupportEXT", name)) {
2975         *addr = loader_inst->wsi_directfb_surface_enabled ? (void *)vkGetPhysicalDeviceDirectFBPresentationSupportEXT : NULL;
2976         return true;
2977     }
2978 #endif  // VK_USE_PLATFORM_DIRECTFB_EXT
2979 #if defined(VK_USE_PLATFORM_ANDROID_KHR)
2980 
2981     // Functions for the VK_KHR_android_surface extension:
2982     if (!strcmp("vkCreateAndroidSurfaceKHR", name)) {
2983         *addr = loader_inst->wsi_android_surface_enabled ? (void *)vkCreateAndroidSurfaceKHR : NULL;
2984         return true;
2985     }
2986 #endif  // VK_USE_PLATFORM_ANDROID_KHR
2987 #if defined(VK_USE_PLATFORM_OHOS)
2988 
2989     // Functions for the VK_OHOS_surface extension:
2990     if (!strcmp("vkCreateSurfaceOHOS", name)) {
2991         *addr = loader_inst->wsi_ohos_surface_enabled ? (void *)vkCreateSurfaceOHOS : NULL;
2992         return true;
2993     }
2994 #endif  // VK_USE_PLATFORM_OHOS
2995 
2996 #if defined(VK_USE_PLATFORM_MACOS_MVK)
2997 
2998     // Functions for the VK_MVK_macos_surface extension:
2999     if (!strcmp("vkCreateMacOSSurfaceMVK", name)) {
3000         *addr = loader_inst->wsi_macos_surface_enabled ? (void *)vkCreateMacOSSurfaceMVK : NULL;
3001         return true;
3002     }
3003 #endif  // VK_USE_PLATFORM_MACOS_MVK
3004 #if defined(VK_USE_PLATFORM_IOS_MVK)
3005 
3006     // Functions for the VK_MVK_ios_surface extension:
3007     if (!strcmp("vkCreateIOSSurfaceMVK", name)) {
3008         *addr = loader_inst->wsi_ios_surface_enabled ? (void *)vkCreateIOSSurfaceMVK : NULL;
3009         return true;
3010     }
3011 #endif  // VK_USE_PLATFORM_IOS_MVK
3012 #if defined(VK_USE_PLATFORM_GGP)
3013 
3014     // Functions for the VK_GGP_stream_descriptor_surface extension:
3015     if (!strcmp("vkCreateStreamDescriptorSurfaceGGP", name)) {
3016         *addr = loader_inst->wsi_ggp_surface_enabled ? (void *)vkCreateStreamDescriptorSurfaceGGP : NULL;
3017         return true;
3018     }
3019 #endif  // VK_USE_PLATFORM_GGP
3020 #if defined(VK_USE_PLATFORM_FUCHSIA)
3021 
3022     // Functions for the VK_FUCHSIA_imagepipe_surface extension:
3023     if (!strcmp("vkCreateImagePipeSurfaceFUCHSIA", name)) {
3024         *addr = loader_inst->wsi_imagepipe_surface_enabled ? (void *)vkCreateImagePipeSurfaceFUCHSIA : NULL;
3025         return true;
3026     }
3027 
3028 #endif  // VK_USE_PLATFORM_FUCHSIA
3029 
3030     // Functions for the VK_EXT_headless_surface extension:
3031     if (!strcmp("vkCreateHeadlessSurfaceEXT", name)) {
3032         *addr = loader_inst->wsi_headless_surface_enabled ? (void *)vkCreateHeadlessSurfaceEXT : NULL;
3033         return true;
3034     }
3035 
3036 #if defined(VK_USE_PLATFORM_METAL_EXT)
3037     // Functions for the VK_MVK_macos_surface extension:
3038     if (!strcmp("vkCreateMetalSurfaceEXT", name)) {
3039         *addr = loader_inst->wsi_metal_surface_enabled ? (void *)vkCreateMetalSurfaceEXT : NULL;
3040         return true;
3041     }
3042 #endif  // VK_USE_PLATFORM_METAL_EXT
3043 
3044 #if defined(VK_USE_PLATFORM_SCREEN_QNX)
3045 
3046     // Functions for the VK_QNX_screen_surface extension:
3047     if (!strcmp("vkCreateScreenSurfaceQNX", name)) {
3048         *addr = loader_inst->wsi_screen_surface_enabled ? (void *)vkCreateScreenSurfaceQNX : NULL;
3049         return true;
3050     }
3051     if (!strcmp("vkGetPhysicalDeviceScreenPresentationSupportQNX", name)) {
3052         *addr = loader_inst->wsi_screen_surface_enabled ? (void *)vkGetPhysicalDeviceScreenPresentationSupportQNX : NULL;
3053         return true;
3054     }
3055 #endif  // VK_USE_PLATFORM_SCREEN_QNX
3056 
3057 #if defined(VK_USE_PLATFORM_VI_NN)
3058 
3059     // Functions for the VK_NN_vi_surface extension:
3060     if (!strcmp("vkCreateViSurfaceNN", name)) {
3061         *addr = loader_inst->wsi_vi_surface_enabled ? (void *)vkCreateViSurfaceNN : NULL;
3062         return true;
3063     }
3064 #endif  // VK_USE_PLATFORM_VI_NN
3065 
3066     // Functions for VK_KHR_display extension:
3067     if (!strcmp("vkGetPhysicalDeviceDisplayPropertiesKHR", name)) {
3068         *addr = loader_inst->wsi_display_enabled ? (void *)vkGetPhysicalDeviceDisplayPropertiesKHR : NULL;
3069         return true;
3070     }
3071     if (!strcmp("vkGetPhysicalDeviceDisplayPlanePropertiesKHR", name)) {
3072         *addr = loader_inst->wsi_display_enabled ? (void *)vkGetPhysicalDeviceDisplayPlanePropertiesKHR : NULL;
3073         return true;
3074     }
3075     if (!strcmp("vkGetDisplayPlaneSupportedDisplaysKHR", name)) {
3076         *addr = loader_inst->wsi_display_enabled ? (void *)vkGetDisplayPlaneSupportedDisplaysKHR : NULL;
3077         return true;
3078     }
3079     if (!strcmp("vkGetDisplayModePropertiesKHR", name)) {
3080         *addr = loader_inst->wsi_display_enabled ? (void *)vkGetDisplayModePropertiesKHR : NULL;
3081         return true;
3082     }
3083     if (!strcmp("vkCreateDisplayModeKHR", name)) {
3084         *addr = loader_inst->wsi_display_enabled ? (void *)vkCreateDisplayModeKHR : NULL;
3085         return true;
3086     }
3087     if (!strcmp("vkGetDisplayPlaneCapabilitiesKHR", name)) {
3088         *addr = loader_inst->wsi_display_enabled ? (void *)vkGetDisplayPlaneCapabilitiesKHR : NULL;
3089         return true;
3090     }
3091     if (!strcmp("vkCreateDisplayPlaneSurfaceKHR", name)) {
3092         *addr = loader_inst->wsi_display_enabled ? (void *)vkCreateDisplayPlaneSurfaceKHR : NULL;
3093         return true;
3094     }
3095 
3096     // Functions for KHR_display_swapchain extension:
3097     if (!strcmp("vkCreateSharedSwapchainsKHR", name)) {
3098         *addr = (void *)vkCreateSharedSwapchainsKHR;
3099         return true;
3100     }
3101 
3102     // Functions for KHR_get_display_properties2
3103     if (!strcmp("vkGetPhysicalDeviceDisplayProperties2KHR", name)) {
3104         *addr = loader_inst->wsi_display_props2_enabled ? (void *)vkGetPhysicalDeviceDisplayProperties2KHR : NULL;
3105         return true;
3106     }
3107     if (!strcmp("vkGetPhysicalDeviceDisplayPlaneProperties2KHR", name)) {
3108         *addr = loader_inst->wsi_display_props2_enabled ? (void *)vkGetPhysicalDeviceDisplayPlaneProperties2KHR : NULL;
3109         return true;
3110     }
3111     if (!strcmp("vkGetDisplayModeProperties2KHR", name)) {
3112         *addr = loader_inst->wsi_display_props2_enabled ? (void *)vkGetDisplayModeProperties2KHR : NULL;
3113         return true;
3114     }
3115     if (!strcmp("vkGetDisplayPlaneCapabilities2KHR", name)) {
3116         *addr = loader_inst->wsi_display_props2_enabled ? (void *)vkGetDisplayPlaneCapabilities2KHR : NULL;
3117         return true;
3118     }
3119 
3120     return false;
3121 }
3122