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