• 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      struct loader_instance *loader_inst = loader_get_instance(instance);
1231      if (NULL == loader_inst) {
1232          loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1233                     "vkCreateSurfaceOHOS: Invalid instance [VUID-vkCreateSurfaceOHOS-instance-parameter]");
1234          abort(); /* Intentionally fail so user can correct issue. */
1235      }
1236      return loader_inst->disp->layer_inst_disp.CreateSurfaceOHOS(loader_inst->instance, pCreateInfo, pAllocator, pSurface);
1237  }
1238  
1239  // This is the instance chain terminator function for CreateSurfaceOHOS
terminator_CreateSurfaceOHOS(VkInstance instance,const VkSurfaceCreateInfoOHOS * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSurfaceKHR * pSurface)1240  VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateSurfaceOHOS(VkInstance instance,
1241                                                                         const VkSurfaceCreateInfoOHOS *pCreateInfo,
1242                                                                         const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
1243      // First, check to ensure the appropriate extension was enabled:
1244      struct loader_instance *loader_inst = loader_get_instance(instance);
1245      if (!loader_inst->wsi_ohos_surface_enabled) {
1246          loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
1247                     "VK_OHOS_surface extension not enabled. vkCreateSurfaceOHOS not executed!\n");
1248          return VK_ERROR_EXTENSION_NOT_PRESENT;
1249      }
1250  
1251      // Next, if so, proceed with the implementation of this function:
1252      VkIcdSurfaceOHOS *pIcdSurface =
1253          loader_instance_heap_alloc(loader_inst, sizeof(VkIcdSurfaceOHOS), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1254      if (pIcdSurface == NULL) {
1255          return VK_ERROR_OUT_OF_HOST_MEMORY;
1256      }
1257  
1258      pIcdSurface->base.platform = VK_ICD_WSI_PLATFORM_OHOS;
1259      pIcdSurface->window = pCreateInfo->window;
1260  
1261      *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface;
1262  
1263      return VK_SUCCESS;
1264  }
1265  
1266  #endif  // VK_USE_PLATFORM_OHOS
1267  
1268  
1269  // Functions for the VK_EXT_headless_surface extension:
1270  
vkCreateHeadlessSurfaceEXT(VkInstance instance,const VkHeadlessSurfaceCreateInfoEXT * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSurfaceKHR * pSurface)1271  LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateHeadlessSurfaceEXT(VkInstance instance,
1272                                                                          const VkHeadlessSurfaceCreateInfoEXT *pCreateInfo,
1273                                                                          const VkAllocationCallbacks *pAllocator,
1274                                                                          VkSurfaceKHR *pSurface) {
1275      struct loader_instance *loader_inst = loader_get_instance(instance);
1276      if (NULL == loader_inst) {
1277          loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1278                     "vkCreateHeadlessSurfaceEXT: Invalid instance [VUID-vkCreateHeadlessSurfaceEXT-instance-parameter]");
1279          abort(); /* Intentionally fail so user can correct issue. */
1280      }
1281      return loader_inst->disp->layer_inst_disp.CreateHeadlessSurfaceEXT(loader_inst->instance, pCreateInfo, pAllocator, pSurface);
1282  }
1283  
terminator_CreateHeadlessSurfaceEXT(VkInstance instance,const VkHeadlessSurfaceCreateInfoEXT * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSurfaceKHR * pSurface)1284  VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateHeadlessSurfaceEXT(VkInstance instance,
1285                                                                     const VkHeadlessSurfaceCreateInfoEXT *pCreateInfo,
1286                                                                     const VkAllocationCallbacks *pAllocator,
1287                                                                     VkSurfaceKHR *pSurface) {
1288      struct loader_instance *inst = loader_get_instance(instance);
1289      VkIcdSurface *pIcdSurface = NULL;
1290      VkResult vkRes = VK_SUCCESS;
1291      uint32_t i = 0;
1292  
1293      if (!inst->wsi_headless_surface_enabled) {
1294          loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0,
1295                     "VK_EXT_headless_surface extension not enabled.  "
1296                     "vkCreateHeadlessSurfaceEXT not executed!\n");
1297          return VK_SUCCESS;
1298      }
1299  
1300      // Next, if so, proceed with the implementation of this function:
1301      pIcdSurface = AllocateIcdSurfaceStruct(inst, sizeof(pIcdSurface->headless_surf.base), sizeof(pIcdSurface->headless_surf));
1302      if (pIcdSurface == NULL) {
1303          vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
1304          goto out;
1305      }
1306  
1307      pIcdSurface->headless_surf.base.platform = VK_ICD_WSI_PLATFORM_HEADLESS;
1308      // Loop through each ICD and determine if they need to create a surface
1309      for (struct loader_icd_term *icd_term = inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
1310          if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
1311              if (NULL != icd_term->dispatch.CreateHeadlessSurfaceEXT) {
1312                  vkRes = icd_term->dispatch.CreateHeadlessSurfaceEXT(icd_term->instance, pCreateInfo, pAllocator,
1313                                                                      &pIcdSurface->real_icd_surfaces[i]);
1314                  if (VK_SUCCESS != vkRes) {
1315                      goto out;
1316                  }
1317              }
1318          }
1319      }
1320  
1321      *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface;
1322  
1323  out:
1324  
1325      if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
1326          if (NULL != pIcdSurface->real_icd_surfaces) {
1327              i = 0;
1328              for (struct loader_icd_term *icd_term = inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
1329                  if ((VkSurfaceKHR)(uintptr_t)NULL != pIcdSurface->real_icd_surfaces[i] &&
1330                      NULL != icd_term->dispatch.DestroySurfaceKHR) {
1331                      icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
1332                  }
1333              }
1334              loader_instance_heap_free(inst, pIcdSurface->real_icd_surfaces);
1335          }
1336          loader_instance_heap_free(inst, pIcdSurface);
1337      }
1338  
1339      return vkRes;
1340  }
1341  
1342  #ifdef VK_USE_PLATFORM_MACOS_MVK
1343  
1344  // Functions for the VK_MVK_macos_surface extension:
1345  
1346  // This is the trampoline entrypoint for CreateMacOSSurfaceMVK
vkCreateMacOSSurfaceMVK(VkInstance instance,const VkMacOSSurfaceCreateInfoMVK * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSurfaceKHR * pSurface)1347  LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateMacOSSurfaceMVK(VkInstance instance,
1348                                                                       const VkMacOSSurfaceCreateInfoMVK *pCreateInfo,
1349                                                                       const VkAllocationCallbacks *pAllocator,
1350                                                                       VkSurfaceKHR *pSurface) {
1351      struct loader_instance *loader_inst = loader_get_instance(instance);
1352      if (NULL == loader_inst) {
1353          loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1354                     "vkCreateMacOSSurfaceMVK: Invalid instance [VUID-vkCreateMacOSSurfaceMVK-instance-parameter]");
1355          abort(); /* Intentionally fail so user can correct issue. */
1356      }
1357      return loader_inst->disp->layer_inst_disp.CreateMacOSSurfaceMVK(loader_inst->instance, pCreateInfo, pAllocator, pSurface);
1358  }
1359  
1360  // This is the instance chain terminator function for CreateMacOSSurfaceKHR
terminator_CreateMacOSSurfaceMVK(VkInstance instance,const VkMacOSSurfaceCreateInfoMVK * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSurfaceKHR * pSurface)1361  VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateMacOSSurfaceMVK(VkInstance instance, const VkMacOSSurfaceCreateInfoMVK *pCreateInfo,
1362                                                                  const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
1363      VkResult vkRes = VK_SUCCESS;
1364      VkIcdSurface *pIcdSurface = NULL;
1365      uint32_t i = 0;
1366  
1367      // First, check to ensure the appropriate extension was enabled:
1368      struct loader_instance *loader_inst = loader_get_instance(instance);
1369      if (!loader_inst->wsi_macos_surface_enabled) {
1370          loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
1371                     "VK_MVK_macos_surface extension not enabled. vkCreateMacOSSurfaceMVK not executed!\n");
1372          vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
1373          goto out;
1374      }
1375  
1376      // Next, if so, proceed with the implementation of this function:
1377      pIcdSurface = AllocateIcdSurfaceStruct(loader_inst, sizeof(pIcdSurface->macos_surf.base), sizeof(pIcdSurface->macos_surf));
1378      if (pIcdSurface == NULL) {
1379          vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
1380          goto out;
1381      }
1382  
1383      pIcdSurface->macos_surf.base.platform = VK_ICD_WSI_PLATFORM_MACOS;
1384      pIcdSurface->macos_surf.pView = pCreateInfo->pView;
1385  
1386      // Loop through each ICD and determine if they need to create a surface
1387      for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
1388          if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
1389              if (NULL != icd_term->dispatch.CreateMacOSSurfaceMVK) {
1390                  vkRes = icd_term->dispatch.CreateMacOSSurfaceMVK(icd_term->instance, pCreateInfo, pAllocator,
1391                                                                   &pIcdSurface->real_icd_surfaces[i]);
1392                  if (VK_SUCCESS != vkRes) {
1393                      goto out;
1394                  }
1395              }
1396          }
1397      }
1398  
1399      *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface;
1400  
1401  out:
1402  
1403      if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
1404          if (NULL != pIcdSurface->real_icd_surfaces) {
1405              i = 0;
1406              for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
1407                  if ((VkSurfaceKHR)(uintptr_t)NULL != pIcdSurface->real_icd_surfaces[i] &&
1408                      NULL != icd_term->dispatch.DestroySurfaceKHR) {
1409                      icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
1410                  }
1411              }
1412              loader_instance_heap_free(loader_inst, pIcdSurface->real_icd_surfaces);
1413          }
1414          loader_instance_heap_free(loader_inst, pIcdSurface);
1415      }
1416  
1417      return vkRes;
1418  }
1419  
1420  #endif  // VK_USE_PLATFORM_MACOS_MVK
1421  
1422  #ifdef VK_USE_PLATFORM_IOS_MVK
1423  
1424  // Functions for the VK_MVK_ios_surface extension:
1425  
1426  // This is the trampoline entrypoint for CreateIOSSurfaceMVK
vkCreateIOSSurfaceMVK(VkInstance instance,const VkIOSSurfaceCreateInfoMVK * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSurfaceKHR * pSurface)1427  LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateIOSSurfaceMVK(VkInstance instance,
1428                                                                     const VkIOSSurfaceCreateInfoMVK *pCreateInfo,
1429                                                                     const VkAllocationCallbacks *pAllocator,
1430                                                                     VkSurfaceKHR *pSurface) {
1431      struct loader_instance *loader_inst = loader_get_instance(instance);
1432      if (NULL == loader_inst) {
1433          loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1434                     "vkCreateIOSSurfaceMVK: Invalid instance [VUID-vkCreateIOSSurfaceMVK-instance-parameter]");
1435          abort(); /* Intentionally fail so user can correct issue. */
1436      }
1437      return loader_inst->disp->layer_inst_disp.CreateIOSSurfaceMVK(loader_inst->instance, pCreateInfo, pAllocator, pSurface);
1438  }
1439  
1440  // This is the instance chain terminator function for CreateIOSSurfaceKHR
terminator_CreateIOSSurfaceMVK(VkInstance instance,const VkIOSSurfaceCreateInfoMVK * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSurfaceKHR * pSurface)1441  VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateIOSSurfaceMVK(VkInstance instance, const VkIOSSurfaceCreateInfoMVK *pCreateInfo,
1442                                                                const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
1443      // First, check to ensure the appropriate extension was enabled:
1444      struct loader_instance *loader_inst = loader_get_instance(instance);
1445      if (!loader_inst->wsi_ios_surface_enabled) {
1446          loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
1447                     "VK_MVK_ios_surface extension not enabled. vkCreateIOSSurfaceMVK not executed!\n");
1448          return VK_ERROR_EXTENSION_NOT_PRESENT;
1449      }
1450  
1451      // Next, if so, proceed with the implementation of this function:
1452      VkIcdSurfaceIOS *pIcdSurface =
1453          loader_instance_heap_alloc(loader_inst, sizeof(VkIcdSurfaceIOS), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1454      if (pIcdSurface == NULL) {
1455          return VK_ERROR_OUT_OF_HOST_MEMORY;
1456      }
1457  
1458      pIcdSurface->base.platform = VK_ICD_WSI_PLATFORM_IOS;
1459      pIcdSurface->pView = pCreateInfo->pView;
1460  
1461      *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface;
1462  
1463      return VK_SUCCESS;
1464  }
1465  
1466  #endif  // VK_USE_PLATFORM_IOS_MVK
1467  
1468  #ifdef VK_USE_PLATFORM_GGP
1469  
1470  // Functions for the VK_GGP_stream_descriptor_surface extension:
1471  
1472  // This is the trampoline entrypoint for CreateStreamDescriptorSurfaceGGP
1473  LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
vkCreateStreamDescriptorSurfaceGGP(VkInstance instance,const VkStreamDescriptorSurfaceCreateInfoGGP * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSurfaceKHR * pSurface)1474  vkCreateStreamDescriptorSurfaceGGP(VkInstance instance, const VkStreamDescriptorSurfaceCreateInfoGGP *pCreateInfo,
1475                                     const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
1476      struct loader_instance *loader_inst = loader_get_instance(instance);
1477      if (NULL == loader_inst) {
1478          loader_log(
1479              NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1480              "vkCreateStreamDescriptorSurfaceGGP: Invalid instance [VUID-vkCreateStreamDescriptorSurfaceGGP-instance-parameter]");
1481          abort(); /* Intentionally fail so user can correct issue. */
1482      }
1483      return loader_inst->disp->layer_inst_disp.CreateStreamDescriptorSurfaceGGP(loader_inst->instance, pCreateInfo, pAllocator,
1484                                                                                 pSurface);
1485  }
1486  
1487  // This is the instance chain terminator function for CreateStreamDescriptorSurfaceGGP
1488  VKAPI_ATTR VkResult VKAPI_CALL
terminator_CreateStreamDescriptorSurfaceGGP(VkInstance instance,const VkStreamDescriptorSurfaceCreateInfoGGP * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSurfaceKHR * pSurface)1489  terminator_CreateStreamDescriptorSurfaceGGP(VkInstance instance, const VkStreamDescriptorSurfaceCreateInfoGGP *pCreateInfo,
1490                                              const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
1491      VkResult vkRes = VK_SUCCESS;
1492      VkIcdSurface *pIcdSurface = NULL;
1493      uint32_t i = 0;
1494  
1495      // First, check to ensure the appropriate extension was enabled:
1496      struct loader_instance *loader_inst = loader_get_instance(instance);
1497      if (!loader_inst->wsi_ggp_surface_enabled) {
1498          loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
1499                     "VK_GGP_stream_descriptor_surface extension not enabled. vkCreateStreamDescriptorSurfaceGGP not executed!\n");
1500          vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
1501          goto out;
1502      }
1503  
1504      // Next, if so, proceed with the implementation of this function:
1505      pIcdSurface = AllocateIcdSurfaceStruct(loader_inst, sizeof(pIcdSurface->ggp_surf.base), sizeof(pIcdSurface->ggp_surf));
1506      if (pIcdSurface == NULL) {
1507          vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
1508          goto out;
1509      }
1510  
1511      pIcdSurface->ggp_surf.base.platform = VK_ICD_WSI_PLATFORM_GGP;
1512      pIcdSurface->ggp_surf.streamDescriptor = pCreateInfo->streamDescriptor;
1513  
1514      // Loop through each ICD and determine if they need to create a surface
1515      for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
1516          if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
1517              if (NULL != icd_term->dispatch.CreateStreamDescriptorSurfaceGGP) {
1518                  vkRes = icd_term->dispatch.CreateStreamDescriptorSurfaceGGP(icd_term->instance, pCreateInfo, pAllocator,
1519                                                                              &pIcdSurface->real_icd_surfaces[i]);
1520                  if (VK_SUCCESS != vkRes) {
1521                      goto out;
1522                  }
1523              }
1524          }
1525      }
1526  
1527      *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface;
1528  
1529  out:
1530  
1531      if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
1532          if (NULL != pIcdSurface->real_icd_surfaces) {
1533              i = 0;
1534              for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
1535                  if ((VkSurfaceKHR)(uintptr_t)NULL != pIcdSurface->real_icd_surfaces[i] &&
1536                      NULL != icd_term->dispatch.DestroySurfaceKHR) {
1537                      icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
1538                  }
1539              }
1540              loader_instance_heap_free(loader_inst, pIcdSurface->real_icd_surfaces);
1541          }
1542          loader_instance_heap_free(loader_inst, pIcdSurface);
1543      }
1544      return vkRes;
1545  }
1546  
1547  #endif  // VK_USE_PLATFORM_GGP
1548  
1549  #if defined(VK_USE_PLATFORM_METAL_EXT)
1550  
vkCreateMetalSurfaceEXT(VkInstance instance,const VkMetalSurfaceCreateInfoEXT * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSurfaceKHR * pSurface)1551  LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateMetalSurfaceEXT(VkInstance instance,
1552                                                                       const VkMetalSurfaceCreateInfoEXT *pCreateInfo,
1553                                                                       const VkAllocationCallbacks *pAllocator,
1554                                                                       VkSurfaceKHR *pSurface) {
1555      struct loader_instance *loader_inst = loader_get_instance(instance);
1556      if (NULL == loader_inst) {
1557          loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1558                     "vkCreateMetalSurfaceEXT: Invalid instance [VUID-vkCreateMetalSurfaceEXT-instance-parameter]");
1559          abort(); /* Intentionally fail so user can correct issue. */
1560      }
1561      return loader_inst->disp->layer_inst_disp.CreateMetalSurfaceEXT(loader_inst->instance, pCreateInfo, pAllocator, pSurface);
1562  }
1563  
terminator_CreateMetalSurfaceEXT(VkInstance instance,const VkMetalSurfaceCreateInfoEXT * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSurfaceKHR * pSurface)1564  VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateMetalSurfaceEXT(VkInstance instance, const VkMetalSurfaceCreateInfoEXT *pCreateInfo,
1565                                                                  const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
1566      VkResult result = VK_SUCCESS;
1567      VkIcdSurface *icd_surface = NULL;
1568      uint32_t i;
1569  
1570      // First, check to ensure the appropriate extension was enabled:
1571      struct loader_instance *loader_inst = loader_get_instance(instance);
1572      if (!loader_inst->wsi_metal_surface_enabled) {
1573          loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
1574                     "VK_EXT_metal_surface extension not enabled. vkCreateMetalSurfaceEXT will not be executed.\n");
1575      }
1576  
1577      // Next, if so, proceed with the implementation of this function:
1578      icd_surface = AllocateIcdSurfaceStruct(loader_inst, sizeof(icd_surface->metal_surf.base), sizeof(icd_surface->metal_surf));
1579      if (icd_surface == NULL) {
1580          result = VK_ERROR_OUT_OF_HOST_MEMORY;
1581          goto out;
1582      }
1583  
1584      icd_surface->metal_surf.base.platform = VK_ICD_WSI_PLATFORM_METAL;
1585      icd_surface->metal_surf.pLayer = pCreateInfo->pLayer;
1586  
1587      // Loop through each ICD and determine if they need to create a surface
1588      i = 0;
1589      for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, ++i) {
1590          if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
1591              if (icd_term->dispatch.CreateMetalSurfaceEXT != NULL) {
1592                  result = icd_term->dispatch.CreateMetalSurfaceEXT(icd_term->instance, pCreateInfo, pAllocator,
1593                                                                    &icd_surface->real_icd_surfaces[i]);
1594                  if (result != VK_SUCCESS) {
1595                      goto out;
1596                  }
1597              }
1598          }
1599      }
1600      *pSurface = (VkSurfaceKHR)icd_surface;
1601  
1602  out:
1603      if (result != VK_SUCCESS && icd_surface != NULL) {
1604          if (icd_surface->real_icd_surfaces != NULL) {
1605              i = 0;
1606              for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, ++i) {
1607                  if (icd_surface->real_icd_surfaces[i] == VK_NULL_HANDLE && icd_term->dispatch.DestroySurfaceKHR != NULL) {
1608                      icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, icd_surface->real_icd_surfaces[i], pAllocator);
1609                  }
1610              }
1611              loader_instance_heap_free(loader_inst, icd_surface->real_icd_surfaces);
1612          }
1613          loader_instance_heap_free(loader_inst, icd_surface);
1614      }
1615      return result;
1616  }
1617  
1618  #endif  // VK_USE_PLATFORM_METAL_EXT
1619  
1620  #ifdef VK_USE_PLATFORM_SCREEN_QNX
1621  
1622  // This is the trampoline entrypoint for CreateScreenSurfaceQNX
vkCreateScreenSurfaceQNX(VkInstance instance,const VkScreenSurfaceCreateInfoQNX * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSurfaceKHR * pSurface)1623  LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateScreenSurfaceQNX(VkInstance instance,
1624                                                                        const VkScreenSurfaceCreateInfoQNX *pCreateInfo,
1625                                                                        const VkAllocationCallbacks *pAllocator,
1626                                                                        VkSurfaceKHR *pSurface) {
1627      struct loader_instance *loader_inst = loader_get_instance(instance);
1628      if (NULL == loader_inst) {
1629          loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1630                     "vkCreateScreenSurfaceQNX: Invalid instance [VUID-vkCreateScreenSurfaceQNX-instance-parameter]");
1631          abort(); /* Intentionally fail so user can correct issue. */
1632      }
1633      return loader_inst->disp->layer_inst_disp.CreateScreenSurfaceQNX(loader_inst->instance, pCreateInfo, pAllocator, pSurface);
1634  }
1635  
1636  // This is the instance chain terminator function for CreateScreenSurfaceQNX
terminator_CreateScreenSurfaceQNX(VkInstance instance,const VkScreenSurfaceCreateInfoQNX * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSurfaceKHR * pSurface)1637  VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateScreenSurfaceQNX(VkInstance instance,
1638                                                                   const VkScreenSurfaceCreateInfoQNX *pCreateInfo,
1639                                                                   const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
1640      VkResult vkRes = VK_SUCCESS;
1641      VkIcdSurface *pIcdSurface = NULL;
1642      uint32_t i = 0;
1643  
1644      // First, check to ensure the appropriate extension was enabled:
1645      struct loader_instance *loader_inst = loader_get_instance(instance);
1646      if (!loader_inst->wsi_screen_surface_enabled) {
1647          loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
1648                     "VK_QNX_screen_surface extension not enabled. vkCreateScreenSurfaceQNX not executed!\n");
1649          vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
1650          goto out;
1651      }
1652  
1653      // Next, if so, proceed with the implementation of this function:
1654      pIcdSurface = AllocateIcdSurfaceStruct(loader_inst, sizeof(pIcdSurface->screen_surf.base), sizeof(pIcdSurface->screen_surf));
1655      if (pIcdSurface == NULL) {
1656          vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
1657          goto out;
1658      }
1659  
1660      pIcdSurface->screen_surf.base.platform = VK_ICD_WSI_PLATFORM_SCREEN;
1661      pIcdSurface->screen_surf.context = pCreateInfo->context;
1662      pIcdSurface->screen_surf.window = pCreateInfo->window;
1663  
1664      // Loop through each ICD and determine if they need to create a surface
1665      for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
1666          if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
1667              if (NULL != icd_term->dispatch.CreateScreenSurfaceQNX) {
1668                  vkRes = icd_term->dispatch.CreateScreenSurfaceQNX(icd_term->instance, pCreateInfo, pAllocator,
1669                                                                    &pIcdSurface->real_icd_surfaces[i]);
1670                  if (VK_SUCCESS != vkRes) {
1671                      goto out;
1672                  }
1673              }
1674          }
1675      }
1676  
1677      *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface;
1678  
1679  out:
1680  
1681      if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
1682          if (NULL != pIcdSurface->real_icd_surfaces) {
1683              i = 0;
1684              for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
1685                  if ((VkSurfaceKHR)(uintptr_t)NULL != pIcdSurface->real_icd_surfaces[i] &&
1686                      NULL != icd_term->dispatch.DestroySurfaceKHR) {
1687                      icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
1688                  }
1689              }
1690              loader_instance_heap_free(loader_inst, pIcdSurface->real_icd_surfaces);
1691          }
1692          loader_instance_heap_free(loader_inst, pIcdSurface);
1693      }
1694  
1695      return vkRes;
1696  }
1697  
1698  // This is the trampoline entrypoint for
1699  // GetPhysicalDeviceScreenPresentationSupportQNX
vkGetPhysicalDeviceScreenPresentationSupportQNX(VkPhysicalDevice physicalDevice,uint32_t queueFamilyIndex,struct _screen_window * window)1700  LOADER_EXPORT VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceScreenPresentationSupportQNX(VkPhysicalDevice physicalDevice,
1701                                                                                               uint32_t queueFamilyIndex,
1702                                                                                               struct _screen_window *window) {
1703      VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
1704      if (VK_NULL_HANDLE == unwrapped_phys_dev) {
1705          loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1706                     "vkGetPhysicalDeviceScreenPresentationSupportQNX: Invalid physicalDevice "
1707                     "[VUID-vkGetPhysicalDeviceScreenPresentationSupportQNX-physicalDevice-parameter]");
1708          abort(); /* Intentionally fail so user can correct issue. */
1709      }
1710      const VkLayerInstanceDispatchTable *disp = loader_get_instance_layer_dispatch(physicalDevice);
1711      VkBool32 res = disp->GetPhysicalDeviceScreenPresentationSupportQNX(unwrapped_phys_dev, queueFamilyIndex, window);
1712      return res;
1713  }
1714  
1715  // This is the instance chain terminator function for
1716  // GetPhysicalDeviceScreenPresentationSupportQNX
terminator_GetPhysicalDeviceScreenPresentationSupportQNX(VkPhysicalDevice physicalDevice,uint32_t queueFamilyIndex,struct _screen_window * window)1717  VKAPI_ATTR VkBool32 VKAPI_CALL terminator_GetPhysicalDeviceScreenPresentationSupportQNX(VkPhysicalDevice physicalDevice,
1718                                                                                          uint32_t queueFamilyIndex,
1719                                                                                          struct _screen_window *window) {
1720      // First, check to ensure the appropriate extension was enabled:
1721      struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
1722      struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
1723      struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
1724      if (!loader_inst->wsi_screen_surface_enabled) {
1725          loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
1726                     "VK_QNX_screen_surface extension not enabled. vkGetPhysicalDeviceScreenPresentationSupportQNX not executed!\n");
1727          return VK_FALSE;
1728      }
1729  
1730      if (NULL == icd_term->dispatch.GetPhysicalDeviceScreenPresentationSupportQNX) {
1731          // return VK_FALSE as this driver doesn't support WSI functionality
1732          loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
1733                     "ICD for selected physical device does not export vkGetPhysicalDeviceScreenPresentationSupportQNX!\n");
1734          return VK_FALSE;
1735      }
1736  
1737      return icd_term->dispatch.GetPhysicalDeviceScreenPresentationSupportQNX(phys_dev_term->phys_dev, queueFamilyIndex, window);
1738  }
1739  #endif  // VK_USE_PLATFORM_SCREEN_QNX
1740  
1741  #ifdef VK_USE_PLATFORM_VI_NN
1742  
1743  // Functions for the VK_NN_vi_surface extension:
1744  
1745  // This is the trampoline entrypoint for CreateViSurfaceNN
vkCreateViSurfaceNN(VkInstance instance,const VkViSurfaceCreateInfoNN * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSurfaceKHR * pSurface)1746  LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateViSurfaceNN(VkInstance instance, const VkViSurfaceCreateInfoNN *pCreateInfo,
1747                                                                   const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
1748      struct loader_instance *loader_inst = loader_get_instance(instance);
1749      if (NULL == loader_inst) {
1750          loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1751                     "vkCreateViSurfaceNN: Invalid instance [VUID-vkCreateViSurfaceNN-instance-parameter]");
1752          abort(); /* Intentionally fail so user can correct issue. */
1753      }
1754      return loader_inst->disp->layer_inst_disp.CreateViSurfaceNN(loader_inst->instance, pCreateInfo, pAllocator, pSurface);
1755  }
1756  
1757  // This is the instance chain terminator function for CreateViSurfaceNN
terminator_CreateViSurfaceNN(VkInstance instance,const VkViSurfaceCreateInfoNN * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSurfaceKHR * pSurface)1758  VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateViSurfaceNN(VkInstance instance, const VkViSurfaceCreateInfoNN *pCreateInfo,
1759                                                              const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
1760      VkResult vkRes = VK_SUCCESS;
1761      VkIcdSurface *pIcdSurface = NULL;
1762      uint32_t i = 0;
1763  
1764      // First, check to ensure the appropriate extension was enabled:
1765      struct loader_instance *loader_inst = loader_get_instance(instance);
1766      if (!loader_inst->wsi_vi_surface_enabled) {
1767          loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
1768                     "VK_NN_vi_surface extension not enabled. vkCreateViSurfaceNN not executed!\n");
1769          vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
1770          goto out;
1771      }
1772  
1773      // Next, if so, proceed with the implementation of this function:
1774      pIcdSurface = AllocateIcdSurfaceStruct(loader_inst, sizeof(pIcdSurface->vi_surf.base), sizeof(pIcdSurface->vi_surf));
1775      if (pIcdSurface == NULL) {
1776          vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
1777          goto out;
1778      }
1779  
1780      pIcdSurface->vi_surf.base.platform = VK_ICD_WSI_PLATFORM_VI;
1781      pIcdSurface->vi_surf.window = pCreateInfo->window;
1782  
1783      // Loop through each ICD and determine if they need to create a surface
1784      for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
1785          if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
1786              if (NULL != icd_term->dispatch.CreateViSurfaceNN) {
1787                  vkRes = icd_term->dispatch.CreateViSurfaceNN(icd_term->instance, pCreateInfo, pAllocator,
1788                                                               &pIcdSurface->real_icd_surfaces[i]);
1789                  if (VK_SUCCESS != vkRes) {
1790                      goto out;
1791                  }
1792              }
1793          }
1794      }
1795  
1796      *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface;
1797  
1798  out:
1799  
1800      if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
1801          if (NULL != pIcdSurface->real_icd_surfaces) {
1802              i = 0;
1803              for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
1804                  if ((VkSurfaceKHR)(uintptr_t)NULL != pIcdSurface->real_icd_surfaces[i] &&
1805                      NULL != icd_term->dispatch.DestroySurfaceKHR) {
1806                      icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
1807                  }
1808              }
1809              loader_instance_heap_free(loader_inst, pIcdSurface->real_icd_surfaces);
1810          }
1811          loader_instance_heap_free(loader_inst, pIcdSurface);
1812      }
1813  
1814      return vkRes;
1815  }
1816  
1817  #endif  // VK_USE_PLATFORM_VI_NN
1818  
1819  // Functions for the VK_KHR_display instance extension:
vkGetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice,uint32_t * pPropertyCount,VkDisplayPropertiesKHR * pProperties)1820  LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice,
1821                                                                                       uint32_t *pPropertyCount,
1822                                                                                       VkDisplayPropertiesKHR *pProperties) {
1823      const VkLayerInstanceDispatchTable *disp;
1824      VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
1825      if (VK_NULL_HANDLE == unwrapped_phys_dev) {
1826          loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1827                     "vkGetPhysicalDeviceDisplayPropertiesKHR: Invalid physicalDevice "
1828                     "[VUID-vkGetPhysicalDeviceDisplayPropertiesKHR-physicalDevice-parameter]");
1829          abort(); /* Intentionally fail so user can correct issue. */
1830      }
1831      disp = loader_get_instance_layer_dispatch(physicalDevice);
1832      VkResult res = disp->GetPhysicalDeviceDisplayPropertiesKHR(unwrapped_phys_dev, pPropertyCount, pProperties);
1833      return res;
1834  }
1835  
terminator_GetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice,uint32_t * pPropertyCount,VkDisplayPropertiesKHR * pProperties)1836  VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice,
1837                                                                                  uint32_t *pPropertyCount,
1838                                                                                  VkDisplayPropertiesKHR *pProperties) {
1839      // First, check to ensure the appropriate extension was enabled:
1840      struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
1841      struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
1842      struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
1843      if (!loader_inst->wsi_display_enabled) {
1844          loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
1845                     "VK_KHR_display extension not enabled. vkGetPhysicalDeviceDisplayPropertiesKHR not executed!\n");
1846          return VK_SUCCESS;
1847      }
1848  
1849      if (NULL == icd_term->dispatch.GetPhysicalDeviceDisplayPropertiesKHR) {
1850          loader_log(loader_inst, VULKAN_LOADER_WARN_BIT, 0,
1851                     "ICD for selected physical device does not export vkGetPhysicalDeviceDisplayPropertiesKHR!\n");
1852          // return 0 for property count as this driver doesn't support WSI functionality
1853          if (pPropertyCount) {
1854              *pPropertyCount = 0;
1855          }
1856          return VK_SUCCESS;
1857      }
1858  
1859      return icd_term->dispatch.GetPhysicalDeviceDisplayPropertiesKHR(phys_dev_term->phys_dev, pPropertyCount, pProperties);
1860  }
1861  
vkGetPhysicalDeviceDisplayPlanePropertiesKHR(VkPhysicalDevice physicalDevice,uint32_t * pPropertyCount,VkDisplayPlanePropertiesKHR * pProperties)1862  LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayPlanePropertiesKHR(
1863      VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, VkDisplayPlanePropertiesKHR *pProperties) {
1864      const VkLayerInstanceDispatchTable *disp;
1865      VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
1866      if (VK_NULL_HANDLE == unwrapped_phys_dev) {
1867          loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1868                     "vkGetPhysicalDeviceDisplayPlanePropertiesKHR: Invalid physicalDevice "
1869                     "[VUID-vkGetPhysicalDeviceDisplayPlanePropertiesKHR-physicalDevice-parameter]");
1870          abort(); /* Intentionally fail so user can correct issue. */
1871      }
1872      disp = loader_get_instance_layer_dispatch(physicalDevice);
1873      VkResult res = disp->GetPhysicalDeviceDisplayPlanePropertiesKHR(unwrapped_phys_dev, pPropertyCount, pProperties);
1874      return res;
1875  }
1876  
terminator_GetPhysicalDeviceDisplayPlanePropertiesKHR(VkPhysicalDevice physicalDevice,uint32_t * pPropertyCount,VkDisplayPlanePropertiesKHR * pProperties)1877  VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceDisplayPlanePropertiesKHR(VkPhysicalDevice physicalDevice,
1878                                                                                       uint32_t *pPropertyCount,
1879                                                                                       VkDisplayPlanePropertiesKHR *pProperties) {
1880      // First, check to ensure the appropriate extension was enabled:
1881      struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
1882      struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
1883      struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
1884      if (!loader_inst->wsi_display_enabled) {
1885          loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
1886                     "VK_KHR_display extension not enabled. vkGetPhysicalDeviceDisplayPlanePropertiesKHR not executed!\n");
1887          return VK_SUCCESS;
1888      }
1889  
1890      if (NULL == icd_term->dispatch.GetPhysicalDeviceDisplayPlanePropertiesKHR) {
1891          loader_log(loader_inst, VULKAN_LOADER_WARN_BIT, 0,
1892                     "ICD for selected physical device does not export vkGetPhysicalDeviceDisplayPlanePropertiesKHR!\n");
1893          // return 0 for property count as this driver doesn't support WSI functionality
1894          if (pPropertyCount) {
1895              *pPropertyCount = 0;
1896          }
1897          return VK_SUCCESS;
1898      }
1899  
1900      return icd_term->dispatch.GetPhysicalDeviceDisplayPlanePropertiesKHR(phys_dev_term->phys_dev, pPropertyCount, pProperties);
1901  }
1902  
vkGetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice,uint32_t planeIndex,uint32_t * pDisplayCount,VkDisplayKHR * pDisplays)1903  LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice,
1904                                                                                     uint32_t planeIndex, uint32_t *pDisplayCount,
1905                                                                                     VkDisplayKHR *pDisplays) {
1906      const VkLayerInstanceDispatchTable *disp;
1907      VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
1908      if (VK_NULL_HANDLE == unwrapped_phys_dev) {
1909          loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1910                     "vkGetDisplayPlaneSupportedDisplaysKHR: Invalid physicalDevice "
1911                     "[VUID-vkGetDisplayPlaneSupportedDisplaysKHR-physicalDevice-parameter]");
1912          abort(); /* Intentionally fail so user can correct issue. */
1913      }
1914      disp = loader_get_instance_layer_dispatch(physicalDevice);
1915      VkResult res = disp->GetDisplayPlaneSupportedDisplaysKHR(unwrapped_phys_dev, planeIndex, pDisplayCount, pDisplays);
1916      return res;
1917  }
1918  
terminator_GetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice,uint32_t planeIndex,uint32_t * pDisplayCount,VkDisplayKHR * pDisplays)1919  VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice, uint32_t planeIndex,
1920                                                                                uint32_t *pDisplayCount, VkDisplayKHR *pDisplays) {
1921      // First, check to ensure the appropriate extension was enabled:
1922      struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
1923      struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
1924      struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
1925      if (!loader_inst->wsi_display_enabled) {
1926          loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
1927                     "VK_KHR_display extension not enabled. vkGetDisplayPlaneSupportedDisplaysKHR not executed!\n");
1928          return VK_SUCCESS;
1929      }
1930  
1931      if (NULL == icd_term->dispatch.GetDisplayPlaneSupportedDisplaysKHR) {
1932          loader_log(loader_inst, VULKAN_LOADER_WARN_BIT, 0,
1933                     "ICD for selected physical device does not export vkGetDisplayPlaneSupportedDisplaysKHR!\n");
1934          // return 0 for property count as this driver doesn't support WSI functionality
1935          if (pDisplayCount) {
1936              *pDisplayCount = 0;
1937          }
1938          return VK_SUCCESS;
1939      }
1940  
1941      return icd_term->dispatch.GetDisplayPlaneSupportedDisplaysKHR(phys_dev_term->phys_dev, planeIndex, pDisplayCount, pDisplays);
1942  }
1943  
vkGetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice,VkDisplayKHR display,uint32_t * pPropertyCount,VkDisplayModePropertiesKHR * pProperties)1944  LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
1945                                                                             uint32_t *pPropertyCount,
1946                                                                             VkDisplayModePropertiesKHR *pProperties) {
1947      const VkLayerInstanceDispatchTable *disp;
1948      VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
1949      if (VK_NULL_HANDLE == unwrapped_phys_dev) {
1950          loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1951                     "vkGetDisplayModePropertiesKHR: Invalid physicalDevice "
1952                     "[VUID-vkGetDisplayModePropertiesKHR-physicalDevice-parameter]");
1953          abort(); /* Intentionally fail so user can correct issue. */
1954      }
1955      disp = loader_get_instance_layer_dispatch(physicalDevice);
1956      VkResult res = disp->GetDisplayModePropertiesKHR(unwrapped_phys_dev, display, pPropertyCount, pProperties);
1957      return res;
1958  }
1959  
terminator_GetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice,VkDisplayKHR display,uint32_t * pPropertyCount,VkDisplayModePropertiesKHR * pProperties)1960  VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
1961                                                                        uint32_t *pPropertyCount,
1962                                                                        VkDisplayModePropertiesKHR *pProperties) {
1963      // First, check to ensure the appropriate extension was enabled:
1964      struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
1965      struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
1966      struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
1967      if (!loader_inst->wsi_display_enabled) {
1968          loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
1969                     "VK_KHR_display extension not enabled. vkGetDisplayModePropertiesKHR not executed!\n");
1970          return VK_SUCCESS;
1971      }
1972  
1973      if (NULL == icd_term->dispatch.GetDisplayModePropertiesKHR) {
1974          loader_log(loader_inst, VULKAN_LOADER_WARN_BIT, 0,
1975                     "ICD for selected physical device does not export vkGetDisplayModePropertiesKHR!\n");
1976          // return 0 for property count as this driver doesn't support WSI functionality
1977          if (pPropertyCount) {
1978              *pPropertyCount = 0;
1979          }
1980          return VK_SUCCESS;
1981      }
1982  
1983      return icd_term->dispatch.GetDisplayModePropertiesKHR(phys_dev_term->phys_dev, display, pPropertyCount, pProperties);
1984  }
1985  
vkCreateDisplayModeKHR(VkPhysicalDevice physicalDevice,VkDisplayKHR display,const VkDisplayModeCreateInfoKHR * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDisplayModeKHR * pMode)1986  LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDisplayModeKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
1987                                                                      const VkDisplayModeCreateInfoKHR *pCreateInfo,
1988                                                                      const VkAllocationCallbacks *pAllocator,
1989                                                                      VkDisplayModeKHR *pMode) {
1990      const VkLayerInstanceDispatchTable *disp;
1991      VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
1992      if (VK_NULL_HANDLE == unwrapped_phys_dev) {
1993          loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1994                     "vkCreateDisplayModeKHR: Invalid physicalDevice "
1995                     "[VUID-vkCreateDisplayModeKHR-physicalDevice-parameter]");
1996          abort(); /* Intentionally fail so user can correct issue. */
1997      }
1998      disp = loader_get_instance_layer_dispatch(physicalDevice);
1999      VkResult res = disp->CreateDisplayModeKHR(unwrapped_phys_dev, display, pCreateInfo, pAllocator, pMode);
2000      return res;
2001  }
2002  
terminator_CreateDisplayModeKHR(VkPhysicalDevice physicalDevice,VkDisplayKHR display,const VkDisplayModeCreateInfoKHR * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDisplayModeKHR * pMode)2003  VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDisplayModeKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
2004                                                                 const VkDisplayModeCreateInfoKHR *pCreateInfo,
2005                                                                 const VkAllocationCallbacks *pAllocator, VkDisplayModeKHR *pMode) {
2006      // First, check to ensure the appropriate extension was enabled:
2007      struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
2008      struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
2009      struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
2010      if (!loader_inst->wsi_display_enabled) {
2011          loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
2012                     "VK_KHR_display extension not enabled. vkCreateDisplayModeKHR not executed!\n");
2013          return VK_ERROR_EXTENSION_NOT_PRESENT;
2014      }
2015  
2016      if (NULL == icd_term->dispatch.CreateDisplayModeKHR) {
2017          // Can't emulate, so return an appropriate error
2018          loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
2019                     "ICD for selected physical device does not export vkCreateDisplayModeKHR!\n");
2020          return VK_ERROR_INITIALIZATION_FAILED;
2021      }
2022  
2023      return icd_term->dispatch.CreateDisplayModeKHR(phys_dev_term->phys_dev, display, pCreateInfo, pAllocator, pMode);
2024  }
2025  
vkGetDisplayPlaneCapabilitiesKHR(VkPhysicalDevice physicalDevice,VkDisplayModeKHR mode,uint32_t planeIndex,VkDisplayPlaneCapabilitiesKHR * pCapabilities)2026  LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayPlaneCapabilitiesKHR(VkPhysicalDevice physicalDevice,
2027                                                                                VkDisplayModeKHR mode, uint32_t planeIndex,
2028                                                                                VkDisplayPlaneCapabilitiesKHR *pCapabilities) {
2029      const VkLayerInstanceDispatchTable *disp;
2030      VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
2031      if (VK_NULL_HANDLE == unwrapped_phys_dev) {
2032          loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2033                     "vkGetDisplayPlaneCapabilitiesKHR: Invalid physicalDevice "
2034                     "[VUID-vkGetDisplayPlaneCapabilitiesKHR-physicalDevice-parameter]");
2035          abort(); /* Intentionally fail so user can correct issue. */
2036      }
2037      disp = loader_get_instance_layer_dispatch(physicalDevice);
2038      VkResult res = disp->GetDisplayPlaneCapabilitiesKHR(unwrapped_phys_dev, mode, planeIndex, pCapabilities);
2039      return res;
2040  }
2041  
terminator_GetDisplayPlaneCapabilitiesKHR(VkPhysicalDevice physicalDevice,VkDisplayModeKHR mode,uint32_t planeIndex,VkDisplayPlaneCapabilitiesKHR * pCapabilities)2042  VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDisplayPlaneCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkDisplayModeKHR mode,
2043                                                                           uint32_t planeIndex,
2044                                                                           VkDisplayPlaneCapabilitiesKHR *pCapabilities) {
2045      // First, check to ensure the appropriate extension was enabled:
2046      struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
2047      struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
2048      struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
2049      if (!loader_inst->wsi_display_enabled) {
2050          loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
2051                     "VK_KHR_display extension not enabled. vkGetDisplayPlaneCapabilitiesKHR not executed!\n");
2052          return VK_SUCCESS;
2053      }
2054  
2055      if (NULL == icd_term->dispatch.GetDisplayPlaneCapabilitiesKHR) {
2056          // Emulate support
2057          loader_log(loader_inst, VULKAN_LOADER_WARN_BIT, 0,
2058                     "ICD for selected physical device does not export vkGetDisplayPlaneCapabilitiesKHR!\n");
2059          if (pCapabilities) {
2060              memset(pCapabilities, 0, sizeof(VkDisplayPlaneCapabilitiesKHR));
2061          }
2062          return VK_SUCCESS;
2063      }
2064  
2065      return icd_term->dispatch.GetDisplayPlaneCapabilitiesKHR(phys_dev_term->phys_dev, mode, planeIndex, pCapabilities);
2066  }
2067  
vkCreateDisplayPlaneSurfaceKHR(VkInstance instance,const VkDisplaySurfaceCreateInfoKHR * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSurfaceKHR * pSurface)2068  LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDisplayPlaneSurfaceKHR(VkInstance instance,
2069                                                                              const VkDisplaySurfaceCreateInfoKHR *pCreateInfo,
2070                                                                              const VkAllocationCallbacks *pAllocator,
2071                                                                              VkSurfaceKHR *pSurface) {
2072      struct loader_instance *loader_inst = loader_get_instance(instance);
2073      if (NULL == loader_inst) {
2074          loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2075                     "vkCreateDisplayPlaneSurfaceKHR: Invalid instance [VUID-vkCreateDisplayPlaneSurfaceKHR-instance-parameter]");
2076          abort(); /* Intentionally fail so user can correct issue. */
2077      }
2078      return loader_inst->disp->layer_inst_disp.CreateDisplayPlaneSurfaceKHR(loader_inst->instance, pCreateInfo, pAllocator,
2079                                                                             pSurface);
2080  }
2081  
terminator_CreateDisplayPlaneSurfaceKHR(VkInstance instance,const VkDisplaySurfaceCreateInfoKHR * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSurfaceKHR * pSurface)2082  VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDisplayPlaneSurfaceKHR(VkInstance instance,
2083                                                                         const VkDisplaySurfaceCreateInfoKHR *pCreateInfo,
2084                                                                         const VkAllocationCallbacks *pAllocator,
2085                                                                         VkSurfaceKHR *pSurface) {
2086      struct loader_instance *inst = loader_get_instance(instance);
2087      VkIcdSurface *pIcdSurface = NULL;
2088      VkResult vkRes = VK_SUCCESS;
2089      uint32_t i = 0;
2090  
2091      if (!inst->wsi_display_enabled) {
2092          loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0,
2093                     "VK_KHR_surface extension not enabled. vkCreateDisplayPlaneSurfaceKHR not executed!\n");
2094          vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
2095          goto out;
2096      }
2097  
2098      // Next, if so, proceed with the implementation of this function:
2099      pIcdSurface = AllocateIcdSurfaceStruct(inst, sizeof(pIcdSurface->display_surf.base), sizeof(pIcdSurface->display_surf));
2100      if (pIcdSurface == NULL) {
2101          vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
2102          goto out;
2103      }
2104  
2105      pIcdSurface->display_surf.base.platform = VK_ICD_WSI_PLATFORM_DISPLAY;
2106      pIcdSurface->display_surf.displayMode = pCreateInfo->displayMode;
2107      pIcdSurface->display_surf.planeIndex = pCreateInfo->planeIndex;
2108      pIcdSurface->display_surf.planeStackIndex = pCreateInfo->planeStackIndex;
2109      pIcdSurface->display_surf.transform = pCreateInfo->transform;
2110      pIcdSurface->display_surf.globalAlpha = pCreateInfo->globalAlpha;
2111      pIcdSurface->display_surf.alphaMode = pCreateInfo->alphaMode;
2112      pIcdSurface->display_surf.imageExtent = pCreateInfo->imageExtent;
2113  
2114      // Loop through each ICD and determine if they need to create a surface
2115      for (struct loader_icd_term *icd_term = inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
2116          if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
2117              if (NULL != icd_term->dispatch.CreateDisplayPlaneSurfaceKHR) {
2118                  vkRes = icd_term->dispatch.CreateDisplayPlaneSurfaceKHR(icd_term->instance, pCreateInfo, pAllocator,
2119                                                                          &pIcdSurface->real_icd_surfaces[i]);
2120                  if (VK_SUCCESS != vkRes) {
2121                      goto out;
2122                  }
2123              }
2124          }
2125      }
2126  
2127      *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface;
2128  
2129  out:
2130  
2131      if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
2132          if (NULL != pIcdSurface->real_icd_surfaces) {
2133              i = 0;
2134              for (struct loader_icd_term *icd_term = inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
2135                  if ((VkSurfaceKHR)(uintptr_t)NULL != pIcdSurface->real_icd_surfaces[i] &&
2136                      NULL != icd_term->dispatch.DestroySurfaceKHR) {
2137                      icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
2138                  }
2139              }
2140              loader_instance_heap_free(inst, pIcdSurface->real_icd_surfaces);
2141          }
2142          loader_instance_heap_free(inst, pIcdSurface);
2143      }
2144  
2145      return vkRes;
2146  }
2147  
2148  // EXT_display_swapchain Extension command
2149  
vkCreateSharedSwapchainsKHR(VkDevice device,uint32_t swapchainCount,const VkSwapchainCreateInfoKHR * pCreateInfos,const VkAllocationCallbacks * pAllocator,VkSwapchainKHR * pSwapchains)2150  LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateSharedSwapchainsKHR(VkDevice device, uint32_t swapchainCount,
2151                                                                           const VkSwapchainCreateInfoKHR *pCreateInfos,
2152                                                                           const VkAllocationCallbacks *pAllocator,
2153                                                                           VkSwapchainKHR *pSwapchains) {
2154      const VkLayerDispatchTable *disp = loader_get_dispatch(device);
2155      if (NULL == disp) {
2156          loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2157                     "vkCreateSharedSwapchainsKHR: Invalid device [VUID-vkCreateSharedSwapchainsKHR-device-parameter]");
2158          abort(); /* Intentionally fail so user can correct issue. */
2159      }
2160      return disp->CreateSharedSwapchainsKHR(device, swapchainCount, pCreateInfos, pAllocator, pSwapchains);
2161  }
2162  
terminator_CreateSharedSwapchainsKHR(VkDevice device,uint32_t swapchainCount,const VkSwapchainCreateInfoKHR * pCreateInfos,const VkAllocationCallbacks * pAllocator,VkSwapchainKHR * pSwapchains)2163  VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateSharedSwapchainsKHR(VkDevice device, uint32_t swapchainCount,
2164                                                                      const VkSwapchainCreateInfoKHR *pCreateInfos,
2165                                                                      const VkAllocationCallbacks *pAllocator,
2166                                                                      VkSwapchainKHR *pSwapchains) {
2167      uint32_t icd_index = 0;
2168      struct loader_device *dev;
2169      struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, &icd_index);
2170      if (NULL != icd_term && NULL != icd_term->dispatch.CreateSharedSwapchainsKHR) {
2171          VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pCreateInfos->surface;
2172          if (NULL != icd_surface->real_icd_surfaces) {
2173              if ((VkSurfaceKHR)(uintptr_t)NULL != icd_surface->real_icd_surfaces[icd_index]) {
2174                  // We found the ICD, and there is an ICD KHR surface
2175                  // associated with it, so copy the CreateInfo struct
2176                  // and point it at the ICD's surface.
2177                  VkSwapchainCreateInfoKHR *pCreateCopy = loader_stack_alloc(sizeof(VkSwapchainCreateInfoKHR) * swapchainCount);
2178                  if (NULL == pCreateCopy) {
2179                      return VK_ERROR_OUT_OF_HOST_MEMORY;
2180                  }
2181                  memcpy(pCreateCopy, pCreateInfos, sizeof(VkSwapchainCreateInfoKHR) * swapchainCount);
2182                  for (uint32_t sc = 0; sc < swapchainCount; sc++) {
2183                      pCreateCopy[sc].surface = icd_surface->real_icd_surfaces[icd_index];
2184                  }
2185                  return icd_term->dispatch.CreateSharedSwapchainsKHR(device, swapchainCount, pCreateCopy, pAllocator, pSwapchains);
2186              }
2187          }
2188          return icd_term->dispatch.CreateSharedSwapchainsKHR(device, swapchainCount, pCreateInfos, pAllocator, pSwapchains);
2189      }
2190      return VK_SUCCESS;
2191  }
2192  
2193  LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
vkGetDeviceGroupPresentCapabilitiesKHR(VkDevice device,VkDeviceGroupPresentCapabilitiesKHR * pDeviceGroupPresentCapabilities)2194  vkGetDeviceGroupPresentCapabilitiesKHR(VkDevice device, VkDeviceGroupPresentCapabilitiesKHR *pDeviceGroupPresentCapabilities) {
2195      const VkLayerDispatchTable *disp = loader_get_dispatch(device);
2196      if (NULL == disp) {
2197          loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2198                     "vkGetDeviceGroupPresentCapabilitiesKHR: Invalid device "
2199                     "[VUID-vkGetDeviceGroupPresentCapabilitiesKHR-device-parameter]");
2200          abort(); /* Intentionally fail so user can correct issue. */
2201      }
2202      return disp->GetDeviceGroupPresentCapabilitiesKHR(device, pDeviceGroupPresentCapabilities);
2203  }
2204  
vkGetDeviceGroupSurfacePresentModesKHR(VkDevice device,VkSurfaceKHR surface,VkDeviceGroupPresentModeFlagsKHR * pModes)2205  LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetDeviceGroupSurfacePresentModesKHR(VkDevice device, VkSurfaceKHR surface,
2206                                                                                      VkDeviceGroupPresentModeFlagsKHR *pModes) {
2207      const VkLayerDispatchTable *disp = loader_get_dispatch(device);
2208      if (NULL == disp) {
2209          loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2210                     "vkGetDeviceGroupSurfacePresentModesKHR: Invalid device "
2211                     "[VUID-vkGetDeviceGroupSurfacePresentModesKHR-device-parameter]");
2212          abort(); /* Intentionally fail so user can correct issue. */
2213      }
2214      return disp->GetDeviceGroupSurfacePresentModesKHR(device, surface, pModes);
2215  }
2216  
terminator_GetDeviceGroupSurfacePresentModesKHR(VkDevice device,VkSurfaceKHR surface,VkDeviceGroupPresentModeFlagsKHR * pModes)2217  VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDeviceGroupSurfacePresentModesKHR(VkDevice device, VkSurfaceKHR surface,
2218                                                                                 VkDeviceGroupPresentModeFlagsKHR *pModes) {
2219      uint32_t icd_index = 0;
2220      struct loader_device *dev;
2221      struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, &icd_index);
2222      if (NULL != icd_term && NULL != icd_term->dispatch.GetDeviceGroupSurfacePresentModesKHR) {
2223          VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)surface;
2224          if (NULL != icd_surface->real_icd_surfaces && (VkSurfaceKHR)(uintptr_t)NULL != icd_surface->real_icd_surfaces[icd_index]) {
2225              return icd_term->dispatch.GetDeviceGroupSurfacePresentModesKHR(device, icd_surface->real_icd_surfaces[icd_index],
2226                                                                             pModes);
2227          }
2228          return icd_term->dispatch.GetDeviceGroupSurfacePresentModesKHR(device, surface, pModes);
2229      }
2230      return VK_SUCCESS;
2231  }
2232  
vkGetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice physicalDevice,VkSurfaceKHR surface,uint32_t * pRectCount,VkRect2D * pRects)2233  LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice physicalDevice,
2234                                                                                       VkSurfaceKHR surface, uint32_t *pRectCount,
2235                                                                                       VkRect2D *pRects) {
2236      const VkLayerInstanceDispatchTable *disp;
2237      VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
2238      if (VK_NULL_HANDLE == unwrapped_phys_dev) {
2239          loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2240                     "vkGetPhysicalDevicePresentRectanglesKHR: Invalid physicalDevice "
2241                     "[VUID-vkGetPhysicalDevicePresentRectanglesKHR-physicalDevice-parameter]");
2242          abort(); /* Intentionally fail so user can correct issue. */
2243      }
2244      disp = loader_get_instance_layer_dispatch(physicalDevice);
2245      return disp->GetPhysicalDevicePresentRectanglesKHR(unwrapped_phys_dev, surface, pRectCount, pRects);
2246  }
2247  
terminator_GetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice physicalDevice,VkSurfaceKHR surface,uint32_t * pRectCount,VkRect2D * pRects)2248  VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice physicalDevice,
2249                                                                                  VkSurfaceKHR surface, uint32_t *pRectCount,
2250                                                                                  VkRect2D *pRects) {
2251      struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
2252      struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
2253      if (NULL == icd_term->dispatch.GetPhysicalDevicePresentRectanglesKHR) {
2254          loader_log(icd_term->this_instance, VULKAN_LOADER_ERROR_BIT, 0,
2255                     "ICD associated with VkPhysicalDevice does not support GetPhysicalDevicePresentRectanglesKHX");
2256          // return as this driver doesn't support WSI functionality
2257          if (pRectCount) {
2258              *pRectCount = 0;
2259          }
2260          return VK_SUCCESS;
2261      }
2262      VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)(surface);
2263      uint8_t icd_index = phys_dev_term->icd_index;
2264      if (NULL != icd_surface->real_icd_surfaces && NULL != (void *)(uintptr_t)(icd_surface->real_icd_surfaces[icd_index])) {
2265          return icd_term->dispatch.GetPhysicalDevicePresentRectanglesKHR(
2266              phys_dev_term->phys_dev, icd_surface->real_icd_surfaces[icd_index], pRectCount, pRects);
2267      }
2268      return icd_term->dispatch.GetPhysicalDevicePresentRectanglesKHR(phys_dev_term->phys_dev, surface, pRectCount, pRects);
2269  }
2270  
vkAcquireNextImage2KHR(VkDevice device,const VkAcquireNextImageInfoKHR * pAcquireInfo,uint32_t * pImageIndex)2271  LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkAcquireNextImage2KHR(VkDevice device, const VkAcquireNextImageInfoKHR *pAcquireInfo,
2272                                                                      uint32_t *pImageIndex) {
2273      const VkLayerDispatchTable *disp = loader_get_dispatch(device);
2274      if (NULL == disp) {
2275          loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2276                     "vkAcquireNextImage2KHR: Invalid device [VUID-vkAcquireNextImage2KHR-device-parameter]");
2277          abort(); /* Intentionally fail so user can correct issue. */
2278      }
2279      return disp->AcquireNextImage2KHR(device, pAcquireInfo, pImageIndex);
2280  }
2281  
2282  // ---- VK_KHR_get_display_properties2 extension trampoline/terminators
2283  
vkGetPhysicalDeviceDisplayProperties2KHR(VkPhysicalDevice physicalDevice,uint32_t * pPropertyCount,VkDisplayProperties2KHR * pProperties)2284  LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayProperties2KHR(VkPhysicalDevice physicalDevice,
2285                                                                                        uint32_t *pPropertyCount,
2286                                                                                        VkDisplayProperties2KHR *pProperties) {
2287      const VkLayerInstanceDispatchTable *disp;
2288      VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
2289      if (VK_NULL_HANDLE == unwrapped_phys_dev) {
2290          loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2291                     "vkGetPhysicalDeviceDisplayProperties2KHR: Invalid physicalDevice "
2292                     "[VUID-vkGetPhysicalDeviceDisplayProperties2KHR-physicalDevice-parameter]");
2293          abort(); /* Intentionally fail so user can correct issue. */
2294      }
2295      disp = loader_get_instance_layer_dispatch(physicalDevice);
2296      return disp->GetPhysicalDeviceDisplayProperties2KHR(unwrapped_phys_dev, pPropertyCount, pProperties);
2297  }
2298  
terminator_GetPhysicalDeviceDisplayProperties2KHR(VkPhysicalDevice physicalDevice,uint32_t * pPropertyCount,VkDisplayProperties2KHR * pProperties)2299  VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceDisplayProperties2KHR(VkPhysicalDevice physicalDevice,
2300                                                                                   uint32_t *pPropertyCount,
2301                                                                                   VkDisplayProperties2KHR *pProperties) {
2302      struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
2303      struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
2304  
2305      // If the function is available in the driver, just call into it
2306      if (icd_term->dispatch.GetPhysicalDeviceDisplayProperties2KHR != NULL) {
2307          return icd_term->dispatch.GetPhysicalDeviceDisplayProperties2KHR(phys_dev_term->phys_dev, pPropertyCount, pProperties);
2308      }
2309  
2310      // We have to emulate the function.
2311      loader_log(icd_term->this_instance, VULKAN_LOADER_INFO_BIT, 0,
2312                 "vkGetPhysicalDeviceDisplayProperties2KHR: Emulating call in ICD \"%s\"", icd_term->scanned_icd->lib_name);
2313  
2314      // If the icd doesn't support VK_KHR_display, then no properties are available
2315      if (icd_term->dispatch.GetPhysicalDeviceDisplayPropertiesKHR == NULL) {
2316          *pPropertyCount = 0;
2317          return VK_SUCCESS;
2318      }
2319  
2320      // If we aren't writing to pProperties, then emulation is straightforward
2321      if (pProperties == NULL || *pPropertyCount == 0) {
2322          return icd_term->dispatch.GetPhysicalDeviceDisplayPropertiesKHR(phys_dev_term->phys_dev, pPropertyCount, NULL);
2323      }
2324  
2325      // If we do have to write to pProperties, then we need to write to a temporary array of VkDisplayPropertiesKHR and copy it
2326      VkDisplayPropertiesKHR *properties = loader_stack_alloc(*pPropertyCount * sizeof(VkDisplayPropertiesKHR));
2327      if (properties == NULL) {
2328          return VK_ERROR_OUT_OF_HOST_MEMORY;
2329      }
2330      VkResult res = icd_term->dispatch.GetPhysicalDeviceDisplayPropertiesKHR(phys_dev_term->phys_dev, pPropertyCount, properties);
2331      if (res < 0) {
2332          return res;
2333      }
2334      for (uint32_t i = 0; i < *pPropertyCount; ++i) {
2335          memcpy(&pProperties[i].displayProperties, &properties[i], sizeof(VkDisplayPropertiesKHR));
2336      }
2337      return res;
2338  }
2339  
vkGetPhysicalDeviceDisplayPlaneProperties2KHR(VkPhysicalDevice physicalDevice,uint32_t * pPropertyCount,VkDisplayPlaneProperties2KHR * pProperties)2340  LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayPlaneProperties2KHR(
2341      VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, VkDisplayPlaneProperties2KHR *pProperties) {
2342      const VkLayerInstanceDispatchTable *disp;
2343      VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
2344      if (VK_NULL_HANDLE == unwrapped_phys_dev) {
2345          loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2346                     "vkGetPhysicalDeviceDisplayPlaneProperties2KHR: Invalid physicalDevice "
2347                     "[VUID-vkGetPhysicalDeviceDisplayPlaneProperties2KHR-physicalDevice-parameter]");
2348          abort(); /* Intentionally fail so user can correct issue. */
2349      }
2350      disp = loader_get_instance_layer_dispatch(physicalDevice);
2351      return disp->GetPhysicalDeviceDisplayPlaneProperties2KHR(unwrapped_phys_dev, pPropertyCount, pProperties);
2352  }
2353  
terminator_GetPhysicalDeviceDisplayPlaneProperties2KHR(VkPhysicalDevice physicalDevice,uint32_t * pPropertyCount,VkDisplayPlaneProperties2KHR * pProperties)2354  VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceDisplayPlaneProperties2KHR(VkPhysicalDevice physicalDevice,
2355                                                                                        uint32_t *pPropertyCount,
2356                                                                                        VkDisplayPlaneProperties2KHR *pProperties) {
2357      struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
2358      struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
2359  
2360      // If the function is available in the driver, just call into it
2361      if (icd_term->dispatch.GetPhysicalDeviceDisplayPlaneProperties2KHR != NULL) {
2362          return icd_term->dispatch.GetPhysicalDeviceDisplayPlaneProperties2KHR(phys_dev_term->phys_dev, pPropertyCount, pProperties);
2363      }
2364  
2365      // We have to emulate the function.
2366      loader_log(icd_term->this_instance, VULKAN_LOADER_INFO_BIT, 0,
2367                 "vkGetPhysicalDeviceDisplayPlaneProperties2KHR: Emulating call in ICD \"%s\"", icd_term->scanned_icd->lib_name);
2368  
2369      // If the icd doesn't support VK_KHR_display, then no properties are available
2370      if (icd_term->dispatch.GetPhysicalDeviceDisplayPlanePropertiesKHR == NULL) {
2371          *pPropertyCount = 0;
2372          return VK_SUCCESS;
2373      }
2374  
2375      // If we aren't writing to pProperties, then emulation is straightforward
2376      if (pProperties == NULL || *pPropertyCount == 0) {
2377          return icd_term->dispatch.GetPhysicalDeviceDisplayPlanePropertiesKHR(phys_dev_term->phys_dev, pPropertyCount, NULL);
2378      }
2379  
2380      // If we do have to write to pProperties, then we need to write to a temporary array of VkDisplayPlanePropertiesKHR and copy it
2381      VkDisplayPlanePropertiesKHR *properties = loader_stack_alloc(*pPropertyCount * sizeof(VkDisplayPlanePropertiesKHR));
2382      if (properties == NULL) {
2383          return VK_ERROR_OUT_OF_HOST_MEMORY;
2384      }
2385      VkResult res =
2386          icd_term->dispatch.GetPhysicalDeviceDisplayPlanePropertiesKHR(phys_dev_term->phys_dev, pPropertyCount, properties);
2387      if (res < 0) {
2388          return res;
2389      }
2390      for (uint32_t i = 0; i < *pPropertyCount; ++i) {
2391          memcpy(&pProperties[i].displayPlaneProperties, &properties[i], sizeof(VkDisplayPlanePropertiesKHR));
2392      }
2393      return res;
2394  }
2395  
vkGetDisplayModeProperties2KHR(VkPhysicalDevice physicalDevice,VkDisplayKHR display,uint32_t * pPropertyCount,VkDisplayModeProperties2KHR * pProperties)2396  LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayModeProperties2KHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
2397                                                                              uint32_t *pPropertyCount,
2398                                                                              VkDisplayModeProperties2KHR *pProperties) {
2399      const VkLayerInstanceDispatchTable *disp;
2400      VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
2401      if (VK_NULL_HANDLE == unwrapped_phys_dev) {
2402          loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2403                     "vkGetDisplayModeProperties2KHR: Invalid physicalDevice "
2404                     "[VUID-vkGetDisplayModeProperties2KHR-physicalDevice-parameter]");
2405          abort(); /* Intentionally fail so user can correct issue. */
2406      }
2407      disp = loader_get_instance_layer_dispatch(physicalDevice);
2408      return disp->GetDisplayModeProperties2KHR(unwrapped_phys_dev, display, pPropertyCount, pProperties);
2409  }
2410  
terminator_GetDisplayModeProperties2KHR(VkPhysicalDevice physicalDevice,VkDisplayKHR display,uint32_t * pPropertyCount,VkDisplayModeProperties2KHR * pProperties)2411  VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDisplayModeProperties2KHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
2412                                                                         uint32_t *pPropertyCount,
2413                                                                         VkDisplayModeProperties2KHR *pProperties) {
2414      struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
2415      struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
2416  
2417      // If the function is available in the driver, just call into it
2418      if (icd_term->dispatch.GetDisplayModeProperties2KHR != NULL) {
2419          return icd_term->dispatch.GetDisplayModeProperties2KHR(phys_dev_term->phys_dev, display, pPropertyCount, pProperties);
2420      }
2421  
2422      // We have to emulate the function.
2423      loader_log(icd_term->this_instance, VULKAN_LOADER_INFO_BIT, 0, "vkGetDisplayModeProperties2KHR: Emulating call in ICD \"%s\"",
2424                 icd_term->scanned_icd->lib_name);
2425  
2426      // If the icd doesn't support VK_KHR_display, then no properties are available
2427      if (icd_term->dispatch.GetDisplayModePropertiesKHR == NULL) {
2428          *pPropertyCount = 0;
2429          return VK_SUCCESS;
2430      }
2431  
2432      // If we aren't writing to pProperties, then emulation is straightforward
2433      if (pProperties == NULL || *pPropertyCount == 0) {
2434          return icd_term->dispatch.GetDisplayModePropertiesKHR(phys_dev_term->phys_dev, display, pPropertyCount, NULL);
2435      }
2436  
2437      // If we do have to write to pProperties, then we need to write to a temporary array of VkDisplayModePropertiesKHR and copy it
2438      VkDisplayModePropertiesKHR *properties = loader_stack_alloc(*pPropertyCount * sizeof(VkDisplayModePropertiesKHR));
2439      if (properties == NULL) {
2440          return VK_ERROR_OUT_OF_HOST_MEMORY;
2441      }
2442      VkResult res = icd_term->dispatch.GetDisplayModePropertiesKHR(phys_dev_term->phys_dev, display, pPropertyCount, properties);
2443      if (res < 0) {
2444          return res;
2445      }
2446      for (uint32_t i = 0; i < *pPropertyCount; ++i) {
2447          memcpy(&pProperties[i].displayModeProperties, &properties[i], sizeof(VkDisplayModePropertiesKHR));
2448      }
2449      return res;
2450  }
2451  
vkGetDisplayPlaneCapabilities2KHR(VkPhysicalDevice physicalDevice,const VkDisplayPlaneInfo2KHR * pDisplayPlaneInfo,VkDisplayPlaneCapabilities2KHR * pCapabilities)2452  LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayPlaneCapabilities2KHR(VkPhysicalDevice physicalDevice,
2453                                                                                 const VkDisplayPlaneInfo2KHR *pDisplayPlaneInfo,
2454                                                                                 VkDisplayPlaneCapabilities2KHR *pCapabilities) {
2455      const VkLayerInstanceDispatchTable *disp;
2456      VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
2457      if (VK_NULL_HANDLE == unwrapped_phys_dev) {
2458          loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2459                     "vkGetDisplayPlaneCapabilities2KHR: Invalid physicalDevice "
2460                     "[VUID-vkGetDisplayPlaneCapabilities2KHR-physicalDevice-parameter]");
2461          abort(); /* Intentionally fail so user can correct issue. */
2462      }
2463      disp = loader_get_instance_layer_dispatch(physicalDevice);
2464      return disp->GetDisplayPlaneCapabilities2KHR(unwrapped_phys_dev, pDisplayPlaneInfo, pCapabilities);
2465  }
2466  
terminator_GetDisplayPlaneCapabilities2KHR(VkPhysicalDevice physicalDevice,const VkDisplayPlaneInfo2KHR * pDisplayPlaneInfo,VkDisplayPlaneCapabilities2KHR * pCapabilities)2467  VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDisplayPlaneCapabilities2KHR(VkPhysicalDevice physicalDevice,
2468                                                                            const VkDisplayPlaneInfo2KHR *pDisplayPlaneInfo,
2469                                                                            VkDisplayPlaneCapabilities2KHR *pCapabilities) {
2470      struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
2471      struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
2472  
2473      // If the function is available in the driver, just call into it
2474      if (icd_term->dispatch.GetDisplayPlaneCapabilities2KHR != NULL) {
2475          return icd_term->dispatch.GetDisplayPlaneCapabilities2KHR(phys_dev_term->phys_dev, pDisplayPlaneInfo, pCapabilities);
2476      }
2477  
2478      // We have to emulate the function.
2479      loader_log(icd_term->this_instance, VULKAN_LOADER_INFO_BIT, 0,
2480                 "vkGetDisplayPlaneCapabilities2KHR: Emulating call in ICD \"%s\"", icd_term->scanned_icd->lib_name);
2481  
2482      // If the icd doesn't support VK_KHR_display, then there are no capabilities
2483      if (NULL == icd_term->dispatch.GetDisplayPlaneCapabilitiesKHR) {
2484          if (pCapabilities) {
2485              memset(&pCapabilities->capabilities, 0, sizeof(VkDisplayPlaneCapabilitiesKHR));
2486          }
2487          return VK_SUCCESS;
2488      }
2489  
2490      // Just call into the old version of the function.
2491      return icd_term->dispatch.GetDisplayPlaneCapabilitiesKHR(phys_dev_term->phys_dev, pDisplayPlaneInfo->mode,
2492                                                               pDisplayPlaneInfo->planeIndex, &pCapabilities->capabilities);
2493  }
2494  
2495  #ifdef VK_USE_PLATFORM_FUCHSIA
2496  
2497  // This is the trampoline entrypoint for CreateImagePipeSurfaceFUCHSIA
vkCreateImagePipeSurfaceFUCHSIA(VkInstance instance,const VkImagePipeSurfaceCreateInfoFUCHSIA * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSurfaceKHR * pSurface)2498  LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateImagePipeSurfaceFUCHSIA(VkInstance instance,
2499                                                                               const VkImagePipeSurfaceCreateInfoFUCHSIA *pCreateInfo,
2500                                                                               const VkAllocationCallbacks *pAllocator,
2501                                                                               VkSurfaceKHR *pSurface) {
2502      struct loader_instance *loader_inst = loader_get_instance(instance);
2503      if (NULL == loader_inst) {
2504          loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2505                     "vkCreateImagePipeSurfaceFUCHSIA: Invalid instance [VUID-vkCreateImagePipeSurfaceFUCHSIA-instance-parameter]");
2506          abort(); /* Intentionally fail so user can correct issue. */
2507      }
2508      return loader_inst->disp->layer_inst_disp.CreateImagePipeSurfaceFUCHSIA(loader_inst->instance, pCreateInfo, pAllocator,
2509                                                                              pSurface);
2510  }
2511  
2512  // This is the instance chain terminator function for CreateImagePipeSurfaceFUCHSIA
terminator_CreateImagePipeSurfaceFUCHSIA(VkInstance instance,const VkImagePipeSurfaceCreateInfoFUCHSIA * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSurfaceKHR * pSurface)2513  VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateImagePipeSurfaceFUCHSIA(VkInstance instance,
2514                                                                          const VkImagePipeSurfaceCreateInfoFUCHSIA *pCreateInfo,
2515                                                                          const VkAllocationCallbacks *pAllocator,
2516                                                                          VkSurfaceKHR *pSurface) {
2517      VkResult vkRes = VK_SUCCESS;
2518      VkIcdSurface *pIcdSurface = NULL;
2519      uint32_t i = 0;
2520  
2521      // Initialize pSurface to NULL just to be safe.
2522      *pSurface = VK_NULL_HANDLE;
2523      // First, check to ensure the appropriate extension was enabled:
2524      struct loader_instance *loader_inst = loader_get_instance(instance);
2525      if (!loader_inst->wsi_imagepipe_surface_enabled) {
2526          loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
2527                     "VK_FUCHSIA_imagepipe_surface extension not enabled.  "
2528                     "vkCreateImagePipeSurfaceFUCHSIA not executed!\n");
2529          vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
2530          goto out;
2531      }
2532  
2533      // Next, if so, proceed with the implementation of this function:
2534      pIcdSurface =
2535          AllocateIcdSurfaceStruct(loader_inst, sizeof(pIcdSurface->imagepipe_surf.base), sizeof(pIcdSurface->imagepipe_surf));
2536      if (pIcdSurface == NULL) {
2537          vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
2538          goto out;
2539      }
2540  
2541      pIcdSurface->imagepipe_surf.base.platform = VK_ICD_WSI_PLATFORM_FUCHSIA;
2542  
2543      // Loop through each ICD and determine if they need to create a surface
2544      for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
2545          if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
2546              if (NULL != icd_term->dispatch.CreateImagePipeSurfaceFUCHSIA) {
2547                  vkRes = icd_term->dispatch.CreateImagePipeSurfaceFUCHSIA(icd_term->instance, pCreateInfo, pAllocator,
2548                                                                           &pIcdSurface->real_icd_surfaces[i]);
2549                  if (VK_SUCCESS != vkRes) {
2550                      goto out;
2551                  }
2552              }
2553          }
2554      }
2555  
2556      *pSurface = (VkSurfaceKHR)(pIcdSurface);
2557  
2558  out:
2559  
2560      if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
2561          if (NULL != pIcdSurface->real_icd_surfaces) {
2562              i = 0;
2563              for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
2564                  if ((VkSurfaceKHR)(uintptr_t)NULL != pIcdSurface->real_icd_surfaces[i] &&
2565                      NULL != icd_term->dispatch.DestroySurfaceKHR) {
2566                      icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
2567                  }
2568              }
2569              loader_instance_heap_free(loader_inst, pIcdSurface->real_icd_surfaces);
2570          }
2571          loader_instance_heap_free(loader_inst, pIcdSurface);
2572      }
2573  
2574      return vkRes;
2575  }
2576  #endif  // VK_USE_PLATFORM_FUCHSIA
2577  
2578  LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
vkGetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceSurfaceInfo2KHR * pSurfaceInfo,VkSurfaceCapabilities2KHR * pSurfaceCapabilities)2579  vkGetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
2580                                             VkSurfaceCapabilities2KHR *pSurfaceCapabilities) {
2581      const VkLayerInstanceDispatchTable *disp;
2582      VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
2583      if (VK_NULL_HANDLE == unwrapped_phys_dev) {
2584          loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2585                     "vkGetPhysicalDeviceSurfaceCapabilities2KHR: Invalid physicalDevice "
2586                     "[VUID-vkGetPhysicalDeviceSurfaceCapabilities2KHR-physicalDevice-parameter]");
2587          abort(); /* Intentionally fail so user can correct issue. */
2588      }
2589      disp = loader_get_instance_layer_dispatch(physicalDevice);
2590      return disp->GetPhysicalDeviceSurfaceCapabilities2KHR(unwrapped_phys_dev, pSurfaceInfo, pSurfaceCapabilities);
2591  }
2592  
terminator_GetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceSurfaceInfo2KHR * pSurfaceInfo,VkSurfaceCapabilities2KHR * pSurfaceCapabilities)2593  VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceCapabilities2KHR(
2594      VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
2595      VkSurfaceCapabilities2KHR *pSurfaceCapabilities) {
2596      struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
2597      struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
2598      struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
2599  
2600      if (!loader_inst->wsi_surface_enabled) {
2601          loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
2602                     "VK_KHR_surface extension not enabled. vkGetPhysicalDeviceSurfaceCapabilities2KHR not executed!\n");
2603          return VK_SUCCESS;
2604      }
2605  
2606      VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)(pSurfaceInfo->surface);
2607      uint8_t icd_index = phys_dev_term->icd_index;
2608  
2609      if (icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2KHR != NULL) {
2610          VkBaseOutStructure *pNext = (VkBaseOutStructure *)pSurfaceCapabilities->pNext;
2611          while (pNext != NULL) {
2612              if ((int)pNext->sType == VK_STRUCTURE_TYPE_SURFACE_PROTECTED_CAPABILITIES_KHR) {
2613                  // Not all ICDs may be supporting VK_KHR_surface_protected_capabilities
2614                  // Initialize VkSurfaceProtectedCapabilitiesKHR.supportsProtected to false and
2615                  // if an ICD supports protected surfaces, it will reset it to true accordingly.
2616                  ((VkSurfaceProtectedCapabilitiesKHR *)pNext)->supportsProtected = VK_FALSE;
2617              }
2618              pNext = (VkBaseOutStructure *)pNext->pNext;
2619          }
2620  
2621          // Pass the call to the driver, possibly unwrapping the ICD surface
2622          if (NULL != icd_surface->real_icd_surfaces && NULL != (void *)(uintptr_t)icd_surface->real_icd_surfaces[icd_index]) {
2623              VkPhysicalDeviceSurfaceInfo2KHR info_copy = *pSurfaceInfo;
2624              info_copy.surface = icd_surface->real_icd_surfaces[icd_index];
2625              return icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2KHR(phys_dev_term->phys_dev, &info_copy,
2626                                                                                 pSurfaceCapabilities);
2627          } else {
2628              return icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2KHR(phys_dev_term->phys_dev, pSurfaceInfo,
2629                                                                                 pSurfaceCapabilities);
2630          }
2631      } else {
2632          // Emulate the call
2633          loader_log(icd_term->this_instance, VULKAN_LOADER_INFO_BIT, 0,
2634                     "vkGetPhysicalDeviceSurfaceCapabilities2KHR: Emulating call in ICD \"%s\" using "
2635                     "vkGetPhysicalDeviceSurfaceCapabilitiesKHR",
2636                     icd_term->scanned_icd->lib_name);
2637  
2638          if (pSurfaceInfo->pNext != NULL) {
2639              loader_log(icd_term->this_instance, VULKAN_LOADER_WARN_BIT, 0,
2640                         "vkGetPhysicalDeviceSurfaceCapabilities2KHR: Emulation found unrecognized structure type in "
2641                         "pSurfaceInfo->pNext - this struct will be ignored");
2642          }
2643  
2644          // Write to the VkSurfaceCapabilities2KHR struct
2645          VkSurfaceKHR surface = pSurfaceInfo->surface;
2646          if (NULL != icd_surface->real_icd_surfaces && NULL != (void *)(uintptr_t)(icd_surface->real_icd_surfaces[icd_index])) {
2647              surface = icd_surface->real_icd_surfaces[icd_index];
2648          }
2649  
2650          // If the icd doesn't support VK_KHR_surface, then there are no capabilities
2651          if (NULL == icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilitiesKHR) {
2652              if (pSurfaceCapabilities) {
2653                  memset(&pSurfaceCapabilities->surfaceCapabilities, 0, sizeof(VkSurfaceCapabilitiesKHR));
2654              }
2655              return VK_SUCCESS;
2656          }
2657          VkResult res = icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilitiesKHR(phys_dev_term->phys_dev, surface,
2658                                                                                    &pSurfaceCapabilities->surfaceCapabilities);
2659  
2660          if (pSurfaceCapabilities->pNext != NULL) {
2661              loader_log(icd_term->this_instance, VULKAN_LOADER_WARN_BIT, 0,
2662                         "vkGetPhysicalDeviceSurfaceCapabilities2KHR: Emulation found unrecognized structure type in "
2663                         "pSurfaceCapabilities->pNext - this struct will be ignored");
2664          }
2665          return res;
2666      }
2667  }
2668  
2669  LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
vkGetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceSurfaceInfo2KHR * pSurfaceInfo,uint32_t * pSurfaceFormatCount,VkSurfaceFormat2KHR * pSurfaceFormats)2670  vkGetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
2671                                        uint32_t *pSurfaceFormatCount, VkSurfaceFormat2KHR *pSurfaceFormats) {
2672      const VkLayerInstanceDispatchTable *disp;
2673      VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
2674      if (VK_NULL_HANDLE == unwrapped_phys_dev) {
2675          loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2676                     "vkGetPhysicalDeviceSurfaceFormats2KHR: Invalid physicalDevice "
2677                     "[VUID-vkGetPhysicalDeviceSurfaceFormats2KHR-physicalDevice-parameter]");
2678          abort(); /* Intentionally fail so user can correct issue. */
2679      }
2680      disp = loader_get_instance_layer_dispatch(physicalDevice);
2681      return disp->GetPhysicalDeviceSurfaceFormats2KHR(unwrapped_phys_dev, pSurfaceInfo, pSurfaceFormatCount, pSurfaceFormats);
2682  }
2683  
terminator_GetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceSurfaceInfo2KHR * pSurfaceInfo,uint32_t * pSurfaceFormatCount,VkSurfaceFormat2KHR * pSurfaceFormats)2684  VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice,
2685                                                                                const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
2686                                                                                uint32_t *pSurfaceFormatCount,
2687                                                                                VkSurfaceFormat2KHR *pSurfaceFormats) {
2688      struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
2689      struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
2690      struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
2691  
2692      if (!loader_inst->wsi_surface_enabled) {
2693          loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
2694                     "VK_KHR_surface extension not enabled. vkGetPhysicalDeviceSurfaceFormats2KHR not executed!\n");
2695          return VK_SUCCESS;
2696      }
2697  
2698      VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)(pSurfaceInfo->surface);
2699      uint8_t icd_index = phys_dev_term->icd_index;
2700  
2701      if (icd_term->dispatch.GetPhysicalDeviceSurfaceFormats2KHR != NULL) {
2702          // Pass the call to the driver, possibly unwrapping the ICD surface
2703          if (NULL != icd_surface->real_icd_surfaces && NULL != (void *)(uintptr_t)(icd_surface->real_icd_surfaces[icd_index])) {
2704              VkPhysicalDeviceSurfaceInfo2KHR info_copy = *pSurfaceInfo;
2705              info_copy.surface = icd_surface->real_icd_surfaces[icd_index];
2706              return icd_term->dispatch.GetPhysicalDeviceSurfaceFormats2KHR(phys_dev_term->phys_dev, &info_copy, pSurfaceFormatCount,
2707                                                                            pSurfaceFormats);
2708          } else {
2709              return icd_term->dispatch.GetPhysicalDeviceSurfaceFormats2KHR(phys_dev_term->phys_dev, pSurfaceInfo,
2710                                                                            pSurfaceFormatCount, pSurfaceFormats);
2711          }
2712      } else {
2713          // Emulate the call
2714          loader_log(icd_term->this_instance, VULKAN_LOADER_INFO_BIT, 0,
2715                     "vkGetPhysicalDeviceSurfaceFormats2KHR: Emulating call in ICD \"%s\" using vkGetPhysicalDeviceSurfaceFormatsKHR",
2716                     icd_term->scanned_icd->lib_name);
2717  
2718          if (pSurfaceInfo->pNext != NULL) {
2719              loader_log(icd_term->this_instance, VULKAN_LOADER_WARN_BIT, 0,
2720                         "vkGetPhysicalDeviceSurfaceFormats2KHR: Emulation found unrecognized structure type in pSurfaceInfo->pNext "
2721                         "- this struct will be ignored");
2722          }
2723  
2724          VkSurfaceKHR surface = pSurfaceInfo->surface;
2725          if (NULL != icd_surface->real_icd_surfaces && NULL != (void *)(uintptr_t)(icd_surface->real_icd_surfaces[icd_index])) {
2726              surface = icd_surface->real_icd_surfaces[icd_index];
2727          }
2728  
2729          // If the icd doesn't support VK_KHR_surface, then there are no formats
2730          if (NULL == icd_term->dispatch.GetPhysicalDeviceSurfaceFormatsKHR) {
2731              if (pSurfaceFormatCount) {
2732                  *pSurfaceFormatCount = 0;
2733              }
2734              return VK_SUCCESS;
2735          }
2736  
2737          if (*pSurfaceFormatCount == 0 || pSurfaceFormats == NULL) {
2738              // Write to pSurfaceFormatCount
2739              return icd_term->dispatch.GetPhysicalDeviceSurfaceFormatsKHR(phys_dev_term->phys_dev, surface, pSurfaceFormatCount,
2740                                                                           NULL);
2741          } else {
2742              // Allocate a temporary array for the output of the old function
2743              VkSurfaceFormatKHR *formats = loader_stack_alloc(*pSurfaceFormatCount * sizeof(VkSurfaceFormatKHR));
2744              if (formats == NULL) {
2745                  return VK_ERROR_OUT_OF_HOST_MEMORY;
2746              }
2747  
2748              VkResult res = icd_term->dispatch.GetPhysicalDeviceSurfaceFormatsKHR(phys_dev_term->phys_dev, surface,
2749                                                                                   pSurfaceFormatCount, formats);
2750              for (uint32_t i = 0; i < *pSurfaceFormatCount; ++i) {
2751                  pSurfaceFormats[i].surfaceFormat = formats[i];
2752                  if (pSurfaceFormats[i].pNext != NULL) {
2753                      loader_log(icd_term->this_instance, VULKAN_LOADER_WARN_BIT, 0,
2754                                 "vkGetPhysicalDeviceSurfaceFormats2KHR: Emulation found unrecognized structure type in "
2755                                 "pSurfaceFormats[%d].pNext - this struct will be ignored",
2756                                 i);
2757                  }
2758              }
2759              return res;
2760          }
2761      }
2762  }
2763  
wsi_swapchain_instance_gpa(struct loader_instance * loader_inst,const char * name,void ** addr)2764  bool wsi_swapchain_instance_gpa(struct loader_instance *loader_inst, const char *name, void **addr) {
2765      *addr = NULL;
2766  
2767      // Functions for the VK_KHR_surface extension:
2768      if (!strcmp("vkDestroySurfaceKHR", name)) {
2769          *addr = loader_inst->wsi_surface_enabled ? (void *)vkDestroySurfaceKHR : NULL;
2770          return true;
2771      }
2772      if (!strcmp("vkGetPhysicalDeviceSurfaceSupportKHR", name)) {
2773          *addr = loader_inst->wsi_surface_enabled ? (void *)vkGetPhysicalDeviceSurfaceSupportKHR : NULL;
2774          return true;
2775      }
2776      if (!strcmp("vkGetPhysicalDeviceSurfaceCapabilitiesKHR", name)) {
2777          *addr = loader_inst->wsi_surface_enabled ? (void *)vkGetPhysicalDeviceSurfaceCapabilitiesKHR : NULL;
2778          return true;
2779      }
2780      if (!strcmp("vkGetPhysicalDeviceSurfaceFormatsKHR", name)) {
2781          *addr = loader_inst->wsi_surface_enabled ? (void *)vkGetPhysicalDeviceSurfaceFormatsKHR : NULL;
2782          return true;
2783      }
2784      if (!strcmp("vkGetPhysicalDeviceSurfacePresentModesKHR", name)) {
2785          *addr = loader_inst->wsi_surface_enabled ? (void *)vkGetPhysicalDeviceSurfacePresentModesKHR : NULL;
2786          return true;
2787      }
2788  
2789      if (!strcmp("vkGetDeviceGroupPresentCapabilitiesKHR", name)) {
2790          *addr = loader_inst->wsi_surface_enabled ? (void *)vkGetDeviceGroupPresentCapabilitiesKHR : NULL;
2791          return true;
2792      }
2793  
2794      if (!strcmp("vkGetDeviceGroupSurfacePresentModesKHR", name)) {
2795          *addr = loader_inst->wsi_surface_enabled ? (void *)vkGetDeviceGroupSurfacePresentModesKHR : NULL;
2796          return true;
2797      }
2798  
2799      if (!strcmp("vkGetPhysicalDevicePresentRectanglesKHR", name)) {
2800          *addr = loader_inst->wsi_surface_enabled ? (void *)vkGetPhysicalDevicePresentRectanglesKHR : NULL;
2801          return true;
2802      }
2803  
2804      // Functions for VK_KHR_get_surface_capabilities2 extension:
2805      if (!strcmp("vkGetPhysicalDeviceSurfaceCapabilities2KHR", name)) {
2806          *addr = loader_inst->wsi_surface_enabled ? (void *)vkGetPhysicalDeviceSurfaceCapabilities2KHR : NULL;
2807          return true;
2808      }
2809  
2810      if (!strcmp("vkGetPhysicalDeviceSurfaceFormats2KHR", name)) {
2811          *addr = loader_inst->wsi_surface_enabled ? (void *)vkGetPhysicalDeviceSurfaceFormats2KHR : NULL;
2812          return true;
2813      }
2814  
2815      // Functions for the VK_KHR_swapchain extension:
2816  
2817      // Note: This is a device extension, and its functions are statically
2818      // exported from the loader.  Per Khronos decisions, the loader's GIPA
2819      // function will return the trampoline function for such device-extension
2820      // functions, regardless of whether the extension has been enabled.
2821      if (!strcmp("vkCreateSwapchainKHR", name)) {
2822          *addr = (void *)vkCreateSwapchainKHR;
2823          return true;
2824      }
2825      if (!strcmp("vkDestroySwapchainKHR", name)) {
2826          *addr = (void *)vkDestroySwapchainKHR;
2827          return true;
2828      }
2829      if (!strcmp("vkGetSwapchainImagesKHR", name)) {
2830          *addr = (void *)vkGetSwapchainImagesKHR;
2831          return true;
2832      }
2833      if (!strcmp("vkAcquireNextImageKHR", name)) {
2834          *addr = (void *)vkAcquireNextImageKHR;
2835          return true;
2836      }
2837      if (!strcmp("vkQueuePresentKHR", name)) {
2838          *addr = (void *)vkQueuePresentKHR;
2839          return true;
2840      }
2841      if (!strcmp("vkAcquireNextImage2KHR", name)) {
2842          *addr = (void *)vkAcquireNextImage2KHR;
2843          return true;
2844      }
2845  
2846  #ifdef VK_USE_PLATFORM_WIN32_KHR
2847  
2848      // Functions for the VK_KHR_win32_surface extension:
2849      if (!strcmp("vkCreateWin32SurfaceKHR", name)) {
2850          *addr = loader_inst->wsi_win32_surface_enabled ? (void *)vkCreateWin32SurfaceKHR : NULL;
2851          return true;
2852      }
2853      if (!strcmp("vkGetPhysicalDeviceWin32PresentationSupportKHR", name)) {
2854          *addr = loader_inst->wsi_win32_surface_enabled ? (void *)vkGetPhysicalDeviceWin32PresentationSupportKHR : NULL;
2855          return true;
2856      }
2857  #endif  // VK_USE_PLATFORM_WIN32_KHR
2858  #ifdef VK_USE_PLATFORM_WAYLAND_KHR
2859  
2860      // Functions for the VK_KHR_wayland_surface extension:
2861      if (!strcmp("vkCreateWaylandSurfaceKHR", name)) {
2862          *addr = loader_inst->wsi_wayland_surface_enabled ? (void *)vkCreateWaylandSurfaceKHR : NULL;
2863          return true;
2864      }
2865      if (!strcmp("vkGetPhysicalDeviceWaylandPresentationSupportKHR", name)) {
2866          *addr = loader_inst->wsi_wayland_surface_enabled ? (void *)vkGetPhysicalDeviceWaylandPresentationSupportKHR : NULL;
2867          return true;
2868      }
2869  #endif  // VK_USE_PLATFORM_WAYLAND_KHR
2870  #ifdef VK_USE_PLATFORM_XCB_KHR
2871  
2872      // Functions for the VK_KHR_xcb_surface extension:
2873      if (!strcmp("vkCreateXcbSurfaceKHR", name)) {
2874          *addr = loader_inst->wsi_xcb_surface_enabled ? (void *)vkCreateXcbSurfaceKHR : NULL;
2875          return true;
2876      }
2877      if (!strcmp("vkGetPhysicalDeviceXcbPresentationSupportKHR", name)) {
2878          *addr = loader_inst->wsi_xcb_surface_enabled ? (void *)vkGetPhysicalDeviceXcbPresentationSupportKHR : NULL;
2879          return true;
2880      }
2881  #endif  // VK_USE_PLATFORM_XCB_KHR
2882  #ifdef VK_USE_PLATFORM_XLIB_KHR
2883  
2884      // Functions for the VK_KHR_xlib_surface extension:
2885      if (!strcmp("vkCreateXlibSurfaceKHR", name)) {
2886          *addr = loader_inst->wsi_xlib_surface_enabled ? (void *)vkCreateXlibSurfaceKHR : NULL;
2887          return true;
2888      }
2889      if (!strcmp("vkGetPhysicalDeviceXlibPresentationSupportKHR", name)) {
2890          *addr = loader_inst->wsi_xlib_surface_enabled ? (void *)vkGetPhysicalDeviceXlibPresentationSupportKHR : NULL;
2891          return true;
2892      }
2893  #endif  // VK_USE_PLATFORM_XLIB_KHR
2894  #ifdef VK_USE_PLATFORM_DIRECTFB_EXT
2895  
2896      // Functions for the VK_EXT_directfb_surface extension:
2897      if (!strcmp("vkCreateDirectFBSurfaceEXT", name)) {
2898          *addr = loader_inst->wsi_directfb_surface_enabled ? (void *)vkCreateDirectFBSurfaceEXT : NULL;
2899          return true;
2900      }
2901      if (!strcmp("vkGetPhysicalDeviceDirectFBPresentationSupportEXT", name)) {
2902          *addr = loader_inst->wsi_directfb_surface_enabled ? (void *)vkGetPhysicalDeviceDirectFBPresentationSupportEXT : NULL;
2903          return true;
2904      }
2905  #endif  // VK_USE_PLATFORM_DIRECTFB_EXT
2906  #ifdef VK_USE_PLATFORM_ANDROID_KHR
2907  
2908      // Functions for the VK_KHR_android_surface extension:
2909      if (!strcmp("vkCreateAndroidSurfaceKHR", name)) {
2910          *addr = loader_inst->wsi_android_surface_enabled ? (void *)vkCreateAndroidSurfaceKHR : NULL;
2911          return true;
2912      }
2913  #endif  // VK_USE_PLATFORM_ANDROID_KHR
2914  #ifdef VK_USE_PLATFORM_OHOS
2915  
2916      // Functions for the VK_OHOS_surface extension:
2917      if (!strcmp("vkCreateSurfaceOHOS", name)) {
2918          *addr = loader_inst->wsi_ohos_surface_enabled ? (void *)vkCreateSurfaceOHOS : NULL;
2919          return true;
2920      }
2921  #endif  // VK_USE_PLATFORM_OHOS
2922  
2923  #ifdef VK_USE_PLATFORM_MACOS_MVK
2924  
2925      // Functions for the VK_MVK_macos_surface extension:
2926      if (!strcmp("vkCreateMacOSSurfaceMVK", name)) {
2927          *addr = loader_inst->wsi_macos_surface_enabled ? (void *)vkCreateMacOSSurfaceMVK : NULL;
2928          return true;
2929      }
2930  #endif  // VK_USE_PLATFORM_MACOS_MVK
2931  #ifdef VK_USE_PLATFORM_IOS_MVK
2932  
2933      // Functions for the VK_MVK_ios_surface extension:
2934      if (!strcmp("vkCreateIOSSurfaceMVK", name)) {
2935          *addr = loader_inst->wsi_ios_surface_enabled ? (void *)vkCreateIOSSurfaceMVK : NULL;
2936          return true;
2937      }
2938  #endif  // VK_USE_PLATFORM_IOS_MVK
2939  #ifdef VK_USE_PLATFORM_GGP
2940  
2941      // Functions for the VK_GGP_stream_descriptor_surface extension:
2942      if (!strcmp("vkCreateStreamDescriptorSurfaceGGP", name)) {
2943          *addr = loader_inst->wsi_ggp_surface_enabled ? (void *)vkCreateStreamDescriptorSurfaceGGP : NULL;
2944          return true;
2945      }
2946  #endif  // VK_USE_PLATFORM_GGP
2947  #ifdef VK_USE_PLATFORM_FUCHSIA
2948  
2949      // Functions for the VK_FUCHSIA_imagepipe_surface extension:
2950      if (!strcmp("vkCreateImagePipeSurfaceFUCHSIA", name)) {
2951          *addr = loader_inst->wsi_imagepipe_surface_enabled ? (void *)vkCreateImagePipeSurfaceFUCHSIA : NULL;
2952          return true;
2953      }
2954  
2955  #endif  // VK_USE_PLATFORM_FUCHSIA
2956  
2957      // Functions for the VK_EXT_headless_surface extension:
2958      if (!strcmp("vkCreateHeadlessSurfaceEXT", name)) {
2959          *addr = loader_inst->wsi_headless_surface_enabled ? (void *)vkCreateHeadlessSurfaceEXT : NULL;
2960          return true;
2961      }
2962  
2963  #if defined(VK_USE_PLATFORM_METAL_EXT)
2964      // Functions for the VK_MVK_macos_surface extension:
2965      if (!strcmp("vkCreateMetalSurfaceEXT", name)) {
2966          *addr = loader_inst->wsi_metal_surface_enabled ? (void *)vkCreateMetalSurfaceEXT : NULL;
2967          return true;
2968      }
2969  #endif  // VK_USE_PLATFORM_METAL_EXT
2970  
2971  #ifdef VK_USE_PLATFORM_SCREEN_QNX
2972  
2973      // Functions for the VK_QNX_screen_surface extension:
2974      if (!strcmp("vkCreateScreenSurfaceQNX", name)) {
2975          *addr = loader_inst->wsi_screen_surface_enabled ? (void *)vkCreateScreenSurfaceQNX : NULL;
2976          return true;
2977      }
2978      if (!strcmp("vkGetPhysicalDeviceScreenPresentationSupportQNX", name)) {
2979          *addr = loader_inst->wsi_screen_surface_enabled ? (void *)vkGetPhysicalDeviceScreenPresentationSupportQNX : NULL;
2980          return true;
2981      }
2982  #endif  // VK_USE_PLATFORM_SCREEN_QNX
2983  
2984  #ifdef VK_USE_PLATFORM_VI_NN
2985  
2986      // Functions for the VK_NN_vi_surface extension:
2987      if (!strcmp("vkCreateViSurfaceNN", name)) {
2988          *addr = loader_inst->wsi_vi_surface_enabled ? (void *)vkCreateViSurfaceNN : NULL;
2989          return true;
2990      }
2991  #endif  // VK_USE_PLATFORM_VI_NN
2992  
2993      // Functions for VK_KHR_display extension:
2994      if (!strcmp("vkGetPhysicalDeviceDisplayPropertiesKHR", name)) {
2995          *addr = loader_inst->wsi_display_enabled ? (void *)vkGetPhysicalDeviceDisplayPropertiesKHR : NULL;
2996          return true;
2997      }
2998      if (!strcmp("vkGetPhysicalDeviceDisplayPlanePropertiesKHR", name)) {
2999          *addr = loader_inst->wsi_display_enabled ? (void *)vkGetPhysicalDeviceDisplayPlanePropertiesKHR : NULL;
3000          return true;
3001      }
3002      if (!strcmp("vkGetDisplayPlaneSupportedDisplaysKHR", name)) {
3003          *addr = loader_inst->wsi_display_enabled ? (void *)vkGetDisplayPlaneSupportedDisplaysKHR : NULL;
3004          return true;
3005      }
3006      if (!strcmp("vkGetDisplayModePropertiesKHR", name)) {
3007          *addr = loader_inst->wsi_display_enabled ? (void *)vkGetDisplayModePropertiesKHR : NULL;
3008          return true;
3009      }
3010      if (!strcmp("vkCreateDisplayModeKHR", name)) {
3011          *addr = loader_inst->wsi_display_enabled ? (void *)vkCreateDisplayModeKHR : NULL;
3012          return true;
3013      }
3014      if (!strcmp("vkGetDisplayPlaneCapabilitiesKHR", name)) {
3015          *addr = loader_inst->wsi_display_enabled ? (void *)vkGetDisplayPlaneCapabilitiesKHR : NULL;
3016          return true;
3017      }
3018      if (!strcmp("vkCreateDisplayPlaneSurfaceKHR", name)) {
3019          *addr = loader_inst->wsi_display_enabled ? (void *)vkCreateDisplayPlaneSurfaceKHR : NULL;
3020          return true;
3021      }
3022  
3023      // Functions for KHR_display_swapchain extension:
3024      if (!strcmp("vkCreateSharedSwapchainsKHR", name)) {
3025          *addr = (void *)vkCreateSharedSwapchainsKHR;
3026          return true;
3027      }
3028  
3029      // Functions for KHR_get_display_properties2
3030      if (!strcmp("vkGetPhysicalDeviceDisplayProperties2KHR", name)) {
3031          *addr = loader_inst->wsi_display_props2_enabled ? (void *)vkGetPhysicalDeviceDisplayProperties2KHR : NULL;
3032          return true;
3033      }
3034      if (!strcmp("vkGetPhysicalDeviceDisplayPlaneProperties2KHR", name)) {
3035          *addr = loader_inst->wsi_display_props2_enabled ? (void *)vkGetPhysicalDeviceDisplayPlaneProperties2KHR : NULL;
3036          return true;
3037      }
3038      if (!strcmp("vkGetDisplayModeProperties2KHR", name)) {
3039          *addr = loader_inst->wsi_display_props2_enabled ? (void *)vkGetDisplayModeProperties2KHR : NULL;
3040          return true;
3041      }
3042      if (!strcmp("vkGetDisplayPlaneCapabilities2KHR", name)) {
3043          *addr = loader_inst->wsi_display_props2_enabled ? (void *)vkGetDisplayPlaneCapabilities2KHR : NULL;
3044          return true;
3045      }
3046  
3047      return false;
3048  }
3049