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