1/*
2 *
3 * Copyright (c) 2015-2023 The Khronos Group Inc.
4 * Copyright (c) 2015-2023 Valve Corporation
5 * Copyright (c) 2015-2023 LunarG, Inc.
6 * Copyright (C) 2015 Google Inc.
7 * Copyright (c) 2021-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
8 * Copyright (c) 2023-2023 RasterGrid Kft.
9 *
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
13 *
14 *     http://www.apache.org/licenses/LICENSE-2.0
15 *
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
21 *
22 * Author: Courtney Goeltzenleuchter <courtney@lunarg.com>
23 * Author: Jon Ashburn <jon@lunarg.com>
24 * Author: Tony Barbour <tony@LunarG.com>
25 * Author: Chia-I Wu <olv@lunarg.com>
26 * Author: Charles Giessen <charles@lunarg.com>
27 */
28
29#include <stdlib.h>
30#include <string.h>
31
32#include "allocation.h"
33#include "debug_utils.h"
34#include "gpa_helper.h"
35#include "loader.h"
36#include "loader_environment.h"
37#include "log.h"
38#include "settings.h"
39#include "vk_loader_extensions.h"
40#include "vk_loader_platform.h"
41#include "wsi.h"
42
43// Trampoline entrypoints are in this file for core Vulkan commands
44
45/* vkGetInstanceProcAddr: Get global level or instance level entrypoint addresses.
46 * @param instance
47 * @param pName
48 * @return
49 *    If pName is a global level entrypoint:
50 *        If instance == NULL || instance is invalid || (instance is valid && instance.minor_version <= 2):
51 *            return global level functions
52 *        Else:
53 *            return NULL
54 *    Else:
55 *        If instance is valid:
56 *            return a trampoline entry point for all dispatchable Vulkan functions both core and extensions.
57 *        Else:
58 *            return NULL
59 *
60 * Note:
61 * Vulkan header updated 1.2.193 changed the behavior of vkGetInstanceProcAddr for global entrypoints. They used to always be
62 * returned regardless of the value of the instance parameter. The spec was amended in this version to only allow querying global
63 * level entrypoints with a NULL instance. However, as to not break old applications, the new behavior is only applied if the
64 * instance passed in is both valid and minor version is greater than 1.2, which was when this change in behavior occurred. Only
65 * instances with a newer version will get the new behavior.
66 */
67LOADER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *pName) {
68    // Always should be able to get vkGetInstanceProcAddr if queried, regardless of the value of instance
69    if (!strcmp(pName, "vkGetInstanceProcAddr")) return (PFN_vkVoidFunction)vkGetInstanceProcAddr;
70
71    // Get entrypoint addresses that are global (no dispatchable object)
72    void *addr = globalGetProcAddr(pName);
73    if (addr != VK_NULL_HANDLE) {
74        // Always can get a global entrypoint from vkGetInstanceProcAddr with a NULL instance handle
75        if (instance == VK_NULL_HANDLE) {
76            return addr;
77        } else {
78            // New behavior only returns a global entrypoint if the instance handle is NULL.
79            // Old behavior is to return a global entrypoint regardless of the value of the instance handle.
80            // Use new behavior if: The instance is valid and the minor version of the instance is greater than 1.2, which
81            // was when the new behavior was added. (eg, it is enforced in the next minor version of vulkan, which will be 1.3)
82
83            // First check if instance is valid - loader_get_instance() returns NULL if it isn't.
84            struct loader_instance *ptr_instance = loader_get_instance(instance);
85            if (ptr_instance != NULL &&
86                loader_check_version_meets_required(loader_combine_version(1, 3, 0), ptr_instance->app_api_version)) {
87                // New behavior
88                return NULL;
89            } else {
90                // Old behavior
91                return addr;
92            }
93        }
94    } else {
95        // All other functions require a valid instance handle to get
96        if (instance == VK_NULL_HANDLE) {
97            return NULL;
98        }
99        struct loader_instance *ptr_instance = loader_get_instance(instance);
100        // If we've gotten here and the pointer is NULL, it's invalid
101        if (ptr_instance == NULL) {
102            loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
103                       "vkGetInstanceProcAddr: Invalid instance [VUID-vkGetInstanceProcAddr-instance-parameter]");
104            abort(); /* Intentionally fail so user can correct issue. */
105        }
106        // Return trampoline code for non-global entrypoints including any extensions.
107        // Device extensions are returned if a layer or ICD supports the extension.
108        // Instance extensions are returned if the extension is enabled and the
109        // loader or someone else supports the extension
110        return trampoline_get_proc_addr(ptr_instance, pName);
111    }
112}
113
114// Get a device level or global level entry point address.
115// @param device
116// @param pName
117// @return
118//    If device is valid, returns a device relative entry point for device level
119//    entry points both core and extensions.
120//    Device relative means call down the device chain.
121LOADER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice device, const char *pName) {
122    if (!pName || pName[0] != 'v' || pName[1] != 'k') return NULL;
123
124    // For entrypoints that loader must handle (ie non-dispatchable or create object)
125    // make sure the loader entrypoint is returned
126    const char *name = pName;
127    name += 2;
128    if (!strcmp(name, "GetDeviceProcAddr")) return (PFN_vkVoidFunction)vkGetDeviceProcAddr;
129    if (!strcmp(name, "DestroyDevice")) return (PFN_vkVoidFunction)vkDestroyDevice;
130    if (!strcmp(name, "GetDeviceQueue")) return (PFN_vkVoidFunction)vkGetDeviceQueue;
131    if (!strcmp(name, "AllocateCommandBuffers")) return (PFN_vkVoidFunction)vkAllocateCommandBuffers;
132
133    // Although CreateDevice is on device chain it's dispatchable object isn't
134    // a VkDevice or child of VkDevice so return NULL.
135    if (!strcmp(pName, "CreateDevice")) return NULL;
136
137    // Because vkGetDeviceQueue2 is a 1.1 entry point, we need to check if the apiVersion provided during instance creation is
138    // sufficient
139    if (!strcmp(name, "GetDeviceQueue2")) {
140        struct loader_device *dev = NULL;
141        uint32_t index = 0;
142        struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, &index);
143        if (NULL != icd_term && dev != NULL) {
144            const struct loader_instance *inst = icd_term->this_instance;
145            uint32_t api_version =
146                VK_MAKE_API_VERSION(0, inst->app_api_version.major, inst->app_api_version.minor, inst->app_api_version.patch);
147            return (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_1)
148                       ? NULL
149                       : (PFN_vkVoidFunction)vkGetDeviceQueue2;
150        }
151        return NULL;
152    }
153    // Return the dispatch table entrypoint for the fastest case
154    const VkLayerDispatchTable *disp_table = loader_get_dispatch(device);
155    if (disp_table == NULL) return NULL;
156
157    bool found_name = false;
158    void *addr = loader_lookup_device_dispatch_table(disp_table, pName, &found_name);
159    if (found_name) return addr;
160
161    if (disp_table->GetDeviceProcAddr == NULL) return NULL;
162    return disp_table->GetDeviceProcAddr(device, pName);
163}
164
165LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(const char *pLayerName,
166                                                                                    uint32_t *pPropertyCount,
167                                                                                    VkExtensionProperties *pProperties) {
168    LOADER_PLATFORM_THREAD_ONCE(&once_init, loader_initialize);
169
170    update_global_loader_settings();
171
172    // We know we need to call at least the terminator
173    VkResult res = VK_SUCCESS;
174    VkEnumerateInstanceExtensionPropertiesChain chain_tail = {
175        .header =
176            {
177                .type = VK_CHAIN_TYPE_ENUMERATE_INSTANCE_EXTENSION_PROPERTIES,
178                .version = VK_CURRENT_CHAIN_VERSION,
179                .size = sizeof(chain_tail),
180            },
181        .pfnNextLayer = &terminator_EnumerateInstanceExtensionProperties,
182        .pNextLink = NULL,
183    };
184    VkEnumerateInstanceExtensionPropertiesChain *chain_head = &chain_tail;
185
186    // Get the implicit layers
187    struct loader_layer_list layers = {0};
188    loader_platform_dl_handle *libs = NULL;
189    size_t lib_count = 0;
190    memset(&layers, 0, sizeof(layers));
191    struct loader_envvar_all_filters layer_filters = {0};
192
193    res = parse_layer_environment_var_filters(NULL, &layer_filters);
194    if (VK_SUCCESS != res) {
195        return res;
196    }
197
198    res = loader_scan_for_implicit_layers(NULL, &layers, &layer_filters);
199    if (VK_SUCCESS != res) {
200        return res;
201    }
202
203    res = loader_init_library_list(&layers, &libs);
204    if (VK_SUCCESS != res) {
205        return res;
206    }
207
208    // Prepend layers onto the chain if they implement this entry point
209    for (uint32_t i = 0; i < layers.count; ++i) {
210        // Skip this layer if it doesn't expose the entry-point
211        if (NULL == layers.list[i].pre_instance_functions.enumerate_instance_extension_properties) {
212            continue;
213        }
214
215        loader_platform_dl_handle layer_lib = loader_platform_open_library(layers.list[i].lib_name);
216        if (layer_lib == NULL) {
217            loader_log(NULL, VULKAN_LOADER_WARN_BIT | VULKAN_LOADER_LAYER_BIT, 0,
218                       "%s: Unable to load implicit layer library \"%s\"", __FUNCTION__, layers.list[i].lib_name);
219            continue;
220        }
221
222        libs[lib_count++] = layer_lib;
223        void *pfn = loader_platform_get_proc_address(layer_lib,
224                                                     layers.list[i].pre_instance_functions.enumerate_instance_extension_properties);
225        if (pfn == NULL) {
226            loader_log(NULL, VULKAN_LOADER_WARN_BIT | VULKAN_LOADER_LAYER_BIT, 0,
227                       "%s: Unable to resolve symbol \"%s\" in implicit layer library \"%s\"", __FUNCTION__,
228                       layers.list[i].pre_instance_functions.enumerate_instance_extension_properties, layers.list[i].lib_name);
229            continue;
230        }
231
232        VkEnumerateInstanceExtensionPropertiesChain *chain_link =
233            loader_alloc(NULL, sizeof(VkEnumerateInstanceExtensionPropertiesChain), VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
234        if (chain_link == NULL) {
235            res = VK_ERROR_OUT_OF_HOST_MEMORY;
236            break;
237        }
238        memset(chain_link, 0, sizeof(VkEnumerateInstanceLayerPropertiesChain));
239        chain_link->header.type = VK_CHAIN_TYPE_ENUMERATE_INSTANCE_EXTENSION_PROPERTIES;
240        chain_link->header.version = VK_CURRENT_CHAIN_VERSION;
241        chain_link->header.size = sizeof(*chain_link);
242        chain_link->pfnNextLayer = pfn;
243        chain_link->pNextLink = chain_head;
244
245        chain_head = chain_link;
246    }
247
248    // Call down the chain
249    if (res == VK_SUCCESS) {
250        res = chain_head->pfnNextLayer(chain_head->pNextLink, pLayerName, pPropertyCount, pProperties);
251    }
252
253    // Free up the layers
254    loader_delete_layer_list_and_properties(NULL, &layers);
255
256    // Tear down the chain
257    while (chain_head != &chain_tail) {
258        VkEnumerateInstanceExtensionPropertiesChain *holder = chain_head;
259        chain_head = (VkEnumerateInstanceExtensionPropertiesChain *)chain_head->pNextLink;
260        loader_free(NULL, holder);
261    }
262
263    // Close the dl handles
264    for (size_t i = 0; i < lib_count; ++i) {
265        loader_platform_close_library(libs[i]);
266    }
267    loader_free(NULL, libs);
268
269    return res;
270}
271
272LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties(uint32_t *pPropertyCount,
273                                                                                VkLayerProperties *pProperties) {
274    LOADER_PLATFORM_THREAD_ONCE(&once_init, loader_initialize);
275
276    update_global_loader_settings();
277
278    // We know we need to call at least the terminator
279    VkResult res = VK_SUCCESS;
280    VkEnumerateInstanceLayerPropertiesChain chain_tail = {
281        .header =
282            {
283                .type = VK_CHAIN_TYPE_ENUMERATE_INSTANCE_LAYER_PROPERTIES,
284                .version = VK_CURRENT_CHAIN_VERSION,
285                .size = sizeof(chain_tail),
286            },
287        .pfnNextLayer = &terminator_EnumerateInstanceLayerProperties,
288        .pNextLink = NULL,
289    };
290    VkEnumerateInstanceLayerPropertiesChain *chain_head = &chain_tail;
291
292    // Get the implicit layers
293    struct loader_layer_list layers;
294    loader_platform_dl_handle *libs = NULL;
295    size_t lib_count = 0;
296    memset(&layers, 0, sizeof(layers));
297    struct loader_envvar_all_filters layer_filters = {0};
298
299    res = parse_layer_environment_var_filters(NULL, &layer_filters);
300    if (VK_SUCCESS != res) {
301        return res;
302    }
303
304    res = loader_scan_for_implicit_layers(NULL, &layers, &layer_filters);
305    if (VK_SUCCESS != res) {
306        return res;
307    }
308
309    res = loader_init_library_list(&layers, &libs);
310    if (VK_SUCCESS != res) {
311        return res;
312    }
313
314    // Prepend layers onto the chain if they implement this entry point
315    for (uint32_t i = 0; i < layers.count; ++i) {
316        // Skip this layer if it doesn't expose the entry-point
317        if (NULL == layers.list[i].pre_instance_functions.enumerate_instance_layer_properties) {
318            continue;
319        }
320
321        loader_platform_dl_handle layer_lib = loader_platform_open_library(layers.list[i].lib_name);
322        if (layer_lib == NULL) {
323            loader_log(NULL, VULKAN_LOADER_WARN_BIT, 0, "%s: Unable to load implicit layer library \"%s\"", __FUNCTION__,
324                       layers.list[i].lib_name);
325            continue;
326        }
327
328        libs[lib_count++] = layer_lib;
329        void *pfn =
330            loader_platform_get_proc_address(layer_lib, layers.list[i].pre_instance_functions.enumerate_instance_layer_properties);
331        if (pfn == NULL) {
332            loader_log(NULL, VULKAN_LOADER_WARN_BIT, 0, "%s: Unable to resolve symbol \"%s\" in implicit layer library \"%s\"",
333                       __FUNCTION__, layers.list[i].pre_instance_functions.enumerate_instance_layer_properties,
334                       layers.list[i].lib_name);
335            continue;
336        }
337
338        VkEnumerateInstanceLayerPropertiesChain *chain_link =
339            loader_alloc(NULL, sizeof(VkEnumerateInstanceLayerPropertiesChain), VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
340        if (chain_link == NULL) {
341            res = VK_ERROR_OUT_OF_HOST_MEMORY;
342            break;
343        }
344        memset(chain_link, 0, sizeof(VkEnumerateInstanceLayerPropertiesChain));
345        chain_link->header.type = VK_CHAIN_TYPE_ENUMERATE_INSTANCE_LAYER_PROPERTIES;
346        chain_link->header.version = VK_CURRENT_CHAIN_VERSION;
347        chain_link->header.size = sizeof(*chain_link);
348        chain_link->pfnNextLayer = pfn;
349        chain_link->pNextLink = chain_head;
350
351        chain_head = chain_link;
352    }
353
354    // Call down the chain
355    if (res == VK_SUCCESS) {
356        res = chain_head->pfnNextLayer(chain_head->pNextLink, pPropertyCount, pProperties);
357    }
358
359    // Free up the layers
360    loader_delete_layer_list_and_properties(NULL, &layers);
361
362    // Tear down the chain
363    while (chain_head != &chain_tail) {
364        VkEnumerateInstanceLayerPropertiesChain *holder = chain_head;
365        chain_head = (VkEnumerateInstanceLayerPropertiesChain *)chain_head->pNextLink;
366        loader_free(NULL, holder);
367    }
368
369    // Close the dl handles
370    for (size_t i = 0; i < lib_count; ++i) {
371        loader_platform_close_library(libs[i]);
372    }
373    loader_free(NULL, libs);
374
375    return res;
376}
377
378LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceVersion(uint32_t *pApiVersion) {
379    LOADER_PLATFORM_THREAD_ONCE(&once_init, loader_initialize);
380
381    update_global_loader_settings();
382
383    if (NULL == pApiVersion) {
384        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
385                   "vkEnumerateInstanceVersion: \'pApiVersion\' must not be NULL "
386                   "(VUID-vkEnumerateInstanceVersion-pApiVersion-parameter");
387        // NOTE: This seems silly, but it's the only allowable failure
388        return VK_ERROR_OUT_OF_HOST_MEMORY;
389    }
390
391    // We know we need to call at least the terminator
392    VkResult res = VK_SUCCESS;
393    VkEnumerateInstanceVersionChain chain_tail = {
394        .header =
395            {
396                .type = VK_CHAIN_TYPE_ENUMERATE_INSTANCE_VERSION,
397                .version = VK_CURRENT_CHAIN_VERSION,
398                .size = sizeof(chain_tail),
399            },
400        .pfnNextLayer = &terminator_EnumerateInstanceVersion,
401        .pNextLink = NULL,
402    };
403    VkEnumerateInstanceVersionChain *chain_head = &chain_tail;
404
405    // Get the implicit layers
406    struct loader_layer_list layers;
407    loader_platform_dl_handle *libs = NULL;
408    size_t lib_count = 0;
409    memset(&layers, 0, sizeof(layers));
410    struct loader_envvar_all_filters layer_filters = {0};
411
412    res = parse_layer_environment_var_filters(NULL, &layer_filters);
413    if (VK_SUCCESS != res) {
414        return res;
415    }
416
417    res = loader_scan_for_implicit_layers(NULL, &layers, &layer_filters);
418    if (VK_SUCCESS != res) {
419        return res;
420    }
421
422    res = loader_init_library_list(&layers, &libs);
423    if (VK_SUCCESS != res) {
424        return res;
425    }
426
427    // Prepend layers onto the chain if they implement this entry point
428    for (uint32_t i = 0; i < layers.count; ++i) {
429        // Skip this layer if it doesn't expose the entry-point
430        if (NULL == layers.list[i].pre_instance_functions.enumerate_instance_version) {
431            continue;
432        }
433
434        loader_platform_dl_handle layer_lib = loader_platform_open_library(layers.list[i].lib_name);
435        if (layer_lib == NULL) {
436            loader_log(NULL, VULKAN_LOADER_WARN_BIT, 0, "%s: Unable to load implicit layer library \"%s\"", __FUNCTION__,
437                       layers.list[i].lib_name);
438            continue;
439        }
440
441        libs[lib_count++] = layer_lib;
442        void *pfn = loader_platform_get_proc_address(layer_lib, layers.list[i].pre_instance_functions.enumerate_instance_version);
443        if (pfn == NULL) {
444            loader_log(NULL, VULKAN_LOADER_WARN_BIT, 0, "%s: Unable to resolve symbol \"%s\" in implicit layer library \"%s\"",
445                       __FUNCTION__, layers.list[i].pre_instance_functions.enumerate_instance_version, layers.list[i].lib_name);
446            continue;
447        }
448
449        VkEnumerateInstanceVersionChain *chain_link =
450            loader_alloc(NULL, sizeof(VkEnumerateInstanceVersionChain), VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
451        if (chain_link == NULL) {
452            res = VK_ERROR_OUT_OF_HOST_MEMORY;
453            break;
454        }
455        memset(chain_link, 0, sizeof(VkEnumerateInstanceLayerPropertiesChain));
456        chain_link->header.type = VK_CHAIN_TYPE_ENUMERATE_INSTANCE_VERSION;
457        chain_link->header.version = VK_CURRENT_CHAIN_VERSION;
458        chain_link->header.size = sizeof(*chain_link);
459        chain_link->pfnNextLayer = pfn;
460        chain_link->pNextLink = chain_head;
461
462        chain_head = chain_link;
463    }
464
465    // Call down the chain
466    if (res == VK_SUCCESS) {
467        res = chain_head->pfnNextLayer(chain_head->pNextLink, pApiVersion);
468    }
469
470    // Free up the layers
471    loader_delete_layer_list_and_properties(NULL, &layers);
472
473    // Tear down the chain
474    while (chain_head != &chain_tail) {
475        VkEnumerateInstanceVersionChain *holder = chain_head;
476        chain_head = (VkEnumerateInstanceVersionChain *)chain_head->pNextLink;
477        loader_free(NULL, holder);
478    }
479
480    // Close the dl handles
481    for (size_t i = 0; i < lib_count; ++i) {
482        loader_platform_close_library(libs[i]);
483    }
484    loader_free(NULL, libs);
485
486    return res;
487}
488
489// Add the "instance-only" debug functions to the list of active debug functions
490// at the very end.  This way it doesn't get replaced by any new messengers
491void loader_add_instance_only_debug_funcs(struct loader_instance *ptr_instance) {
492    VkLayerDbgFunctionNode *cur_node = ptr_instance->current_dbg_function_head;
493    if (cur_node == NULL) {
494        ptr_instance->current_dbg_function_head = ptr_instance->instance_only_dbg_function_head;
495    } else {
496        while (cur_node != NULL) {
497            if (cur_node == ptr_instance->instance_only_dbg_function_head) {
498                // Already added
499                break;
500            }
501            // Last item
502            else if (cur_node->pNext == NULL) {
503                cur_node->pNext = ptr_instance->instance_only_dbg_function_head;
504            }
505            cur_node = cur_node->pNext;
506        }
507    }
508}
509
510// Remove the "instance-only" debug functions from the list of active debug functions.
511// It should be added after the last actual debug utils/debug report function.
512void loader_remove_instance_only_debug_funcs(struct loader_instance *ptr_instance) {
513    VkLayerDbgFunctionNode *cur_node = ptr_instance->current_dbg_function_head;
514
515    // Only thing in list is the instance only head
516    if (cur_node == ptr_instance->instance_only_dbg_function_head) {
517        ptr_instance->current_dbg_function_head = NULL;
518    }
519    while (cur_node != NULL) {
520        if (cur_node->pNext == ptr_instance->instance_only_dbg_function_head) {
521            cur_node->pNext = NULL;
522            break;
523        }
524        cur_node = cur_node->pNext;
525    }
526}
527
528LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo,
529                                                              const VkAllocationCallbacks *pAllocator, VkInstance *pInstance) {
530    struct loader_instance *ptr_instance = NULL;
531    VkInstance created_instance = VK_NULL_HANDLE;
532    VkResult res = VK_ERROR_INITIALIZATION_FAILED;
533    VkInstanceCreateInfo ici = {0};
534    struct loader_envvar_all_filters layer_filters = {0};
535
536    LOADER_PLATFORM_THREAD_ONCE(&once_init, loader_initialize);
537
538    if (pCreateInfo == NULL) {
539        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
540                   "vkCreateInstance: \'pCreateInfo\' is NULL (VUID-vkCreateInstance-pCreateInfo-parameter)");
541        goto out;
542    }
543    ici = *pCreateInfo;
544
545    if (pInstance == NULL) {
546        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
547                   "vkCreateInstance \'pInstance\' not valid (VUID-vkCreateInstance-pInstance-parameter)");
548        goto out;
549    }
550
551    ptr_instance =
552        (struct loader_instance *)loader_calloc(pAllocator, sizeof(struct loader_instance), VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
553
554    if (ptr_instance == NULL) {
555        res = VK_ERROR_OUT_OF_HOST_MEMORY;
556        goto out;
557    }
558
559    loader_platform_thread_lock_mutex(&loader_lock);
560    if (pAllocator) {
561        ptr_instance->alloc_callbacks = *pAllocator;
562    }
563    ptr_instance->magic = LOADER_MAGIC_NUMBER;
564
565    // Save the application version
566    if (NULL == pCreateInfo->pApplicationInfo || 0 == pCreateInfo->pApplicationInfo->apiVersion) {
567        ptr_instance->app_api_version = LOADER_VERSION_1_0_0;
568    } else {
569        ptr_instance->app_api_version = loader_make_version(pCreateInfo->pApplicationInfo->apiVersion);
570    }
571
572    // Look for one or more VK_EXT_debug_report or VK_EXT_debug_utils create info structures
573    // and setup a callback(s) for each one found.
574
575    // Handle cases of VK_EXT_debug_utils
576    // Setup the temporary messenger(s) here to catch early issues:
577    res = util_CreateDebugUtilsMessengers(ptr_instance, pCreateInfo->pNext, pAllocator);
578    if (VK_ERROR_OUT_OF_HOST_MEMORY == res) {
579        // Failure of setting up one or more of the messenger.
580        goto out;
581    }
582
583    // Handle cases of VK_EXT_debug_report
584    // Setup the temporary callback(s) here to catch early issues:
585    res = util_CreateDebugReportCallbacks(ptr_instance, pCreateInfo->pNext, pAllocator);
586    if (VK_ERROR_OUT_OF_HOST_MEMORY == res) {
587        // Failure of setting up one or more of the callback.
588        goto out;
589    }
590
591    VkResult settings_file_res = get_loader_settings(ptr_instance, &ptr_instance->settings);
592    if (settings_file_res == VK_ERROR_OUT_OF_HOST_MEMORY) {
593        res = settings_file_res;
594        goto out;
595    }
596    if (ptr_instance->settings.settings_active) {
597        log_settings(ptr_instance, &ptr_instance->settings);
598    }
599
600    // Providing an apiVersion less than VK_API_VERSION_1_0 but greater than zero prevents the validation layers from starting
601    if (pCreateInfo->pApplicationInfo && pCreateInfo->pApplicationInfo->apiVersion < VK_API_VERSION_1_0) {
602        loader_log(ptr_instance, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT, 0,
603                   "VkInstanceCreateInfo::pApplicationInfo::apiVersion has value of %u which is not permitted. If apiVersion is "
604                   "not 0, then it must be "
605                   "greater than or equal to the value of VK_API_VERSION_1_0 [VUID-VkApplicationInfo-apiVersion]",
606                   pCreateInfo->pApplicationInfo->apiVersion);
607    }
608
609    // Check the VkInstanceCreateInfoFlags wether to allow the portability enumeration flag
610    if ((pCreateInfo->flags & VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR) == 1) {
611        ptr_instance->portability_enumeration_flag_bit_set = true;
612    }
613    // Make sure the extension has been enabled
614    if (pCreateInfo->ppEnabledExtensionNames) {
615        for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
616            if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME) == 0) {
617                ptr_instance->portability_enumeration_extension_enabled = true;
618                if (ptr_instance->portability_enumeration_flag_bit_set) {
619                    ptr_instance->portability_enumeration_enabled = true;
620                    loader_log(ptr_instance, VULKAN_LOADER_INFO_BIT, 0,
621                               "Portability enumeration bit was set, enumerating portability drivers.");
622                }
623            }
624        }
625    }
626
627    // Make sure the application provided API version has the correct variant
628    if (NULL != pCreateInfo->pApplicationInfo) {
629        uint32_t variant_version = VK_API_VERSION_VARIANT(pCreateInfo->pApplicationInfo->apiVersion);
630        const uint32_t expected_variant = 0;
631        if (expected_variant != variant_version) {
632            loader_log(ptr_instance, VULKAN_LOADER_WARN_BIT, 0,
633                       "vkCreateInstance: The API Variant specified in pCreateInfo->pApplicationInfo.apiVersion is %d instead of "
634                       "the expected value of %d.",
635                       variant_version, expected_variant);
636        }
637    }
638
639    res = parse_layer_environment_var_filters(ptr_instance, &layer_filters);
640    if (VK_SUCCESS != res) {
641        goto out;
642    }
643
644    // Due to implicit layers need to get layer list even if
645    // enabledLayerCount == 0 and VK_INSTANCE_LAYERS is unset. For now always
646    // get layer list via loader_scan_for_layers().
647    memset(&ptr_instance->instance_layer_list, 0, sizeof(ptr_instance->instance_layer_list));
648    res = loader_scan_for_layers(ptr_instance, &ptr_instance->instance_layer_list, &layer_filters);
649    if (VK_SUCCESS != res) {
650        goto out;
651    }
652
653    // Validate the app requested layers to be enabled
654    if (pCreateInfo->enabledLayerCount > 0) {
655        res = loader_validate_layers(ptr_instance, pCreateInfo->enabledLayerCount, pCreateInfo->ppEnabledLayerNames,
656                                     &ptr_instance->instance_layer_list);
657        if (res != VK_SUCCESS) {
658            goto out;
659        }
660    }
661
662    // Scan/discover all System and Environment Variable ICD libraries
663    bool skipped_portability_drivers = false;
664    res = loader_icd_scan(ptr_instance, &ptr_instance->icd_tramp_list, pCreateInfo, &skipped_portability_drivers);
665    if (res == VK_ERROR_OUT_OF_HOST_MEMORY) {
666        goto out;
667    }
668
669    if (ptr_instance->icd_tramp_list.count == 0) {
670        // No drivers found
671        if (skipped_portability_drivers) {
672            if (ptr_instance->portability_enumeration_extension_enabled && !ptr_instance->portability_enumeration_flag_bit_set) {
673                loader_log(ptr_instance, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_DRIVER_BIT, 0,
674                           "vkCreateInstance: Found drivers that contain devices which support the portability subset, but "
675                           "the instance does not enumerate portability drivers! Applications that wish to enumerate portability "
676                           "drivers must set the VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR bit in the VkInstanceCreateInfo "
677                           "flags.");
678            } else if (ptr_instance->portability_enumeration_flag_bit_set &&
679                       !ptr_instance->portability_enumeration_extension_enabled) {
680                loader_log(ptr_instance, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_DRIVER_BIT, 0,
681                           "VkInstanceCreateInfo: If flags has the VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR bit set, the "
682                           "list of enabled extensions in ppEnabledExtensionNames must contain VK_KHR_portability_enumeration "
683                           "[VUID-VkInstanceCreateInfo-flags-06559 ]"
684                           "Applications that wish to enumerate portability drivers must enable the VK_KHR_portability_enumeration "
685                           "instance extension.");
686            } else {
687                loader_log(ptr_instance, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_DRIVER_BIT, 0,
688                           "vkCreateInstance: Found drivers that contain devices which support the portability subset, but "
689                           "the instance does not enumerate portability drivers! Applications that wish to enumerate portability "
690                           "drivers must set the VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR bit in the VkInstanceCreateInfo "
691                           "flags and enable the VK_KHR_portability_enumeration instance extension.");
692            }
693        }
694        loader_log(ptr_instance, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_DRIVER_BIT, 0, "vkCreateInstance: Found no drivers!");
695        res = VK_ERROR_INCOMPATIBLE_DRIVER;
696        goto out;
697    }
698
699    // Get extensions from all ICD's, merge so no duplicates, then validate
700    res = loader_get_icd_loader_instance_extensions(ptr_instance, &ptr_instance->icd_tramp_list, &ptr_instance->ext_list);
701    if (res != VK_SUCCESS) {
702        goto out;
703    }
704    res = loader_validate_instance_extensions(ptr_instance, &ptr_instance->ext_list, &ptr_instance->instance_layer_list,
705                                              &layer_filters, &ici);
706    if (res != VK_SUCCESS) {
707        goto out;
708    }
709
710    ptr_instance->disp = loader_instance_heap_alloc(ptr_instance, sizeof(struct loader_instance_dispatch_table),
711                                                    VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
712    if (ptr_instance->disp == NULL) {
713        loader_log(ptr_instance, VULKAN_LOADER_ERROR_BIT, 0,
714                   "vkCreateInstance:  Failed to allocate Loader's full Instance dispatch table.");
715        res = VK_ERROR_OUT_OF_HOST_MEMORY;
716        goto out;
717    }
718    memcpy(&ptr_instance->disp->layer_inst_disp, &instance_disp, sizeof(instance_disp));
719
720    loader_platform_thread_lock_mutex(&loader_global_instance_list_lock);
721    ptr_instance->next = loader.instances;
722    loader.instances = ptr_instance;
723    loader_platform_thread_unlock_mutex(&loader_global_instance_list_lock);
724
725    // Activate any layers on instance chain
726    res = loader_enable_instance_layers(ptr_instance, &ici, &ptr_instance->instance_layer_list, &layer_filters);
727    if (res != VK_SUCCESS) {
728        goto out;
729    }
730
731    created_instance = (VkInstance)ptr_instance;
732    res = loader_create_instance_chain(&ici, pAllocator, ptr_instance, &created_instance);
733
734    if (VK_SUCCESS == res) {
735        // Check for enabled extensions here to setup the loader structures so the loader knows what extensions
736        // it needs to worry about.
737        // We do it in the terminator and again above the layers here since we may think different extensions
738        // are enabled than what's down in the terminator.
739        // This is why we don't clear inside of these function calls.
740        // The clearing should actually be handled by the overall memset of the pInstance structure above.
741        wsi_create_instance(ptr_instance, &ici);
742        check_for_enabled_debug_extensions(ptr_instance, &ici);
743        extensions_create_instance(ptr_instance, &ici);
744
745        *pInstance = (VkInstance)ptr_instance;
746
747        // Finally have the layers in place and everyone has seen
748        // the CreateInstance command go by. This allows the layer's
749        // GetInstanceProcAddr functions to return valid extension functions
750        // if enabled.
751        loader_activate_instance_layer_extensions(ptr_instance, created_instance);
752        ptr_instance->instance_finished_creation = true;
753    } else if (VK_ERROR_EXTENSION_NOT_PRESENT == res && !ptr_instance->create_terminator_invalid_extension) {
754        loader_log(ptr_instance, VULKAN_LOADER_WARN_BIT, 0,
755                   "vkCreateInstance: Layer returning invalid extension error not triggered by ICD/Loader (Policy #LLP_LAYER_17).");
756    }
757
758out:
759
760    if (NULL != ptr_instance) {
761        if (res != VK_SUCCESS) {
762            loader_platform_thread_lock_mutex(&loader_global_instance_list_lock);
763            // error path, should clean everything up
764            if (loader.instances == ptr_instance) {
765                loader.instances = ptr_instance->next;
766            }
767            loader_platform_thread_unlock_mutex(&loader_global_instance_list_lock);
768
769            free_loader_settings(ptr_instance, &ptr_instance->settings);
770
771            loader_instance_heap_free(ptr_instance, ptr_instance->disp);
772            // Remove any created VK_EXT_debug_report or VK_EXT_debug_utils items
773            destroy_debug_callbacks_chain(ptr_instance, pAllocator);
774
775            loader_destroy_pointer_layer_list(ptr_instance, &ptr_instance->expanded_activated_layer_list);
776            loader_destroy_pointer_layer_list(ptr_instance, &ptr_instance->app_activated_layer_list);
777
778            loader_delete_layer_list_and_properties(ptr_instance, &ptr_instance->instance_layer_list);
779            loader_scanned_icd_clear(ptr_instance, &ptr_instance->icd_tramp_list);
780            loader_destroy_generic_list(ptr_instance, (struct loader_generic_list *)&ptr_instance->ext_list);
781
782            // Free any icd_terms that were created.
783            // If an OOM occurs from a layer, terminator_CreateInstance won't be reached where this kind of
784            // cleanup normally occurs
785            struct loader_icd_term *icd_term = NULL;
786            while (NULL != ptr_instance->icd_terms) {
787                icd_term = ptr_instance->icd_terms;
788                // Call destroy Instance on each driver in case we successfully called down the chain but failed on
789                // our way back out of it.
790                if (icd_term->instance) {
791                    icd_term->dispatch.DestroyInstance(icd_term->instance, pAllocator);
792                }
793                icd_term->instance = VK_NULL_HANDLE;
794                ptr_instance->icd_terms = icd_term->next;
795                loader_icd_destroy(ptr_instance, icd_term, pAllocator);
796            }
797
798            free_string_list(ptr_instance, &ptr_instance->enabled_layer_names);
799
800            loader_instance_heap_free(ptr_instance, ptr_instance);
801        } else {
802            // success path, swap out created debug callbacks out so they aren't used until instance destruction
803            loader_remove_instance_only_debug_funcs(ptr_instance);
804        }
805        // Only unlock when ptr_instance isn't NULL, as if it is, the above code didn't make it to when loader_lock was locked.
806        loader_platform_thread_unlock_mutex(&loader_lock);
807    }
808
809    return res;
810}
811
812LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) {
813    const VkLayerInstanceDispatchTable *disp;
814    struct loader_instance *ptr_instance = NULL;
815
816    if (instance == VK_NULL_HANDLE) {
817        return;
818    }
819    loader_platform_thread_lock_mutex(&loader_lock);
820
821    ptr_instance = loader_get_instance(instance);
822    if (ptr_instance == NULL) {
823        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
824                   "vkDestroyInstance: Invalid instance [VUID-vkDestroyInstance-instance-parameter]");
825        loader_platform_thread_unlock_mutex(&loader_lock);
826        abort(); /* Intentionally fail so user can correct issue. */
827    }
828
829    if (pAllocator) {
830        ptr_instance->alloc_callbacks = *pAllocator;
831    }
832
833    // Remove any callbacks that weren't cleaned up by the application
834    destroy_debug_callbacks_chain(ptr_instance, pAllocator);
835
836    // Swap in the debug callbacks created during instance creation
837    loader_add_instance_only_debug_funcs(ptr_instance);
838
839    disp = loader_get_instance_layer_dispatch(instance);
840    disp->DestroyInstance(ptr_instance->instance, pAllocator);
841
842    free_loader_settings(ptr_instance, &ptr_instance->settings);
843
844    loader_destroy_pointer_layer_list(ptr_instance, &ptr_instance->expanded_activated_layer_list);
845    loader_destroy_pointer_layer_list(ptr_instance, &ptr_instance->app_activated_layer_list);
846
847    loader_delete_layer_list_and_properties(ptr_instance, &ptr_instance->instance_layer_list);
848
849    free_string_list(ptr_instance, &ptr_instance->enabled_layer_names);
850
851    if (ptr_instance->phys_devs_tramp) {
852        for (uint32_t i = 0; i < ptr_instance->phys_dev_count_tramp; i++) {
853            loader_instance_heap_free(ptr_instance, ptr_instance->phys_devs_tramp[i]);
854        }
855        loader_instance_heap_free(ptr_instance, ptr_instance->phys_devs_tramp);
856    }
857
858    // Destroy the debug callbacks created during instance creation
859    destroy_debug_callbacks_chain(ptr_instance, pAllocator);
860
861    loader_instance_heap_free(ptr_instance, ptr_instance->disp);
862    loader_instance_heap_free(ptr_instance, ptr_instance);
863    loader_platform_thread_unlock_mutex(&loader_lock);
864
865    // Unload preloaded layers, so if vkEnumerateInstanceExtensionProperties or vkCreateInstance is called again, the ICD's are
866    // up to date
867    loader_unload_preloaded_icds();
868}
869
870LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount,
871                                                                        VkPhysicalDevice *pPhysicalDevices) {
872    VkResult res = VK_SUCCESS;
873    struct loader_instance *inst;
874
875    loader_platform_thread_lock_mutex(&loader_lock);
876
877    inst = loader_get_instance(instance);
878    if (NULL == inst) {
879        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
880                   "vkEnumeratePhysicalDevices: Invalid instance [VUID-vkEnumeratePhysicalDevices-instance-parameter]");
881        abort(); /* Intentionally fail so user can correct issue. */
882    }
883
884    if (NULL == pPhysicalDeviceCount) {
885        loader_log(inst, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
886                   "vkEnumeratePhysicalDevices: Received NULL pointer for physical device count return value. "
887                   "[VUID-vkEnumeratePhysicalDevices-pPhysicalDeviceCount-parameter]");
888        res = VK_ERROR_INITIALIZATION_FAILED;
889        goto out;
890    }
891
892    // Call down the chain to get the physical device info
893    res = inst->disp->layer_inst_disp.EnumeratePhysicalDevices(inst->instance, pPhysicalDeviceCount, pPhysicalDevices);
894
895    if (NULL != pPhysicalDevices && (VK_SUCCESS == res || VK_INCOMPLETE == res)) {
896        // Wrap the PhysDev object for loader usage, return wrapped objects
897        VkResult update_res = setup_loader_tramp_phys_devs(inst, *pPhysicalDeviceCount, pPhysicalDevices);
898        if (VK_SUCCESS != update_res) {
899            res = update_res;
900        }
901    }
902
903out:
904
905    loader_platform_thread_unlock_mutex(&loader_lock);
906    return res;
907}
908
909LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice,
910                                                                     VkPhysicalDeviceFeatures *pFeatures) {
911    const VkLayerInstanceDispatchTable *disp;
912    VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
913    if (VK_NULL_HANDLE == unwrapped_phys_dev) {
914        loader_log(
915            NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
916            "vkGetPhysicalDeviceFeatures: Invalid physicalDevice [VUID-vkGetPhysicalDeviceFeatures-physicalDevice-parameter]");
917        abort(); /* Intentionally fail so user can correct issue. */
918    }
919    disp = loader_get_instance_layer_dispatch(physicalDevice);
920    disp->GetPhysicalDeviceFeatures(unwrapped_phys_dev, pFeatures);
921}
922
923LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format,
924                                                                             VkFormatProperties *pFormatInfo) {
925    const VkLayerInstanceDispatchTable *disp;
926    VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
927    if (VK_NULL_HANDLE == unwrapped_phys_dev) {
928        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
929                   "vkGetPhysicalDeviceFormatProperties: Invalid physicalDevice "
930                   "[VUID-vkGetPhysicalDeviceFormatProperties-physicalDevice-parameter]");
931        abort(); /* Intentionally fail so user can correct issue. */
932    }
933    disp = loader_get_instance_layer_dispatch(physicalDevice);
934    disp->GetPhysicalDeviceFormatProperties(unwrapped_phys_dev, format, pFormatInfo);
935}
936
937LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceImageFormatProperties(
938    VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage,
939    VkImageCreateFlags flags, VkImageFormatProperties *pImageFormatProperties) {
940    const VkLayerInstanceDispatchTable *disp;
941    VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
942    if (VK_NULL_HANDLE == unwrapped_phys_dev) {
943        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
944                   "vkGetPhysicalDeviceImageFormatProperties: Invalid physicalDevice "
945                   "[VUID-vkGetPhysicalDeviceImageFormatProperties-physicalDevice-parameter]");
946        abort(); /* Intentionally fail so user can correct issue. */
947    }
948    disp = loader_get_instance_layer_dispatch(physicalDevice);
949    return disp->GetPhysicalDeviceImageFormatProperties(unwrapped_phys_dev, format, type, tiling, usage, flags,
950                                                        pImageFormatProperties);
951}
952
953LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,
954                                                                       VkPhysicalDeviceProperties *pProperties) {
955    const VkLayerInstanceDispatchTable *disp;
956    VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
957    if (VK_NULL_HANDLE == unwrapped_phys_dev) {
958        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
959                   "vkGetPhysicalDeviceProperties: Invalid physicalDevice "
960                   "[VUID-vkGetPhysicalDeviceProperties-physicalDevice-parameter]");
961        abort(); /* Intentionally fail so user can correct issue. */
962    }
963    disp = loader_get_instance_layer_dispatch(physicalDevice);
964    disp->GetPhysicalDeviceProperties(unwrapped_phys_dev, pProperties);
965}
966
967LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice,
968                                                                                  uint32_t *pQueueFamilyPropertyCount,
969                                                                                  VkQueueFamilyProperties *pQueueProperties) {
970    const VkLayerInstanceDispatchTable *disp;
971    VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
972    if (VK_NULL_HANDLE == unwrapped_phys_dev) {
973        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
974                   "vkGetPhysicalDeviceQueueFamilyProperties: Invalid physicalDevice "
975                   "[VUID-vkGetPhysicalDeviceQueueFamilyProperties-physicalDevice-parameter]");
976        abort(); /* Intentionally fail so user can correct issue. */
977    }
978    disp = loader_get_instance_layer_dispatch(physicalDevice);
979    disp->GetPhysicalDeviceQueueFamilyProperties(unwrapped_phys_dev, pQueueFamilyPropertyCount, pQueueProperties);
980}
981
982LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceMemoryProperties(VkPhysicalDevice physicalDevice,
983                                                                             VkPhysicalDeviceMemoryProperties *pMemoryProperties) {
984    const VkLayerInstanceDispatchTable *disp;
985    VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
986    if (VK_NULL_HANDLE == unwrapped_phys_dev) {
987        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
988                   "vkGetPhysicalDeviceMemoryProperties: Invalid physicalDevice "
989                   "[VUID-vkGetPhysicalDeviceMemoryProperties-physicalDevice-parameter]");
990        abort(); /* Intentionally fail so user can correct issue. */
991    }
992    disp = loader_get_instance_layer_dispatch(physicalDevice);
993    disp->GetPhysicalDeviceMemoryProperties(unwrapped_phys_dev, pMemoryProperties);
994}
995
996LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo,
997                                                            const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) {
998    if (VK_NULL_HANDLE == loader_unwrap_physical_device(physicalDevice)) {
999        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1000                   "vkCreateDevice: Invalid physicalDevice [VUID-vkCreateDevice-physicalDevice-parameter]");
1001        abort(); /* Intentionally fail so user can correct issue. */
1002    }
1003    loader_platform_thread_lock_mutex(&loader_lock);
1004    VkResult res = loader_layer_create_device(NULL, physicalDevice, pCreateInfo, pAllocator, pDevice, NULL, NULL);
1005    loader_platform_thread_unlock_mutex(&loader_lock);
1006    return res;
1007}
1008
1009LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
1010    const VkLayerDispatchTable *disp;
1011
1012    if (device == VK_NULL_HANDLE) {
1013        return;
1014    }
1015    disp = loader_get_dispatch(device);
1016    if (NULL == disp) {
1017        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1018                   "vkDestroyDevice: Invalid device [VUID-vkDestroyDevice-device-parameter]");
1019        abort(); /* Intentionally fail so user can correct issue. */
1020    }
1021
1022    loader_platform_thread_lock_mutex(&loader_lock);
1023
1024    loader_layer_destroy_device(device, pAllocator, disp->DestroyDevice);
1025
1026    loader_platform_thread_unlock_mutex(&loader_lock);
1027}
1028
1029LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
1030                                                                                  const char *pLayerName, uint32_t *pPropertyCount,
1031                                                                                  VkExtensionProperties *pProperties) {
1032    VkResult res = VK_SUCCESS;
1033    struct loader_physical_device_tramp *phys_dev;
1034    const VkLayerInstanceDispatchTable *disp;
1035    phys_dev = (struct loader_physical_device_tramp *)physicalDevice;
1036    if (VK_NULL_HANDLE == physicalDevice || PHYS_TRAMP_MAGIC_NUMBER != phys_dev->magic) {
1037        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1038                   "vkEnumerateDeviceExtensionProperties: Invalid physicalDevice "
1039                   "[VUID-vkEnumerateDeviceExtensionProperties-physicalDevice-parameter]");
1040        abort(); /* Intentionally fail so user can correct issue. */
1041    }
1042
1043    loader_platform_thread_lock_mutex(&loader_lock);
1044
1045    // always pass this call down the instance chain which will terminate
1046    // in the ICD. This allows layers to filter the extensions coming back
1047    // up the chain. In the terminator we look up layer extensions from the
1048    // manifest file if it wasn't provided by the layer itself.
1049    disp = loader_get_instance_layer_dispatch(physicalDevice);
1050    res = disp->EnumerateDeviceExtensionProperties(phys_dev->phys_dev, pLayerName, pPropertyCount, pProperties);
1051
1052    loader_platform_thread_unlock_mutex(&loader_lock);
1053    return res;
1054}
1055
1056LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice,
1057                                                                              uint32_t *pPropertyCount,
1058                                                                              VkLayerProperties *pProperties) {
1059    uint32_t copy_size;
1060    struct loader_physical_device_tramp *phys_dev;
1061    loader_platform_thread_lock_mutex(&loader_lock);
1062
1063    // Don't dispatch this call down the instance chain, want all device layers
1064    // enumerated and instance chain may not contain all device layers
1065    // TODO re-evaluate the above statement we maybe able to start calling
1066    // down the chain
1067
1068    phys_dev = (struct loader_physical_device_tramp *)physicalDevice;
1069    if (VK_NULL_HANDLE == physicalDevice || PHYS_TRAMP_MAGIC_NUMBER != phys_dev->magic) {
1070        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1071                   "vkEnumerateDeviceLayerProperties: Invalid physicalDevice "
1072                   "[VUID-vkEnumerateDeviceLayerProperties-physicalDevice-parameter]");
1073        loader_platform_thread_unlock_mutex(&loader_lock);
1074        abort(); /* Intentionally fail so user can correct issue. */
1075    }
1076
1077    const struct loader_instance *inst = phys_dev->this_instance;
1078
1079    uint32_t count = inst->app_activated_layer_list.count;
1080    if (count == 0 || pProperties == NULL) {
1081        *pPropertyCount = count;
1082        loader_platform_thread_unlock_mutex(&loader_lock);
1083        return VK_SUCCESS;
1084    }
1085
1086    copy_size = (*pPropertyCount < count) ? *pPropertyCount : count;
1087    for (uint32_t i = 0; i < copy_size; i++) {
1088        memcpy(&pProperties[i], &(inst->app_activated_layer_list.list[i]->info), sizeof(VkLayerProperties));
1089    }
1090    *pPropertyCount = copy_size;
1091
1092    if (copy_size < count) {
1093        loader_platform_thread_unlock_mutex(&loader_lock);
1094        return VK_INCOMPLETE;
1095    }
1096
1097    loader_platform_thread_unlock_mutex(&loader_lock);
1098    return VK_SUCCESS;
1099}
1100
1101LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetDeviceQueue(VkDevice device, uint32_t queueNodeIndex, uint32_t queueIndex,
1102                                                          VkQueue *pQueue) {
1103    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1104    if (NULL == disp) {
1105        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1106                   "vkGetDeviceQueue: Invalid device [VUID-vkGetDeviceQueue-device-parameter]");
1107        abort(); /* Intentionally fail so user can correct issue. */
1108    }
1109
1110    disp->GetDeviceQueue(device, queueNodeIndex, queueIndex, pQueue);
1111    if (pQueue != NULL && *pQueue != NULL) {
1112        loader_set_dispatch(*pQueue, disp);
1113    }
1114}
1115
1116LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkQueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits,
1117                                                           VkFence fence) {
1118    const VkLayerDispatchTable *disp = loader_get_dispatch(queue);
1119    if (NULL == disp) {
1120        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1121                   "vkQueueSubmit: Invalid queue [VUID-vkQueueSubmit-queue-parameter]");
1122        abort(); /* Intentionally fail so user can correct issue. */
1123    }
1124
1125    return disp->QueueSubmit(queue, submitCount, pSubmits, fence);
1126}
1127
1128LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkQueueWaitIdle(VkQueue queue) {
1129    const VkLayerDispatchTable *disp = loader_get_dispatch(queue);
1130    if (NULL == disp) {
1131        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1132                   "vkQueueWaitIdle: Invalid queue [VUID-vkQueueWaitIdle-queue-parameter]");
1133        abort(); /* Intentionally fail so user can correct issue. */
1134    }
1135
1136    return disp->QueueWaitIdle(queue);
1137}
1138
1139LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkDeviceWaitIdle(VkDevice device) {
1140    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1141    if (NULL == disp) {
1142        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1143                   "vkDeviceWaitIdle: Invalid device [VUID-vkDeviceWaitIdle-device-parameter]");
1144        abort(); /* Intentionally fail so user can correct issue. */
1145    }
1146
1147    return disp->DeviceWaitIdle(device);
1148}
1149
1150LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkAllocateMemory(VkDevice device, const VkMemoryAllocateInfo *pAllocateInfo,
1151                                                              const VkAllocationCallbacks *pAllocator, VkDeviceMemory *pMemory) {
1152    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1153    if (NULL == disp) {
1154        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1155                   "vkAllocateMemory: Invalid device [VUID-vkAllocateMemory-device-parameter]");
1156        abort(); /* Intentionally fail so user can correct issue. */
1157    }
1158
1159    return disp->AllocateMemory(device, pAllocateInfo, pAllocator, pMemory);
1160}
1161
1162LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkFreeMemory(VkDevice device, VkDeviceMemory mem,
1163                                                      const VkAllocationCallbacks *pAllocator) {
1164    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1165    if (NULL == disp) {
1166        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1167                   "vkFreeMemory: Invalid device [VUID-vkFreeMemory-device-parameter]");
1168        abort(); /* Intentionally fail so user can correct issue. */
1169    }
1170
1171    disp->FreeMemory(device, mem, pAllocator);
1172}
1173
1174LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkMapMemory(VkDevice device, VkDeviceMemory mem, VkDeviceSize offset,
1175                                                         VkDeviceSize size, VkFlags flags, void **ppData) {
1176    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1177    if (NULL == disp) {
1178        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1179                   "vkMapMemory: Invalid device [VUID-vkMapMemory-device-parameter]");
1180        abort(); /* Intentionally fail so user can correct issue. */
1181    }
1182
1183    return disp->MapMemory(device, mem, offset, size, flags, ppData);
1184}
1185
1186LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkUnmapMemory(VkDevice device, VkDeviceMemory mem) {
1187    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1188    if (NULL == disp) {
1189        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1190                   "vkUnmapMemory: Invalid device [VUID-vkUnmapMemory-device-parameter]");
1191        abort(); /* Intentionally fail so user can correct issue. */
1192    }
1193
1194    disp->UnmapMemory(device, mem);
1195}
1196
1197LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkFlushMappedMemoryRanges(VkDevice device, uint32_t memoryRangeCount,
1198                                                                       const VkMappedMemoryRange *pMemoryRanges) {
1199    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1200    if (NULL == disp) {
1201        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1202                   "vkFlushMappedMemoryRanges: Invalid device [VUID-vkFlushMappedMemoryRanges-device-parameter]");
1203        abort(); /* Intentionally fail so user can correct issue. */
1204    }
1205
1206    return disp->FlushMappedMemoryRanges(device, memoryRangeCount, pMemoryRanges);
1207}
1208
1209LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkInvalidateMappedMemoryRanges(VkDevice device, uint32_t memoryRangeCount,
1210                                                                            const VkMappedMemoryRange *pMemoryRanges) {
1211    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1212    if (NULL == disp) {
1213        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1214                   "vkInvalidateMappedMemoryRanges: Invalid device [VUID-vkInvalidateMappedMemoryRanges-device-parameter]");
1215        abort(); /* Intentionally fail so user can correct issue. */
1216    }
1217
1218    return disp->InvalidateMappedMemoryRanges(device, memoryRangeCount, pMemoryRanges);
1219}
1220
1221LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetDeviceMemoryCommitment(VkDevice device, VkDeviceMemory memory,
1222                                                                     VkDeviceSize *pCommittedMemoryInBytes) {
1223    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1224    if (NULL == disp) {
1225        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1226                   "vkGetDeviceMemoryCommitment: Invalid device [VUID-vkGetDeviceMemoryCommitment-device-parameter]");
1227        abort(); /* Intentionally fail so user can correct issue. */
1228    }
1229
1230    disp->GetDeviceMemoryCommitment(device, memory, pCommittedMemoryInBytes);
1231}
1232
1233LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkBindBufferMemory(VkDevice device, VkBuffer buffer, VkDeviceMemory mem,
1234                                                                VkDeviceSize offset) {
1235    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1236    if (NULL == disp) {
1237        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1238                   "vkBindBufferMemory: Invalid device [VUID-vkBindBufferMemory-device-parameter]");
1239        abort(); /* Intentionally fail so user can correct issue. */
1240    }
1241
1242    return disp->BindBufferMemory(device, buffer, mem, offset);
1243}
1244
1245LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkBindImageMemory(VkDevice device, VkImage image, VkDeviceMemory mem,
1246                                                               VkDeviceSize offset) {
1247    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1248    if (NULL == disp) {
1249        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1250                   "vkBindImageMemory: Invalid device [VUID-vkBindImageMemory-device-parameter]");
1251        abort(); /* Intentionally fail so user can correct issue. */
1252    }
1253
1254    return disp->BindImageMemory(device, image, mem, offset);
1255}
1256
1257LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetBufferMemoryRequirements(VkDevice device, VkBuffer buffer,
1258                                                                       VkMemoryRequirements *pMemoryRequirements) {
1259    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1260    if (NULL == disp) {
1261        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1262                   "vkGetBufferMemoryRequirements: Invalid device [VUID-vkGetBufferMemoryRequirements-device-parameter]");
1263        abort(); /* Intentionally fail so user can correct issue. */
1264    }
1265
1266    disp->GetBufferMemoryRequirements(device, buffer, pMemoryRequirements);
1267}
1268
1269LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetImageMemoryRequirements(VkDevice device, VkImage image,
1270                                                                      VkMemoryRequirements *pMemoryRequirements) {
1271    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1272    if (NULL == disp) {
1273        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1274                   "vkGetImageMemoryRequirements: Invalid device [VUID-vkGetImageMemoryRequirements-device-parameter]");
1275        abort(); /* Intentionally fail so user can correct issue. */
1276    }
1277
1278    disp->GetImageMemoryRequirements(device, image, pMemoryRequirements);
1279}
1280
1281LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1282vkGetImageSparseMemoryRequirements(VkDevice device, VkImage image, uint32_t *pSparseMemoryRequirementCount,
1283                                   VkSparseImageMemoryRequirements *pSparseMemoryRequirements) {
1284    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1285    if (NULL == disp) {
1286        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1287                   "vkGetImageSparseMemoryRequirements: Invalid device [VUID-vkGetImageSparseMemoryRequirements-device-parameter]");
1288        abort(); /* Intentionally fail so user can correct issue. */
1289    }
1290
1291    disp->GetImageSparseMemoryRequirements(device, image, pSparseMemoryRequirementCount, pSparseMemoryRequirements);
1292}
1293
1294LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceSparseImageFormatProperties(
1295    VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkSampleCountFlagBits samples, VkImageUsageFlags usage,
1296    VkImageTiling tiling, uint32_t *pPropertyCount, VkSparseImageFormatProperties *pProperties) {
1297    const VkLayerInstanceDispatchTable *disp;
1298    VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
1299    if (VK_NULL_HANDLE == unwrapped_phys_dev) {
1300        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1301                   "vkGetPhysicalDeviceSparseImageFormatProperties: Invalid physicalDevice "
1302                   "[VUID-vkGetPhysicalDeviceSparseImageFormatProperties-physicalDevice-parameter]");
1303        abort(); /* Intentionally fail so user can correct issue. */
1304    }
1305
1306    disp = loader_get_instance_layer_dispatch(physicalDevice);
1307    disp->GetPhysicalDeviceSparseImageFormatProperties(unwrapped_phys_dev, format, type, samples, usage, tiling, pPropertyCount,
1308                                                       pProperties);
1309}
1310
1311LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkQueueBindSparse(VkQueue queue, uint32_t bindInfoCount,
1312                                                               const VkBindSparseInfo *pBindInfo, VkFence fence) {
1313    const VkLayerDispatchTable *disp = loader_get_dispatch(queue);
1314    if (NULL == disp) {
1315        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1316                   "vkQueueBindSparse: Invalid queue [VUID-vkQueueBindSparse-queue-parameter]");
1317        abort(); /* Intentionally fail so user can correct issue. */
1318    }
1319
1320    return disp->QueueBindSparse(queue, bindInfoCount, pBindInfo, fence);
1321}
1322
1323LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateFence(VkDevice device, const VkFenceCreateInfo *pCreateInfo,
1324                                                           const VkAllocationCallbacks *pAllocator, VkFence *pFence) {
1325    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1326    if (NULL == disp) {
1327        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1328                   "vkCreateFence: Invalid device [VUID-vkCreateFence-device-parameter]");
1329        abort(); /* Intentionally fail so user can correct issue. */
1330    }
1331
1332    return disp->CreateFence(device, pCreateInfo, pAllocator, pFence);
1333}
1334
1335LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyFence(VkDevice device, VkFence fence, const VkAllocationCallbacks *pAllocator) {
1336    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1337    if (NULL == disp) {
1338        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1339                   "vkDestroyFence: Invalid device [VUID-vkDestroyFence-device-parameter]");
1340        abort(); /* Intentionally fail so user can correct issue. */
1341    }
1342
1343    disp->DestroyFence(device, fence, pAllocator);
1344}
1345
1346LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkResetFences(VkDevice device, uint32_t fenceCount, const VkFence *pFences) {
1347    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1348    if (NULL == disp) {
1349        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1350                   "vkResetFences: Invalid device [VUID-vkResetFences-device-parameter]");
1351        abort(); /* Intentionally fail so user can correct issue. */
1352    }
1353
1354    return disp->ResetFences(device, fenceCount, pFences);
1355}
1356
1357LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetFenceStatus(VkDevice device, VkFence fence) {
1358    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1359    if (NULL == disp) {
1360        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1361                   "vkGetFenceStatus: Invalid device [VUID-vkGetFenceStatus-device-parameter]");
1362        abort(); /* Intentionally fail so user can correct issue. */
1363    }
1364
1365    return disp->GetFenceStatus(device, fence);
1366}
1367
1368LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkWaitForFences(VkDevice device, uint32_t fenceCount, const VkFence *pFences,
1369                                                             VkBool32 waitAll, uint64_t timeout) {
1370    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1371    if (NULL == disp) {
1372        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1373                   "vkWaitForFences: Invalid device [VUID-vkWaitForFences-device-parameter]");
1374        abort(); /* Intentionally fail so user can correct issue. */
1375    }
1376
1377    return disp->WaitForFences(device, fenceCount, pFences, waitAll, timeout);
1378}
1379
1380LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateSemaphore(VkDevice device, const VkSemaphoreCreateInfo *pCreateInfo,
1381                                                               const VkAllocationCallbacks *pAllocator, VkSemaphore *pSemaphore) {
1382    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1383    if (NULL == disp) {
1384        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1385                   "vkCreateSemaphore: Invalid device [VUID-vkCreateSemaphore-device-parameter]");
1386        abort(); /* Intentionally fail so user can correct issue. */
1387    }
1388
1389    return disp->CreateSemaphore(device, pCreateInfo, pAllocator, pSemaphore);
1390}
1391
1392LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroySemaphore(VkDevice device, VkSemaphore semaphore,
1393                                                            const VkAllocationCallbacks *pAllocator) {
1394    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1395    if (NULL == disp) {
1396        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1397                   "vkDestroySemaphore: Invalid device [VUID-vkDestroySemaphore-device-parameter]");
1398        abort(); /* Intentionally fail so user can correct issue. */
1399    }
1400
1401    disp->DestroySemaphore(device, semaphore, pAllocator);
1402}
1403
1404LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateEvent(VkDevice device, const VkEventCreateInfo *pCreateInfo,
1405                                                           const VkAllocationCallbacks *pAllocator, VkEvent *pEvent) {
1406    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1407    if (NULL == disp) {
1408        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1409                   "vkCreateEvent: Invalid device [VUID-vkCreateEvent-device-parameter]");
1410        abort(); /* Intentionally fail so user can correct issue. */
1411    }
1412
1413    return disp->CreateEvent(device, pCreateInfo, pAllocator, pEvent);
1414}
1415
1416LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyEvent(VkDevice device, VkEvent event, const VkAllocationCallbacks *pAllocator) {
1417    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1418    if (NULL == disp) {
1419        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1420                   "vkDestroyEvent: Invalid device [VUID-vkDestroyEvent-device-parameter]");
1421        abort(); /* Intentionally fail so user can correct issue. */
1422    }
1423
1424    disp->DestroyEvent(device, event, pAllocator);
1425}
1426
1427LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetEventStatus(VkDevice device, VkEvent event) {
1428    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1429    if (NULL == disp) {
1430        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1431                   "vkGetEventStatus: Invalid device [VUID-vkGetEventStatus-device-parameter]");
1432        abort(); /* Intentionally fail so user can correct issue. */
1433    }
1434
1435    return disp->GetEventStatus(device, event);
1436}
1437
1438LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkSetEvent(VkDevice device, VkEvent event) {
1439    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1440    if (NULL == disp) {
1441        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1442                   "vkSetEvent: Invalid device [VUID-vkSetEvent-device-parameter]");
1443        abort(); /* Intentionally fail so user can correct issue. */
1444    }
1445
1446    return disp->SetEvent(device, event);
1447}
1448
1449LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkResetEvent(VkDevice device, VkEvent event) {
1450    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1451    if (NULL == disp) {
1452        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1453                   "vkResetEvent: Invalid device [VUID-vkResetEvent-device-parameter]");
1454        abort(); /* Intentionally fail so user can correct issue. */
1455    }
1456
1457    return disp->ResetEvent(device, event);
1458}
1459
1460LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateQueryPool(VkDevice device, const VkQueryPoolCreateInfo *pCreateInfo,
1461                                                               const VkAllocationCallbacks *pAllocator, VkQueryPool *pQueryPool) {
1462    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1463    if (NULL == disp) {
1464        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1465                   "vkCreateQueryPool: Invalid device [VUID-vkCreateQueryPool-device-parameter]");
1466        abort(); /* Intentionally fail so user can correct issue. */
1467    }
1468
1469    return disp->CreateQueryPool(device, pCreateInfo, pAllocator, pQueryPool);
1470}
1471
1472LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyQueryPool(VkDevice device, VkQueryPool queryPool,
1473                                                            const VkAllocationCallbacks *pAllocator) {
1474    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1475    if (NULL == disp) {
1476        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1477                   "vkDestroyQueryPool: Invalid device [VUID-vkDestroyQueryPool-device-parameter]");
1478        abort(); /* Intentionally fail so user can correct issue. */
1479    }
1480
1481    disp->DestroyQueryPool(device, queryPool, pAllocator);
1482}
1483
1484LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetQueryPoolResults(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery,
1485                                                                   uint32_t queryCount, size_t dataSize, void *pData,
1486                                                                   VkDeviceSize stride, VkQueryResultFlags flags) {
1487    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1488    if (NULL == disp) {
1489        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1490                   "vkGetQueryPoolResults: Invalid device [VUID-vkGetQueryPoolResults-device-parameter]");
1491        abort(); /* Intentionally fail so user can correct issue. */
1492    }
1493
1494    return disp->GetQueryPoolResults(device, queryPool, firstQuery, queryCount, dataSize, pData, stride, flags);
1495}
1496
1497LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateBuffer(VkDevice device, const VkBufferCreateInfo *pCreateInfo,
1498                                                            const VkAllocationCallbacks *pAllocator, VkBuffer *pBuffer) {
1499    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1500    if (NULL == disp) {
1501        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1502                   "vkCreateBuffer: Invalid device [VUID-vkCreateBuffer-device-parameter]");
1503        abort(); /* Intentionally fail so user can correct issue. */
1504    }
1505
1506    return disp->CreateBuffer(device, pCreateInfo, pAllocator, pBuffer);
1507}
1508
1509LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyBuffer(VkDevice device, VkBuffer buffer,
1510                                                         const VkAllocationCallbacks *pAllocator) {
1511    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1512    if (NULL == disp) {
1513        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1514                   "vkDestroyBuffer: Invalid device [VUID-vkDestroyBuffer-device-parameter]");
1515        abort(); /* Intentionally fail so user can correct issue. */
1516    }
1517
1518    disp->DestroyBuffer(device, buffer, pAllocator);
1519}
1520
1521LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateBufferView(VkDevice device, const VkBufferViewCreateInfo *pCreateInfo,
1522                                                                const VkAllocationCallbacks *pAllocator, VkBufferView *pView) {
1523    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1524    if (NULL == disp) {
1525        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1526                   "vkCreateBufferView: Invalid device [VUID-vkCreateBufferView-device-parameter]");
1527        abort(); /* Intentionally fail so user can correct issue. */
1528    }
1529
1530    return disp->CreateBufferView(device, pCreateInfo, pAllocator, pView);
1531}
1532
1533LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyBufferView(VkDevice device, VkBufferView bufferView,
1534                                                             const VkAllocationCallbacks *pAllocator) {
1535    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1536    if (NULL == disp) {
1537        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1538                   "vkDestroyBufferView: Invalid device [VUID-vkDestroyBufferView-device-parameter]");
1539        abort(); /* Intentionally fail so user can correct issue. */
1540    }
1541
1542    disp->DestroyBufferView(device, bufferView, pAllocator);
1543}
1544
1545LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateImage(VkDevice device, const VkImageCreateInfo *pCreateInfo,
1546                                                           const VkAllocationCallbacks *pAllocator, VkImage *pImage) {
1547    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1548    if (NULL == disp) {
1549        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1550                   "vkCreateImage: Invalid device [VUID-vkCreateImage-device-parameter]");
1551        abort(); /* Intentionally fail so user can correct issue. */
1552    }
1553
1554    return disp->CreateImage(device, pCreateInfo, pAllocator, pImage);
1555}
1556
1557LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyImage(VkDevice device, VkImage image, const VkAllocationCallbacks *pAllocator) {
1558    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1559    if (NULL == disp) {
1560        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1561                   "vkDestroyImage: Invalid device [VUID-vkDestroyImage-device-parameter]");
1562        abort(); /* Intentionally fail so user can correct issue. */
1563    }
1564
1565    disp->DestroyImage(device, image, pAllocator);
1566}
1567
1568LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetImageSubresourceLayout(VkDevice device, VkImage image,
1569                                                                     const VkImageSubresource *pSubresource,
1570                                                                     VkSubresourceLayout *pLayout) {
1571    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1572    if (NULL == disp) {
1573        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1574                   "vkGetImageSubresourceLayout: Invalid device [VUID-vkGetImageSubresourceLayout-device-parameter]");
1575        abort(); /* Intentionally fail so user can correct issue. */
1576    }
1577
1578    disp->GetImageSubresourceLayout(device, image, pSubresource, pLayout);
1579}
1580
1581LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateImageView(VkDevice device, const VkImageViewCreateInfo *pCreateInfo,
1582                                                               const VkAllocationCallbacks *pAllocator, VkImageView *pView) {
1583    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1584    if (NULL == disp) {
1585        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1586                   "vkCreateImageView: Invalid device [VUID-vkCreateImageView-device-parameter]");
1587        abort(); /* Intentionally fail so user can correct issue. */
1588    }
1589
1590    return disp->CreateImageView(device, pCreateInfo, pAllocator, pView);
1591}
1592
1593LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyImageView(VkDevice device, VkImageView imageView,
1594                                                            const VkAllocationCallbacks *pAllocator) {
1595    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1596    if (NULL == disp) {
1597        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1598                   "vkDestroyImageView: Invalid device [VUID-vkDestroyImageView-device-parameter]");
1599        abort(); /* Intentionally fail so user can correct issue. */
1600    }
1601
1602    disp->DestroyImageView(device, imageView, pAllocator);
1603}
1604
1605LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateShaderModule(VkDevice device, const VkShaderModuleCreateInfo *pCreateInfo,
1606                                                                  const VkAllocationCallbacks *pAllocator,
1607                                                                  VkShaderModule *pShader) {
1608    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1609    if (NULL == disp) {
1610        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1611                   "vkCreateShaderModule: Invalid device [VUID-vkCreateShaderModule-device-parameter]");
1612        abort(); /* Intentionally fail so user can correct issue. */
1613    }
1614
1615    return disp->CreateShaderModule(device, pCreateInfo, pAllocator, pShader);
1616}
1617
1618LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyShaderModule(VkDevice device, VkShaderModule shaderModule,
1619                                                               const VkAllocationCallbacks *pAllocator) {
1620    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1621    if (NULL == disp) {
1622        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1623                   "vkDestroyShaderModule: Invalid device [VUID-vkDestroyShaderModule-device-parameter]");
1624        abort(); /* Intentionally fail so user can correct issue. */
1625    }
1626
1627    disp->DestroyShaderModule(device, shaderModule, pAllocator);
1628}
1629
1630LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreatePipelineCache(VkDevice device, const VkPipelineCacheCreateInfo *pCreateInfo,
1631                                                                   const VkAllocationCallbacks *pAllocator,
1632                                                                   VkPipelineCache *pPipelineCache) {
1633    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1634    if (NULL == disp) {
1635        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1636                   "vkCreatePipelineCache: Invalid device [VUID-vkCreatePipelineCache-device-parameter]");
1637        abort(); /* Intentionally fail so user can correct issue. */
1638    }
1639
1640    return disp->CreatePipelineCache(device, pCreateInfo, pAllocator, pPipelineCache);
1641}
1642
1643LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyPipelineCache(VkDevice device, VkPipelineCache pipelineCache,
1644                                                                const VkAllocationCallbacks *pAllocator) {
1645    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1646    if (NULL == disp) {
1647        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1648                   "vkDestroyPipelineCache: Invalid device [VUID-vkDestroyPipelineCache-device-parameter]");
1649        abort(); /* Intentionally fail so user can correct issue. */
1650    }
1651
1652    disp->DestroyPipelineCache(device, pipelineCache, pAllocator);
1653}
1654
1655LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPipelineCacheData(VkDevice device, VkPipelineCache pipelineCache,
1656                                                                    size_t *pDataSize, void *pData) {
1657    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1658    if (NULL == disp) {
1659        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1660                   "vkGetPipelineCacheData: Invalid device [VUID-vkGetPipelineCacheData-device-parameter]");
1661        abort(); /* Intentionally fail so user can correct issue. */
1662    }
1663
1664    return disp->GetPipelineCacheData(device, pipelineCache, pDataSize, pData);
1665}
1666
1667LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkMergePipelineCaches(VkDevice device, VkPipelineCache dstCache,
1668                                                                   uint32_t srcCacheCount, const VkPipelineCache *pSrcCaches) {
1669    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1670    if (NULL == disp) {
1671        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1672                   "vkMergePipelineCaches: Invalid device [VUID-vkMergePipelineCaches-device-parameter]");
1673        abort(); /* Intentionally fail so user can correct issue. */
1674    }
1675
1676    return disp->MergePipelineCaches(device, dstCache, srcCacheCount, pSrcCaches);
1677}
1678
1679LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache,
1680                                                                       uint32_t createInfoCount,
1681                                                                       const VkGraphicsPipelineCreateInfo *pCreateInfos,
1682                                                                       const VkAllocationCallbacks *pAllocator,
1683                                                                       VkPipeline *pPipelines) {
1684    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1685    if (NULL == disp) {
1686        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1687                   "vkCreateGraphicsPipelines: Invalid device [VUID-vkCreateGraphicsPipelines-device-parameter]");
1688        abort(); /* Intentionally fail so user can correct issue. */
1689    }
1690
1691    return disp->CreateGraphicsPipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines);
1692}
1693
1694LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache,
1695                                                                      uint32_t createInfoCount,
1696                                                                      const VkComputePipelineCreateInfo *pCreateInfos,
1697                                                                      const VkAllocationCallbacks *pAllocator,
1698                                                                      VkPipeline *pPipelines) {
1699    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1700    if (NULL == disp) {
1701        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1702                   "vkCreateComputePipelines: Invalid device [VUID-vkCreateComputePipelines-device-parameter]");
1703        abort(); /* Intentionally fail so user can correct issue. */
1704    }
1705
1706    return disp->CreateComputePipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines);
1707}
1708
1709LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyPipeline(VkDevice device, VkPipeline pipeline,
1710                                                           const VkAllocationCallbacks *pAllocator) {
1711    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1712    if (NULL == disp) {
1713        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1714                   "vkDestroyPipeline: Invalid device [VUID-vkDestroyPipeline-device-parameter]");
1715        abort(); /* Intentionally fail so user can correct issue. */
1716    }
1717
1718    disp->DestroyPipeline(device, pipeline, pAllocator);
1719}
1720
1721LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreatePipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo *pCreateInfo,
1722                                                                    const VkAllocationCallbacks *pAllocator,
1723                                                                    VkPipelineLayout *pPipelineLayout) {
1724    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1725    if (NULL == disp) {
1726        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1727                   "vkCreatePipelineLayout: Invalid device [VUID-vkCreatePipelineLayout-device-parameter]");
1728        abort(); /* Intentionally fail so user can correct issue. */
1729    }
1730
1731    return disp->CreatePipelineLayout(device, pCreateInfo, pAllocator, pPipelineLayout);
1732}
1733
1734LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyPipelineLayout(VkDevice device, VkPipelineLayout pipelineLayout,
1735                                                                 const VkAllocationCallbacks *pAllocator) {
1736    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1737    if (NULL == disp) {
1738        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1739                   "vkDestroyPipelineLayout: Invalid device [VUID-vkDestroyPipelineLayout-device-parameter]");
1740        abort(); /* Intentionally fail so user can correct issue. */
1741    }
1742
1743    disp->DestroyPipelineLayout(device, pipelineLayout, pAllocator);
1744}
1745
1746LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateSampler(VkDevice device, const VkSamplerCreateInfo *pCreateInfo,
1747                                                             const VkAllocationCallbacks *pAllocator, VkSampler *pSampler) {
1748    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1749    if (NULL == disp) {
1750        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1751                   "vkCreateSampler: Invalid device [VUID-vkCreateSampler-device-parameter]");
1752        abort(); /* Intentionally fail so user can correct issue. */
1753    }
1754
1755    return disp->CreateSampler(device, pCreateInfo, pAllocator, pSampler);
1756}
1757
1758LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroySampler(VkDevice device, VkSampler sampler,
1759                                                          const VkAllocationCallbacks *pAllocator) {
1760    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1761    if (NULL == disp) {
1762        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1763                   "vkDestroySampler: Invalid device [VUID-vkDestroySampler-device-parameter]");
1764        abort(); /* Intentionally fail so user can correct issue. */
1765    }
1766
1767    disp->DestroySampler(device, sampler, pAllocator);
1768}
1769
1770LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDescriptorSetLayout(VkDevice device,
1771                                                                         const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
1772                                                                         const VkAllocationCallbacks *pAllocator,
1773                                                                         VkDescriptorSetLayout *pSetLayout) {
1774    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1775    if (NULL == disp) {
1776        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1777                   "vkCreateDescriptorSetLayout: Invalid device [VUID-vkCreateDescriptorSetLayout-device-parameter]");
1778        abort(); /* Intentionally fail so user can correct issue. */
1779    }
1780
1781    return disp->CreateDescriptorSetLayout(device, pCreateInfo, pAllocator, pSetLayout);
1782}
1783
1784LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyDescriptorSetLayout(VkDevice device, VkDescriptorSetLayout descriptorSetLayout,
1785                                                                      const VkAllocationCallbacks *pAllocator) {
1786    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1787    if (NULL == disp) {
1788        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1789                   "vkDestroyDescriptorSetLayout: Invalid device [VUID-vkDestroyDescriptorSetLayout-device-parameter]");
1790        abort(); /* Intentionally fail so user can correct issue. */
1791    }
1792
1793    disp->DestroyDescriptorSetLayout(device, descriptorSetLayout, pAllocator);
1794}
1795
1796LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDescriptorPool(VkDevice device, const VkDescriptorPoolCreateInfo *pCreateInfo,
1797                                                                    const VkAllocationCallbacks *pAllocator,
1798                                                                    VkDescriptorPool *pDescriptorPool) {
1799    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1800    if (NULL == disp) {
1801        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1802                   "vkCreateDescriptorPool: Invalid device [VUID-vkCreateDescriptorPool-device-parameter]");
1803        abort(); /* Intentionally fail so user can correct issue. */
1804    }
1805
1806    return disp->CreateDescriptorPool(device, pCreateInfo, pAllocator, pDescriptorPool);
1807}
1808
1809LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
1810                                                                 const VkAllocationCallbacks *pAllocator) {
1811    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1812    if (NULL == disp) {
1813        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1814                   "vkDestroyDescriptorPool: Invalid device [VUID-vkDestroyDescriptorPool-device-parameter]");
1815        abort(); /* Intentionally fail so user can correct issue. */
1816    }
1817
1818    disp->DestroyDescriptorPool(device, descriptorPool, pAllocator);
1819}
1820
1821LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
1822                                                                   VkDescriptorPoolResetFlags flags) {
1823    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1824    if (NULL == disp) {
1825        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1826                   "vkResetDescriptorPool: Invalid device [VUID-vkResetDescriptorPool-device-parameter]");
1827        abort(); /* Intentionally fail so user can correct issue. */
1828    }
1829
1830    return disp->ResetDescriptorPool(device, descriptorPool, flags);
1831}
1832
1833LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkAllocateDescriptorSets(VkDevice device,
1834                                                                      const VkDescriptorSetAllocateInfo *pAllocateInfo,
1835                                                                      VkDescriptorSet *pDescriptorSets) {
1836    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1837    if (NULL == disp) {
1838        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1839                   "vkAllocateDescriptorSets: Invalid device [VUID-vkAllocateDescriptorSets-device-parameter]");
1840        abort(); /* Intentionally fail so user can correct issue. */
1841    }
1842
1843    return disp->AllocateDescriptorSets(device, pAllocateInfo, pDescriptorSets);
1844}
1845
1846LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool,
1847                                                                  uint32_t descriptorSetCount,
1848                                                                  const VkDescriptorSet *pDescriptorSets) {
1849    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1850    if (NULL == disp) {
1851        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1852                   "vkFreeDescriptorSets: Invalid device [VUID-vkFreeDescriptorSets-device-parameter]");
1853        abort(); /* Intentionally fail so user can correct issue. */
1854    }
1855
1856    return disp->FreeDescriptorSets(device, descriptorPool, descriptorSetCount, pDescriptorSets);
1857}
1858
1859LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkUpdateDescriptorSets(VkDevice device, uint32_t descriptorWriteCount,
1860                                                                const VkWriteDescriptorSet *pDescriptorWrites,
1861                                                                uint32_t descriptorCopyCount,
1862                                                                const VkCopyDescriptorSet *pDescriptorCopies) {
1863    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1864    if (NULL == disp) {
1865        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1866                   "vkUpdateDescriptorSets: Invalid device [VUID-vkUpdateDescriptorSets-device-parameter]");
1867        abort(); /* Intentionally fail so user can correct issue. */
1868    }
1869
1870    disp->UpdateDescriptorSets(device, descriptorWriteCount, pDescriptorWrites, descriptorCopyCount, pDescriptorCopies);
1871}
1872
1873LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateFramebuffer(VkDevice device, const VkFramebufferCreateInfo *pCreateInfo,
1874                                                                 const VkAllocationCallbacks *pAllocator,
1875                                                                 VkFramebuffer *pFramebuffer) {
1876    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1877    if (NULL == disp) {
1878        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1879                   "vkCreateFramebuffer: Invalid device [VUID-vkCreateFramebuffer-device-parameter]");
1880        abort(); /* Intentionally fail so user can correct issue. */
1881    }
1882
1883    return disp->CreateFramebuffer(device, pCreateInfo, pAllocator, pFramebuffer);
1884}
1885
1886LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyFramebuffer(VkDevice device, VkFramebuffer framebuffer,
1887                                                              const VkAllocationCallbacks *pAllocator) {
1888    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1889    if (NULL == disp) {
1890        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1891                   "vkDestroyFramebuffer: Invalid device [VUID-vkDestroyFramebuffer-device-parameter]");
1892        abort(); /* Intentionally fail so user can correct issue. */
1893    }
1894
1895    disp->DestroyFramebuffer(device, framebuffer, pAllocator);
1896}
1897
1898LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo *pCreateInfo,
1899                                                                const VkAllocationCallbacks *pAllocator,
1900                                                                VkRenderPass *pRenderPass) {
1901    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1902    if (NULL == disp) {
1903        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1904                   "vkCreateRenderPass: Invalid device [VUID-vkCreateRenderPass-device-parameter]");
1905        abort(); /* Intentionally fail so user can correct issue. */
1906    }
1907
1908    return disp->CreateRenderPass(device, pCreateInfo, pAllocator, pRenderPass);
1909}
1910
1911LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyRenderPass(VkDevice device, VkRenderPass renderPass,
1912                                                             const VkAllocationCallbacks *pAllocator) {
1913    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1914    if (NULL == disp) {
1915        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1916                   "vkDestroyRenderPass: Invalid device [VUID-vkDestroyRenderPass-device-parameter]");
1917        abort(); /* Intentionally fail so user can correct issue. */
1918    }
1919
1920    disp->DestroyRenderPass(device, renderPass, pAllocator);
1921}
1922
1923LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetRenderAreaGranularity(VkDevice device, VkRenderPass renderPass,
1924                                                                    VkExtent2D *pGranularity) {
1925    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1926    if (NULL == disp) {
1927        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1928                   "vkGetRenderAreaGranularity: Invalid device [VUID-vkGetRenderAreaGranularity-device-parameter]");
1929        abort(); /* Intentionally fail so user can correct issue. */
1930    }
1931
1932    disp->GetRenderAreaGranularity(device, renderPass, pGranularity);
1933}
1934
1935LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateCommandPool(VkDevice device, const VkCommandPoolCreateInfo *pCreateInfo,
1936                                                                 const VkAllocationCallbacks *pAllocator,
1937                                                                 VkCommandPool *pCommandPool) {
1938    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1939    if (NULL == disp) {
1940        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1941                   "vkCreateCommandPool: Invalid device [VUID-vkCreateCommandPool-device-parameter]");
1942        abort(); /* Intentionally fail so user can correct issue. */
1943    }
1944
1945    return disp->CreateCommandPool(device, pCreateInfo, pAllocator, pCommandPool);
1946}
1947
1948LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyCommandPool(VkDevice device, VkCommandPool commandPool,
1949                                                              const VkAllocationCallbacks *pAllocator) {
1950    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1951    if (NULL == disp) {
1952        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1953                   "vkDestroyCommandPool: Invalid device [VUID-vkDestroyCommandPool-device-parameter]");
1954        abort(); /* Intentionally fail so user can correct issue. */
1955    }
1956
1957    disp->DestroyCommandPool(device, commandPool, pAllocator);
1958}
1959
1960LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkResetCommandPool(VkDevice device, VkCommandPool commandPool,
1961                                                                VkCommandPoolResetFlags flags) {
1962    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1963    if (NULL == disp) {
1964        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1965                   "vkResetCommandPool: Invalid device [VUID-vkResetCommandPool-device-parameter]");
1966        abort(); /* Intentionally fail so user can correct issue. */
1967    }
1968
1969    return disp->ResetCommandPool(device, commandPool, flags);
1970}
1971
1972LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkAllocateCommandBuffers(VkDevice device,
1973                                                                      const VkCommandBufferAllocateInfo *pAllocateInfo,
1974                                                                      VkCommandBuffer *pCommandBuffers) {
1975    VkResult res;
1976    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1977    if (NULL == disp) {
1978        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1979                   "vkAllocateCommandBuffers: Invalid device [VUID-vkAllocateCommandBuffers-device-parameter]");
1980        abort(); /* Intentionally fail so user can correct issue. */
1981    }
1982
1983    res = disp->AllocateCommandBuffers(device, pAllocateInfo, pCommandBuffers);
1984    if (res == VK_SUCCESS) {
1985        for (uint32_t i = 0; i < pAllocateInfo->commandBufferCount; i++) {
1986            if (pCommandBuffers[i]) {
1987                loader_set_dispatch(pCommandBuffers[i], disp);
1988            }
1989        }
1990    }
1991
1992    return res;
1993}
1994
1995LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkFreeCommandBuffers(VkDevice device, VkCommandPool commandPool,
1996                                                              uint32_t commandBufferCount, const VkCommandBuffer *pCommandBuffers) {
1997    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
1998    if (NULL == disp) {
1999        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2000                   "vkFreeCommandBuffers: Invalid device [VUID-vkFreeCommandBuffers-device-parameter]");
2001        abort(); /* Intentionally fail so user can correct issue. */
2002    }
2003
2004    disp->FreeCommandBuffers(device, commandPool, commandBufferCount, pCommandBuffers);
2005}
2006
2007LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkBeginCommandBuffer(VkCommandBuffer commandBuffer,
2008                                                                  const VkCommandBufferBeginInfo *pBeginInfo) {
2009    const VkLayerDispatchTable *disp;
2010
2011    disp = loader_get_dispatch(commandBuffer);
2012    if (NULL == disp) {
2013        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2014                   "vkBeginCommandBuffer: Invalid commandBuffer [VUID-vkBeginCommandBuffer-commandBuffer-parameter]");
2015        abort(); /* Intentionally fail so user can correct issue. */
2016    }
2017
2018    return disp->BeginCommandBuffer(commandBuffer, pBeginInfo);
2019}
2020
2021LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEndCommandBuffer(VkCommandBuffer commandBuffer) {
2022    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
2023    if (NULL == disp) {
2024        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2025                   "vkEndCommandBuffer: Invalid commandBuffer [VUID-vkEndCommandBuffer-commandBuffer-parameter]");
2026        abort(); /* Intentionally fail so user can correct issue. */
2027    }
2028
2029    return disp->EndCommandBuffer(commandBuffer);
2030}
2031
2032LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkResetCommandBuffer(VkCommandBuffer commandBuffer, VkCommandBufferResetFlags flags) {
2033    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
2034    if (NULL == disp) {
2035        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2036                   "vkResetCommandBuffer: Invalid commandBuffer [VUID-vkResetCommandBuffer-commandBuffer-parameter]");
2037        abort(); /* Intentionally fail so user can correct issue. */
2038    }
2039
2040    return disp->ResetCommandBuffer(commandBuffer, flags);
2041}
2042
2043LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdBindPipeline(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint,
2044                                                           VkPipeline pipeline) {
2045    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
2046    if (NULL == disp) {
2047        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2048                   "vkCmdBindPipeline: Invalid commandBuffer [VUID-vkCmdBindPipeline-commandBuffer-parameter]");
2049        abort(); /* Intentionally fail so user can correct issue. */
2050    }
2051
2052    disp->CmdBindPipeline(commandBuffer, pipelineBindPoint, pipeline);
2053}
2054
2055LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetViewport(VkCommandBuffer commandBuffer, uint32_t firstViewport,
2056                                                          uint32_t viewportCount, const VkViewport *pViewports) {
2057    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
2058    if (NULL == disp) {
2059        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2060                   "vkCmdSetViewport: Invalid commandBuffer [VUID-vkCmdSetViewport-commandBuffer-parameter]");
2061        abort(); /* Intentionally fail so user can correct issue. */
2062    }
2063
2064    disp->CmdSetViewport(commandBuffer, firstViewport, viewportCount, pViewports);
2065}
2066
2067LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetScissor(VkCommandBuffer commandBuffer, uint32_t firstScissor,
2068                                                         uint32_t scissorCount, const VkRect2D *pScissors) {
2069    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
2070    if (NULL == disp) {
2071        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2072                   "vkCmdSetScissor: Invalid commandBuffer [VUID-vkCmdSetScissor-commandBuffer-parameter]");
2073        abort(); /* Intentionally fail so user can correct issue. */
2074    }
2075
2076    disp->CmdSetScissor(commandBuffer, firstScissor, scissorCount, pScissors);
2077}
2078
2079LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetLineWidth(VkCommandBuffer commandBuffer, float lineWidth) {
2080    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
2081    if (NULL == disp) {
2082        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2083                   "vkCmdSetLineWidth: Invalid commandBuffer [VUID-vkCmdSetLineWidth-commandBuffer-parameter]");
2084        abort(); /* Intentionally fail so user can correct issue. */
2085    }
2086
2087    disp->CmdSetLineWidth(commandBuffer, lineWidth);
2088}
2089
2090LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBias(VkCommandBuffer commandBuffer, float depthBiasConstantFactor,
2091                                                           float depthBiasClamp, float depthBiasSlopeFactor) {
2092    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
2093    if (NULL == disp) {
2094        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2095                   "vkCmdSetDepthBias: Invalid commandBuffer [VUID-vkCmdSetDepthBias-commandBuffer-parameter]");
2096        abort(); /* Intentionally fail so user can correct issue. */
2097    }
2098
2099    disp->CmdSetDepthBias(commandBuffer, depthBiasConstantFactor, depthBiasClamp, depthBiasSlopeFactor);
2100}
2101
2102LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetBlendConstants(VkCommandBuffer commandBuffer, const float blendConstants[4]) {
2103    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
2104    if (NULL == disp) {
2105        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2106                   "vkCmdSetBlendConstants: Invalid commandBuffer [VUID-vkCmdSetBlendConstants-commandBuffer-parameter]");
2107        abort(); /* Intentionally fail so user can correct issue. */
2108    }
2109
2110    disp->CmdSetBlendConstants(commandBuffer, blendConstants);
2111}
2112
2113LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBounds(VkCommandBuffer commandBuffer, float minDepthBounds,
2114                                                             float maxDepthBounds) {
2115    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
2116    if (NULL == disp) {
2117        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2118                   "vkCmdSetDepthBounds: Invalid commandBuffer [VUID-vkCmdSetDepthBounds-commandBuffer-parameter]");
2119        abort(); /* Intentionally fail so user can correct issue. */
2120    }
2121
2122    disp->CmdSetDepthBounds(commandBuffer, minDepthBounds, maxDepthBounds);
2123}
2124
2125LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilCompareMask(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask,
2126                                                                    uint32_t compareMask) {
2127    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
2128    if (NULL == disp) {
2129        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2130                   "vkCmdSetStencilCompareMask: Invalid commandBuffer [VUID-vkCmdSetStencilCompareMask-commandBuffer-parameter]");
2131        abort(); /* Intentionally fail so user can correct issue. */
2132    }
2133
2134    disp->CmdSetStencilCompareMask(commandBuffer, faceMask, compareMask);
2135}
2136
2137LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilWriteMask(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask,
2138                                                                  uint32_t writeMask) {
2139    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
2140    if (NULL == disp) {
2141        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2142                   "vkCmdSetStencilWriteMask: Invalid commandBuffer [VUID-vkCmdSetStencilWriteMask-commandBuffer-parameter]");
2143        abort(); /* Intentionally fail so user can correct issue. */
2144    }
2145
2146    disp->CmdSetStencilWriteMask(commandBuffer, faceMask, writeMask);
2147}
2148
2149LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilReference(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask,
2150                                                                  uint32_t reference) {
2151    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
2152    if (NULL == disp) {
2153        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2154                   "vkCmdSetStencilReference: Invalid commandBuffer [VUID-vkCmdSetStencilReference-commandBuffer-parameter]");
2155        abort(); /* Intentionally fail so user can correct issue. */
2156    }
2157
2158    disp->CmdSetStencilReference(commandBuffer, faceMask, reference);
2159}
2160
2161LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdBindDescriptorSets(VkCommandBuffer commandBuffer,
2162                                                                 VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout,
2163                                                                 uint32_t firstSet, uint32_t descriptorSetCount,
2164                                                                 const VkDescriptorSet *pDescriptorSets,
2165                                                                 uint32_t dynamicOffsetCount, const uint32_t *pDynamicOffsets) {
2166    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
2167    if (NULL == disp) {
2168        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2169                   "vkCmdBindDescriptorSets: Invalid commandBuffer [VUID-vkCmdBindDescriptorSets-commandBuffer-parameter]");
2170        abort(); /* Intentionally fail so user can correct issue. */
2171    }
2172
2173    disp->CmdBindDescriptorSets(commandBuffer, pipelineBindPoint, layout, firstSet, descriptorSetCount, pDescriptorSets,
2174                                dynamicOffsetCount, pDynamicOffsets);
2175}
2176
2177LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdBindIndexBuffer(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
2178                                                              VkIndexType indexType) {
2179    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
2180    if (NULL == disp) {
2181        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2182                   "vkCmdBindIndexBuffer: Invalid commandBuffer [VUID-vkCmdBindIndexBuffer-commandBuffer-parameter]");
2183        abort(); /* Intentionally fail so user can correct issue. */
2184    }
2185
2186    disp->CmdBindIndexBuffer(commandBuffer, buffer, offset, indexType);
2187}
2188
2189LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdBindVertexBuffers(VkCommandBuffer commandBuffer, uint32_t firstBinding,
2190                                                                uint32_t bindingCount, const VkBuffer *pBuffers,
2191                                                                const VkDeviceSize *pOffsets) {
2192    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
2193    if (NULL == disp) {
2194        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2195                   "vkCmdBindVertexBuffers: Invalid commandBuffer [VUID-vkCmdBindVertexBuffers-commandBuffer-parameter]");
2196        abort(); /* Intentionally fail so user can correct issue. */
2197    }
2198
2199    disp->CmdBindVertexBuffers(commandBuffer, firstBinding, bindingCount, pBuffers, pOffsets);
2200}
2201
2202LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount,
2203                                                   uint32_t firstVertex, uint32_t firstInstance) {
2204    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
2205    if (NULL == disp) {
2206        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2207                   "vkCmdDraw: Invalid commandBuffer [VUID-vkCmdDraw-commandBuffer-parameter]");
2208        abort(); /* Intentionally fail so user can correct issue. */
2209    }
2210
2211    disp->CmdDraw(commandBuffer, vertexCount, instanceCount, firstVertex, firstInstance);
2212}
2213
2214LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount,
2215                                                          uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset,
2216                                                          uint32_t firstInstance) {
2217    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
2218    if (NULL == disp) {
2219        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2220                   "vkCmdDrawIndexed: Invalid commandBuffer [VUID-vkCmdDrawIndexed-commandBuffer-parameter]");
2221        abort(); /* Intentionally fail so user can correct issue. */
2222    }
2223
2224    disp->CmdDrawIndexed(commandBuffer, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
2225}
2226
2227LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
2228                                                           uint32_t drawCount, uint32_t stride) {
2229    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
2230    if (NULL == disp) {
2231        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2232                   "vkCmdDrawIndirect: Invalid commandBuffer [VUID-vkCmdDrawIndirect-commandBuffer-parameter]");
2233        abort(); /* Intentionally fail so user can correct issue. */
2234    }
2235
2236    disp->CmdDrawIndirect(commandBuffer, buffer, offset, drawCount, stride);
2237}
2238
2239LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer,
2240                                                                  VkDeviceSize offset, uint32_t drawCount, uint32_t stride) {
2241    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
2242    if (NULL == disp) {
2243        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2244                   "vkCmdDrawIndexedIndirect: Invalid commandBuffer [VUID-vkCmdDrawIndexedIndirect-commandBuffer-parameter]");
2245        abort(); /* Intentionally fail so user can correct issue. */
2246    }
2247
2248    disp->CmdDrawIndexedIndirect(commandBuffer, buffer, offset, drawCount, stride);
2249}
2250
2251LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z) {
2252    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
2253    if (NULL == disp) {
2254        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2255                   "vkCmdDispatch: Invalid commandBuffer [VUID-vkCmdDispatch-commandBuffer-parameter]");
2256        abort(); /* Intentionally fail so user can correct issue. */
2257    }
2258
2259    disp->CmdDispatch(commandBuffer, x, y, z);
2260}
2261
2262LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer,
2263                                                               VkDeviceSize offset) {
2264    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
2265    if (NULL == disp) {
2266        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2267                   "vkCmdDispatchIndirect: Invalid commandBuffer [VUID-vkCmdDispatchIndirect-commandBuffer-parameter]");
2268        abort(); /* Intentionally fail so user can correct issue. */
2269    }
2270
2271    disp->CmdDispatchIndirect(commandBuffer, buffer, offset);
2272}
2273
2274LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdCopyBuffer(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkBuffer dstBuffer,
2275                                                         uint32_t regionCount, const VkBufferCopy *pRegions) {
2276    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
2277    if (NULL == disp) {
2278        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2279                   "vkCmdCopyBuffer: Invalid commandBuffer [VUID-vkCmdCopyBuffer-commandBuffer-parameter]");
2280        abort(); /* Intentionally fail so user can correct issue. */
2281    }
2282
2283    disp->CmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, regionCount, pRegions);
2284}
2285
2286LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdCopyImage(VkCommandBuffer commandBuffer, VkImage srcImage,
2287                                                        VkImageLayout srcImageLayout, VkImage dstImage,
2288                                                        VkImageLayout dstImageLayout, uint32_t regionCount,
2289                                                        const VkImageCopy *pRegions) {
2290    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
2291    if (NULL == disp) {
2292        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2293                   "vkCmdCopyImage: Invalid commandBuffer [VUID-vkCmdCopyImage-commandBuffer-parameter]");
2294        abort(); /* Intentionally fail so user can correct issue. */
2295    }
2296
2297    disp->CmdCopyImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions);
2298}
2299
2300LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdBlitImage(VkCommandBuffer commandBuffer, VkImage srcImage,
2301                                                        VkImageLayout srcImageLayout, VkImage dstImage,
2302                                                        VkImageLayout dstImageLayout, uint32_t regionCount,
2303                                                        const VkImageBlit *pRegions, VkFilter filter) {
2304    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
2305    if (NULL == disp) {
2306        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2307                   "vkCmdBlitImage: Invalid commandBuffer [VUID-vkCmdBlitImage-commandBuffer-parameter]");
2308        abort(); /* Intentionally fail so user can correct issue. */
2309    }
2310
2311    disp->CmdBlitImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions, filter);
2312}
2313
2314LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdCopyBufferToImage(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkImage dstImage,
2315                                                                VkImageLayout dstImageLayout, uint32_t regionCount,
2316                                                                const VkBufferImageCopy *pRegions) {
2317    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
2318    if (NULL == disp) {
2319        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2320                   "vkCmdCopyBufferToImage: Invalid commandBuffer [VUID-vkCmdCopyBufferToImage-commandBuffer-parameter]");
2321        abort(); /* Intentionally fail so user can correct issue. */
2322    }
2323
2324    disp->CmdCopyBufferToImage(commandBuffer, srcBuffer, dstImage, dstImageLayout, regionCount, pRegions);
2325}
2326
2327LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdCopyImageToBuffer(VkCommandBuffer commandBuffer, VkImage srcImage,
2328                                                                VkImageLayout srcImageLayout, VkBuffer dstBuffer,
2329                                                                uint32_t regionCount, const VkBufferImageCopy *pRegions) {
2330    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
2331    if (NULL == disp) {
2332        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2333                   "vkCmdCopyImageToBuffer: Invalid commandBuffer [VUID-vkCmdCopyImageToBuffer-commandBuffer-parameter]");
2334        abort(); /* Intentionally fail so user can correct issue. */
2335    }
2336
2337    disp->CmdCopyImageToBuffer(commandBuffer, srcImage, srcImageLayout, dstBuffer, regionCount, pRegions);
2338}
2339
2340LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer,
2341                                                           VkDeviceSize dstOffset, VkDeviceSize dataSize, const void *pData) {
2342    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
2343    if (NULL == disp) {
2344        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2345                   "vkCmdUpdateBuffer: Invalid commandBuffer [VUID-vkCmdUpdateBuffer-commandBuffer-parameter]");
2346        abort(); /* Intentionally fail so user can correct issue. */
2347    }
2348
2349    disp->CmdUpdateBuffer(commandBuffer, dstBuffer, dstOffset, dataSize, pData);
2350}
2351
2352LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdFillBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset,
2353                                                         VkDeviceSize size, uint32_t data) {
2354    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
2355    if (NULL == disp) {
2356        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2357                   "vkCmdFillBuffer: Invalid commandBuffer [VUID-vkCmdFillBuffer-commandBuffer-parameter]");
2358        abort(); /* Intentionally fail so user can correct issue. */
2359    }
2360
2361    disp->CmdFillBuffer(commandBuffer, dstBuffer, dstOffset, size, data);
2362}
2363
2364LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdClearColorImage(VkCommandBuffer commandBuffer, VkImage image,
2365                                                              VkImageLayout imageLayout, const VkClearColorValue *pColor,
2366                                                              uint32_t rangeCount, const VkImageSubresourceRange *pRanges) {
2367    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
2368    if (NULL == disp) {
2369        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2370                   "vkCmdClearColorImage: Invalid commandBuffer [VUID-vkCmdClearColorImage-commandBuffer-parameter]");
2371        abort(); /* Intentionally fail so user can correct issue. */
2372    }
2373
2374    disp->CmdClearColorImage(commandBuffer, image, imageLayout, pColor, rangeCount, pRanges);
2375}
2376
2377LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdClearDepthStencilImage(VkCommandBuffer commandBuffer, VkImage image,
2378                                                                     VkImageLayout imageLayout,
2379                                                                     const VkClearDepthStencilValue *pDepthStencil,
2380                                                                     uint32_t rangeCount, const VkImageSubresourceRange *pRanges) {
2381    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
2382    if (NULL == disp) {
2383        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2384                   "vkCmdClearDepthStencilImage: Invalid commandBuffer [VUID-vkCmdClearDepthStencilImage-commandBuffer-parameter]");
2385        abort(); /* Intentionally fail so user can correct issue. */
2386    }
2387
2388    disp->CmdClearDepthStencilImage(commandBuffer, image, imageLayout, pDepthStencil, rangeCount, pRanges);
2389}
2390
2391LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdClearAttachments(VkCommandBuffer commandBuffer, uint32_t attachmentCount,
2392                                                               const VkClearAttachment *pAttachments, uint32_t rectCount,
2393                                                               const VkClearRect *pRects) {
2394    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
2395    if (NULL == disp) {
2396        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2397                   "vkCmdClearAttachments: Invalid commandBuffer [VUID-vkCmdClearAttachments-commandBuffer-parameter]");
2398        abort(); /* Intentionally fail so user can correct issue. */
2399    }
2400
2401    disp->CmdClearAttachments(commandBuffer, attachmentCount, pAttachments, rectCount, pRects);
2402}
2403
2404LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdResolveImage(VkCommandBuffer commandBuffer, VkImage srcImage,
2405                                                           VkImageLayout srcImageLayout, VkImage dstImage,
2406                                                           VkImageLayout dstImageLayout, uint32_t regionCount,
2407                                                           const VkImageResolve *pRegions) {
2408    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
2409    if (NULL == disp) {
2410        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2411                   "vkCmdResolveImage: Invalid commandBuffer [VUID-vkCmdResolveImage-commandBuffer-parameter]");
2412        abort(); /* Intentionally fail so user can correct issue. */
2413    }
2414
2415    disp->CmdResolveImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions);
2416}
2417
2418LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetEvent(VkCommandBuffer commandBuffer, VkEvent event,
2419                                                       VkPipelineStageFlags stageMask) {
2420    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
2421    if (NULL == disp) {
2422        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2423                   "vkCmdSetEvent: Invalid commandBuffer [VUID-vkCmdSetEvent-commandBuffer-parameter]");
2424        abort(); /* Intentionally fail so user can correct issue. */
2425    }
2426
2427    disp->CmdSetEvent(commandBuffer, event, stageMask);
2428}
2429
2430LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdResetEvent(VkCommandBuffer commandBuffer, VkEvent event,
2431                                                         VkPipelineStageFlags stageMask) {
2432    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
2433    if (NULL == disp) {
2434        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2435                   "vkCmdResetEvent: Invalid commandBuffer [VUID-vkCmdResetEvent-commandBuffer-parameter]");
2436        abort(); /* Intentionally fail so user can correct issue. */
2437    }
2438
2439    disp->CmdResetEvent(commandBuffer, event, stageMask);
2440}
2441
2442LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdWaitEvents(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent *pEvents,
2443                                                         VkPipelineStageFlags sourceStageMask, VkPipelineStageFlags dstStageMask,
2444                                                         uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers,
2445                                                         uint32_t bufferMemoryBarrierCount,
2446                                                         const VkBufferMemoryBarrier *pBufferMemoryBarriers,
2447                                                         uint32_t imageMemoryBarrierCount,
2448                                                         const VkImageMemoryBarrier *pImageMemoryBarriers) {
2449    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
2450    if (NULL == disp) {
2451        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2452                   "vkCmdWaitEvents: Invalid commandBuffer [VUID-vkCmdWaitEvents-commandBuffer-parameter]");
2453        abort(); /* Intentionally fail so user can correct issue. */
2454    }
2455
2456    disp->CmdWaitEvents(commandBuffer, eventCount, pEvents, sourceStageMask, dstStageMask, memoryBarrierCount, pMemoryBarriers,
2457                        bufferMemoryBarrierCount, pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers);
2458}
2459
2460LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdPipelineBarrier(VkCommandBuffer commandBuffer, VkPipelineStageFlags srcStageMask,
2461                                                              VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags,
2462                                                              uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers,
2463                                                              uint32_t bufferMemoryBarrierCount,
2464                                                              const VkBufferMemoryBarrier *pBufferMemoryBarriers,
2465                                                              uint32_t imageMemoryBarrierCount,
2466                                                              const VkImageMemoryBarrier *pImageMemoryBarriers) {
2467    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
2468    if (NULL == disp) {
2469        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2470                   "vkCmdPipelineBarrier: Invalid commandBuffer [VUID-vkCmdPipelineBarrier-commandBuffer-parameter]");
2471        abort(); /* Intentionally fail so user can correct issue. */
2472    }
2473
2474    disp->CmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags, memoryBarrierCount, pMemoryBarriers,
2475                             bufferMemoryBarrierCount, pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers);
2476}
2477
2478LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdBeginQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t slot,
2479                                                         VkFlags flags) {
2480    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
2481    if (NULL == disp) {
2482        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2483                   "vkCmdBeginQuery: Invalid commandBuffer [VUID-vkCmdBeginQuery-commandBuffer-parameter]");
2484        abort(); /* Intentionally fail so user can correct issue. */
2485    }
2486
2487    disp->CmdBeginQuery(commandBuffer, queryPool, slot, flags);
2488}
2489
2490LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdEndQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t slot) {
2491    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
2492    if (NULL == disp) {
2493        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2494                   "vkCmdEndQuery: Invalid commandBuffer [VUID-vkCmdEndQuery-commandBuffer-parameter]");
2495        abort(); /* Intentionally fail so user can correct issue. */
2496    }
2497
2498    disp->CmdEndQuery(commandBuffer, queryPool, slot);
2499}
2500
2501LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdResetQueryPool(VkCommandBuffer commandBuffer, VkQueryPool queryPool,
2502                                                             uint32_t firstQuery, uint32_t queryCount) {
2503    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
2504    if (NULL == disp) {
2505        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2506                   "vkCmdResetQueryPool: Invalid commandBuffer [VUID-vkCmdResetQueryPool-commandBuffer-parameter]");
2507        abort(); /* Intentionally fail so user can correct issue. */
2508    }
2509
2510    disp->CmdResetQueryPool(commandBuffer, queryPool, firstQuery, queryCount);
2511}
2512
2513LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdWriteTimestamp(VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage,
2514                                                             VkQueryPool queryPool, uint32_t slot) {
2515    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
2516    if (NULL == disp) {
2517        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2518                   "vkCmdWriteTimestamp: Invalid commandBuffer [VUID-vkCmdWriteTimestamp-commandBuffer-parameter]");
2519        abort(); /* Intentionally fail so user can correct issue. */
2520    }
2521
2522    disp->CmdWriteTimestamp(commandBuffer, pipelineStage, queryPool, slot);
2523}
2524
2525LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdCopyQueryPoolResults(VkCommandBuffer commandBuffer, VkQueryPool queryPool,
2526                                                                   uint32_t firstQuery, uint32_t queryCount, VkBuffer dstBuffer,
2527                                                                   VkDeviceSize dstOffset, VkDeviceSize stride, VkFlags flags) {
2528    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
2529    if (NULL == disp) {
2530        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2531                   "vkCmdCopyQueryPoolResults: Invalid commandBuffer [VUID-vkCmdCopyQueryPoolResults-commandBuffer-parameter]");
2532        abort(); /* Intentionally fail so user can correct issue. */
2533    }
2534
2535    disp->CmdCopyQueryPoolResults(commandBuffer, queryPool, firstQuery, queryCount, dstBuffer, dstOffset, stride, flags);
2536}
2537
2538LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdPushConstants(VkCommandBuffer commandBuffer, VkPipelineLayout layout,
2539                                                            VkShaderStageFlags stageFlags, uint32_t offset, uint32_t size,
2540                                                            const void *pValues) {
2541    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
2542    if (NULL == disp) {
2543        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2544                   "vkCmdPushConstants: Invalid commandBuffer [VUID-vkCmdPushConstants-commandBuffer-parameter]");
2545        abort(); /* Intentionally fail so user can correct issue. */
2546    }
2547
2548    disp->CmdPushConstants(commandBuffer, layout, stageFlags, offset, size, pValues);
2549}
2550
2551LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdBeginRenderPass(VkCommandBuffer commandBuffer,
2552                                                              const VkRenderPassBeginInfo *pRenderPassBegin,
2553                                                              VkSubpassContents contents) {
2554    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
2555    if (NULL == disp) {
2556        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2557                   "vkCmdBeginRenderPass: Invalid commandBuffer [VUID-vkCmdBeginRenderPass-commandBuffer-parameter]");
2558        abort(); /* Intentionally fail so user can correct issue. */
2559    }
2560
2561    disp->CmdBeginRenderPass(commandBuffer, pRenderPassBegin, contents);
2562}
2563
2564LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpassContents contents) {
2565    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
2566    if (NULL == disp) {
2567        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2568                   "vkCmdNextSubpass: Invalid commandBuffer [VUID-vkCmdNextSubpass-commandBuffer-parameter]");
2569        abort(); /* Intentionally fail so user can correct issue. */
2570    }
2571
2572    disp->CmdNextSubpass(commandBuffer, contents);
2573}
2574
2575LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdEndRenderPass(VkCommandBuffer commandBuffer) {
2576    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
2577    if (NULL == disp) {
2578        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2579                   "vkCmdEndRenderPass: Invalid commandBuffer [VUID-vkCmdEndRenderPass-commandBuffer-parameter]");
2580        abort(); /* Intentionally fail so user can correct issue. */
2581    }
2582
2583    disp->CmdEndRenderPass(commandBuffer);
2584}
2585
2586LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBuffersCount,
2587                                                              const VkCommandBuffer *pCommandBuffers) {
2588    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
2589    if (NULL == disp) {
2590        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2591                   "vkCmdExecuteCommands: Invalid commandBuffer [VUID-vkCmdExecuteCommands-commandBuffer-parameter]");
2592        abort(); /* Intentionally fail so user can correct issue. */
2593    }
2594
2595    disp->CmdExecuteCommands(commandBuffer, commandBuffersCount, pCommandBuffers);
2596}
2597
2598// ---- Vulkan core 1.1 trampolines
2599
2600LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDeviceGroups(
2601    VkInstance instance, uint32_t *pPhysicalDeviceGroupCount, VkPhysicalDeviceGroupProperties *pPhysicalDeviceGroupProperties) {
2602    VkResult res = VK_SUCCESS;
2603    struct loader_instance *inst = NULL;
2604
2605    loader_platform_thread_lock_mutex(&loader_lock);
2606
2607    inst = loader_get_instance(instance);
2608    if (NULL == inst) {
2609        loader_log(
2610            NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2611            "vkEnumeratePhysicalDeviceGroupsKHR: Invalid instance [VUID-vkEnumeratePhysicalDeviceGroups-instance-parameter]");
2612        abort(); /* Intentionally fail so user can correct issue. */
2613    }
2614
2615    if (NULL == pPhysicalDeviceGroupCount) {
2616        loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0,
2617                   "vkEnumeratePhysicalDeviceGroupsKHR: Received NULL pointer for physical "
2618                   "device group count return value.");
2619        res = VK_ERROR_INITIALIZATION_FAILED;
2620        goto out;
2621    }
2622
2623    // Call down the chain to get the physical device group info.
2624    res = inst->disp->layer_inst_disp.EnumeratePhysicalDeviceGroups(inst->instance, pPhysicalDeviceGroupCount,
2625                                                                    pPhysicalDeviceGroupProperties);
2626    if (NULL != pPhysicalDeviceGroupProperties && (VK_SUCCESS == res || VK_INCOMPLETE == res)) {
2627        // Wrap the PhysDev object for loader usage, return wrapped objects
2628        VkResult update_res = setup_loader_tramp_phys_dev_groups(inst, *pPhysicalDeviceGroupCount, pPhysicalDeviceGroupProperties);
2629        if (VK_SUCCESS != update_res) {
2630            res = update_res;
2631        }
2632    }
2633
2634out:
2635
2636    loader_platform_thread_unlock_mutex(&loader_lock);
2637    return res;
2638}
2639
2640LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice,
2641                                                                      VkPhysicalDeviceFeatures2 *pFeatures) {
2642    VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
2643    if (VK_NULL_HANDLE == unwrapped_phys_dev) {
2644        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2645                   "vkGetPhysicalDeviceFeatures2: Invalid physicalDevice "
2646                   "[VUID-vkGetPhysicalDeviceFeatures2-physicalDevice-parameter]");
2647        abort(); /* Intentionally fail so user can correct issue. */
2648    }
2649    const VkLayerInstanceDispatchTable *disp = loader_get_instance_layer_dispatch(physicalDevice);
2650    const struct loader_instance *inst = ((struct loader_physical_device_tramp *)physicalDevice)->this_instance;
2651
2652    if (inst != NULL && inst->enabled_known_extensions.khr_get_physical_device_properties2) {
2653        disp->GetPhysicalDeviceFeatures2KHR(unwrapped_phys_dev, pFeatures);
2654    } else {
2655        disp->GetPhysicalDeviceFeatures2(unwrapped_phys_dev, pFeatures);
2656    }
2657}
2658
2659LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,
2660                                                                        VkPhysicalDeviceProperties2 *pProperties) {
2661    VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
2662    if (VK_NULL_HANDLE == unwrapped_phys_dev) {
2663        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2664                   "vkGetPhysicalDeviceProperties2: Invalid physicalDevice "
2665                   "[VUID-vkGetPhysicalDeviceProperties2-physicalDevice-parameter]");
2666        abort(); /* Intentionally fail so user can correct issue. */
2667    }
2668    const VkLayerInstanceDispatchTable *disp = loader_get_instance_layer_dispatch(physicalDevice);
2669    const struct loader_instance *inst = ((struct loader_physical_device_tramp *)physicalDevice)->this_instance;
2670
2671    if (inst != NULL && inst->enabled_known_extensions.khr_get_physical_device_properties2) {
2672        disp->GetPhysicalDeviceProperties2KHR(unwrapped_phys_dev, pProperties);
2673    } else {
2674        disp->GetPhysicalDeviceProperties2(unwrapped_phys_dev, pProperties);
2675    }
2676}
2677
2678LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice, VkFormat format,
2679                                                                              VkFormatProperties2 *pFormatProperties) {
2680    VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
2681    if (VK_NULL_HANDLE == unwrapped_phys_dev) {
2682        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2683                   "vkGetPhysicalDeviceFormatProperties2: Invalid physicalDevice "
2684                   "[VUID-vkGetPhysicalDeviceFormatProperties2-physicalDevice-parameter]");
2685        abort(); /* Intentionally fail so user can correct issue. */
2686    }
2687    const VkLayerInstanceDispatchTable *disp = loader_get_instance_layer_dispatch(physicalDevice);
2688    const struct loader_instance *inst = ((struct loader_physical_device_tramp *)physicalDevice)->this_instance;
2689
2690    if (inst != NULL && inst->enabled_known_extensions.khr_get_physical_device_properties2) {
2691        disp->GetPhysicalDeviceFormatProperties2KHR(unwrapped_phys_dev, format, pFormatProperties);
2692    } else {
2693        disp->GetPhysicalDeviceFormatProperties2(unwrapped_phys_dev, format, pFormatProperties);
2694    }
2695}
2696
2697LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
2698vkGetPhysicalDeviceImageFormatProperties2(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo,
2699                                          VkImageFormatProperties2 *pImageFormatProperties) {
2700    VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
2701    if (VK_NULL_HANDLE == unwrapped_phys_dev) {
2702        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2703                   "vkGetPhysicalDeviceImageFormatProperties2: Invalid physicalDevice "
2704                   "[VUID-vkGetPhysicalDeviceImageFormatProperties2-physicalDevice-parameter]");
2705        abort(); /* Intentionally fail so user can correct issue. */
2706    }
2707    const VkLayerInstanceDispatchTable *disp = loader_get_instance_layer_dispatch(physicalDevice);
2708    const struct loader_instance *inst = ((struct loader_physical_device_tramp *)physicalDevice)->this_instance;
2709
2710    if (inst != NULL && inst->enabled_known_extensions.khr_get_physical_device_properties2) {
2711        return disp->GetPhysicalDeviceImageFormatProperties2KHR(unwrapped_phys_dev, pImageFormatInfo, pImageFormatProperties);
2712    } else {
2713        return disp->GetPhysicalDeviceImageFormatProperties2(unwrapped_phys_dev, pImageFormatInfo, pImageFormatProperties);
2714    }
2715}
2716
2717LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyProperties2(
2718    VkPhysicalDevice physicalDevice, uint32_t *pQueueFamilyPropertyCount, VkQueueFamilyProperties2 *pQueueFamilyProperties) {
2719    VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
2720    if (VK_NULL_HANDLE == unwrapped_phys_dev) {
2721        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2722                   "vkGetPhysicalDeviceQueueFamilyProperties2: Invalid physicalDevice "
2723                   "[VUID-vkGetPhysicalDeviceQueueFamilyProperties2-physicalDevice-parameter]");
2724        abort(); /* Intentionally fail so user can correct issue. */
2725    }
2726    const VkLayerInstanceDispatchTable *disp = loader_get_instance_layer_dispatch(physicalDevice);
2727    const struct loader_instance *inst = ((struct loader_physical_device_tramp *)physicalDevice)->this_instance;
2728
2729    if (inst != NULL && inst->enabled_known_extensions.khr_get_physical_device_properties2) {
2730        disp->GetPhysicalDeviceQueueFamilyProperties2KHR(unwrapped_phys_dev, pQueueFamilyPropertyCount, pQueueFamilyProperties);
2731    } else {
2732        disp->GetPhysicalDeviceQueueFamilyProperties2(unwrapped_phys_dev, pQueueFamilyPropertyCount, pQueueFamilyProperties);
2733    }
2734}
2735
2736LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
2737vkGetPhysicalDeviceMemoryProperties2(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties2 *pMemoryProperties) {
2738    VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
2739    if (VK_NULL_HANDLE == unwrapped_phys_dev) {
2740        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2741                   "vkGetPhysicalDeviceMemoryProperties2: Invalid physicalDevice "
2742                   "[VUID-vkGetPhysicalDeviceMemoryProperties2-physicalDevice-parameter]");
2743        abort(); /* Intentionally fail so user can correct issue. */
2744    }
2745    const VkLayerInstanceDispatchTable *disp = loader_get_instance_layer_dispatch(physicalDevice);
2746    const struct loader_instance *inst = ((struct loader_physical_device_tramp *)physicalDevice)->this_instance;
2747
2748    if (inst != NULL && inst->enabled_known_extensions.khr_get_physical_device_properties2) {
2749        disp->GetPhysicalDeviceMemoryProperties2KHR(unwrapped_phys_dev, pMemoryProperties);
2750    } else {
2751        disp->GetPhysicalDeviceMemoryProperties2(unwrapped_phys_dev, pMemoryProperties);
2752    }
2753}
2754
2755LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceSparseImageFormatProperties2(
2756    VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2 *pFormatInfo, uint32_t *pPropertyCount,
2757    VkSparseImageFormatProperties2 *pProperties) {
2758    VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
2759    if (VK_NULL_HANDLE == unwrapped_phys_dev) {
2760        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2761                   "vkGetPhysicalDeviceSparseImageFormatProperties2: Invalid physicalDevice "
2762                   "[VUID-vkGetPhysicalDeviceSparseImageFormatProperties2-physicalDevice-parameter]");
2763        abort(); /* Intentionally fail so user can correct issue. */
2764    }
2765    const VkLayerInstanceDispatchTable *disp = loader_get_instance_layer_dispatch(physicalDevice);
2766    const struct loader_instance *inst = ((struct loader_physical_device_tramp *)physicalDevice)->this_instance;
2767
2768    if (inst != NULL && inst->enabled_known_extensions.khr_get_physical_device_properties2) {
2769        disp->GetPhysicalDeviceSparseImageFormatProperties2KHR(unwrapped_phys_dev, pFormatInfo, pPropertyCount, pProperties);
2770    } else {
2771        disp->GetPhysicalDeviceSparseImageFormatProperties2(unwrapped_phys_dev, pFormatInfo, pPropertyCount, pProperties);
2772    }
2773}
2774
2775LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalBufferProperties(
2776    VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalBufferInfo *pExternalBufferInfo,
2777    VkExternalBufferProperties *pExternalBufferProperties) {
2778    VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
2779    if (VK_NULL_HANDLE == unwrapped_phys_dev) {
2780        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2781                   "vkGetPhysicalDeviceExternalBufferProperties: Invalid physicalDevice "
2782                   "[VUID-vkGetPhysicalDeviceExternalBufferProperties-physicalDevice-parameter]");
2783        abort(); /* Intentionally fail so user can correct issue. */
2784    }
2785    const VkLayerInstanceDispatchTable *disp = loader_get_instance_layer_dispatch(physicalDevice);
2786    const struct loader_instance *inst = ((struct loader_physical_device_tramp *)physicalDevice)->this_instance;
2787
2788    if (inst != NULL && inst->enabled_known_extensions.khr_external_memory_capabilities) {
2789        disp->GetPhysicalDeviceExternalBufferPropertiesKHR(unwrapped_phys_dev, pExternalBufferInfo, pExternalBufferProperties);
2790    } else {
2791        disp->GetPhysicalDeviceExternalBufferProperties(unwrapped_phys_dev, pExternalBufferInfo, pExternalBufferProperties);
2792    }
2793}
2794
2795LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalSemaphoreProperties(
2796    VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalSemaphoreInfo *pExternalSemaphoreInfo,
2797    VkExternalSemaphoreProperties *pExternalSemaphoreProperties) {
2798    VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
2799    if (VK_NULL_HANDLE == unwrapped_phys_dev) {
2800        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2801                   "vkGetPhysicalDeviceExternalSemaphoreProperties: Invalid physicalDevice "
2802                   "[VUID-vkGetPhysicalDeviceExternalSemaphoreProperties-physicalDevice-parameter]");
2803        abort(); /* Intentionally fail so user can correct issue. */
2804    }
2805    const VkLayerInstanceDispatchTable *disp = loader_get_instance_layer_dispatch(physicalDevice);
2806    const struct loader_instance *inst = ((struct loader_physical_device_tramp *)physicalDevice)->this_instance;
2807
2808    if (inst != NULL && inst->enabled_known_extensions.khr_external_semaphore_capabilities) {
2809        disp->GetPhysicalDeviceExternalSemaphorePropertiesKHR(unwrapped_phys_dev, pExternalSemaphoreInfo,
2810                                                              pExternalSemaphoreProperties);
2811    } else {
2812        disp->GetPhysicalDeviceExternalSemaphoreProperties(unwrapped_phys_dev, pExternalSemaphoreInfo,
2813                                                           pExternalSemaphoreProperties);
2814    }
2815}
2816
2817LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalFenceProperties(
2818    VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalFenceInfo *pExternalFenceInfo,
2819    VkExternalFenceProperties *pExternalFenceProperties) {
2820    VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
2821    if (VK_NULL_HANDLE == unwrapped_phys_dev) {
2822        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2823                   "vkGetPhysicalDeviceExternalFenceProperties: Invalid physicalDevice "
2824                   "[VUID-vkGetPhysicalDeviceExternalFenceProperties-physicalDevice-parameter]");
2825        abort(); /* Intentionally fail so user can correct issue. */
2826    }
2827    const VkLayerInstanceDispatchTable *disp = loader_get_instance_layer_dispatch(physicalDevice);
2828    const struct loader_instance *inst = ((struct loader_physical_device_tramp *)physicalDevice)->this_instance;
2829
2830    if (inst != NULL && inst->enabled_known_extensions.khr_external_fence_capabilities) {
2831        disp->GetPhysicalDeviceExternalFencePropertiesKHR(unwrapped_phys_dev, pExternalFenceInfo, pExternalFenceProperties);
2832    } else {
2833        disp->GetPhysicalDeviceExternalFenceProperties(unwrapped_phys_dev, pExternalFenceInfo, pExternalFenceProperties);
2834    }
2835}
2836
2837LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkBindBufferMemory2(VkDevice device, uint32_t bindInfoCount,
2838                                                                 const VkBindBufferMemoryInfo *pBindInfos) {
2839    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
2840    if (NULL == disp) {
2841        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2842                   "vkBindBufferMemory2: Invalid device [VUID-vkBindBufferMemory2-device-parameter]");
2843        abort(); /* Intentionally fail so user can correct issue. */
2844    }
2845    return disp->BindBufferMemory2(device, bindInfoCount, pBindInfos);
2846}
2847
2848LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkBindImageMemory2(VkDevice device, uint32_t bindInfoCount,
2849                                                                const VkBindImageMemoryInfo *pBindInfos) {
2850    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
2851    if (NULL == disp) {
2852        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2853                   "vkBindImageMemory2: Invalid device [VUID-vkBindImageMemory2-device-parameter]");
2854        abort(); /* Intentionally fail so user can correct issue. */
2855    }
2856    return disp->BindImageMemory2(device, bindInfoCount, pBindInfos);
2857}
2858
2859LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetDeviceGroupPeerMemoryFeatures(VkDevice device, uint32_t heapIndex,
2860                                                                            uint32_t localDeviceIndex, uint32_t remoteDeviceIndex,
2861                                                                            VkPeerMemoryFeatureFlags *pPeerMemoryFeatures) {
2862    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
2863    if (NULL == disp) {
2864        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2865                   "vkGetDeviceGroupPeerMemoryFeatures: Invalid device [VUID-vkGetDeviceGroupPeerMemoryFeatures-device-parameter]");
2866        abort(); /* Intentionally fail so user can correct issue. */
2867    }
2868    disp->GetDeviceGroupPeerMemoryFeatures(device, heapIndex, localDeviceIndex, remoteDeviceIndex, pPeerMemoryFeatures);
2869}
2870
2871LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetDeviceMask(VkCommandBuffer commandBuffer, uint32_t deviceMask) {
2872    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
2873    if (NULL == disp) {
2874        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2875                   "vkCmdSetDeviceMask: Invalid commandBuffer [VUID-vkCmdSetDeviceMask-commandBuffer-parameter]");
2876        abort(); /* Intentionally fail so user can correct issue. */
2877    }
2878    disp->CmdSetDeviceMask(commandBuffer, deviceMask);
2879}
2880
2881LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdDispatchBase(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY,
2882                                                           uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY,
2883                                                           uint32_t groupCountZ) {
2884    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
2885    if (NULL == disp) {
2886        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2887                   "vkCmdDispatchBase: Invalid commandBuffer [VUID-vkCmdDispatchBase-commandBuffer-parameter]");
2888        abort(); /* Intentionally fail so user can correct issue. */
2889    }
2890    disp->CmdDispatchBase(commandBuffer, baseGroupX, baseGroupY, baseGroupZ, groupCountX, groupCountY, groupCountZ);
2891}
2892
2893LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetImageMemoryRequirements2(VkDevice device, const VkImageMemoryRequirementsInfo2 *pInfo,
2894                                                                       VkMemoryRequirements2 *pMemoryRequirements) {
2895    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
2896    if (NULL == disp) {
2897        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2898                   "vkGetImageMemoryRequirements2: Invalid device [VUID-vkGetImageMemoryRequirements2-device-parameter]");
2899        abort(); /* Intentionally fail so user can correct issue. */
2900    }
2901    disp->GetImageMemoryRequirements2(device, pInfo, pMemoryRequirements);
2902}
2903
2904LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetBufferMemoryRequirements2(VkDevice device,
2905                                                                        const VkBufferMemoryRequirementsInfo2 *pInfo,
2906                                                                        VkMemoryRequirements2 *pMemoryRequirements) {
2907    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
2908    if (NULL == disp) {
2909        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2910                   "vkGetBufferMemoryRequirements2: Invalid device [VUID-vkGetBufferMemoryRequirements2-device-parameter]");
2911        abort(); /* Intentionally fail so user can correct issue. */
2912    }
2913    disp->GetBufferMemoryRequirements2(device, pInfo, pMemoryRequirements);
2914}
2915
2916LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetImageSparseMemoryRequirements2(
2917    VkDevice device, const VkImageSparseMemoryRequirementsInfo2 *pInfo, uint32_t *pSparseMemoryRequirementCount,
2918    VkSparseImageMemoryRequirements2 *pSparseMemoryRequirements) {
2919    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
2920    if (NULL == disp) {
2921        loader_log(
2922            NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2923            "vkGetImageSparseMemoryRequirements2: Invalid device [VUID-vkGetImageSparseMemoryRequirements2-device-parameter]");
2924        abort(); /* Intentionally fail so user can correct issue. */
2925    }
2926    disp->GetImageSparseMemoryRequirements2(device, pInfo, pSparseMemoryRequirementCount, pSparseMemoryRequirements);
2927}
2928
2929LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkTrimCommandPool(VkDevice device, VkCommandPool commandPool,
2930                                                           VkCommandPoolTrimFlags flags) {
2931    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
2932    if (NULL == disp) {
2933        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2934                   "vkTrimCommandPool: Invalid device [VUID-vkTrimCommandPool-device-parameter]");
2935        abort(); /* Intentionally fail so user can correct issue. */
2936    }
2937    disp->TrimCommandPool(device, commandPool, flags);
2938}
2939
2940LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetDeviceQueue2(VkDevice device, const VkDeviceQueueInfo2 *pQueueInfo, VkQueue *pQueue) {
2941    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
2942    if (NULL == disp) {
2943        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2944                   "vkGetDeviceQueue2: Invalid device [VUID-vkGetDeviceQueue2-device-parameter]");
2945        abort(); /* Intentionally fail so user can correct issue. */
2946    }
2947    disp->GetDeviceQueue2(device, pQueueInfo, pQueue);
2948    if (pQueue != NULL && *pQueue != NULL) {
2949        loader_set_dispatch(*pQueue, disp);
2950    }
2951}
2952
2953LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateSamplerYcbcrConversion(VkDevice device,
2954                                                                            const VkSamplerYcbcrConversionCreateInfo *pCreateInfo,
2955                                                                            const VkAllocationCallbacks *pAllocator,
2956                                                                            VkSamplerYcbcrConversion *pYcbcrConversion) {
2957    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
2958    if (NULL == disp) {
2959        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2960                   "vkCreateSamplerYcbcrConversion: Invalid device [VUID-vkCreateSamplerYcbcrConversion-device-parameter]");
2961        abort(); /* Intentionally fail so user can correct issue. */
2962    }
2963    return disp->CreateSamplerYcbcrConversion(device, pCreateInfo, pAllocator, pYcbcrConversion);
2964}
2965
2966LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroySamplerYcbcrConversion(VkDevice device, VkSamplerYcbcrConversion ycbcrConversion,
2967                                                                         const VkAllocationCallbacks *pAllocator) {
2968    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
2969    if (NULL == disp) {
2970        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2971                   "vkDestroySamplerYcbcrConversion: Invalid device [VUID-vkDestroySamplerYcbcrConversion-device-parameter]");
2972        abort(); /* Intentionally fail so user can correct issue. */
2973    }
2974    disp->DestroySamplerYcbcrConversion(device, ycbcrConversion, pAllocator);
2975}
2976
2977LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetDescriptorSetLayoutSupport(VkDevice device,
2978                                                                         const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
2979                                                                         VkDescriptorSetLayoutSupport *pSupport) {
2980    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
2981    if (NULL == disp) {
2982        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2983                   "vkGetDescriptorSetLayoutSupport: Invalid device [VUID-vkGetDescriptorSetLayoutSupport-device-parameter]");
2984        abort(); /* Intentionally fail so user can correct issue. */
2985    }
2986    disp->GetDescriptorSetLayoutSupport(device, pCreateInfo, pSupport);
2987}
2988
2989LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
2990vkCreateDescriptorUpdateTemplate(VkDevice device, const VkDescriptorUpdateTemplateCreateInfo *pCreateInfo,
2991                                 const VkAllocationCallbacks *pAllocator, VkDescriptorUpdateTemplate *pDescriptorUpdateTemplate) {
2992    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
2993    if (NULL == disp) {
2994        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2995                   "vkCreateDescriptorUpdateTemplate: Invalid device [VUID-vkCreateDescriptorUpdateTemplate-device-parameter]");
2996        abort(); /* Intentionally fail so user can correct issue. */
2997    }
2998    return disp->CreateDescriptorUpdateTemplate(device, pCreateInfo, pAllocator, pDescriptorUpdateTemplate);
2999}
3000
3001LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyDescriptorUpdateTemplate(VkDevice device,
3002                                                                           VkDescriptorUpdateTemplate descriptorUpdateTemplate,
3003                                                                           const VkAllocationCallbacks *pAllocator) {
3004    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
3005    if (NULL == disp) {
3006        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
3007                   "vkDestroyDescriptorUpdateTemplate: Invalid device [VUID-vkDestroyDescriptorUpdateTemplate-device-parameter]");
3008        abort(); /* Intentionally fail so user can correct issue. */
3009    }
3010    disp->DestroyDescriptorUpdateTemplate(device, descriptorUpdateTemplate, pAllocator);
3011}
3012
3013LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkUpdateDescriptorSetWithTemplate(VkDevice device, VkDescriptorSet descriptorSet,
3014                                                                           VkDescriptorUpdateTemplate descriptorUpdateTemplate,
3015                                                                           const void *pData) {
3016    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
3017    if (NULL == disp) {
3018        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
3019                   "vkUpdateDescriptorSetWithTemplate: Invalid device [VUID-vkUpdateDescriptorSetWithTemplate-device-parameter]");
3020        abort(); /* Intentionally fail so user can correct issue. */
3021    }
3022    disp->UpdateDescriptorSetWithTemplate(device, descriptorSet, descriptorUpdateTemplate, pData);
3023}
3024
3025// ---- Vulkan core 1.2 trampolines
3026
3027LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateRenderPass2(VkDevice device, const VkRenderPassCreateInfo2 *pCreateInfo,
3028                                                                 const VkAllocationCallbacks *pAllocator,
3029                                                                 VkRenderPass *pRenderPass) {
3030    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
3031    if (NULL == disp) {
3032        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
3033                   "vkCreateRenderPass2: Invalid device [VUID-vkCreateRenderPass2-device-parameter]");
3034        abort(); /* Intentionally fail so user can correct issue. */
3035    }
3036    return disp->CreateRenderPass2(device, pCreateInfo, pAllocator, pRenderPass);
3037}
3038
3039LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdBeginRenderPass2(VkCommandBuffer commandBuffer,
3040                                                               const VkRenderPassBeginInfo *pRenderPassBegin,
3041                                                               const VkSubpassBeginInfo *pSubpassBeginInfo) {
3042    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
3043    if (NULL == disp) {
3044        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
3045                   "vkCmdBeginRenderPass2: Invalid commandBuffer [VUID-vkCmdBeginRenderPass2-commandBuffer-parameter]");
3046        abort(); /* Intentionally fail so user can correct issue. */
3047    }
3048    disp->CmdBeginRenderPass2(commandBuffer, pRenderPassBegin, pSubpassBeginInfo);
3049}
3050
3051LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdNextSubpass2(VkCommandBuffer commandBuffer,
3052                                                           const VkSubpassBeginInfo *pSubpassBeginInfo,
3053                                                           const VkSubpassEndInfo *pSubpassEndInfo) {
3054    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
3055    if (NULL == disp) {
3056        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
3057                   "vkCmdNextSubpass2: Invalid commandBuffer [VUID-vkCmdNextSubpass2-commandBuffer-parameter]");
3058        abort(); /* Intentionally fail so user can correct issue. */
3059    }
3060    disp->CmdNextSubpass2(commandBuffer, pSubpassBeginInfo, pSubpassEndInfo);
3061}
3062
3063LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdEndRenderPass2(VkCommandBuffer commandBuffer,
3064                                                             const VkSubpassEndInfo *pSubpassEndInfo) {
3065    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
3066    if (NULL == disp) {
3067        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
3068                   "vkCmdEndRenderPass2: Invalid commandBuffer [VUID-vkCmdEndRenderPass2-commandBuffer-parameter]");
3069        abort(); /* Intentionally fail so user can correct issue. */
3070    }
3071    disp->CmdEndRenderPass2(commandBuffer, pSubpassEndInfo);
3072}
3073
3074LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
3075                                                                VkBuffer countBuffer, VkDeviceSize countBufferOffset,
3076                                                                uint32_t maxDrawCount, uint32_t stride) {
3077    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
3078    if (NULL == disp) {
3079        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
3080                   "vkCmdDrawIndirectCount: Invalid commandBuffer [VUID-vkCmdDrawIndirectCount-commandBuffer-parameter]");
3081        abort(); /* Intentionally fail so user can correct issue. */
3082    }
3083    disp->CmdDrawIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount, stride);
3084}
3085
3086LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexedIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer,
3087                                                                       VkDeviceSize offset, VkBuffer countBuffer,
3088                                                                       VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
3089                                                                       uint32_t stride) {
3090    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
3091    if (NULL == disp) {
3092        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
3093                   "vkCmdDrawIndexedIndirectCount: Invalid commandBuffer "
3094                   "[VUID-vkCmdDrawIndexedIndirectCount-commandBuffer-parameter]");
3095        abort(); /* Intentionally fail so user can correct issue. */
3096    }
3097    disp->CmdDrawIndexedIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount, stride);
3098}
3099
3100LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetSemaphoreCounterValue(VkDevice device, VkSemaphore semaphore, uint64_t *pValue) {
3101    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
3102    if (NULL == disp) {
3103        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
3104                   "vkGetSemaphoreCounterValue: Invalid device [VUID-vkGetSemaphoreCounterValue-device-parameter]");
3105        abort(); /* Intentionally fail so user can correct issue. */
3106    }
3107    return disp->GetSemaphoreCounterValue(device, semaphore, pValue);
3108}
3109
3110LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkWaitSemaphores(VkDevice device, const VkSemaphoreWaitInfo *pWaitInfo,
3111                                                              uint64_t timeout) {
3112    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
3113    if (NULL == disp) {
3114        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
3115                   "vkWaitSemaphores: Invalid device [VUID-vkWaitSemaphores-device-parameter]");
3116        abort(); /* Intentionally fail so user can correct issue. */
3117    }
3118    return disp->WaitSemaphores(device, pWaitInfo, timeout);
3119}
3120
3121LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkSignalSemaphore(VkDevice device, const VkSemaphoreSignalInfo *pSignalInfo) {
3122    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
3123    if (NULL == disp) {
3124        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
3125                   "vkSignalSemaphore: Invalid device [VUID-vkSignalSemaphore-device-parameter]");
3126        abort(); /* Intentionally fail so user can correct issue. */
3127    }
3128    return disp->SignalSemaphore(device, pSignalInfo);
3129}
3130
3131LOADER_EXPORT VKAPI_ATTR VkDeviceAddress VKAPI_CALL vkGetBufferDeviceAddress(VkDevice device,
3132                                                                             const VkBufferDeviceAddressInfo *pInfo) {
3133    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
3134    if (NULL == disp) {
3135        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
3136                   "vkGetBufferDeviceAddress: Invalid device [VUID-vkGetBufferDeviceAddress-device-parameter]");
3137        abort(); /* Intentionally fail so user can correct issue. */
3138    }
3139    return disp->GetBufferDeviceAddress(device, pInfo);
3140}
3141
3142LOADER_EXPORT VKAPI_ATTR uint64_t VKAPI_CALL vkGetBufferOpaqueCaptureAddress(VkDevice device,
3143                                                                             const VkBufferDeviceAddressInfo *pInfo) {
3144    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
3145    if (NULL == disp) {
3146        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
3147                   "vkGetBufferOpaqueCaptureAddress: Invalid device [VUID-vkGetBufferOpaqueCaptureAddress-device-parameter]");
3148        abort(); /* Intentionally fail so user can correct issue. */
3149    }
3150    return disp->GetBufferOpaqueCaptureAddress(device, pInfo);
3151}
3152
3153LOADER_EXPORT VKAPI_ATTR uint64_t VKAPI_CALL
3154vkGetDeviceMemoryOpaqueCaptureAddress(VkDevice device, const VkDeviceMemoryOpaqueCaptureAddressInfo *pInfo) {
3155    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
3156    if (NULL == disp) {
3157        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
3158                   "vkGetDeviceMemoryOpaqueCaptureAddress: Invalid device "
3159                   "[VUID-vkGetDeviceMemoryOpaqueCaptureAddress-device-parameter]");
3160        abort(); /* Intentionally fail so user can correct issue. */
3161    }
3162    return disp->GetDeviceMemoryOpaqueCaptureAddress(device, pInfo);
3163}
3164
3165LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkResetQueryPool(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery,
3166                                                          uint32_t queryCount) {
3167    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
3168    if (NULL == disp) {
3169        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
3170                   "vkResetQueryPool: Invalid device [VUID-vkResetQueryPool-device-parameter]");
3171        abort(); /* Intentionally fail so user can correct issue. */
3172    }
3173    disp->ResetQueryPool(device, queryPool, firstQuery, queryCount);
3174}
3175
3176// ---- Vulkan core 1.3 trampolines
3177
3178// Instance
3179
3180LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceToolProperties(VkPhysicalDevice physicalDevice,
3181                                                                               uint32_t *pToolCount,
3182                                                                               VkPhysicalDeviceToolProperties *pToolProperties) {
3183    VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
3184    const VkLayerInstanceDispatchTable *disp = loader_get_instance_layer_dispatch(physicalDevice);
3185
3186    return disp->GetPhysicalDeviceToolProperties(unwrapped_phys_dev, pToolCount, pToolProperties);
3187}
3188
3189// Device
3190
3191LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdBeginRendering(VkCommandBuffer commandBuffer, const VkRenderingInfo *pRenderingInfo) {
3192    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
3193    disp->CmdBeginRendering(commandBuffer, pRenderingInfo);
3194}
3195
3196LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdBindVertexBuffers2(VkCommandBuffer commandBuffer, uint32_t firstBinding,
3197                                                                 uint32_t bindingCount, const VkBuffer *pBuffers,
3198                                                                 const VkDeviceSize *pOffsets, const VkDeviceSize *pSizes,
3199                                                                 const VkDeviceSize *pStrides) {
3200    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
3201    disp->CmdBindVertexBuffers2(commandBuffer, firstBinding, bindingCount, pBuffers, pOffsets, pSizes, pStrides);
3202}
3203
3204LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdBlitImage2(VkCommandBuffer commandBuffer, const VkBlitImageInfo2 *pBlitImageInfo) {
3205    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
3206    disp->CmdBlitImage2(commandBuffer, pBlitImageInfo);
3207}
3208
3209LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdCopyBuffer2(VkCommandBuffer commandBuffer, const VkCopyBufferInfo2 *pCopyBufferInfo) {
3210    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
3211    disp->CmdCopyBuffer2(commandBuffer, pCopyBufferInfo);
3212}
3213
3214LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdCopyBufferToImage2(VkCommandBuffer commandBuffer,
3215                                                                 const VkCopyBufferToImageInfo2 *pCopyBufferToImageInfo) {
3216    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
3217    disp->CmdCopyBufferToImage2(commandBuffer, pCopyBufferToImageInfo);
3218}
3219
3220LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdCopyImage2(VkCommandBuffer commandBuffer, const VkCopyImageInfo2 *pCopyImageInfo) {
3221    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
3222    disp->CmdCopyImage2(commandBuffer, pCopyImageInfo);
3223}
3224
3225LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdCopyImageToBuffer2(VkCommandBuffer commandBuffer,
3226                                                                 const VkCopyImageToBufferInfo2 *pCopyImageToBufferInfo) {
3227    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
3228    disp->CmdCopyImageToBuffer2(commandBuffer, pCopyImageToBufferInfo);
3229}
3230
3231LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdEndRendering(VkCommandBuffer commandBuffer) {
3232    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
3233    disp->CmdEndRendering(commandBuffer);
3234}
3235
3236LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdPipelineBarrier2(VkCommandBuffer commandBuffer,
3237                                                               const VkDependencyInfo *pDependencyInfo) {
3238    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
3239    disp->CmdPipelineBarrier2(commandBuffer, pDependencyInfo);
3240}
3241
3242LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdResetEvent2(VkCommandBuffer commandBuffer, VkEvent event,
3243                                                          VkPipelineStageFlags2 stageMask) {
3244    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
3245    disp->CmdResetEvent2(commandBuffer, event, stageMask);
3246}
3247
3248LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdResolveImage2(VkCommandBuffer commandBuffer,
3249                                                            const VkResolveImageInfo2 *pResolveImageInfo) {
3250    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
3251    disp->CmdResolveImage2(commandBuffer, pResolveImageInfo);
3252}
3253
3254LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetCullMode(VkCommandBuffer commandBuffer, VkCullModeFlags cullMode) {
3255    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
3256    disp->CmdSetCullMode(commandBuffer, cullMode);
3257}
3258
3259LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBiasEnable(VkCommandBuffer commandBuffer, VkBool32 depthBiasEnable) {
3260    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
3261    disp->CmdSetDepthBiasEnable(commandBuffer, depthBiasEnable);
3262}
3263
3264LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBoundsTestEnable(VkCommandBuffer commandBuffer,
3265                                                                       VkBool32 depthBoundsTestEnable) {
3266    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
3267    disp->CmdSetDepthBoundsTestEnable(commandBuffer, depthBoundsTestEnable);
3268}
3269
3270LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthCompareOp(VkCommandBuffer commandBuffer, VkCompareOp depthCompareOp) {
3271    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
3272    disp->CmdSetDepthCompareOp(commandBuffer, depthCompareOp);
3273}
3274
3275LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthTestEnable(VkCommandBuffer commandBuffer, VkBool32 depthTestEnable) {
3276    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
3277    disp->CmdSetDepthTestEnable(commandBuffer, depthTestEnable);
3278}
3279
3280LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthWriteEnable(VkCommandBuffer commandBuffer, VkBool32 depthWriteEnable) {
3281    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
3282    disp->CmdSetDepthWriteEnable(commandBuffer, depthWriteEnable);
3283}
3284
3285LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetEvent2(VkCommandBuffer commandBuffer, VkEvent event,
3286                                                        const VkDependencyInfo *pDependencyInfo) {
3287    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
3288    disp->CmdSetEvent2(commandBuffer, event, pDependencyInfo);
3289}
3290
3291LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetFrontFace(VkCommandBuffer commandBuffer, VkFrontFace frontFace) {
3292    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
3293    disp->CmdSetFrontFace(commandBuffer, frontFace);
3294}
3295
3296LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetPrimitiveRestartEnable(VkCommandBuffer commandBuffer,
3297                                                                        VkBool32 primitiveRestartEnable) {
3298    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
3299    disp->CmdSetPrimitiveRestartEnable(commandBuffer, primitiveRestartEnable);
3300}
3301
3302LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetPrimitiveTopology(VkCommandBuffer commandBuffer,
3303                                                                   VkPrimitiveTopology primitiveTopology) {
3304    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
3305    disp->CmdSetPrimitiveTopology(commandBuffer, primitiveTopology);
3306}
3307
3308LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetRasterizerDiscardEnable(VkCommandBuffer commandBuffer,
3309                                                                         VkBool32 rasterizerDiscardEnable) {
3310    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
3311    disp->CmdSetRasterizerDiscardEnable(commandBuffer, rasterizerDiscardEnable);
3312}
3313
3314LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetScissorWithCount(VkCommandBuffer commandBuffer, uint32_t scissorCount,
3315                                                                  const VkRect2D *pScissors) {
3316    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
3317    disp->CmdSetScissorWithCount(commandBuffer, scissorCount, pScissors);
3318}
3319
3320LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilOp(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask,
3321                                                           VkStencilOp failOp, VkStencilOp passOp, VkStencilOp depthFailOp,
3322                                                           VkCompareOp compareOp) {
3323    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
3324    disp->CmdSetStencilOp(commandBuffer, faceMask, failOp, passOp, depthFailOp, compareOp);
3325}
3326
3327LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilTestEnable(VkCommandBuffer commandBuffer, VkBool32 stencilTestEnable) {
3328    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
3329    disp->CmdSetStencilTestEnable(commandBuffer, stencilTestEnable);
3330}
3331
3332LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetViewportWithCount(VkCommandBuffer commandBuffer, uint32_t viewportCount,
3333                                                                   const VkViewport *pViewports) {
3334    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
3335    disp->CmdSetViewportWithCount(commandBuffer, viewportCount, pViewports);
3336}
3337
3338LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdWaitEvents2(VkCommandBuffer commandBuffer, uint32_t eventCount,
3339                                                          const VkEvent *pEvents, const VkDependencyInfo *pDependencyInfos) {
3340    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
3341    disp->CmdWaitEvents2(commandBuffer, eventCount, pEvents, pDependencyInfos);
3342}
3343
3344LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdWriteTimestamp2(VkCommandBuffer commandBuffer, VkPipelineStageFlags2 stage,
3345                                                              VkQueryPool queryPool, uint32_t query) {
3346    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
3347    disp->CmdWriteTimestamp2(commandBuffer, stage, queryPool, query);
3348}
3349
3350LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreatePrivateDataSlot(VkDevice device,
3351                                                                     const VkPrivateDataSlotCreateInfo *pCreateInfo,
3352                                                                     const VkAllocationCallbacks *pAllocator,
3353                                                                     VkPrivateDataSlot *pPrivateDataSlot) {
3354    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
3355    return disp->CreatePrivateDataSlot(device, pCreateInfo, pAllocator, pPrivateDataSlot);
3356}
3357
3358LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyPrivateDataSlot(VkDevice device, VkPrivateDataSlot privateDataSlot,
3359                                                                  const VkAllocationCallbacks *pAllocator) {
3360    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
3361    disp->DestroyPrivateDataSlot(device, privateDataSlot, pAllocator);
3362}
3363
3364LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetDeviceBufferMemoryRequirements(VkDevice device,
3365                                                                             const VkDeviceBufferMemoryRequirements *pInfo,
3366                                                                             VkMemoryRequirements2 *pMemoryRequirements) {
3367    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
3368    disp->GetDeviceBufferMemoryRequirements(device, pInfo, pMemoryRequirements);
3369}
3370
3371LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetDeviceImageMemoryRequirements(VkDevice device,
3372                                                                            const VkDeviceImageMemoryRequirements *pInfo,
3373                                                                            VkMemoryRequirements2 *pMemoryRequirements) {
3374    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
3375    disp->GetDeviceImageMemoryRequirements(device, pInfo, pMemoryRequirements);
3376}
3377
3378LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetDeviceImageSparseMemoryRequirements(
3379    VkDevice device, const VkDeviceImageMemoryRequirements *pInfo, uint32_t *pSparseMemoryRequirementCount,
3380    VkSparseImageMemoryRequirements2 *pSparseMemoryRequirements) {
3381    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
3382    disp->GetDeviceImageSparseMemoryRequirements(device, pInfo, pSparseMemoryRequirementCount, pSparseMemoryRequirements);
3383}
3384
3385LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetPrivateData(VkDevice device, VkObjectType objectType, uint64_t objectHandle,
3386                                                          VkPrivateDataSlot privateDataSlot, uint64_t *pData) {
3387    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
3388    disp->GetPrivateData(device, objectType, objectHandle, privateDataSlot, pData);
3389}
3390
3391LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkSetPrivateData(VkDevice device, VkObjectType objectType, uint64_t objectHandle,
3392                                                              VkPrivateDataSlot privateDataSlot, uint64_t data) {
3393    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
3394    return disp->SetPrivateData(device, objectType, objectHandle, privateDataSlot, data);
3395}
3396
3397LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkQueueSubmit2(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2 *pSubmits,
3398                                                            VkFence fence) {
3399    const VkLayerDispatchTable *disp = loader_get_dispatch(queue);
3400    return disp->QueueSubmit2(queue, submitCount, pSubmits, fence);
3401}
3402