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