Coverage Report

Created: 2025-10-10 06:38

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