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