Coverage Report

Created: 2026-07-16 07:04

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