1 /*
2  *
3  * Copyright (c) 2015-2016 The Khronos Group Inc.
4  * Copyright (c) 2015-2016 Valve Corporation
5  * Copyright (c) 2015-2016 LunarG, Inc.
6  * Copyright (C) 2015 Google Inc.
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a copy
9  * of this software and/or associated documentation files (the "Materials"), to
10  * deal in the Materials without restriction, including without limitation the
11  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
12  * sell copies of the Materials, and to permit persons to whom the Materials are
13  * furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice(s) and this permission notice shall be included in
16  * all copies or substantial portions of the Materials.
17  *
18  * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21  *
22  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
23  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
24  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
25  * USE OR OTHER DEALINGS IN THE MATERIALS.
26  *
27  * Author: Courtney Goeltzenleuchter <courtney@lunarg.com>
28  * Author: Jon Ashburn <jon@lunarg.com>
29  * Author: Tony Barbour <tony@LunarG.com>
30  * Author: Chia-I Wu <olv@lunarg.com>
31  */
32 #define _GNU_SOURCE
33 #include <stdlib.h>
34 #include <string.h>
35 
36 #include "vk_loader_platform.h"
37 #include "loader.h"
38 #include "debug_report.h"
39 #include "wsi.h"
40 #include "gpa_helper.h"
41 #include "table_ops.h"
42 
43 /* Trampoline entrypoints are in this file for core Vulkan commands */
44 /**
45  * Get an instance level or global level entry point address.
46  * @param instance
47  * @param pName
48  * @return
49  *    If instance == NULL returns a global level functions only
50  *    If instance is valid returns a trampoline entry point for all dispatchable
51  * Vulkan
52  *    functions both core and extensions.
53  */
54 LOADER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
vkGetInstanceProcAddr(VkInstance instance,const char * pName)55 vkGetInstanceProcAddr(VkInstance instance, const char *pName) {
56 
57     void *addr;
58 
59     addr = globalGetProcAddr(pName);
60     if (instance == VK_NULL_HANDLE) {
61         // get entrypoint addresses that are global (no dispatchable object)
62 
63         return addr;
64     } else {
65         // if a global entrypoint return NULL
66         if (addr)
67             return NULL;
68     }
69 
70     struct loader_instance *ptr_instance = loader_get_instance(instance);
71     if (ptr_instance == NULL)
72         return NULL;
73     // Return trampoline code for non-global entrypoints including any
74     // extensions.
75     // Device extensions are returned if a layer or ICD supports the extension.
76     // Instance extensions are returned if the extension is enabled and the
77     // loader
78     // or someone else supports the extension
79     return trampolineGetProcAddr(ptr_instance, pName);
80 }
81 
82 /**
83  * Get a device level or global level entry point address.
84  * @param device
85  * @param pName
86  * @return
87  *    If device is valid, returns a device relative entry point for device level
88  *    entry points both core and extensions.
89  *    Device relative means call down the device chain.
90  */
91 LOADER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
vkGetDeviceProcAddr(VkDevice device,const char * pName)92 vkGetDeviceProcAddr(VkDevice device, const char *pName) {
93     void *addr;
94 
95     /* for entrypoints that loader must handle (ie non-dispatchable or create
96        object)
97        make sure the loader entrypoint is returned */
98     addr = loader_non_passthrough_gdpa(pName);
99     if (addr) {
100         return addr;
101     }
102 
103     /* Although CreateDevice is on device chain it's dispatchable object isn't
104      * a VkDevice or child of VkDevice so return NULL.
105      */
106     if (!strcmp(pName, "CreateDevice"))
107         return NULL;
108 
109     /* return the dispatch table entrypoint for the fastest case */
110     const VkLayerDispatchTable *disp_table = *(VkLayerDispatchTable **)device;
111     if (disp_table == NULL)
112         return NULL;
113 
114     addr = loader_lookup_device_dispatch_table(disp_table, pName);
115     if (addr)
116         return addr;
117 
118     if (disp_table->GetDeviceProcAddr == NULL)
119         return NULL;
120     return disp_table->GetDeviceProcAddr(device, pName);
121 }
122 
123 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
vkEnumerateInstanceExtensionProperties(const char * pLayerName,uint32_t * pPropertyCount,VkExtensionProperties * pProperties)124 vkEnumerateInstanceExtensionProperties(const char *pLayerName,
125                                        uint32_t *pPropertyCount,
126                                        VkExtensionProperties *pProperties) {
127     struct loader_extension_list *global_ext_list = NULL;
128     struct loader_layer_list instance_layers;
129     struct loader_extension_list icd_extensions;
130     struct loader_icd_libs icd_libs;
131     uint32_t copy_size;
132 
133     tls_instance = NULL;
134     memset(&icd_extensions, 0, sizeof(icd_extensions));
135     memset(&instance_layers, 0, sizeof(instance_layers));
136     loader_platform_thread_once(&once_init, loader_initialize);
137 
138     /* get layer libraries if needed */
139     if (pLayerName && strlen(pLayerName) != 0) {
140         if (vk_string_validate(MaxLoaderStringLength, pLayerName) ==
141             VK_STRING_ERROR_NONE) {
142             loader_layer_scan(NULL, &instance_layers, NULL);
143             for (uint32_t i = 0; i < instance_layers.count; i++) {
144                 struct loader_layer_properties *props =
145                     &instance_layers.list[i];
146                 if (strcmp(props->info.layerName, pLayerName) == 0) {
147                     global_ext_list = &props->instance_extension_list;
148                 }
149             }
150         } else {
151             assert(VK_FALSE && "vkEnumerateInstanceExtensionProperties:  "
152                                "pLayerName is too long or is badly formed");
153             return VK_ERROR_EXTENSION_NOT_PRESENT;
154         }
155     } else {
156         /* Scan/discover all ICD libraries */
157         memset(&icd_libs, 0, sizeof(struct loader_icd_libs));
158         loader_icd_scan(NULL, &icd_libs);
159         /* get extensions from all ICD's, merge so no duplicates */
160         loader_get_icd_loader_instance_extensions(NULL, &icd_libs,
161                                                   &icd_extensions);
162         loader_scanned_icd_clear(NULL, &icd_libs);
163         global_ext_list = &icd_extensions;
164     }
165 
166     if (global_ext_list == NULL) {
167         loader_destroy_layer_list(NULL, &instance_layers);
168         return VK_ERROR_LAYER_NOT_PRESENT;
169     }
170 
171     if (pProperties == NULL) {
172         *pPropertyCount = global_ext_list->count;
173         loader_destroy_layer_list(NULL, &instance_layers);
174         loader_destroy_generic_list(
175             NULL, (struct loader_generic_list *)&icd_extensions);
176         return VK_SUCCESS;
177     }
178 
179     copy_size = *pPropertyCount < global_ext_list->count
180                     ? *pPropertyCount
181                     : global_ext_list->count;
182     for (uint32_t i = 0; i < copy_size; i++) {
183         memcpy(&pProperties[i], &global_ext_list->list[i],
184                sizeof(VkExtensionProperties));
185     }
186     *pPropertyCount = copy_size;
187     loader_destroy_generic_list(NULL,
188                                 (struct loader_generic_list *)&icd_extensions);
189 
190     if (copy_size < global_ext_list->count) {
191         loader_destroy_layer_list(NULL, &instance_layers);
192         return VK_INCOMPLETE;
193     }
194 
195     loader_destroy_layer_list(NULL, &instance_layers);
196     return VK_SUCCESS;
197 }
198 
199 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
vkEnumerateInstanceLayerProperties(uint32_t * pPropertyCount,VkLayerProperties * pProperties)200 vkEnumerateInstanceLayerProperties(uint32_t *pPropertyCount,
201                                    VkLayerProperties *pProperties) {
202 
203     struct loader_layer_list instance_layer_list;
204     tls_instance = NULL;
205 
206     loader_platform_thread_once(&once_init, loader_initialize);
207 
208     uint32_t copy_size;
209 
210     /* get layer libraries */
211     memset(&instance_layer_list, 0, sizeof(instance_layer_list));
212     loader_layer_scan(NULL, &instance_layer_list, NULL);
213 
214     if (pProperties == NULL) {
215         *pPropertyCount = instance_layer_list.count;
216         loader_destroy_layer_list(NULL, &instance_layer_list);
217         return VK_SUCCESS;
218     }
219 
220     copy_size = (*pPropertyCount < instance_layer_list.count)
221                     ? *pPropertyCount
222                     : instance_layer_list.count;
223     for (uint32_t i = 0; i < copy_size; i++) {
224         memcpy(&pProperties[i], &instance_layer_list.list[i].info,
225                sizeof(VkLayerProperties));
226     }
227 
228     *pPropertyCount = copy_size;
229     loader_destroy_layer_list(NULL, &instance_layer_list);
230 
231     if (copy_size < instance_layer_list.count) {
232         return VK_INCOMPLETE;
233     }
234 
235     return VK_SUCCESS;
236 }
237 
238 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
vkCreateInstance(const VkInstanceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkInstance * pInstance)239 vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo,
240                  const VkAllocationCallbacks *pAllocator,
241                  VkInstance *pInstance) {
242     struct loader_instance *ptr_instance = NULL;
243     VkInstance created_instance = VK_NULL_HANDLE;
244     VkResult res = VK_ERROR_INITIALIZATION_FAILED;
245     VkDebugReportCallbackEXT instance_callback = VK_NULL_HANDLE;
246     void *pNext = (void *)pCreateInfo->pNext;
247 
248     loader_platform_thread_once(&once_init, loader_initialize);
249 
250 #if 0
251 	if (pAllocator) {
252         ptr_instance = (struct loader_instance *) pAllocator->pfnAllocation(
253                            pAllocator->pUserData,
254                            sizeof(struct loader_instance),
255                            sizeof(int *),
256                            VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
257     } else {
258 #endif
259     ptr_instance =
260         (struct loader_instance *)malloc(sizeof(struct loader_instance));
261     //}
262     if (ptr_instance == NULL) {
263         return VK_ERROR_OUT_OF_HOST_MEMORY;
264     }
265 
266     tls_instance = ptr_instance;
267     loader_platform_thread_lock_mutex(&loader_lock);
268     memset(ptr_instance, 0, sizeof(struct loader_instance));
269 #if 0
270     if (pAllocator) {
271         ptr_instance->alloc_callbacks = *pAllocator;
272     }
273 #endif
274 
275     /*
276      * Look for a debug report create info structure
277      * and setup a callback if found.
278      */
279     while (pNext) {
280         if (((VkInstanceCreateInfo *)pNext)->sType ==
281             VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT) {
282             instance_callback = (VkDebugReportCallbackEXT)ptr_instance;
283             if (util_CreateDebugReportCallback(ptr_instance, pNext, NULL,
284                                                instance_callback)) {
285                 loader_heap_free(ptr_instance, ptr_instance);
286                 loader_platform_thread_unlock_mutex(&loader_lock);
287                 return VK_ERROR_OUT_OF_HOST_MEMORY;
288             }
289         }
290         pNext = (void *)((VkInstanceCreateInfo *)pNext)->pNext;
291     }
292 
293     /* Due to implicit layers need to get layer list even if
294      * enabledLayerCount == 0 and VK_INSTANCE_LAYERS is unset. For now always
295      * get layer list (both instance and device) via loader_layer_scan(). */
296     memset(&ptr_instance->instance_layer_list, 0,
297            sizeof(ptr_instance->instance_layer_list));
298     memset(&ptr_instance->device_layer_list, 0,
299            sizeof(ptr_instance->device_layer_list));
300     loader_layer_scan(ptr_instance, &ptr_instance->instance_layer_list,
301                       &ptr_instance->device_layer_list);
302 
303     /* validate the app requested layers to be enabled */
304     if (pCreateInfo->enabledLayerCount > 0) {
305         res =
306             loader_validate_layers(ptr_instance, pCreateInfo->enabledLayerCount,
307                                    pCreateInfo->ppEnabledLayerNames,
308                                    &ptr_instance->instance_layer_list);
309         if (res != VK_SUCCESS) {
310             util_DestroyDebugReportCallback(ptr_instance, instance_callback,
311                                             NULL);
312             loader_heap_free(ptr_instance, ptr_instance);
313             loader_platform_thread_unlock_mutex(&loader_lock);
314             return res;
315         }
316     }
317 
318     /* convert any meta layers to the actual layers makes a copy of layer name*/
319     uint32_t saved_layer_count = pCreateInfo->enabledLayerCount;
320     char **saved_layer_names;
321     char **saved_layer_ptr;
322     saved_layer_names =
323         loader_stack_alloc(sizeof(char *) * pCreateInfo->enabledLayerCount);
324     for (uint32_t i = 0; i < saved_layer_count; i++) {
325         saved_layer_names[i] = (char *)pCreateInfo->ppEnabledLayerNames[i];
326     }
327     saved_layer_ptr = (char **)pCreateInfo->ppEnabledLayerNames;
328 
329     loader_expand_layer_names(
330         ptr_instance, std_validation_str,
331         sizeof(std_validation_names) / sizeof(std_validation_names[0]),
332         std_validation_names, (uint32_t *)&pCreateInfo->enabledLayerCount,
333         (char ***)&pCreateInfo->ppEnabledLayerNames);
334 
335     /* Scan/discover all ICD libraries */
336     memset(&ptr_instance->icd_libs, 0, sizeof(ptr_instance->icd_libs));
337     loader_icd_scan(ptr_instance, &ptr_instance->icd_libs);
338 
339     /* get extensions from all ICD's, merge so no duplicates, then validate */
340     loader_get_icd_loader_instance_extensions(
341         ptr_instance, &ptr_instance->icd_libs, &ptr_instance->ext_list);
342     res = loader_validate_instance_extensions(
343         ptr_instance, &ptr_instance->ext_list,
344         &ptr_instance->instance_layer_list, pCreateInfo);
345     if (res != VK_SUCCESS) {
346         loader_unexpand_inst_layer_names(ptr_instance, saved_layer_count,
347                                          saved_layer_names, saved_layer_ptr,
348                                          pCreateInfo);
349         loader_delete_layer_properties(ptr_instance,
350                                        &ptr_instance->device_layer_list);
351         loader_delete_layer_properties(ptr_instance,
352                                        &ptr_instance->instance_layer_list);
353         loader_scanned_icd_clear(ptr_instance, &ptr_instance->icd_libs);
354         loader_destroy_generic_list(
355             ptr_instance,
356             (struct loader_generic_list *)&ptr_instance->ext_list);
357         util_DestroyDebugReportCallback(ptr_instance, instance_callback, NULL);
358         loader_platform_thread_unlock_mutex(&loader_lock);
359         loader_heap_free(ptr_instance, ptr_instance);
360         return res;
361     }
362 
363     ptr_instance->disp =
364         loader_heap_alloc(ptr_instance, sizeof(VkLayerInstanceDispatchTable),
365                           VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
366     if (ptr_instance->disp == NULL) {
367         loader_unexpand_inst_layer_names(ptr_instance, saved_layer_count,
368                                          saved_layer_names, saved_layer_ptr,
369                                          pCreateInfo);
370         loader_delete_layer_properties(ptr_instance,
371                                        &ptr_instance->device_layer_list);
372         loader_delete_layer_properties(ptr_instance,
373                                        &ptr_instance->instance_layer_list);
374         loader_scanned_icd_clear(ptr_instance, &ptr_instance->icd_libs);
375         loader_destroy_generic_list(
376             ptr_instance,
377             (struct loader_generic_list *)&ptr_instance->ext_list);
378         util_DestroyDebugReportCallback(ptr_instance, instance_callback, NULL);
379         loader_platform_thread_unlock_mutex(&loader_lock);
380         loader_heap_free(ptr_instance, ptr_instance);
381         return VK_ERROR_OUT_OF_HOST_MEMORY;
382     }
383     memcpy(ptr_instance->disp, &instance_disp, sizeof(instance_disp));
384     ptr_instance->next = loader.instances;
385     loader.instances = ptr_instance;
386 
387     /* activate any layers on instance chain */
388     res = loader_enable_instance_layers(ptr_instance, pCreateInfo,
389                                         &ptr_instance->instance_layer_list);
390     if (res != VK_SUCCESS) {
391         loader_unexpand_inst_layer_names(ptr_instance, saved_layer_count,
392                                          saved_layer_names, saved_layer_ptr,
393                                          pCreateInfo);
394         loader_delete_layer_properties(ptr_instance,
395                                        &ptr_instance->device_layer_list);
396         loader_delete_layer_properties(ptr_instance,
397                                        &ptr_instance->instance_layer_list);
398         loader_scanned_icd_clear(ptr_instance, &ptr_instance->icd_libs);
399         loader_destroy_generic_list(
400             ptr_instance,
401             (struct loader_generic_list *)&ptr_instance->ext_list);
402         loader.instances = ptr_instance->next;
403         util_DestroyDebugReportCallback(ptr_instance, instance_callback, NULL);
404         loader_platform_thread_unlock_mutex(&loader_lock);
405         loader_heap_free(ptr_instance, ptr_instance->disp);
406         loader_heap_free(ptr_instance, ptr_instance);
407         return res;
408     }
409 
410     created_instance = (VkInstance)ptr_instance;
411     res = loader_create_instance_chain(pCreateInfo, pAllocator, ptr_instance,
412                                        &created_instance);
413 
414     if (res == VK_SUCCESS) {
415         wsi_create_instance(ptr_instance, pCreateInfo);
416         debug_report_create_instance(ptr_instance, pCreateInfo);
417 
418         *pInstance = created_instance;
419 
420         /*
421          * Finally have the layers in place and everyone has seen
422          * the CreateInstance command go by. This allows the layer's
423          * GetInstanceProcAddr functions to return valid extension functions
424          * if enabled.
425          */
426         loader_activate_instance_layer_extensions(ptr_instance, *pInstance);
427     } else {
428         // TODO: cleanup here.
429     }
430 
431     /* Remove temporary debug_report callback */
432     util_DestroyDebugReportCallback(ptr_instance, instance_callback, NULL);
433     loader_unexpand_inst_layer_names(ptr_instance, saved_layer_count,
434                                      saved_layer_names, saved_layer_ptr,
435                                      pCreateInfo);
436     loader_platform_thread_unlock_mutex(&loader_lock);
437     return res;
438 }
439 
440 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
441 vkDestroyInstance(VkInstance instance,
442                   const VkAllocationCallbacks *pAllocator) {
443     const VkLayerInstanceDispatchTable *disp;
444     struct loader_instance *ptr_instance = NULL;
445     disp = loader_get_instance_dispatch(instance);
446 
447     loader_platform_thread_lock_mutex(&loader_lock);
448 
449     /* TODO: Do we need a temporary callback here to catch cleanup issues? */
450 
451     ptr_instance = loader_get_instance(instance);
452     disp->DestroyInstance(instance, pAllocator);
453 
454     loader_deactivate_instance_layers(ptr_instance);
455     if (ptr_instance->phys_devs)
456         loader_heap_free(ptr_instance, ptr_instance->phys_devs);
457     loader_heap_free(ptr_instance, ptr_instance->disp);
458     loader_heap_free(ptr_instance, ptr_instance);
459     loader_platform_thread_unlock_mutex(&loader_lock);
460 }
461 
462 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
463 vkEnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount,
464                            VkPhysicalDevice *pPhysicalDevices) {
465     const VkLayerInstanceDispatchTable *disp;
466     VkResult res;
467     uint32_t count, i;
468     struct loader_instance *inst;
469     disp = loader_get_instance_dispatch(instance);
470 
471     loader_platform_thread_lock_mutex(&loader_lock);
472     res = disp->EnumeratePhysicalDevices(instance, pPhysicalDeviceCount,
473                                          pPhysicalDevices);
474 
475     if (res != VK_SUCCESS && res != VK_INCOMPLETE) {
476         loader_platform_thread_unlock_mutex(&loader_lock);
477         return res;
478     }
479 
480     if (!pPhysicalDevices) {
481         loader_platform_thread_unlock_mutex(&loader_lock);
482         return res;
483     }
484 
485     // wrap the PhysDev object for loader usage, return wrapped objects
486     inst = loader_get_instance(instance);
487     if (!inst) {
488         loader_platform_thread_unlock_mutex(&loader_lock);
489         return VK_ERROR_INITIALIZATION_FAILED;
490     }
491     if (inst->phys_devs)
492         loader_heap_free(inst, inst->phys_devs);
493     count = inst->total_gpu_count;
494     inst->phys_devs = (struct loader_physical_device *)loader_heap_alloc(
495         inst, count * sizeof(struct loader_physical_device),
496         VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
497     if (!inst->phys_devs) {
498         loader_platform_thread_unlock_mutex(&loader_lock);
499         return VK_ERROR_OUT_OF_HOST_MEMORY;
500     }
501 
502     for (i = 0; i < count; i++) {
503 
504         // initialize the loader's physicalDevice object
505         loader_set_dispatch((void *)&inst->phys_devs[i], inst->disp);
506         inst->phys_devs[i].this_icd = inst->phys_devs_term[i].this_icd;
507         inst->phys_devs[i].phys_dev = pPhysicalDevices[i];
508 
509         // copy wrapped object into Application provided array
510         pPhysicalDevices[i] = (VkPhysicalDevice)&inst->phys_devs[i];
511     }
512     loader_platform_thread_unlock_mutex(&loader_lock);
513     return res;
514 }
515 
516 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
517 vkGetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice,
518                             VkPhysicalDeviceFeatures *pFeatures) {
519     const VkLayerInstanceDispatchTable *disp;
520     VkPhysicalDevice unwrapped_phys_dev =
521         loader_unwrap_physical_device(physicalDevice);
522     disp = loader_get_instance_dispatch(physicalDevice);
523     disp->GetPhysicalDeviceFeatures(unwrapped_phys_dev, pFeatures);
524 }
525 
526 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
527 vkGetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice,
528                                     VkFormat format,
529                                     VkFormatProperties *pFormatInfo) {
530     const VkLayerInstanceDispatchTable *disp;
531     VkPhysicalDevice unwrapped_pd =
532         loader_unwrap_physical_device(physicalDevice);
533     disp = loader_get_instance_dispatch(physicalDevice);
534     disp->GetPhysicalDeviceFormatProperties(unwrapped_pd, format, pFormatInfo);
535 }
536 
537 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
538 vkGetPhysicalDeviceImageFormatProperties(
539     VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type,
540     VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags,
541     VkImageFormatProperties *pImageFormatProperties) {
542     const VkLayerInstanceDispatchTable *disp;
543     VkPhysicalDevice unwrapped_phys_dev =
544         loader_unwrap_physical_device(physicalDevice);
545     disp = loader_get_instance_dispatch(physicalDevice);
546     return disp->GetPhysicalDeviceImageFormatProperties(
547         unwrapped_phys_dev, format, type, tiling, usage, flags,
548         pImageFormatProperties);
549 }
550 
551 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
552 vkGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,
553                               VkPhysicalDeviceProperties *pProperties) {
554     const VkLayerInstanceDispatchTable *disp;
555     VkPhysicalDevice unwrapped_phys_dev =
556         loader_unwrap_physical_device(physicalDevice);
557     disp = loader_get_instance_dispatch(physicalDevice);
558     disp->GetPhysicalDeviceProperties(unwrapped_phys_dev, pProperties);
559 }
560 
561 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
562 vkGetPhysicalDeviceQueueFamilyProperties(
563     VkPhysicalDevice physicalDevice, uint32_t *pQueueFamilyPropertyCount,
564     VkQueueFamilyProperties *pQueueProperties) {
565     const VkLayerInstanceDispatchTable *disp;
566     VkPhysicalDevice unwrapped_phys_dev =
567         loader_unwrap_physical_device(physicalDevice);
568     disp = loader_get_instance_dispatch(physicalDevice);
569     disp->GetPhysicalDeviceQueueFamilyProperties(
570         unwrapped_phys_dev, pQueueFamilyPropertyCount, pQueueProperties);
571 }
572 
573 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceMemoryProperties(
574     VkPhysicalDevice physicalDevice,
575     VkPhysicalDeviceMemoryProperties *pMemoryProperties) {
576     const VkLayerInstanceDispatchTable *disp;
577     VkPhysicalDevice unwrapped_phys_dev =
578         loader_unwrap_physical_device(physicalDevice);
579     disp = loader_get_instance_dispatch(physicalDevice);
580     disp->GetPhysicalDeviceMemoryProperties(unwrapped_phys_dev,
581                                             pMemoryProperties);
582 }
583 
584 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
585 vkCreateDevice(VkPhysicalDevice physicalDevice,
586                const VkDeviceCreateInfo *pCreateInfo,
587                const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) {
588     VkResult res;
589     struct loader_physical_device *phys_dev;
590     struct loader_icd *icd;
591     struct loader_device *dev;
592     struct loader_instance *inst;
593     struct loader_layer_list activated_layer_list = {0};
594 
595     assert(pCreateInfo->queueCreateInfoCount >= 1);
596 
597     loader_platform_thread_lock_mutex(&loader_lock);
598 
599     phys_dev = (struct loader_physical_device *)physicalDevice;
600     icd = phys_dev->this_icd;
601     if (!icd) {
602         loader_platform_thread_unlock_mutex(&loader_lock);
603         return VK_ERROR_INITIALIZATION_FAILED;
604     }
605 
606     inst = (struct loader_instance *)phys_dev->this_icd->this_instance;
607 
608     if (!icd->CreateDevice) {
609         loader_platform_thread_unlock_mutex(&loader_lock);
610         return VK_ERROR_INITIALIZATION_FAILED;
611     }
612 
613     /* validate any app enabled layers are available */
614     if (pCreateInfo->enabledLayerCount > 0) {
615         res = loader_validate_layers(inst, pCreateInfo->enabledLayerCount,
616                                      pCreateInfo->ppEnabledLayerNames,
617                                      &inst->device_layer_list);
618         if (res != VK_SUCCESS) {
619             loader_platform_thread_unlock_mutex(&loader_lock);
620             return res;
621         }
622     }
623 
624     /* Get the physical device (ICD) extensions  */
625     struct loader_extension_list icd_exts;
626     if (!loader_init_generic_list(inst, (struct loader_generic_list *)&icd_exts,
627                                   sizeof(VkExtensionProperties))) {
628         loader_platform_thread_unlock_mutex(&loader_lock);
629         return VK_ERROR_OUT_OF_HOST_MEMORY;
630     }
631 
632     //TODO handle more than one phys dev per icd (icd->phys_devs[0])
633     res = loader_add_device_extensions(
634         inst, icd, icd->phys_devs[0],
635         phys_dev->this_icd->this_icd_lib->lib_name, &icd_exts);
636     if (res != VK_SUCCESS) {
637         loader_platform_thread_unlock_mutex(&loader_lock);
638         return res;
639     }
640 
641     /* convert any meta layers to the actual layers makes a copy of layer name*/
642     uint32_t saved_layer_count = pCreateInfo->enabledLayerCount;
643     char **saved_layer_names;
644     char **saved_layer_ptr;
645     saved_layer_names =
646         loader_stack_alloc(sizeof(char *) * pCreateInfo->enabledLayerCount);
647     for (uint32_t i = 0; i < saved_layer_count; i++) {
648         saved_layer_names[i] = (char *)pCreateInfo->ppEnabledLayerNames[i];
649     }
650     saved_layer_ptr = (char **)pCreateInfo->ppEnabledLayerNames;
651 
652     loader_expand_layer_names(
653         inst, std_validation_str,
654         sizeof(std_validation_names) / sizeof(std_validation_names[0]),
655         std_validation_names, (uint32_t *)&pCreateInfo->enabledLayerCount,
656         (char ***)&pCreateInfo->ppEnabledLayerNames);
657 
658     /* fetch a list of all layers activated, explicit and implicit */
659     res = loader_enable_device_layers(inst, icd, &activated_layer_list,
660                                       pCreateInfo, &inst->device_layer_list);
661     if (res != VK_SUCCESS) {
662         loader_unexpand_dev_layer_names(inst, saved_layer_count,
663                                         saved_layer_names, saved_layer_ptr,
664                                         pCreateInfo);
665         loader_platform_thread_unlock_mutex(&loader_lock);
666         return res;
667     }
668 
669     /* make sure requested extensions to be enabled are supported */
670     res = loader_validate_device_extensions(phys_dev, &activated_layer_list,
671                                             &icd_exts, pCreateInfo);
672     if (res != VK_SUCCESS) {
673         loader_unexpand_dev_layer_names(inst, saved_layer_count,
674                                         saved_layer_names, saved_layer_ptr,
675                                         pCreateInfo);
676         loader_destroy_generic_list(
677             inst, (struct loader_generic_list *)&activated_layer_list);
678         loader_platform_thread_unlock_mutex(&loader_lock);
679         return res;
680     }
681 
682     dev = loader_add_logical_device(inst, &icd->logical_device_list);
683     if (dev == NULL) {
684         loader_unexpand_dev_layer_names(inst, saved_layer_count,
685                                         saved_layer_names, saved_layer_ptr,
686                                         pCreateInfo);
687         loader_destroy_generic_list(
688             inst, (struct loader_generic_list *)&activated_layer_list);
689         loader_platform_thread_unlock_mutex(&loader_lock);
690         return VK_ERROR_OUT_OF_HOST_MEMORY;
691     }
692 
693     /* move the locally filled layer list into the device, and pass ownership of
694      * the memory */
695     dev->activated_layer_list.capacity = activated_layer_list.capacity;
696     dev->activated_layer_list.count = activated_layer_list.count;
697     dev->activated_layer_list.list = activated_layer_list.list;
698     memset(&activated_layer_list, 0, sizeof(activated_layer_list));
699 
700     /* activate any layers on device chain which terminates with device*/
701     res = loader_enable_device_layers(inst, icd, &dev->activated_layer_list,
702                                       pCreateInfo, &inst->device_layer_list);
703     if (res != VK_SUCCESS) {
704         loader_unexpand_dev_layer_names(inst, saved_layer_count,
705                                         saved_layer_names, saved_layer_ptr,
706                                         pCreateInfo);
707         loader_remove_logical_device(inst, icd, dev);
708         loader_platform_thread_unlock_mutex(&loader_lock);
709         return res;
710     }
711 
712     res = loader_create_device_chain(phys_dev, pCreateInfo, pAllocator, inst,
713                                      icd, dev);
714     if (res != VK_SUCCESS) {
715         loader_unexpand_dev_layer_names(inst, saved_layer_count,
716                                         saved_layer_names, saved_layer_ptr,
717                                         pCreateInfo);
718         loader_remove_logical_device(inst, icd, dev);
719         loader_platform_thread_unlock_mutex(&loader_lock);
720         return res;
721     }
722 
723     *pDevice = dev->device;
724 
725     /* initialize any device extension dispatch entry's from the instance list*/
726     loader_init_dispatch_dev_ext(inst, dev);
727 
728     /* initialize WSI device extensions as part of core dispatch since loader
729      * has
730      * dedicated trampoline code for these*/
731     loader_init_device_extension_dispatch_table(
732         &dev->loader_dispatch,
733         dev->loader_dispatch.core_dispatch.GetDeviceProcAddr, *pDevice);
734 
735     loader_unexpand_dev_layer_names(inst, saved_layer_count, saved_layer_names,
736                                     saved_layer_ptr, pCreateInfo);
737 
738     loader_platform_thread_unlock_mutex(&loader_lock);
739     return res;
740 }
741 
742 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
743 vkDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
744     const VkLayerDispatchTable *disp;
745     struct loader_device *dev;
746 
747     loader_platform_thread_lock_mutex(&loader_lock);
748 
749     struct loader_icd *icd = loader_get_icd_and_device(device, &dev);
750     const struct loader_instance *inst = icd->this_instance;
751     disp = loader_get_dispatch(device);
752 
753     disp->DestroyDevice(device, pAllocator);
754     dev->device = NULL;
755     loader_remove_logical_device(inst, icd, dev);
756 
757     loader_platform_thread_unlock_mutex(&loader_lock);
758 }
759 
760 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
761 vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
762                                      const char *pLayerName,
763                                      uint32_t *pPropertyCount,
764                                      VkExtensionProperties *pProperties) {
765     VkResult res = VK_SUCCESS;
766     struct loader_physical_device *phys_dev;
767     phys_dev = (struct loader_physical_device *)physicalDevice;
768 
769     loader_platform_thread_lock_mutex(&loader_lock);
770 
771     /* If pLayerName == NULL, then querying ICD extensions, pass this call
772        down the instance chain which will terminate in the ICD. This allows
773        layers to filter the extensions coming back up the chain.
774        If pLayerName != NULL then get layer extensions from manifest file.  */
775     if (pLayerName == NULL || strlen(pLayerName) == 0) {
776         const VkLayerInstanceDispatchTable *disp;
777 
778         disp = loader_get_instance_dispatch(physicalDevice);
779         res = disp->EnumerateDeviceExtensionProperties(
780             phys_dev->phys_dev, NULL, pPropertyCount, pProperties);
781     } else {
782 
783         uint32_t count;
784         uint32_t copy_size;
785         const struct loader_instance *inst = phys_dev->this_icd->this_instance;
786         if (vk_string_validate(MaxLoaderStringLength, pLayerName) ==
787             VK_STRING_ERROR_NONE) {
788 
789             struct loader_device_extension_list *dev_ext_list = NULL;
790             for (uint32_t i = 0; i < inst->device_layer_list.count; i++) {
791                 struct loader_layer_properties *props =
792                     &inst->device_layer_list.list[i];
793                 if (strcmp(props->info.layerName, pLayerName) == 0) {
794                     dev_ext_list = &props->device_extension_list;
795                 }
796             }
797             count = (dev_ext_list == NULL) ? 0 : dev_ext_list->count;
798             if (pProperties == NULL) {
799                 *pPropertyCount = count;
800                 loader_platform_thread_unlock_mutex(&loader_lock);
801                 return VK_SUCCESS;
802             }
803 
804             copy_size = *pPropertyCount < count ? *pPropertyCount : count;
805             for (uint32_t i = 0; i < copy_size; i++) {
806                 memcpy(&pProperties[i], &dev_ext_list->list[i].props,
807                        sizeof(VkExtensionProperties));
808             }
809             *pPropertyCount = copy_size;
810 
811             if (copy_size < count) {
812                 loader_platform_thread_unlock_mutex(&loader_lock);
813                 return VK_INCOMPLETE;
814             }
815         } else {
816             loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
817                        "vkEnumerateDeviceExtensionProperties:  pLayerName "
818                        "is too long or is badly formed");
819             loader_platform_thread_unlock_mutex(&loader_lock);
820             return VK_ERROR_EXTENSION_NOT_PRESENT;
821         }
822     }
823 
824     loader_platform_thread_unlock_mutex(&loader_lock);
825     return res;
826 }
827 
828 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
829 vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice,
830                                  uint32_t *pPropertyCount,
831                                  VkLayerProperties *pProperties) {
832     uint32_t copy_size;
833     struct loader_physical_device *phys_dev;
834 
835     loader_platform_thread_lock_mutex(&loader_lock);
836 
837     /* Don't dispatch this call down the instance chain, want all device layers
838        enumerated and instance chain may not contain all device layers */
839 
840     phys_dev = (struct loader_physical_device *)physicalDevice;
841     const struct loader_instance *inst = phys_dev->this_icd->this_instance;
842     uint32_t count = inst->device_layer_list.count;
843 
844     if (pProperties == NULL) {
845         *pPropertyCount = count;
846         loader_platform_thread_unlock_mutex(&loader_lock);
847         return VK_SUCCESS;
848     }
849 
850     copy_size = (*pPropertyCount < count) ? *pPropertyCount : count;
851     for (uint32_t i = 0; i < copy_size; i++) {
852         memcpy(&pProperties[i], &(inst->device_layer_list.list[i].info),
853                sizeof(VkLayerProperties));
854     }
855     *pPropertyCount = copy_size;
856 
857     if (copy_size < count) {
858         loader_platform_thread_unlock_mutex(&loader_lock);
859         return VK_INCOMPLETE;
860     }
861 
862     loader_platform_thread_unlock_mutex(&loader_lock);
863     return VK_SUCCESS;
864 }
865 
866 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
867 vkGetDeviceQueue(VkDevice device, uint32_t queueNodeIndex, uint32_t queueIndex,
868                  VkQueue *pQueue) {
869     const VkLayerDispatchTable *disp;
870 
871     disp = loader_get_dispatch(device);
872 
873     disp->GetDeviceQueue(device, queueNodeIndex, queueIndex, pQueue);
874     loader_set_dispatch(*pQueue, disp);
875 }
876 
877 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
878 vkQueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits,
879               VkFence fence) {
880     const VkLayerDispatchTable *disp;
881 
882     disp = loader_get_dispatch(queue);
883 
884     return disp->QueueSubmit(queue, submitCount, pSubmits, fence);
885 }
886 
887 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkQueueWaitIdle(VkQueue queue) {
888     const VkLayerDispatchTable *disp;
889 
890     disp = loader_get_dispatch(queue);
891 
892     return disp->QueueWaitIdle(queue);
893 }
894 
895 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkDeviceWaitIdle(VkDevice device) {
896     const VkLayerDispatchTable *disp;
897 
898     disp = loader_get_dispatch(device);
899 
900     return disp->DeviceWaitIdle(device);
901 }
902 
903 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
904 vkAllocateMemory(VkDevice device, const VkMemoryAllocateInfo *pAllocateInfo,
905                  const VkAllocationCallbacks *pAllocator,
906                  VkDeviceMemory *pMemory) {
907     const VkLayerDispatchTable *disp;
908 
909     disp = loader_get_dispatch(device);
910 
911     return disp->AllocateMemory(device, pAllocateInfo, pAllocator, pMemory);
912 }
913 
914 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
915 vkFreeMemory(VkDevice device, VkDeviceMemory mem,
916              const VkAllocationCallbacks *pAllocator) {
917     const VkLayerDispatchTable *disp;
918 
919     disp = loader_get_dispatch(device);
920 
921     disp->FreeMemory(device, mem, pAllocator);
922 }
923 
924 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
925 vkMapMemory(VkDevice device, VkDeviceMemory mem, VkDeviceSize offset,
926             VkDeviceSize size, VkFlags flags, void **ppData) {
927     const VkLayerDispatchTable *disp;
928 
929     disp = loader_get_dispatch(device);
930 
931     return disp->MapMemory(device, mem, offset, size, flags, ppData);
932 }
933 
934 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
935 vkUnmapMemory(VkDevice device, VkDeviceMemory mem) {
936     const VkLayerDispatchTable *disp;
937 
938     disp = loader_get_dispatch(device);
939 
940     disp->UnmapMemory(device, mem);
941 }
942 
943 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
944 vkFlushMappedMemoryRanges(VkDevice device, uint32_t memoryRangeCount,
945                           const VkMappedMemoryRange *pMemoryRanges) {
946     const VkLayerDispatchTable *disp;
947 
948     disp = loader_get_dispatch(device);
949 
950     return disp->FlushMappedMemoryRanges(device, memoryRangeCount,
951                                          pMemoryRanges);
952 }
953 
954 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
955 vkInvalidateMappedMemoryRanges(VkDevice device, uint32_t memoryRangeCount,
956                                const VkMappedMemoryRange *pMemoryRanges) {
957     const VkLayerDispatchTable *disp;
958 
959     disp = loader_get_dispatch(device);
960 
961     return disp->InvalidateMappedMemoryRanges(device, memoryRangeCount,
962                                               pMemoryRanges);
963 }
964 
965 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
966 vkGetDeviceMemoryCommitment(VkDevice device, VkDeviceMemory memory,
967                             VkDeviceSize *pCommittedMemoryInBytes) {
968     const VkLayerDispatchTable *disp;
969 
970     disp = loader_get_dispatch(device);
971 
972     disp->GetDeviceMemoryCommitment(device, memory, pCommittedMemoryInBytes);
973 }
974 
975 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
976 vkBindBufferMemory(VkDevice device, VkBuffer buffer, VkDeviceMemory mem,
977                    VkDeviceSize offset) {
978     const VkLayerDispatchTable *disp;
979 
980     disp = loader_get_dispatch(device);
981 
982     return disp->BindBufferMemory(device, buffer, mem, offset);
983 }
984 
985 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
986 vkBindImageMemory(VkDevice device, VkImage image, VkDeviceMemory mem,
987                   VkDeviceSize offset) {
988     const VkLayerDispatchTable *disp;
989 
990     disp = loader_get_dispatch(device);
991 
992     return disp->BindImageMemory(device, image, mem, offset);
993 }
994 
995 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
996 vkGetBufferMemoryRequirements(VkDevice device, VkBuffer buffer,
997                               VkMemoryRequirements *pMemoryRequirements) {
998     const VkLayerDispatchTable *disp;
999 
1000     disp = loader_get_dispatch(device);
1001 
1002     disp->GetBufferMemoryRequirements(device, buffer, pMemoryRequirements);
1003 }
1004 
1005 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1006 vkGetImageMemoryRequirements(VkDevice device, VkImage image,
1007                              VkMemoryRequirements *pMemoryRequirements) {
1008     const VkLayerDispatchTable *disp;
1009 
1010     disp = loader_get_dispatch(device);
1011 
1012     disp->GetImageMemoryRequirements(device, image, pMemoryRequirements);
1013 }
1014 
1015 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetImageSparseMemoryRequirements(
1016     VkDevice device, VkImage image, uint32_t *pSparseMemoryRequirementCount,
1017     VkSparseImageMemoryRequirements *pSparseMemoryRequirements) {
1018     const VkLayerDispatchTable *disp;
1019 
1020     disp = loader_get_dispatch(device);
1021 
1022     disp->GetImageSparseMemoryRequirements(device, image,
1023                                            pSparseMemoryRequirementCount,
1024                                            pSparseMemoryRequirements);
1025 }
1026 
1027 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1028 vkGetPhysicalDeviceSparseImageFormatProperties(
1029     VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type,
1030     VkSampleCountFlagBits samples, VkImageUsageFlags usage,
1031     VkImageTiling tiling, uint32_t *pPropertyCount,
1032     VkSparseImageFormatProperties *pProperties) {
1033     const VkLayerInstanceDispatchTable *disp;
1034     VkPhysicalDevice unwrapped_phys_dev =
1035         loader_unwrap_physical_device(physicalDevice);
1036     disp = loader_get_instance_dispatch(physicalDevice);
1037 
1038     disp->GetPhysicalDeviceSparseImageFormatProperties(
1039         unwrapped_phys_dev, format, type, samples, usage, tiling,
1040         pPropertyCount, pProperties);
1041 }
1042 
1043 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
1044 vkQueueBindSparse(VkQueue queue, uint32_t bindInfoCount,
1045                   const VkBindSparseInfo *pBindInfo, VkFence fence) {
1046     const VkLayerDispatchTable *disp;
1047 
1048     disp = loader_get_dispatch(queue);
1049 
1050     return disp->QueueBindSparse(queue, bindInfoCount, pBindInfo, fence);
1051 }
1052 
1053 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
1054 vkCreateFence(VkDevice device, const VkFenceCreateInfo *pCreateInfo,
1055               const VkAllocationCallbacks *pAllocator, VkFence *pFence) {
1056     const VkLayerDispatchTable *disp;
1057 
1058     disp = loader_get_dispatch(device);
1059 
1060     return disp->CreateFence(device, pCreateInfo, pAllocator, pFence);
1061 }
1062 
1063 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1064 vkDestroyFence(VkDevice device, VkFence fence,
1065                const VkAllocationCallbacks *pAllocator) {
1066     const VkLayerDispatchTable *disp;
1067 
1068     disp = loader_get_dispatch(device);
1069 
1070     disp->DestroyFence(device, fence, pAllocator);
1071 }
1072 
1073 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
1074 vkResetFences(VkDevice device, uint32_t fenceCount, const VkFence *pFences) {
1075     const VkLayerDispatchTable *disp;
1076 
1077     disp = loader_get_dispatch(device);
1078 
1079     return disp->ResetFences(device, fenceCount, pFences);
1080 }
1081 
1082 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
1083 vkGetFenceStatus(VkDevice device, VkFence fence) {
1084     const VkLayerDispatchTable *disp;
1085 
1086     disp = loader_get_dispatch(device);
1087 
1088     return disp->GetFenceStatus(device, fence);
1089 }
1090 
1091 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
1092 vkWaitForFences(VkDevice device, uint32_t fenceCount, const VkFence *pFences,
1093                 VkBool32 waitAll, uint64_t timeout) {
1094     const VkLayerDispatchTable *disp;
1095 
1096     disp = loader_get_dispatch(device);
1097 
1098     return disp->WaitForFences(device, fenceCount, pFences, waitAll, timeout);
1099 }
1100 
1101 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
1102 vkCreateSemaphore(VkDevice device, const VkSemaphoreCreateInfo *pCreateInfo,
1103                   const VkAllocationCallbacks *pAllocator,
1104                   VkSemaphore *pSemaphore) {
1105     const VkLayerDispatchTable *disp;
1106 
1107     disp = loader_get_dispatch(device);
1108 
1109     return disp->CreateSemaphore(device, pCreateInfo, pAllocator, pSemaphore);
1110 }
1111 
1112 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1113 vkDestroySemaphore(VkDevice device, VkSemaphore semaphore,
1114                    const VkAllocationCallbacks *pAllocator) {
1115     const VkLayerDispatchTable *disp;
1116 
1117     disp = loader_get_dispatch(device);
1118 
1119     disp->DestroySemaphore(device, semaphore, pAllocator);
1120 }
1121 
1122 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
1123 vkCreateEvent(VkDevice device, const VkEventCreateInfo *pCreateInfo,
1124               const VkAllocationCallbacks *pAllocator, VkEvent *pEvent) {
1125     const VkLayerDispatchTable *disp;
1126 
1127     disp = loader_get_dispatch(device);
1128 
1129     return disp->CreateEvent(device, pCreateInfo, pAllocator, pEvent);
1130 }
1131 
1132 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1133 vkDestroyEvent(VkDevice device, VkEvent event,
1134                const VkAllocationCallbacks *pAllocator) {
1135     const VkLayerDispatchTable *disp;
1136 
1137     disp = loader_get_dispatch(device);
1138 
1139     disp->DestroyEvent(device, event, pAllocator);
1140 }
1141 
1142 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
1143 vkGetEventStatus(VkDevice device, VkEvent event) {
1144     const VkLayerDispatchTable *disp;
1145 
1146     disp = loader_get_dispatch(device);
1147 
1148     return disp->GetEventStatus(device, event);
1149 }
1150 
1151 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
1152 vkSetEvent(VkDevice device, VkEvent event) {
1153     const VkLayerDispatchTable *disp;
1154 
1155     disp = loader_get_dispatch(device);
1156 
1157     return disp->SetEvent(device, event);
1158 }
1159 
1160 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
1161 vkResetEvent(VkDevice device, VkEvent event) {
1162     const VkLayerDispatchTable *disp;
1163 
1164     disp = loader_get_dispatch(device);
1165 
1166     return disp->ResetEvent(device, event);
1167 }
1168 
1169 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
1170 vkCreateQueryPool(VkDevice device, const VkQueryPoolCreateInfo *pCreateInfo,
1171                   const VkAllocationCallbacks *pAllocator,
1172                   VkQueryPool *pQueryPool) {
1173     const VkLayerDispatchTable *disp;
1174 
1175     disp = loader_get_dispatch(device);
1176 
1177     return disp->CreateQueryPool(device, pCreateInfo, pAllocator, pQueryPool);
1178 }
1179 
1180 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1181 vkDestroyQueryPool(VkDevice device, VkQueryPool queryPool,
1182                    const VkAllocationCallbacks *pAllocator) {
1183     const VkLayerDispatchTable *disp;
1184 
1185     disp = loader_get_dispatch(device);
1186 
1187     disp->DestroyQueryPool(device, queryPool, pAllocator);
1188 }
1189 
1190 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
1191 vkGetQueryPoolResults(VkDevice device, VkQueryPool queryPool,
1192                       uint32_t firstQuery, uint32_t queryCount, size_t dataSize,
1193                       void *pData, VkDeviceSize stride,
1194                       VkQueryResultFlags flags) {
1195     const VkLayerDispatchTable *disp;
1196 
1197     disp = loader_get_dispatch(device);
1198 
1199     return disp->GetQueryPoolResults(device, queryPool, firstQuery, queryCount,
1200                                      dataSize, pData, stride, flags);
1201 }
1202 
1203 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
1204 vkCreateBuffer(VkDevice device, const VkBufferCreateInfo *pCreateInfo,
1205                const VkAllocationCallbacks *pAllocator, VkBuffer *pBuffer) {
1206     const VkLayerDispatchTable *disp;
1207 
1208     disp = loader_get_dispatch(device);
1209 
1210     return disp->CreateBuffer(device, pCreateInfo, pAllocator, pBuffer);
1211 }
1212 
1213 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1214 vkDestroyBuffer(VkDevice device, VkBuffer buffer,
1215                 const VkAllocationCallbacks *pAllocator) {
1216     const VkLayerDispatchTable *disp;
1217 
1218     disp = loader_get_dispatch(device);
1219 
1220     disp->DestroyBuffer(device, buffer, pAllocator);
1221 }
1222 
1223 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
1224 vkCreateBufferView(VkDevice device, const VkBufferViewCreateInfo *pCreateInfo,
1225                    const VkAllocationCallbacks *pAllocator,
1226                    VkBufferView *pView) {
1227     const VkLayerDispatchTable *disp;
1228 
1229     disp = loader_get_dispatch(device);
1230 
1231     return disp->CreateBufferView(device, pCreateInfo, pAllocator, pView);
1232 }
1233 
1234 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1235 vkDestroyBufferView(VkDevice device, VkBufferView bufferView,
1236                     const VkAllocationCallbacks *pAllocator) {
1237     const VkLayerDispatchTable *disp;
1238 
1239     disp = loader_get_dispatch(device);
1240 
1241     disp->DestroyBufferView(device, bufferView, pAllocator);
1242 }
1243 
1244 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
1245 vkCreateImage(VkDevice device, const VkImageCreateInfo *pCreateInfo,
1246               const VkAllocationCallbacks *pAllocator, VkImage *pImage) {
1247     const VkLayerDispatchTable *disp;
1248 
1249     disp = loader_get_dispatch(device);
1250 
1251     return disp->CreateImage(device, pCreateInfo, pAllocator, pImage);
1252 }
1253 
1254 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1255 vkDestroyImage(VkDevice device, VkImage image,
1256                const VkAllocationCallbacks *pAllocator) {
1257     const VkLayerDispatchTable *disp;
1258 
1259     disp = loader_get_dispatch(device);
1260 
1261     disp->DestroyImage(device, image, pAllocator);
1262 }
1263 
1264 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1265 vkGetImageSubresourceLayout(VkDevice device, VkImage image,
1266                             const VkImageSubresource *pSubresource,
1267                             VkSubresourceLayout *pLayout) {
1268     const VkLayerDispatchTable *disp;
1269 
1270     disp = loader_get_dispatch(device);
1271 
1272     disp->GetImageSubresourceLayout(device, image, pSubresource, pLayout);
1273 }
1274 
1275 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
1276 vkCreateImageView(VkDevice device, const VkImageViewCreateInfo *pCreateInfo,
1277                   const VkAllocationCallbacks *pAllocator, VkImageView *pView) {
1278     const VkLayerDispatchTable *disp;
1279 
1280     disp = loader_get_dispatch(device);
1281 
1282     return disp->CreateImageView(device, pCreateInfo, pAllocator, pView);
1283 }
1284 
1285 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1286 vkDestroyImageView(VkDevice device, VkImageView imageView,
1287                    const VkAllocationCallbacks *pAllocator) {
1288     const VkLayerDispatchTable *disp;
1289 
1290     disp = loader_get_dispatch(device);
1291 
1292     disp->DestroyImageView(device, imageView, pAllocator);
1293 }
1294 
1295 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
1296 vkCreateShaderModule(VkDevice device,
1297                      const VkShaderModuleCreateInfo *pCreateInfo,
1298                      const VkAllocationCallbacks *pAllocator,
1299                      VkShaderModule *pShader) {
1300     const VkLayerDispatchTable *disp;
1301 
1302     disp = loader_get_dispatch(device);
1303 
1304     return disp->CreateShaderModule(device, pCreateInfo, pAllocator, pShader);
1305 }
1306 
1307 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1308 vkDestroyShaderModule(VkDevice device, VkShaderModule shaderModule,
1309                       const VkAllocationCallbacks *pAllocator) {
1310     const VkLayerDispatchTable *disp;
1311 
1312     disp = loader_get_dispatch(device);
1313 
1314     disp->DestroyShaderModule(device, shaderModule, pAllocator);
1315 }
1316 
1317 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
1318 vkCreatePipelineCache(VkDevice device,
1319                       const VkPipelineCacheCreateInfo *pCreateInfo,
1320                       const VkAllocationCallbacks *pAllocator,
1321                       VkPipelineCache *pPipelineCache) {
1322     const VkLayerDispatchTable *disp;
1323 
1324     disp = loader_get_dispatch(device);
1325 
1326     return disp->CreatePipelineCache(device, pCreateInfo, pAllocator,
1327                                      pPipelineCache);
1328 }
1329 
1330 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1331 vkDestroyPipelineCache(VkDevice device, VkPipelineCache pipelineCache,
1332                        const VkAllocationCallbacks *pAllocator) {
1333     const VkLayerDispatchTable *disp;
1334 
1335     disp = loader_get_dispatch(device);
1336 
1337     disp->DestroyPipelineCache(device, pipelineCache, pAllocator);
1338 }
1339 
1340 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
1341 vkGetPipelineCacheData(VkDevice device, VkPipelineCache pipelineCache,
1342                        size_t *pDataSize, void *pData) {
1343     const VkLayerDispatchTable *disp;
1344 
1345     disp = loader_get_dispatch(device);
1346 
1347     return disp->GetPipelineCacheData(device, pipelineCache, pDataSize, pData);
1348 }
1349 
1350 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
1351 vkMergePipelineCaches(VkDevice device, VkPipelineCache dstCache,
1352                       uint32_t srcCacheCount,
1353                       const VkPipelineCache *pSrcCaches) {
1354     const VkLayerDispatchTable *disp;
1355 
1356     disp = loader_get_dispatch(device);
1357 
1358     return disp->MergePipelineCaches(device, dstCache, srcCacheCount,
1359                                      pSrcCaches);
1360 }
1361 
1362 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
1363 vkCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache,
1364                           uint32_t createInfoCount,
1365                           const VkGraphicsPipelineCreateInfo *pCreateInfos,
1366                           const VkAllocationCallbacks *pAllocator,
1367                           VkPipeline *pPipelines) {
1368     const VkLayerDispatchTable *disp;
1369 
1370     disp = loader_get_dispatch(device);
1371 
1372     return disp->CreateGraphicsPipelines(device, pipelineCache, createInfoCount,
1373                                          pCreateInfos, pAllocator, pPipelines);
1374 }
1375 
1376 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
1377 vkCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache,
1378                          uint32_t createInfoCount,
1379                          const VkComputePipelineCreateInfo *pCreateInfos,
1380                          const VkAllocationCallbacks *pAllocator,
1381                          VkPipeline *pPipelines) {
1382     const VkLayerDispatchTable *disp;
1383 
1384     disp = loader_get_dispatch(device);
1385 
1386     return disp->CreateComputePipelines(device, pipelineCache, createInfoCount,
1387                                         pCreateInfos, pAllocator, pPipelines);
1388 }
1389 
1390 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1391 vkDestroyPipeline(VkDevice device, VkPipeline pipeline,
1392                   const VkAllocationCallbacks *pAllocator) {
1393     const VkLayerDispatchTable *disp;
1394 
1395     disp = loader_get_dispatch(device);
1396 
1397     disp->DestroyPipeline(device, pipeline, pAllocator);
1398 }
1399 
1400 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
1401 vkCreatePipelineLayout(VkDevice device,
1402                        const VkPipelineLayoutCreateInfo *pCreateInfo,
1403                        const VkAllocationCallbacks *pAllocator,
1404                        VkPipelineLayout *pPipelineLayout) {
1405     const VkLayerDispatchTable *disp;
1406 
1407     disp = loader_get_dispatch(device);
1408 
1409     return disp->CreatePipelineLayout(device, pCreateInfo, pAllocator,
1410                                       pPipelineLayout);
1411 }
1412 
1413 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1414 vkDestroyPipelineLayout(VkDevice device, VkPipelineLayout pipelineLayout,
1415                         const VkAllocationCallbacks *pAllocator) {
1416     const VkLayerDispatchTable *disp;
1417 
1418     disp = loader_get_dispatch(device);
1419 
1420     disp->DestroyPipelineLayout(device, pipelineLayout, pAllocator);
1421 }
1422 
1423 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
1424 vkCreateSampler(VkDevice device, const VkSamplerCreateInfo *pCreateInfo,
1425                 const VkAllocationCallbacks *pAllocator, VkSampler *pSampler) {
1426     const VkLayerDispatchTable *disp;
1427 
1428     disp = loader_get_dispatch(device);
1429 
1430     return disp->CreateSampler(device, pCreateInfo, pAllocator, pSampler);
1431 }
1432 
1433 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1434 vkDestroySampler(VkDevice device, VkSampler sampler,
1435                  const VkAllocationCallbacks *pAllocator) {
1436     const VkLayerDispatchTable *disp;
1437 
1438     disp = loader_get_dispatch(device);
1439 
1440     disp->DestroySampler(device, sampler, pAllocator);
1441 }
1442 
1443 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
1444 vkCreateDescriptorSetLayout(VkDevice device,
1445                             const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
1446                             const VkAllocationCallbacks *pAllocator,
1447                             VkDescriptorSetLayout *pSetLayout) {
1448     const VkLayerDispatchTable *disp;
1449 
1450     disp = loader_get_dispatch(device);
1451 
1452     return disp->CreateDescriptorSetLayout(device, pCreateInfo, pAllocator,
1453                                            pSetLayout);
1454 }
1455 
1456 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1457 vkDestroyDescriptorSetLayout(VkDevice device,
1458                              VkDescriptorSetLayout descriptorSetLayout,
1459                              const VkAllocationCallbacks *pAllocator) {
1460     const VkLayerDispatchTable *disp;
1461 
1462     disp = loader_get_dispatch(device);
1463 
1464     disp->DestroyDescriptorSetLayout(device, descriptorSetLayout, pAllocator);
1465 }
1466 
1467 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
1468 vkCreateDescriptorPool(VkDevice device,
1469                        const VkDescriptorPoolCreateInfo *pCreateInfo,
1470                        const VkAllocationCallbacks *pAllocator,
1471                        VkDescriptorPool *pDescriptorPool) {
1472     const VkLayerDispatchTable *disp;
1473 
1474     disp = loader_get_dispatch(device);
1475 
1476     return disp->CreateDescriptorPool(device, pCreateInfo, pAllocator,
1477                                       pDescriptorPool);
1478 }
1479 
1480 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1481 vkDestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
1482                         const VkAllocationCallbacks *pAllocator) {
1483     const VkLayerDispatchTable *disp;
1484 
1485     disp = loader_get_dispatch(device);
1486 
1487     disp->DestroyDescriptorPool(device, descriptorPool, pAllocator);
1488 }
1489 
1490 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
1491 vkResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
1492                       VkDescriptorPoolResetFlags flags) {
1493     const VkLayerDispatchTable *disp;
1494 
1495     disp = loader_get_dispatch(device);
1496 
1497     return disp->ResetDescriptorPool(device, descriptorPool, flags);
1498 }
1499 
1500 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
1501 vkAllocateDescriptorSets(VkDevice device,
1502                          const VkDescriptorSetAllocateInfo *pAllocateInfo,
1503                          VkDescriptorSet *pDescriptorSets) {
1504     const VkLayerDispatchTable *disp;
1505 
1506     disp = loader_get_dispatch(device);
1507 
1508     return disp->AllocateDescriptorSets(device, pAllocateInfo, pDescriptorSets);
1509 }
1510 
1511 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
1512 vkFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool,
1513                      uint32_t descriptorSetCount,
1514                      const VkDescriptorSet *pDescriptorSets) {
1515     const VkLayerDispatchTable *disp;
1516 
1517     disp = loader_get_dispatch(device);
1518 
1519     return disp->FreeDescriptorSets(device, descriptorPool, descriptorSetCount,
1520                                     pDescriptorSets);
1521 }
1522 
1523 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1524 vkUpdateDescriptorSets(VkDevice device, uint32_t descriptorWriteCount,
1525                        const VkWriteDescriptorSet *pDescriptorWrites,
1526                        uint32_t descriptorCopyCount,
1527                        const VkCopyDescriptorSet *pDescriptorCopies) {
1528     const VkLayerDispatchTable *disp;
1529 
1530     disp = loader_get_dispatch(device);
1531 
1532     disp->UpdateDescriptorSets(device, descriptorWriteCount, pDescriptorWrites,
1533                                descriptorCopyCount, pDescriptorCopies);
1534 }
1535 
1536 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
1537 vkCreateFramebuffer(VkDevice device, const VkFramebufferCreateInfo *pCreateInfo,
1538                     const VkAllocationCallbacks *pAllocator,
1539                     VkFramebuffer *pFramebuffer) {
1540     const VkLayerDispatchTable *disp;
1541 
1542     disp = loader_get_dispatch(device);
1543 
1544     return disp->CreateFramebuffer(device, pCreateInfo, pAllocator,
1545                                    pFramebuffer);
1546 }
1547 
1548 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1549 vkDestroyFramebuffer(VkDevice device, VkFramebuffer framebuffer,
1550                      const VkAllocationCallbacks *pAllocator) {
1551     const VkLayerDispatchTable *disp;
1552 
1553     disp = loader_get_dispatch(device);
1554 
1555     disp->DestroyFramebuffer(device, framebuffer, pAllocator);
1556 }
1557 
1558 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
1559 vkCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo *pCreateInfo,
1560                    const VkAllocationCallbacks *pAllocator,
1561                    VkRenderPass *pRenderPass) {
1562     const VkLayerDispatchTable *disp;
1563 
1564     disp = loader_get_dispatch(device);
1565 
1566     return disp->CreateRenderPass(device, pCreateInfo, pAllocator, pRenderPass);
1567 }
1568 
1569 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1570 vkDestroyRenderPass(VkDevice device, VkRenderPass renderPass,
1571                     const VkAllocationCallbacks *pAllocator) {
1572     const VkLayerDispatchTable *disp;
1573 
1574     disp = loader_get_dispatch(device);
1575 
1576     disp->DestroyRenderPass(device, renderPass, pAllocator);
1577 }
1578 
1579 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1580 vkGetRenderAreaGranularity(VkDevice device, VkRenderPass renderPass,
1581                            VkExtent2D *pGranularity) {
1582     const VkLayerDispatchTable *disp;
1583 
1584     disp = loader_get_dispatch(device);
1585 
1586     disp->GetRenderAreaGranularity(device, renderPass, pGranularity);
1587 }
1588 
1589 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
1590 vkCreateCommandPool(VkDevice device, const VkCommandPoolCreateInfo *pCreateInfo,
1591                     const VkAllocationCallbacks *pAllocator,
1592                     VkCommandPool *pCommandPool) {
1593     const VkLayerDispatchTable *disp;
1594 
1595     disp = loader_get_dispatch(device);
1596 
1597     return disp->CreateCommandPool(device, pCreateInfo, pAllocator,
1598                                    pCommandPool);
1599 }
1600 
1601 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1602 vkDestroyCommandPool(VkDevice device, VkCommandPool commandPool,
1603                      const VkAllocationCallbacks *pAllocator) {
1604     const VkLayerDispatchTable *disp;
1605 
1606     disp = loader_get_dispatch(device);
1607 
1608     disp->DestroyCommandPool(device, commandPool, pAllocator);
1609 }
1610 
1611 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
1612 vkResetCommandPool(VkDevice device, VkCommandPool commandPool,
1613                    VkCommandPoolResetFlags flags) {
1614     const VkLayerDispatchTable *disp;
1615 
1616     disp = loader_get_dispatch(device);
1617 
1618     return disp->ResetCommandPool(device, commandPool, flags);
1619 }
1620 
1621 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
1622 vkAllocateCommandBuffers(VkDevice device,
1623                          const VkCommandBufferAllocateInfo *pAllocateInfo,
1624                          VkCommandBuffer *pCommandBuffers) {
1625     const VkLayerDispatchTable *disp;
1626     VkResult res;
1627 
1628     disp = loader_get_dispatch(device);
1629 
1630     res = disp->AllocateCommandBuffers(device, pAllocateInfo, pCommandBuffers);
1631     if (res == VK_SUCCESS) {
1632         for (uint32_t i = 0; i < pAllocateInfo->commandBufferCount; i++) {
1633             if (pCommandBuffers[i]) {
1634                 loader_init_dispatch(pCommandBuffers[i], disp);
1635             }
1636         }
1637     }
1638 
1639     return res;
1640 }
1641 
1642 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1643 vkFreeCommandBuffers(VkDevice device, VkCommandPool commandPool,
1644                      uint32_t commandBufferCount,
1645                      const VkCommandBuffer *pCommandBuffers) {
1646     const VkLayerDispatchTable *disp;
1647 
1648     disp = loader_get_dispatch(device);
1649 
1650     disp->FreeCommandBuffers(device, commandPool, commandBufferCount,
1651                              pCommandBuffers);
1652 }
1653 
1654 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
1655 vkBeginCommandBuffer(VkCommandBuffer commandBuffer,
1656                      const VkCommandBufferBeginInfo *pBeginInfo) {
1657     const VkLayerDispatchTable *disp;
1658 
1659     disp = loader_get_dispatch(commandBuffer);
1660 
1661     return disp->BeginCommandBuffer(commandBuffer, pBeginInfo);
1662 }
1663 
1664 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
1665 vkEndCommandBuffer(VkCommandBuffer commandBuffer) {
1666     const VkLayerDispatchTable *disp;
1667 
1668     disp = loader_get_dispatch(commandBuffer);
1669 
1670     return disp->EndCommandBuffer(commandBuffer);
1671 }
1672 
1673 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
1674 vkResetCommandBuffer(VkCommandBuffer commandBuffer,
1675                      VkCommandBufferResetFlags flags) {
1676     const VkLayerDispatchTable *disp;
1677 
1678     disp = loader_get_dispatch(commandBuffer);
1679 
1680     return disp->ResetCommandBuffer(commandBuffer, flags);
1681 }
1682 
1683 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1684 vkCmdBindPipeline(VkCommandBuffer commandBuffer,
1685                   VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline) {
1686     const VkLayerDispatchTable *disp;
1687 
1688     disp = loader_get_dispatch(commandBuffer);
1689 
1690     disp->CmdBindPipeline(commandBuffer, pipelineBindPoint, pipeline);
1691 }
1692 
1693 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1694 vkCmdSetViewport(VkCommandBuffer commandBuffer, uint32_t firstViewport,
1695                  uint32_t viewportCount, const VkViewport *pViewports) {
1696     const VkLayerDispatchTable *disp;
1697 
1698     disp = loader_get_dispatch(commandBuffer);
1699 
1700     disp->CmdSetViewport(commandBuffer, firstViewport, viewportCount,
1701                          pViewports);
1702 }
1703 
1704 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1705 vkCmdSetScissor(VkCommandBuffer commandBuffer, uint32_t firstScissor,
1706                 uint32_t scissorCount, const VkRect2D *pScissors) {
1707     const VkLayerDispatchTable *disp;
1708 
1709     disp = loader_get_dispatch(commandBuffer);
1710 
1711     disp->CmdSetScissor(commandBuffer, firstScissor, scissorCount, pScissors);
1712 }
1713 
1714 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1715 vkCmdSetLineWidth(VkCommandBuffer commandBuffer, float lineWidth) {
1716     const VkLayerDispatchTable *disp;
1717 
1718     disp = loader_get_dispatch(commandBuffer);
1719 
1720     disp->CmdSetLineWidth(commandBuffer, lineWidth);
1721 }
1722 
1723 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1724 vkCmdSetDepthBias(VkCommandBuffer commandBuffer, float depthBiasConstantFactor,
1725                   float depthBiasClamp, float depthBiasSlopeFactor) {
1726     const VkLayerDispatchTable *disp;
1727 
1728     disp = loader_get_dispatch(commandBuffer);
1729 
1730     disp->CmdSetDepthBias(commandBuffer, depthBiasConstantFactor,
1731                           depthBiasClamp, depthBiasSlopeFactor);
1732 }
1733 
1734 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1735 vkCmdSetBlendConstants(VkCommandBuffer commandBuffer,
1736                        const float blendConstants[4]) {
1737     const VkLayerDispatchTable *disp;
1738 
1739     disp = loader_get_dispatch(commandBuffer);
1740 
1741     disp->CmdSetBlendConstants(commandBuffer, blendConstants);
1742 }
1743 
1744 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1745 vkCmdSetDepthBounds(VkCommandBuffer commandBuffer, float minDepthBounds,
1746                     float maxDepthBounds) {
1747     const VkLayerDispatchTable *disp;
1748 
1749     disp = loader_get_dispatch(commandBuffer);
1750 
1751     disp->CmdSetDepthBounds(commandBuffer, minDepthBounds, maxDepthBounds);
1752 }
1753 
1754 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1755 vkCmdSetStencilCompareMask(VkCommandBuffer commandBuffer,
1756                            VkStencilFaceFlags faceMask, uint32_t compareMask) {
1757     const VkLayerDispatchTable *disp;
1758 
1759     disp = loader_get_dispatch(commandBuffer);
1760 
1761     disp->CmdSetStencilCompareMask(commandBuffer, faceMask, compareMask);
1762 }
1763 
1764 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1765 vkCmdSetStencilWriteMask(VkCommandBuffer commandBuffer,
1766                          VkStencilFaceFlags faceMask, uint32_t writeMask) {
1767     const VkLayerDispatchTable *disp;
1768 
1769     disp = loader_get_dispatch(commandBuffer);
1770 
1771     disp->CmdSetStencilWriteMask(commandBuffer, faceMask, writeMask);
1772 }
1773 
1774 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1775 vkCmdSetStencilReference(VkCommandBuffer commandBuffer,
1776                          VkStencilFaceFlags faceMask, uint32_t reference) {
1777     const VkLayerDispatchTable *disp;
1778 
1779     disp = loader_get_dispatch(commandBuffer);
1780 
1781     disp->CmdSetStencilReference(commandBuffer, faceMask, reference);
1782 }
1783 
1784 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdBindDescriptorSets(
1785     VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint,
1786     VkPipelineLayout layout, uint32_t firstSet, uint32_t descriptorSetCount,
1787     const VkDescriptorSet *pDescriptorSets, uint32_t dynamicOffsetCount,
1788     const uint32_t *pDynamicOffsets) {
1789     const VkLayerDispatchTable *disp;
1790 
1791     disp = loader_get_dispatch(commandBuffer);
1792 
1793     disp->CmdBindDescriptorSets(commandBuffer, pipelineBindPoint, layout,
1794                                 firstSet, descriptorSetCount, pDescriptorSets,
1795                                 dynamicOffsetCount, pDynamicOffsets);
1796 }
1797 
1798 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1799 vkCmdBindIndexBuffer(VkCommandBuffer commandBuffer, VkBuffer buffer,
1800                      VkDeviceSize offset, VkIndexType indexType) {
1801     const VkLayerDispatchTable *disp;
1802 
1803     disp = loader_get_dispatch(commandBuffer);
1804 
1805     disp->CmdBindIndexBuffer(commandBuffer, buffer, offset, indexType);
1806 }
1807 
1808 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1809 vkCmdBindVertexBuffers(VkCommandBuffer commandBuffer, uint32_t firstBinding,
1810                        uint32_t bindingCount, const VkBuffer *pBuffers,
1811                        const VkDeviceSize *pOffsets) {
1812     const VkLayerDispatchTable *disp;
1813 
1814     disp = loader_get_dispatch(commandBuffer);
1815 
1816     disp->CmdBindVertexBuffers(commandBuffer, firstBinding, bindingCount,
1817                                pBuffers, pOffsets);
1818 }
1819 
1820 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1821 vkCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount,
1822           uint32_t instanceCount, uint32_t firstVertex,
1823           uint32_t firstInstance) {
1824     const VkLayerDispatchTable *disp;
1825 
1826     disp = loader_get_dispatch(commandBuffer);
1827 
1828     disp->CmdDraw(commandBuffer, vertexCount, instanceCount, firstVertex,
1829                   firstInstance);
1830 }
1831 
1832 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1833 vkCmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount,
1834                  uint32_t instanceCount, uint32_t firstIndex,
1835                  int32_t vertexOffset, uint32_t firstInstance) {
1836     const VkLayerDispatchTable *disp;
1837 
1838     disp = loader_get_dispatch(commandBuffer);
1839 
1840     disp->CmdDrawIndexed(commandBuffer, indexCount, instanceCount, firstIndex,
1841                          vertexOffset, firstInstance);
1842 }
1843 
1844 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1845 vkCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer,
1846                   VkDeviceSize offset, uint32_t drawCount, uint32_t stride) {
1847     const VkLayerDispatchTable *disp;
1848 
1849     disp = loader_get_dispatch(commandBuffer);
1850 
1851     disp->CmdDrawIndirect(commandBuffer, buffer, offset, drawCount, stride);
1852 }
1853 
1854 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1855 vkCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer,
1856                          VkDeviceSize offset, uint32_t drawCount,
1857                          uint32_t stride) {
1858     const VkLayerDispatchTable *disp;
1859 
1860     disp = loader_get_dispatch(commandBuffer);
1861 
1862     disp->CmdDrawIndexedIndirect(commandBuffer, buffer, offset, drawCount,
1863                                  stride);
1864 }
1865 
1866 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1867 vkCmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y,
1868               uint32_t z) {
1869     const VkLayerDispatchTable *disp;
1870 
1871     disp = loader_get_dispatch(commandBuffer);
1872 
1873     disp->CmdDispatch(commandBuffer, x, y, z);
1874 }
1875 
1876 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1877 vkCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer,
1878                       VkDeviceSize offset) {
1879     const VkLayerDispatchTable *disp;
1880 
1881     disp = loader_get_dispatch(commandBuffer);
1882 
1883     disp->CmdDispatchIndirect(commandBuffer, buffer, offset);
1884 }
1885 
1886 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1887 vkCmdCopyBuffer(VkCommandBuffer commandBuffer, VkBuffer srcBuffer,
1888                 VkBuffer dstBuffer, uint32_t regionCount,
1889                 const VkBufferCopy *pRegions) {
1890     const VkLayerDispatchTable *disp;
1891 
1892     disp = loader_get_dispatch(commandBuffer);
1893 
1894     disp->CmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, regionCount,
1895                         pRegions);
1896 }
1897 
1898 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1899 vkCmdCopyImage(VkCommandBuffer commandBuffer, VkImage srcImage,
1900                VkImageLayout srcImageLayout, VkImage dstImage,
1901                VkImageLayout dstImageLayout, uint32_t regionCount,
1902                const VkImageCopy *pRegions) {
1903     const VkLayerDispatchTable *disp;
1904 
1905     disp = loader_get_dispatch(commandBuffer);
1906 
1907     disp->CmdCopyImage(commandBuffer, srcImage, srcImageLayout, dstImage,
1908                        dstImageLayout, regionCount, pRegions);
1909 }
1910 
1911 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1912 vkCmdBlitImage(VkCommandBuffer commandBuffer, VkImage srcImage,
1913                VkImageLayout srcImageLayout, VkImage dstImage,
1914                VkImageLayout dstImageLayout, uint32_t regionCount,
1915                const VkImageBlit *pRegions, VkFilter filter) {
1916     const VkLayerDispatchTable *disp;
1917 
1918     disp = loader_get_dispatch(commandBuffer);
1919 
1920     disp->CmdBlitImage(commandBuffer, srcImage, srcImageLayout, dstImage,
1921                        dstImageLayout, regionCount, pRegions, filter);
1922 }
1923 
1924 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1925 vkCmdCopyBufferToImage(VkCommandBuffer commandBuffer, VkBuffer srcBuffer,
1926                        VkImage dstImage, VkImageLayout dstImageLayout,
1927                        uint32_t regionCount,
1928                        const VkBufferImageCopy *pRegions) {
1929     const VkLayerDispatchTable *disp;
1930 
1931     disp = loader_get_dispatch(commandBuffer);
1932 
1933     disp->CmdCopyBufferToImage(commandBuffer, srcBuffer, dstImage,
1934                                dstImageLayout, regionCount, pRegions);
1935 }
1936 
1937 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1938 vkCmdCopyImageToBuffer(VkCommandBuffer commandBuffer, VkImage srcImage,
1939                        VkImageLayout srcImageLayout, VkBuffer dstBuffer,
1940                        uint32_t regionCount,
1941                        const VkBufferImageCopy *pRegions) {
1942     const VkLayerDispatchTable *disp;
1943 
1944     disp = loader_get_dispatch(commandBuffer);
1945 
1946     disp->CmdCopyImageToBuffer(commandBuffer, srcImage, srcImageLayout,
1947                                dstBuffer, regionCount, pRegions);
1948 }
1949 
1950 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1951 vkCmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer,
1952                   VkDeviceSize dstOffset, VkDeviceSize dataSize,
1953                   const uint32_t *pData) {
1954     const VkLayerDispatchTable *disp;
1955 
1956     disp = loader_get_dispatch(commandBuffer);
1957 
1958     disp->CmdUpdateBuffer(commandBuffer, dstBuffer, dstOffset, dataSize, pData);
1959 }
1960 
1961 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1962 vkCmdFillBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer,
1963                 VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data) {
1964     const VkLayerDispatchTable *disp;
1965 
1966     disp = loader_get_dispatch(commandBuffer);
1967 
1968     disp->CmdFillBuffer(commandBuffer, dstBuffer, dstOffset, size, data);
1969 }
1970 
1971 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1972 vkCmdClearColorImage(VkCommandBuffer commandBuffer, VkImage image,
1973                      VkImageLayout imageLayout, const VkClearColorValue *pColor,
1974                      uint32_t rangeCount,
1975                      const VkImageSubresourceRange *pRanges) {
1976     const VkLayerDispatchTable *disp;
1977 
1978     disp = loader_get_dispatch(commandBuffer);
1979 
1980     disp->CmdClearColorImage(commandBuffer, image, imageLayout, pColor,
1981                              rangeCount, pRanges);
1982 }
1983 
1984 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1985 vkCmdClearDepthStencilImage(VkCommandBuffer commandBuffer, VkImage image,
1986                             VkImageLayout imageLayout,
1987                             const VkClearDepthStencilValue *pDepthStencil,
1988                             uint32_t rangeCount,
1989                             const VkImageSubresourceRange *pRanges) {
1990     const VkLayerDispatchTable *disp;
1991 
1992     disp = loader_get_dispatch(commandBuffer);
1993 
1994     disp->CmdClearDepthStencilImage(commandBuffer, image, imageLayout,
1995                                     pDepthStencil, rangeCount, pRanges);
1996 }
1997 
1998 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
1999 vkCmdClearAttachments(VkCommandBuffer commandBuffer, uint32_t attachmentCount,
2000                       const VkClearAttachment *pAttachments, uint32_t rectCount,
2001                       const VkClearRect *pRects) {
2002     const VkLayerDispatchTable *disp;
2003 
2004     disp = loader_get_dispatch(commandBuffer);
2005 
2006     disp->CmdClearAttachments(commandBuffer, attachmentCount, pAttachments,
2007                               rectCount, pRects);
2008 }
2009 
2010 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
2011 vkCmdResolveImage(VkCommandBuffer commandBuffer, VkImage srcImage,
2012                   VkImageLayout srcImageLayout, VkImage dstImage,
2013                   VkImageLayout dstImageLayout, uint32_t regionCount,
2014                   const VkImageResolve *pRegions) {
2015     const VkLayerDispatchTable *disp;
2016 
2017     disp = loader_get_dispatch(commandBuffer);
2018 
2019     disp->CmdResolveImage(commandBuffer, srcImage, srcImageLayout, dstImage,
2020                           dstImageLayout, regionCount, pRegions);
2021 }
2022 
2023 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
2024 vkCmdSetEvent(VkCommandBuffer commandBuffer, VkEvent event,
2025               VkPipelineStageFlags stageMask) {
2026     const VkLayerDispatchTable *disp;
2027 
2028     disp = loader_get_dispatch(commandBuffer);
2029 
2030     disp->CmdSetEvent(commandBuffer, event, stageMask);
2031 }
2032 
2033 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
2034 vkCmdResetEvent(VkCommandBuffer commandBuffer, VkEvent event,
2035                 VkPipelineStageFlags stageMask) {
2036     const VkLayerDispatchTable *disp;
2037 
2038     disp = loader_get_dispatch(commandBuffer);
2039 
2040     disp->CmdResetEvent(commandBuffer, event, stageMask);
2041 }
2042 
2043 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
2044 vkCmdWaitEvents(VkCommandBuffer commandBuffer, uint32_t eventCount,
2045                 const VkEvent *pEvents, VkPipelineStageFlags sourceStageMask,
2046                 VkPipelineStageFlags dstStageMask, uint32_t memoryBarrierCount,
2047                 const VkMemoryBarrier *pMemoryBarriers,
2048                 uint32_t bufferMemoryBarrierCount,
2049                 const VkBufferMemoryBarrier *pBufferMemoryBarriers,
2050                 uint32_t imageMemoryBarrierCount,
2051                 const VkImageMemoryBarrier *pImageMemoryBarriers) {
2052     const VkLayerDispatchTable *disp;
2053 
2054     disp = loader_get_dispatch(commandBuffer);
2055 
2056     disp->CmdWaitEvents(commandBuffer, eventCount, pEvents, sourceStageMask,
2057                         dstStageMask, memoryBarrierCount, pMemoryBarriers,
2058                         bufferMemoryBarrierCount, pBufferMemoryBarriers,
2059                         imageMemoryBarrierCount, pImageMemoryBarriers);
2060 }
2061 
2062 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdPipelineBarrier(
2063     VkCommandBuffer commandBuffer, VkPipelineStageFlags srcStageMask,
2064     VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags,
2065     uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers,
2066     uint32_t bufferMemoryBarrierCount,
2067     const VkBufferMemoryBarrier *pBufferMemoryBarriers,
2068     uint32_t imageMemoryBarrierCount,
2069     const VkImageMemoryBarrier *pImageMemoryBarriers) {
2070     const VkLayerDispatchTable *disp;
2071 
2072     disp = loader_get_dispatch(commandBuffer);
2073 
2074     disp->CmdPipelineBarrier(
2075         commandBuffer, srcStageMask, dstStageMask, dependencyFlags,
2076         memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount,
2077         pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers);
2078 }
2079 
2080 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
2081 vkCmdBeginQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool,
2082                 uint32_t slot, VkFlags flags) {
2083     const VkLayerDispatchTable *disp;
2084 
2085     disp = loader_get_dispatch(commandBuffer);
2086 
2087     disp->CmdBeginQuery(commandBuffer, queryPool, slot, flags);
2088 }
2089 
2090 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
2091 vkCmdEndQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool,
2092               uint32_t slot) {
2093     const VkLayerDispatchTable *disp;
2094 
2095     disp = loader_get_dispatch(commandBuffer);
2096 
2097     disp->CmdEndQuery(commandBuffer, queryPool, slot);
2098 }
2099 
2100 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
2101 vkCmdResetQueryPool(VkCommandBuffer commandBuffer, VkQueryPool queryPool,
2102                     uint32_t firstQuery, uint32_t queryCount) {
2103     const VkLayerDispatchTable *disp;
2104 
2105     disp = loader_get_dispatch(commandBuffer);
2106 
2107     disp->CmdResetQueryPool(commandBuffer, queryPool, firstQuery, queryCount);
2108 }
2109 
2110 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
2111 vkCmdWriteTimestamp(VkCommandBuffer commandBuffer,
2112                     VkPipelineStageFlagBits pipelineStage,
2113                     VkQueryPool queryPool, uint32_t slot) {
2114     const VkLayerDispatchTable *disp;
2115 
2116     disp = loader_get_dispatch(commandBuffer);
2117 
2118     disp->CmdWriteTimestamp(commandBuffer, pipelineStage, queryPool, slot);
2119 }
2120 
2121 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
2122 vkCmdCopyQueryPoolResults(VkCommandBuffer commandBuffer, VkQueryPool queryPool,
2123                           uint32_t firstQuery, uint32_t queryCount,
2124                           VkBuffer dstBuffer, VkDeviceSize dstOffset,
2125                           VkDeviceSize stride, VkFlags flags) {
2126     const VkLayerDispatchTable *disp;
2127 
2128     disp = loader_get_dispatch(commandBuffer);
2129 
2130     disp->CmdCopyQueryPoolResults(commandBuffer, queryPool, firstQuery,
2131                                   queryCount, dstBuffer, dstOffset, stride,
2132                                   flags);
2133 }
2134 
2135 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
2136 vkCmdPushConstants(VkCommandBuffer commandBuffer, VkPipelineLayout layout,
2137                    VkShaderStageFlags stageFlags, uint32_t offset,
2138                    uint32_t size, const void *pValues) {
2139     const VkLayerDispatchTable *disp;
2140 
2141     disp = loader_get_dispatch(commandBuffer);
2142 
2143     disp->CmdPushConstants(commandBuffer, layout, stageFlags, offset, size,
2144                            pValues);
2145 }
2146 
2147 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
2148 vkCmdBeginRenderPass(VkCommandBuffer commandBuffer,
2149                      const VkRenderPassBeginInfo *pRenderPassBegin,
2150                      VkSubpassContents contents) {
2151     const VkLayerDispatchTable *disp;
2152 
2153     disp = loader_get_dispatch(commandBuffer);
2154 
2155     disp->CmdBeginRenderPass(commandBuffer, pRenderPassBegin, contents);
2156 }
2157 
2158 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
2159 vkCmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpassContents contents) {
2160     const VkLayerDispatchTable *disp;
2161 
2162     disp = loader_get_dispatch(commandBuffer);
2163 
2164     disp->CmdNextSubpass(commandBuffer, contents);
2165 }
2166 
2167 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
2168 vkCmdEndRenderPass(VkCommandBuffer commandBuffer) {
2169     const VkLayerDispatchTable *disp;
2170 
2171     disp = loader_get_dispatch(commandBuffer);
2172 
2173     disp->CmdEndRenderPass(commandBuffer);
2174 }
2175 
2176 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
2177 vkCmdExecuteCommands(VkCommandBuffer commandBuffer,
2178                      uint32_t commandBuffersCount,
2179                      const VkCommandBuffer *pCommandBuffers) {
2180     const VkLayerDispatchTable *disp;
2181 
2182     disp = loader_get_dispatch(commandBuffer);
2183 
2184     disp->CmdExecuteCommands(commandBuffer, commandBuffersCount,
2185                              pCommandBuffers);
2186 }
2187