Coverage Report

Created: 2025-07-11 06:49

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