Coverage Report

Created: 2025-12-31 06:57

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