Coverage Report

Created: 2026-10-19 06:59

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