Coverage Report

Created: 2026-08-30 07:16

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