trampoline.c revision 01d2ae18f05184e04eb29a2ab30480f8d4660d25
1/*
2 * Vulkan
3 *
4 * Copyright (C) 2014 LunarG, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24#define _GNU_SOURCE
25#include <stdlib.h>
26#include <string.h>
27
28#include "vk_loader_platform.h"
29#include "loader.h"
30#include "debug_report.h"
31#include "wsi_swapchain.h"
32
33
34/* Trampoline entrypoints */
35LOADER_EXPORT VkResult VKAPI vkCreateInstance(
36        const VkInstanceCreateInfo* pCreateInfo,
37        VkInstance* pInstance)
38{
39    struct loader_instance *ptr_instance = NULL;
40    VkResult res = VK_ERROR_INITIALIZATION_FAILED;
41
42    loader_platform_thread_once(&once_init, loader_initialize);
43
44    if (pCreateInfo->pAllocCb
45            && pCreateInfo->pAllocCb->pfnAlloc
46            && pCreateInfo->pAllocCb->pfnFree) {
47        ptr_instance = (struct loader_instance *) pCreateInfo->pAllocCb->pfnAlloc(
48                           pCreateInfo->pAllocCb->pUserData,
49                           sizeof(struct loader_instance),
50                           sizeof(VkInstance),
51                           VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
52    } else {
53        ptr_instance = (struct loader_instance *) malloc(sizeof(struct loader_instance));
54    }
55    if (ptr_instance == NULL) {
56        return VK_ERROR_OUT_OF_HOST_MEMORY;
57    }
58
59    tls_instance = ptr_instance;
60    loader_platform_thread_lock_mutex(&loader_lock);
61    memset(ptr_instance, 0, sizeof(struct loader_instance));
62
63    if (pCreateInfo->pAllocCb
64            && pCreateInfo->pAllocCb->pfnAlloc
65            && pCreateInfo->pAllocCb->pfnFree) {
66        ptr_instance->alloc_callbacks.pUserData = pCreateInfo->pAllocCb->pUserData;
67        ptr_instance->alloc_callbacks.pfnAlloc = pCreateInfo->pAllocCb->pfnAlloc;
68        ptr_instance->alloc_callbacks.pfnFree = pCreateInfo->pAllocCb->pfnFree;
69    }
70
71    /* Due to implicit layers need to get layer list even if
72     * layerCount == 0 and VK_INSTANCE_LAYERS is unset. For now always
73     * get layer list (both instance and device) via loader_layer_scan(). */
74    memset(&ptr_instance->instance_layer_list, 0, sizeof(ptr_instance->instance_layer_list));
75    memset(&ptr_instance->device_layer_list, 0, sizeof(ptr_instance->device_layer_list));
76    loader_layer_scan(ptr_instance,
77
78
79                      &ptr_instance->instance_layer_list,
80                      &ptr_instance->device_layer_list);
81
82    /* validate the app requested layers to be enabled */
83    if (pCreateInfo->layerCount > 0) {
84        res = loader_validate_layers(pCreateInfo->layerCount,
85                                     pCreateInfo->ppEnabledLayerNames,
86                                     &ptr_instance->instance_layer_list);
87        if (res != VK_SUCCESS) {
88            loader_platform_thread_unlock_mutex(&loader_lock);
89            return res;
90        }
91    }
92
93    /* Scan/discover all ICD libraries */
94    memset(&ptr_instance->icd_libs, 0, sizeof(ptr_instance->icd_libs));
95    loader_icd_scan(ptr_instance, &ptr_instance->icd_libs);
96
97    /* get extensions from all ICD's, merge so no duplicates, then validate */
98    loader_get_icd_loader_instance_extensions(ptr_instance,
99                                              &ptr_instance->icd_libs,
100                                              &ptr_instance->ext_list);
101    res = loader_validate_instance_extensions(&ptr_instance->ext_list,
102                                              &ptr_instance->instance_layer_list,
103                                              pCreateInfo);
104    if (res != VK_SUCCESS) {
105        loader_delete_layer_properties(ptr_instance,
106                                       &ptr_instance->device_layer_list);
107        loader_delete_layer_properties(ptr_instance,
108                                       &ptr_instance->instance_layer_list);
109        loader_scanned_icd_clear(ptr_instance, &ptr_instance->icd_libs);
110        loader_destroy_ext_list(ptr_instance, &ptr_instance->ext_list);
111        loader_platform_thread_unlock_mutex(&loader_lock);
112        loader_heap_free(ptr_instance, ptr_instance);
113        return res;
114    }
115
116    ptr_instance->disp = loader_heap_alloc(
117                             ptr_instance,
118                             sizeof(VkLayerInstanceDispatchTable),
119                             VK_SYSTEM_ALLOC_TYPE_INTERNAL);
120    if (ptr_instance->disp == NULL) {
121        loader_delete_layer_properties(ptr_instance,
122                                       &ptr_instance->device_layer_list);
123        loader_delete_layer_properties(ptr_instance,
124                                       &ptr_instance->instance_layer_list);
125        loader_scanned_icd_clear(ptr_instance,
126                                 &ptr_instance->icd_libs);
127        loader_destroy_ext_list(ptr_instance,
128                                &ptr_instance->ext_list);
129        loader_platform_thread_unlock_mutex(&loader_lock);
130        loader_heap_free(ptr_instance, ptr_instance);
131        return VK_ERROR_OUT_OF_HOST_MEMORY;
132    }
133    memcpy(ptr_instance->disp, &instance_disp, sizeof(instance_disp));
134    ptr_instance->next = loader.instances;
135    loader.instances = ptr_instance;
136
137    /* activate any layers on instance chain */
138    res = loader_enable_instance_layers(ptr_instance,
139                                        pCreateInfo,
140                                        &ptr_instance->instance_layer_list);
141    if (res != VK_SUCCESS) {
142        loader_delete_layer_properties(ptr_instance,
143                                       &ptr_instance->device_layer_list);
144        loader_delete_layer_properties(ptr_instance,
145                                       &ptr_instance->instance_layer_list);
146        loader_scanned_icd_clear(ptr_instance,
147                                 &ptr_instance->icd_libs);
148        loader_destroy_ext_list(ptr_instance,
149                                &ptr_instance->ext_list);
150        loader.instances = ptr_instance->next;
151        loader_platform_thread_unlock_mutex(&loader_lock);
152        loader_heap_free(ptr_instance, ptr_instance->disp);
153        loader_heap_free(ptr_instance, ptr_instance);
154        return res;
155    }
156    loader_activate_instance_layers(ptr_instance);
157
158    wsi_swapchain_create_instance(ptr_instance, pCreateInfo);
159    debug_report_create_instance(ptr_instance, pCreateInfo);
160
161
162    *pInstance = (VkInstance) ptr_instance;
163
164    res = ptr_instance->disp->CreateInstance(pCreateInfo, pInstance);
165
166    /*
167     * Finally have the layers in place and everyone has seen
168     * the CreateInstance command go by. This allows the layer's
169     * GetInstanceProcAddr functions to return valid extension functions
170     * if enabled.
171     */
172    loader_activate_instance_layer_extensions(ptr_instance);
173
174    loader_platform_thread_unlock_mutex(&loader_lock);
175    return res;
176}
177
178LOADER_EXPORT void VKAPI vkDestroyInstance(
179                                            VkInstance instance)
180{
181    const VkLayerInstanceDispatchTable *disp;
182    struct loader_instance *ptr_instance = NULL;
183    disp = loader_get_instance_dispatch(instance);
184
185    loader_platform_thread_lock_mutex(&loader_lock);
186
187    ptr_instance = loader_get_instance(instance);
188    disp->DestroyInstance(instance);
189
190    loader_deactivate_instance_layers(ptr_instance);
191    loader_heap_free(ptr_instance, ptr_instance->disp);
192    loader_heap_free(ptr_instance, ptr_instance);
193    loader_platform_thread_unlock_mutex(&loader_lock);
194}
195
196LOADER_EXPORT VkResult VKAPI vkEnumeratePhysicalDevices(
197                                            VkInstance instance,
198                                            uint32_t* pPhysicalDeviceCount,
199                                            VkPhysicalDevice* pPhysicalDevices)
200{
201    const VkLayerInstanceDispatchTable *disp;
202    VkResult res;
203    disp = loader_get_instance_dispatch(instance);
204
205    loader_platform_thread_lock_mutex(&loader_lock);
206    res = disp->EnumeratePhysicalDevices(instance, pPhysicalDeviceCount,
207                                         pPhysicalDevices);
208    loader_platform_thread_unlock_mutex(&loader_lock);
209    return res;
210}
211
212
213
214
215
216
217LOADER_EXPORT void VKAPI vkGetPhysicalDeviceFeatures(
218                                            VkPhysicalDevice gpu,
219                                            VkPhysicalDeviceFeatures *pFeatures)
220{
221    const VkLayerInstanceDispatchTable *disp;
222
223    disp = loader_get_instance_dispatch(gpu);
224    disp->GetPhysicalDeviceFeatures(gpu, pFeatures);
225}
226
227LOADER_EXPORT void VKAPI vkGetPhysicalDeviceFormatProperties(
228                                            VkPhysicalDevice gpu,
229                                            VkFormat format,
230                                            VkFormatProperties *pFormatInfo)
231{
232    const VkLayerInstanceDispatchTable *disp;
233
234    disp = loader_get_instance_dispatch(gpu);
235    disp->GetPhysicalDeviceFormatProperties(gpu, format, pFormatInfo);
236}
237
238LOADER_EXPORT void VKAPI vkGetPhysicalDeviceImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags, VkImageFormatProperties* pImageFormatProperties)
239{
240    const VkLayerInstanceDispatchTable *disp;
241
242    disp = loader_get_instance_dispatch(physicalDevice);
243    disp->GetPhysicalDeviceImageFormatProperties(physicalDevice, format, type, tiling, usage, flags, pImageFormatProperties);
244}
245
246LOADER_EXPORT void VKAPI vkGetPhysicalDeviceProperties(
247                                            VkPhysicalDevice gpu,
248                                            VkPhysicalDeviceProperties* pProperties)
249{
250    const VkLayerInstanceDispatchTable *disp;
251
252    disp = loader_get_instance_dispatch(gpu);
253    disp->GetPhysicalDeviceProperties(gpu, pProperties);
254}
255
256LOADER_EXPORT void VKAPI vkGetPhysicalDeviceQueueFamilyProperties(
257                                            VkPhysicalDevice gpu,
258                                            uint32_t* pCount,
259                                            VkQueueFamilyProperties* pQueueProperties)
260{
261    const VkLayerInstanceDispatchTable *disp;
262
263    disp = loader_get_instance_dispatch(gpu);
264    disp->GetPhysicalDeviceQueueFamilyProperties(gpu, pCount, pQueueProperties);
265}
266
267LOADER_EXPORT void VKAPI vkGetPhysicalDeviceMemoryProperties(
268                                            VkPhysicalDevice gpu,
269                                            VkPhysicalDeviceMemoryProperties* pMemoryProperties)
270{
271    const VkLayerInstanceDispatchTable *disp;
272
273    disp = loader_get_instance_dispatch(gpu);
274    disp->GetPhysicalDeviceMemoryProperties(gpu, pMemoryProperties);
275}
276
277LOADER_EXPORT VkResult VKAPI vkCreateDevice(
278        VkPhysicalDevice gpu,
279        const VkDeviceCreateInfo* pCreateInfo,
280        VkDevice* pDevice)
281{
282    VkResult res;
283
284    loader_platform_thread_lock_mutex(&loader_lock);
285
286    res = loader_CreateDevice(gpu, pCreateInfo, pDevice);
287
288    loader_platform_thread_unlock_mutex(&loader_lock);
289    return res;
290}
291
292LOADER_EXPORT void VKAPI vkDestroyDevice(VkDevice device)
293{
294    const VkLayerDispatchTable *disp;
295    struct loader_device *dev;
296    struct loader_icd *icd = loader_get_icd_and_device(device, &dev);
297    const struct loader_instance *inst = icd->this_instance;
298    disp = loader_get_dispatch(device);
299
300    loader_platform_thread_lock_mutex(&loader_lock);
301    disp->DestroyDevice(device);
302    loader_remove_logical_device(inst, device);
303    loader_platform_thread_unlock_mutex(&loader_lock);
304}
305
306LOADER_EXPORT VkResult VKAPI vkEnumerateDeviceExtensionProperties(
307    VkPhysicalDevice                            physicalDevice,
308    const char*                                 pLayerName,
309    uint32_t*                                   pCount,
310    VkExtensionProperties*                      pProperties)
311{
312    VkResult res;
313
314    loader_platform_thread_lock_mutex(&loader_lock);
315    //TODO convert over to using instance chain dispatch
316    res = loader_EnumerateDeviceExtensionProperties(physicalDevice, pLayerName, pCount, pProperties);
317    loader_platform_thread_unlock_mutex(&loader_lock);
318    return res;
319}
320
321LOADER_EXPORT VkResult VKAPI vkEnumerateDeviceLayerProperties(
322    VkPhysicalDevice                            physicalDevice,
323    uint32_t*                                   pCount,
324    VkLayerProperties*                          pProperties)
325{
326    VkResult res;
327
328    loader_platform_thread_lock_mutex(&loader_lock);
329    //TODO convert over to using instance chain dispatch
330    res = loader_EnumerateDeviceLayerProperties(physicalDevice, pCount, pProperties);
331    loader_platform_thread_unlock_mutex(&loader_lock);
332    return res;
333}
334
335LOADER_EXPORT void VKAPI vkGetDeviceQueue(VkDevice device, uint32_t queueNodeIndex, uint32_t queueIndex, VkQueue* pQueue)
336{
337    const VkLayerDispatchTable *disp;
338
339    disp = loader_get_dispatch(device);
340
341    disp->GetDeviceQueue(device, queueNodeIndex, queueIndex, pQueue);
342    loader_set_dispatch(*pQueue, disp);
343}
344
345LOADER_EXPORT VkResult VKAPI vkQueueSubmit(VkQueue queue, uint32_t cmdBufferCount, const VkCmdBuffer* pCmdBuffers, VkFence fence)
346{
347    const VkLayerDispatchTable *disp;
348
349    disp = loader_get_dispatch(queue);
350
351    return disp->QueueSubmit(queue, cmdBufferCount, pCmdBuffers, fence);
352}
353
354LOADER_EXPORT VkResult VKAPI vkQueueWaitIdle(VkQueue queue)
355{
356    const VkLayerDispatchTable *disp;
357
358    disp = loader_get_dispatch(queue);
359
360    return disp->QueueWaitIdle(queue);
361}
362
363LOADER_EXPORT VkResult VKAPI vkDeviceWaitIdle(VkDevice device)
364{
365    const VkLayerDispatchTable *disp;
366
367    disp = loader_get_dispatch(device);
368
369    return disp->DeviceWaitIdle(device);
370}
371
372LOADER_EXPORT VkResult VKAPI vkAllocMemory(VkDevice device, const VkMemoryAllocInfo* pAllocInfo, VkDeviceMemory* pMem)
373{
374    const VkLayerDispatchTable *disp;
375
376    disp = loader_get_dispatch(device);
377
378    return disp->AllocMemory(device, pAllocInfo, pMem);
379}
380
381LOADER_EXPORT void VKAPI vkFreeMemory(VkDevice device, VkDeviceMemory mem)
382{
383    const VkLayerDispatchTable *disp;
384
385    disp = loader_get_dispatch(device);
386
387    disp->FreeMemory(device, mem);
388}
389
390LOADER_EXPORT VkResult VKAPI vkMapMemory(VkDevice device, VkDeviceMemory mem, VkDeviceSize offset, VkDeviceSize size, VkFlags flags, void** ppData)
391{
392    const VkLayerDispatchTable *disp;
393
394    disp = loader_get_dispatch(device);
395
396    return disp->MapMemory(device, mem, offset, size, flags, ppData);
397}
398
399LOADER_EXPORT void VKAPI vkUnmapMemory(VkDevice device, VkDeviceMemory mem)
400{
401    const VkLayerDispatchTable *disp;
402
403    disp = loader_get_dispatch(device);
404
405    disp->UnmapMemory(device, mem);
406}
407
408LOADER_EXPORT VkResult VKAPI vkFlushMappedMemoryRanges(VkDevice device, uint32_t memRangeCount, const VkMappedMemoryRange* pMemRanges)
409{
410    const VkLayerDispatchTable *disp;
411
412    disp = loader_get_dispatch(device);
413
414    return disp->FlushMappedMemoryRanges(device, memRangeCount, pMemRanges);
415}
416
417LOADER_EXPORT VkResult VKAPI vkInvalidateMappedMemoryRanges(VkDevice device, uint32_t memRangeCount, const VkMappedMemoryRange* pMemRanges)
418{
419    const VkLayerDispatchTable *disp;
420
421    disp = loader_get_dispatch(device);
422
423    return disp->InvalidateMappedMemoryRanges(device, memRangeCount, pMemRanges);
424}
425
426LOADER_EXPORT void VKAPI vkGetDeviceMemoryCommitment(VkDevice device, VkDeviceMemory memory, VkDeviceSize* pCommittedMemoryInBytes)
427{
428    const VkLayerDispatchTable *disp;
429
430    disp = loader_get_dispatch(device);
431
432    disp->GetDeviceMemoryCommitment(device, memory, pCommittedMemoryInBytes);
433}
434
435LOADER_EXPORT VkResult VKAPI vkBindBufferMemory(VkDevice device, VkBuffer buffer, VkDeviceMemory mem, VkDeviceSize offset)
436{
437    const VkLayerDispatchTable *disp;
438
439    disp = loader_get_dispatch(device);
440
441    return disp->BindBufferMemory(device, buffer, mem, offset);
442}
443
444LOADER_EXPORT VkResult VKAPI vkBindImageMemory(VkDevice device, VkImage image, VkDeviceMemory mem, VkDeviceSize offset)
445{
446    const VkLayerDispatchTable *disp;
447
448    disp = loader_get_dispatch(device);
449
450    return disp->BindImageMemory(device, image, mem, offset);
451}
452
453LOADER_EXPORT void VKAPI vkGetBufferMemoryRequirements(VkDevice device, VkBuffer buffer, VkMemoryRequirements* pMemoryRequirements)
454{
455    const VkLayerDispatchTable *disp;
456
457    disp = loader_get_dispatch(device);
458
459    disp->GetBufferMemoryRequirements(device, buffer, pMemoryRequirements);
460}
461
462LOADER_EXPORT void VKAPI vkGetImageMemoryRequirements(VkDevice device, VkImage image, VkMemoryRequirements* pMemoryRequirements)
463{
464    const VkLayerDispatchTable *disp;
465
466    disp = loader_get_dispatch(device);
467
468    disp->GetImageMemoryRequirements(device, image, pMemoryRequirements);
469}
470
471LOADER_EXPORT void VKAPI vkGetImageSparseMemoryRequirements(VkDevice device, VkImage image, uint32_t* pNumRequirements, VkSparseImageMemoryRequirements* pSparseMemoryRequirements)
472{
473    const VkLayerDispatchTable *disp;
474
475    disp = loader_get_dispatch(device);
476
477    disp->GetImageSparseMemoryRequirements(device, image, pNumRequirements, pSparseMemoryRequirements);
478}
479
480LOADER_EXPORT void VKAPI vkGetPhysicalDeviceSparseImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, uint32_t samples, VkImageUsageFlags usage, VkImageTiling tiling, uint32_t* pNumProperties, VkSparseImageFormatProperties* pProperties)
481{
482    const VkLayerInstanceDispatchTable *disp;
483
484    disp = loader_get_instance_dispatch(physicalDevice);
485
486    disp->GetPhysicalDeviceSparseImageFormatProperties(physicalDevice, format, type, samples, usage, tiling, pNumProperties, pProperties);
487}
488
489LOADER_EXPORT VkResult VKAPI vkQueueBindSparseBufferMemory(VkQueue queue, VkBuffer buffer, uint32_t numBindings, const VkSparseMemoryBindInfo* pBindInfo)
490{
491    const VkLayerDispatchTable *disp;
492
493    disp = loader_get_dispatch(queue);
494
495    return disp->QueueBindSparseBufferMemory(queue, buffer, numBindings, pBindInfo);
496}
497
498LOADER_EXPORT VkResult VKAPI vkQueueBindSparseImageOpaqueMemory(VkQueue queue, VkImage image, uint32_t numBindings, const VkSparseMemoryBindInfo* pBindInfo)
499{
500    const VkLayerDispatchTable *disp;
501
502    disp = loader_get_dispatch(queue);
503
504    return disp->QueueBindSparseImageOpaqueMemory(queue, image, numBindings, pBindInfo);
505}
506
507LOADER_EXPORT VkResult VKAPI vkQueueBindSparseImageMemory(VkQueue queue, VkImage image, uint32_t numBindings, const VkSparseImageMemoryBindInfo* pBindInfo)
508{
509    const VkLayerDispatchTable *disp;
510
511    disp = loader_get_dispatch(queue);
512
513    return disp->QueueBindSparseImageMemory(queue, image, numBindings, pBindInfo);
514}
515
516LOADER_EXPORT VkResult VKAPI vkCreateFence(VkDevice device, const VkFenceCreateInfo* pCreateInfo, VkFence* pFence)
517{
518    const VkLayerDispatchTable *disp;
519
520    disp = loader_get_dispatch(device);
521
522    return disp->CreateFence(device, pCreateInfo, pFence);
523}
524
525LOADER_EXPORT void VKAPI vkDestroyFence(VkDevice device, VkFence fence)
526{
527    const VkLayerDispatchTable *disp;
528
529    disp = loader_get_dispatch(device);
530
531    disp->DestroyFence(device, fence);
532}
533
534LOADER_EXPORT VkResult VKAPI vkResetFences(VkDevice device, uint32_t fenceCount, const VkFence* pFences)
535{
536    const VkLayerDispatchTable *disp;
537
538    disp = loader_get_dispatch(device);
539
540    return disp->ResetFences(device, fenceCount, pFences);
541}
542
543LOADER_EXPORT VkResult VKAPI vkGetFenceStatus(VkDevice device, VkFence fence)
544{
545    const VkLayerDispatchTable *disp;
546
547    disp = loader_get_dispatch(device);
548
549    return disp->GetFenceStatus(device, fence);
550}
551
552LOADER_EXPORT VkResult VKAPI vkWaitForFences(VkDevice device, uint32_t fenceCount, const VkFence* pFences, VkBool32 waitAll, uint64_t timeout)
553{
554    const VkLayerDispatchTable *disp;
555
556    disp = loader_get_dispatch(device);
557
558    return disp->WaitForFences(device, fenceCount, pFences, waitAll, timeout);
559}
560
561LOADER_EXPORT VkResult VKAPI vkCreateSemaphore(VkDevice device, const VkSemaphoreCreateInfo* pCreateInfo, VkSemaphore* pSemaphore)
562{
563    const VkLayerDispatchTable *disp;
564
565    disp = loader_get_dispatch(device);
566
567    return disp->CreateSemaphore(device, pCreateInfo, pSemaphore);
568}
569
570LOADER_EXPORT void VKAPI vkDestroySemaphore(VkDevice device, VkSemaphore semaphore)
571{
572    const VkLayerDispatchTable *disp;
573
574    disp = loader_get_dispatch(device);
575
576    disp->DestroySemaphore(device, semaphore);
577}
578
579LOADER_EXPORT VkResult VKAPI vkQueueSignalSemaphore(VkQueue queue, VkSemaphore semaphore)
580{
581    const VkLayerDispatchTable *disp;
582
583    disp = loader_get_dispatch(queue);
584
585    return disp->QueueSignalSemaphore(queue, semaphore);
586}
587
588LOADER_EXPORT VkResult VKAPI vkQueueWaitSemaphore(VkQueue queue, VkSemaphore semaphore)
589{
590    const VkLayerDispatchTable *disp;
591
592    disp = loader_get_dispatch(queue);
593
594    return disp->QueueWaitSemaphore(queue, semaphore);
595}
596
597LOADER_EXPORT VkResult VKAPI vkCreateEvent(VkDevice device, const VkEventCreateInfo* pCreateInfo, VkEvent* pEvent)
598{
599    const VkLayerDispatchTable *disp;
600
601    disp = loader_get_dispatch(device);
602
603    return disp->CreateEvent(device, pCreateInfo, pEvent);
604}
605
606LOADER_EXPORT void VKAPI vkDestroyEvent(VkDevice device, VkEvent event)
607{
608    const VkLayerDispatchTable *disp;
609
610    disp = loader_get_dispatch(device);
611
612    disp->DestroyEvent(device, event);
613}
614
615LOADER_EXPORT VkResult VKAPI vkGetEventStatus(VkDevice device, VkEvent event)
616{
617    const VkLayerDispatchTable *disp;
618
619    disp = loader_get_dispatch(device);
620
621    return disp->GetEventStatus(device, event);
622}
623
624LOADER_EXPORT VkResult VKAPI vkSetEvent(VkDevice device, VkEvent event)
625{
626    const VkLayerDispatchTable *disp;
627
628    disp = loader_get_dispatch(device);
629
630    return disp->SetEvent(device, event);
631}
632
633LOADER_EXPORT VkResult VKAPI vkResetEvent(VkDevice device, VkEvent event)
634{
635    const VkLayerDispatchTable *disp;
636
637    disp = loader_get_dispatch(device);
638
639    return disp->ResetEvent(device, event);
640}
641
642LOADER_EXPORT VkResult VKAPI vkCreateQueryPool(VkDevice device, const VkQueryPoolCreateInfo* pCreateInfo, VkQueryPool* pQueryPool)
643{
644    const VkLayerDispatchTable *disp;
645
646    disp = loader_get_dispatch(device);
647
648    return disp->CreateQueryPool(device, pCreateInfo, pQueryPool);
649}
650
651LOADER_EXPORT void VKAPI vkDestroyQueryPool(VkDevice device, VkQueryPool queryPool)
652{
653    const VkLayerDispatchTable *disp;
654
655    disp = loader_get_dispatch(device);
656
657    disp->DestroyQueryPool(device, queryPool);
658}
659
660LOADER_EXPORT VkResult VKAPI vkGetQueryPoolResults(VkDevice device, VkQueryPool queryPool, uint32_t startQuery, uint32_t queryCount, size_t* pDataSize, void* pData, VkQueryResultFlags flags)
661{
662    const VkLayerDispatchTable *disp;
663
664    disp = loader_get_dispatch(device);
665
666    return disp->GetQueryPoolResults(device, queryPool, startQuery, queryCount, pDataSize, pData, flags);
667}
668
669LOADER_EXPORT VkResult VKAPI vkCreateBuffer(VkDevice device, const VkBufferCreateInfo* pCreateInfo, VkBuffer* pBuffer)
670{
671    const VkLayerDispatchTable *disp;
672
673    disp = loader_get_dispatch(device);
674
675    return disp->CreateBuffer(device, pCreateInfo, pBuffer);
676}
677
678LOADER_EXPORT void VKAPI vkDestroyBuffer(VkDevice device, VkBuffer buffer)
679{
680    const VkLayerDispatchTable *disp;
681
682    disp = loader_get_dispatch(device);
683
684    disp->DestroyBuffer(device, buffer);
685}
686
687LOADER_EXPORT VkResult VKAPI vkCreateBufferView(VkDevice device, const VkBufferViewCreateInfo* pCreateInfo, VkBufferView* pView)
688{
689    const VkLayerDispatchTable *disp;
690
691    disp = loader_get_dispatch(device);
692
693    return disp->CreateBufferView(device, pCreateInfo, pView);
694}
695
696LOADER_EXPORT void VKAPI vkDestroyBufferView(VkDevice device, VkBufferView bufferView)
697{
698    const VkLayerDispatchTable *disp;
699
700    disp = loader_get_dispatch(device);
701
702    disp->DestroyBufferView(device, bufferView);
703}
704
705LOADER_EXPORT VkResult VKAPI vkCreateImage(VkDevice device, const VkImageCreateInfo* pCreateInfo, VkImage* pImage)
706{
707    const VkLayerDispatchTable *disp;
708
709    disp = loader_get_dispatch(device);
710
711    return disp->CreateImage(device, pCreateInfo, pImage);
712}
713
714LOADER_EXPORT void VKAPI vkDestroyImage(VkDevice device, VkImage image)
715{
716    const VkLayerDispatchTable *disp;
717
718    disp = loader_get_dispatch(device);
719
720    disp->DestroyImage(device, image);
721}
722
723LOADER_EXPORT void VKAPI vkGetImageSubresourceLayout(VkDevice device, VkImage image, const VkImageSubresource* pSubresource, VkSubresourceLayout* pLayout)
724{
725    const VkLayerDispatchTable *disp;
726
727    disp = loader_get_dispatch(device);
728
729    disp->GetImageSubresourceLayout(device, image, pSubresource, pLayout);
730}
731
732LOADER_EXPORT VkResult VKAPI vkCreateImageView(VkDevice device, const VkImageViewCreateInfo* pCreateInfo, VkImageView* pView)
733{
734    const VkLayerDispatchTable *disp;
735
736    disp = loader_get_dispatch(device);
737
738    return disp->CreateImageView(device, pCreateInfo, pView);
739}
740
741LOADER_EXPORT void VKAPI vkDestroyImageView(VkDevice device, VkImageView imageView)
742{
743    const VkLayerDispatchTable *disp;
744
745    disp = loader_get_dispatch(device);
746
747    disp->DestroyImageView(device, imageView);
748}
749
750LOADER_EXPORT VkResult VKAPI vkCreateShaderModule(VkDevice device, const VkShaderModuleCreateInfo* pCreateInfo, VkShaderModule* pShader)
751{
752    const VkLayerDispatchTable *disp;
753
754    disp = loader_get_dispatch(device);
755
756    return disp->CreateShaderModule(device, pCreateInfo, pShader);
757}
758
759LOADER_EXPORT void VKAPI vkDestroyShaderModule(VkDevice device, VkShaderModule shaderModule)
760{
761    const VkLayerDispatchTable *disp;
762
763    disp = loader_get_dispatch(device);
764
765    disp->DestroyShaderModule(device, shaderModule);
766}
767
768LOADER_EXPORT VkResult VKAPI vkCreateShader(VkDevice device, const VkShaderCreateInfo* pCreateInfo, VkShader* pShader)
769{
770    const VkLayerDispatchTable *disp;
771
772    disp = loader_get_dispatch(device);
773
774    return disp->CreateShader(device, pCreateInfo, pShader);
775}
776
777LOADER_EXPORT void VKAPI vkDestroyShader(VkDevice device, VkShader shader)
778{
779    const VkLayerDispatchTable *disp;
780
781    disp = loader_get_dispatch(device);
782
783    disp->DestroyShader(device, shader);
784}
785
786LOADER_EXPORT VkResult VKAPI vkCreatePipelineCache(VkDevice device, const VkPipelineCacheCreateInfo* pCreateInfo, VkPipelineCache* pPipelineCache)
787{
788    const VkLayerDispatchTable *disp;
789
790    disp = loader_get_dispatch(device);
791
792    return disp->CreatePipelineCache(device, pCreateInfo, pPipelineCache);
793}
794
795LOADER_EXPORT void VKAPI vkDestroyPipelineCache(VkDevice device, VkPipelineCache pipelineCache)
796{
797    const VkLayerDispatchTable *disp;
798
799    disp = loader_get_dispatch(device);
800
801    disp->DestroyPipelineCache(device, pipelineCache);
802}
803
804LOADER_EXPORT size_t VKAPI vkGetPipelineCacheSize(VkDevice device, VkPipelineCache pipelineCache)
805{
806    const VkLayerDispatchTable *disp;
807
808    disp = loader_get_dispatch(device);
809
810    return disp->GetPipelineCacheSize(device, pipelineCache);
811}
812
813LOADER_EXPORT VkResult VKAPI vkGetPipelineCacheData(VkDevice device, VkPipelineCache pipelineCache, size_t dataSize, void* pData)
814{
815    const VkLayerDispatchTable *disp;
816
817    disp = loader_get_dispatch(device);
818
819    return disp->GetPipelineCacheData(device, pipelineCache, dataSize, pData);
820}
821
822LOADER_EXPORT VkResult VKAPI vkMergePipelineCaches(VkDevice device, VkPipelineCache destCache, uint32_t srcCacheCount, const VkPipelineCache* pSrcCaches)
823{
824    const VkLayerDispatchTable *disp;
825
826    disp = loader_get_dispatch(device);
827
828    return disp->MergePipelineCaches(device, destCache, srcCacheCount, pSrcCaches);
829}
830
831LOADER_EXPORT VkResult VKAPI vkCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count, const VkGraphicsPipelineCreateInfo* pCreateInfos, VkPipeline* pPipelines)
832{
833    const VkLayerDispatchTable *disp;
834
835    disp = loader_get_dispatch(device);
836
837    return disp->CreateGraphicsPipelines(device, pipelineCache, count, pCreateInfos, pPipelines);
838}
839
840LOADER_EXPORT VkResult VKAPI vkCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count, const VkComputePipelineCreateInfo* pCreateInfos, VkPipeline* pPipelines)
841{
842    const VkLayerDispatchTable *disp;
843
844    disp = loader_get_dispatch(device);
845
846    return disp->CreateComputePipelines(device, pipelineCache, count, pCreateInfos, pPipelines);
847}
848
849LOADER_EXPORT void VKAPI vkDestroyPipeline(VkDevice device, VkPipeline pipeline)
850{
851    const VkLayerDispatchTable *disp;
852
853    disp = loader_get_dispatch(device);
854
855    disp->DestroyPipeline(device, pipeline);
856}
857
858LOADER_EXPORT VkResult VKAPI vkCreatePipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo* pCreateInfo, VkPipelineLayout* pPipelineLayout)
859{
860    const VkLayerDispatchTable *disp;
861
862    disp = loader_get_dispatch(device);
863
864    return disp->CreatePipelineLayout(device, pCreateInfo, pPipelineLayout);
865}
866
867LOADER_EXPORT void VKAPI vkDestroyPipelineLayout(VkDevice device, VkPipelineLayout pipelineLayout)
868{
869    const VkLayerDispatchTable *disp;
870
871    disp = loader_get_dispatch(device);
872
873    disp->DestroyPipelineLayout(device, pipelineLayout);
874}
875
876LOADER_EXPORT VkResult VKAPI vkCreateSampler(VkDevice device, const VkSamplerCreateInfo* pCreateInfo, VkSampler* pSampler)
877{
878    const VkLayerDispatchTable *disp;
879
880    disp = loader_get_dispatch(device);
881
882    return disp->CreateSampler(device, pCreateInfo, pSampler);
883}
884
885LOADER_EXPORT void VKAPI vkDestroySampler(VkDevice device, VkSampler sampler)
886{
887    const VkLayerDispatchTable *disp;
888
889    disp = loader_get_dispatch(device);
890
891    disp->DestroySampler(device, sampler);
892}
893
894
895LOADER_EXPORT VkResult VKAPI vkCreateDescriptorSetLayout(VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, VkDescriptorSetLayout* pSetLayout)
896{
897    const VkLayerDispatchTable *disp;
898
899    disp = loader_get_dispatch(device);
900
901    return disp->CreateDescriptorSetLayout(device, pCreateInfo, pSetLayout);
902}
903
904LOADER_EXPORT void VKAPI vkDestroyDescriptorSetLayout(VkDevice device, VkDescriptorSetLayout descriptorSetLayout)
905{
906    const VkLayerDispatchTable *disp;
907
908    disp = loader_get_dispatch(device);
909
910    disp->DestroyDescriptorSetLayout(device, descriptorSetLayout);
911}
912
913LOADER_EXPORT VkResult VKAPI vkCreateDescriptorPool(VkDevice device, const VkDescriptorPoolCreateInfo* pCreateInfo, VkDescriptorPool* pDescriptorPool)
914{
915    const VkLayerDispatchTable *disp;
916
917    disp = loader_get_dispatch(device);
918
919    return disp->CreateDescriptorPool(device, pCreateInfo, pDescriptorPool);
920}
921
922LOADER_EXPORT void VKAPI vkDestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool)
923{
924    const VkLayerDispatchTable *disp;
925
926    disp = loader_get_dispatch(device);
927
928    disp->DestroyDescriptorPool(device, descriptorPool);
929}
930
931
932LOADER_EXPORT VkResult VKAPI vkResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool)
933{
934    const VkLayerDispatchTable *disp;
935
936    disp = loader_get_dispatch(device);
937
938    return disp->ResetDescriptorPool(device, descriptorPool);
939}
940
941LOADER_EXPORT VkResult VKAPI vkAllocDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorSetUsage setUsage, uint32_t count, const VkDescriptorSetLayout* pSetLayouts, VkDescriptorSet* pDescriptorSets)
942{
943    const VkLayerDispatchTable *disp;
944
945    disp = loader_get_dispatch(device);
946
947    return disp->AllocDescriptorSets(device, descriptorPool, setUsage, count, pSetLayouts, pDescriptorSets);
948}
949
950LOADER_EXPORT VkResult VKAPI vkFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, uint32_t count, const VkDescriptorSet* pDescriptorSets)
951{
952    const VkLayerDispatchTable *disp;
953
954    disp = loader_get_dispatch(device);
955
956    return disp->FreeDescriptorSets(device, descriptorPool, count, pDescriptorSets);
957}
958
959LOADER_EXPORT void VKAPI vkUpdateDescriptorSets(VkDevice device, uint32_t writeCount, const VkWriteDescriptorSet* pDescriptorWrites, uint32_t copyCount, const VkCopyDescriptorSet* pDescriptorCopies)
960{
961    const VkLayerDispatchTable *disp;
962
963    disp = loader_get_dispatch(device);
964
965    disp->UpdateDescriptorSets(device, writeCount, pDescriptorWrites, copyCount, pDescriptorCopies);
966}
967
968LOADER_EXPORT VkResult VKAPI vkCreateFramebuffer(VkDevice device, const VkFramebufferCreateInfo* pCreateInfo, VkFramebuffer* pFramebuffer)
969{
970    const VkLayerDispatchTable *disp;
971
972    disp = loader_get_dispatch(device);
973
974    return disp->CreateFramebuffer(device, pCreateInfo, pFramebuffer);
975}
976
977LOADER_EXPORT void VKAPI vkDestroyFramebuffer(VkDevice device, VkFramebuffer framebuffer)
978{
979    const VkLayerDispatchTable *disp;
980
981    disp = loader_get_dispatch(device);
982
983    disp->DestroyFramebuffer(device, framebuffer);
984}
985
986LOADER_EXPORT VkResult VKAPI vkCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo* pCreateInfo, VkRenderPass* pRenderPass)
987{
988    const VkLayerDispatchTable *disp;
989
990    disp = loader_get_dispatch(device);
991
992    return disp->CreateRenderPass(device, pCreateInfo, pRenderPass);
993}
994
995LOADER_EXPORT void VKAPI vkDestroyRenderPass(VkDevice device, VkRenderPass renderPass)
996{
997    const VkLayerDispatchTable *disp;
998
999    disp = loader_get_dispatch(device);
1000
1001    disp->DestroyRenderPass(device, renderPass);
1002}
1003
1004LOADER_EXPORT void VKAPI vkGetRenderAreaGranularity(VkDevice device, VkRenderPass renderPass, VkExtent2D* pGranularity)
1005{
1006    const VkLayerDispatchTable *disp;
1007
1008    disp = loader_get_dispatch(device);
1009
1010    disp->GetRenderAreaGranularity(device, renderPass, pGranularity);
1011}
1012
1013LOADER_EXPORT VkResult VKAPI vkCreateCommandPool(VkDevice device, const VkCmdPoolCreateInfo* pCreateInfo, VkCmdPool* pCmdPool)
1014{
1015    const VkLayerDispatchTable *disp;
1016
1017    disp = loader_get_dispatch(device);
1018
1019    return disp->CreateCommandPool(device, pCreateInfo, pCmdPool);
1020}
1021
1022LOADER_EXPORT void VKAPI vkDestroyCommandPool(VkDevice device, VkCmdPool cmdPool)
1023{
1024    const VkLayerDispatchTable *disp;
1025
1026    disp = loader_get_dispatch(device);
1027
1028    disp->DestroyCommandPool(device, cmdPool);
1029}
1030
1031LOADER_EXPORT VkResult VKAPI vkResetCommandPool(VkDevice device, VkCmdPool cmdPool, VkCmdPoolResetFlags flags)
1032{
1033    const VkLayerDispatchTable *disp;
1034
1035    disp = loader_get_dispatch(device);
1036
1037    return disp->ResetCommandPool(device, cmdPool, flags);
1038}
1039
1040LOADER_EXPORT VkResult VKAPI vkCreateCommandBuffer(VkDevice device, const VkCmdBufferCreateInfo* pCreateInfo, VkCmdBuffer* pCmdBuffer)
1041{
1042    const VkLayerDispatchTable *disp;
1043    VkResult res;
1044
1045    disp = loader_get_dispatch(device);
1046
1047    res = disp->CreateCommandBuffer(device, pCreateInfo, pCmdBuffer);
1048    if (res == VK_SUCCESS) {
1049        loader_init_dispatch(*pCmdBuffer, disp);
1050    }
1051
1052    return res;
1053}
1054
1055LOADER_EXPORT void VKAPI vkDestroyCommandBuffer(VkDevice device, VkCmdBuffer cmdBuffer)
1056{
1057    const VkLayerDispatchTable *disp;
1058
1059    disp = loader_get_dispatch(device);
1060
1061    disp->DestroyCommandBuffer(device, cmdBuffer);
1062}
1063
1064LOADER_EXPORT VkResult VKAPI vkBeginCommandBuffer(VkCmdBuffer cmdBuffer, const VkCmdBufferBeginInfo* pBeginInfo)
1065{
1066    const VkLayerDispatchTable *disp;
1067
1068    disp = loader_get_dispatch(cmdBuffer);
1069
1070    return disp->BeginCommandBuffer(cmdBuffer, pBeginInfo);
1071}
1072
1073LOADER_EXPORT VkResult VKAPI vkEndCommandBuffer(VkCmdBuffer cmdBuffer)
1074{
1075    const VkLayerDispatchTable *disp;
1076
1077    disp = loader_get_dispatch(cmdBuffer);
1078
1079    return disp->EndCommandBuffer(cmdBuffer);
1080}
1081
1082LOADER_EXPORT VkResult VKAPI vkResetCommandBuffer(VkCmdBuffer cmdBuffer, VkCmdBufferResetFlags flags)
1083{
1084    const VkLayerDispatchTable *disp;
1085
1086    disp = loader_get_dispatch(cmdBuffer);
1087
1088    return disp->ResetCommandBuffer(cmdBuffer, flags);
1089}
1090
1091LOADER_EXPORT void VKAPI vkCmdBindPipeline(VkCmdBuffer cmdBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline)
1092{
1093    const VkLayerDispatchTable *disp;
1094
1095    disp = loader_get_dispatch(cmdBuffer);
1096
1097    disp->CmdBindPipeline(cmdBuffer, pipelineBindPoint, pipeline);
1098}
1099
1100LOADER_EXPORT void VKAPI vkCmdSetViewport(VkCmdBuffer cmdBuffer, uint32_t viewportCount, const VkViewport* pViewports)
1101{
1102    const VkLayerDispatchTable *disp;
1103
1104    disp = loader_get_dispatch(cmdBuffer);
1105
1106    disp->CmdSetViewport(cmdBuffer, viewportCount, pViewports);
1107}
1108
1109LOADER_EXPORT void VKAPI vkCmdSetScissor(VkCmdBuffer cmdBuffer, uint32_t scissorCount, const VkRect2D* pScissors)
1110{
1111    const VkLayerDispatchTable *disp;
1112
1113    disp = loader_get_dispatch(cmdBuffer);
1114
1115    disp->CmdSetScissor(cmdBuffer, scissorCount, pScissors);
1116}
1117
1118LOADER_EXPORT void VKAPI vkCmdSetLineWidth(VkCmdBuffer cmdBuffer, float lineWidth)
1119{
1120    const VkLayerDispatchTable *disp;
1121
1122    disp = loader_get_dispatch(cmdBuffer);
1123
1124    disp->CmdSetLineWidth(cmdBuffer, lineWidth);
1125}
1126
1127LOADER_EXPORT void VKAPI vkCmdSetDepthBias(VkCmdBuffer cmdBuffer, float depthBias, float depthBiasClamp, float slopeScaledDepthBias)
1128{
1129    const VkLayerDispatchTable *disp;
1130
1131    disp = loader_get_dispatch(cmdBuffer);
1132
1133    disp->CmdSetDepthBias(cmdBuffer, depthBias, depthBiasClamp, slopeScaledDepthBias);
1134}
1135
1136LOADER_EXPORT void VKAPI vkCmdSetBlendConstants(VkCmdBuffer cmdBuffer, const float blendConst[4])
1137{
1138    const VkLayerDispatchTable *disp;
1139
1140    disp = loader_get_dispatch(cmdBuffer);
1141
1142    disp->CmdSetBlendConstants(cmdBuffer, blendConst);
1143}
1144
1145LOADER_EXPORT void VKAPI vkCmdSetDepthBounds(VkCmdBuffer cmdBuffer, float minDepthBounds, float maxDepthBounds)
1146{
1147    const VkLayerDispatchTable *disp;
1148
1149    disp = loader_get_dispatch(cmdBuffer);
1150
1151    disp->CmdSetDepthBounds(cmdBuffer, minDepthBounds, maxDepthBounds);
1152}
1153
1154LOADER_EXPORT void VKAPI vkCmdSetStencilCompareMask(VkCmdBuffer cmdBuffer, VkStencilFaceFlags faceMask, uint32_t stencilCompareMask)
1155{
1156    const VkLayerDispatchTable *disp;
1157
1158    disp = loader_get_dispatch(cmdBuffer);
1159
1160    disp->CmdSetStencilCompareMask(cmdBuffer, faceMask, stencilCompareMask);
1161}
1162
1163LOADER_EXPORT void VKAPI vkCmdSetStencilWriteMask(VkCmdBuffer cmdBuffer, VkStencilFaceFlags faceMask, uint32_t stencilWriteMask)
1164{
1165    const VkLayerDispatchTable *disp;
1166
1167    disp = loader_get_dispatch(cmdBuffer);
1168
1169    disp->CmdSetStencilWriteMask(cmdBuffer, faceMask, stencilWriteMask);
1170}
1171
1172LOADER_EXPORT void VKAPI vkCmdSetStencilReference(VkCmdBuffer cmdBuffer, VkStencilFaceFlags faceMask, uint32_t stencilReference)
1173{
1174    const VkLayerDispatchTable *disp;
1175
1176    disp = loader_get_dispatch(cmdBuffer);
1177
1178    disp->CmdSetStencilReference(cmdBuffer, faceMask, stencilReference);
1179}
1180
1181LOADER_EXPORT void VKAPI vkCmdBindDescriptorSets(VkCmdBuffer cmdBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, uint32_t firstSet, uint32_t setCount, const VkDescriptorSet* pDescriptorSets, uint32_t dynamicOffsetCount, const uint32_t* pDynamicOffsets)
1182{
1183    const VkLayerDispatchTable *disp;
1184
1185    disp = loader_get_dispatch(cmdBuffer);
1186
1187    disp->CmdBindDescriptorSets(cmdBuffer, pipelineBindPoint, layout, firstSet, setCount, pDescriptorSets, dynamicOffsetCount, pDynamicOffsets);
1188}
1189
1190LOADER_EXPORT void VKAPI vkCmdBindIndexBuffer(VkCmdBuffer cmdBuffer, VkBuffer buffer, VkDeviceSize offset, VkIndexType indexType)
1191{
1192    const VkLayerDispatchTable *disp;
1193
1194    disp = loader_get_dispatch(cmdBuffer);
1195
1196    disp->CmdBindIndexBuffer(cmdBuffer, buffer, offset, indexType);
1197}
1198
1199LOADER_EXPORT void VKAPI vkCmdBindVertexBuffers(VkCmdBuffer cmdBuffer, uint32_t startBinding, uint32_t bindingCount, const VkBuffer* pBuffers, const VkDeviceSize* pOffsets)
1200{
1201    const VkLayerDispatchTable *disp;
1202
1203    disp = loader_get_dispatch(cmdBuffer);
1204
1205    disp->CmdBindVertexBuffers(cmdBuffer, startBinding, bindingCount, pBuffers, pOffsets);
1206}
1207
1208LOADER_EXPORT void VKAPI vkCmdDraw(VkCmdBuffer cmdBuffer, uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance)
1209{
1210    const VkLayerDispatchTable *disp;
1211
1212    disp = loader_get_dispatch(cmdBuffer);
1213
1214    disp->CmdDraw(cmdBuffer, vertexCount, instanceCount, firstVertex, firstInstance);
1215}
1216
1217LOADER_EXPORT void VKAPI vkCmdDrawIndexed(VkCmdBuffer cmdBuffer, uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance)
1218{
1219    const VkLayerDispatchTable *disp;
1220
1221    disp = loader_get_dispatch(cmdBuffer);
1222
1223    disp->CmdDrawIndexed(cmdBuffer, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
1224}
1225
1226LOADER_EXPORT void VKAPI vkCmdDrawIndirect(VkCmdBuffer cmdBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count, uint32_t stride)
1227{
1228    const VkLayerDispatchTable *disp;
1229
1230    disp = loader_get_dispatch(cmdBuffer);
1231
1232    disp->CmdDrawIndirect(cmdBuffer, buffer, offset, count, stride);
1233}
1234
1235LOADER_EXPORT void VKAPI vkCmdDrawIndexedIndirect(VkCmdBuffer cmdBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count, uint32_t stride)
1236{
1237    const VkLayerDispatchTable *disp;
1238
1239    disp = loader_get_dispatch(cmdBuffer);
1240
1241    disp->CmdDrawIndexedIndirect(cmdBuffer, buffer, offset, count, stride);
1242}
1243
1244LOADER_EXPORT void VKAPI vkCmdDispatch(VkCmdBuffer cmdBuffer, uint32_t x, uint32_t y, uint32_t z)
1245{
1246    const VkLayerDispatchTable *disp;
1247
1248    disp = loader_get_dispatch(cmdBuffer);
1249
1250    disp->CmdDispatch(cmdBuffer, x, y, z);
1251}
1252
1253LOADER_EXPORT void VKAPI vkCmdDispatchIndirect(VkCmdBuffer cmdBuffer, VkBuffer buffer, VkDeviceSize offset)
1254{
1255    const VkLayerDispatchTable *disp;
1256
1257    disp = loader_get_dispatch(cmdBuffer);
1258
1259    disp->CmdDispatchIndirect(cmdBuffer, buffer, offset);
1260}
1261
1262LOADER_EXPORT void VKAPI vkCmdCopyBuffer(VkCmdBuffer cmdBuffer, VkBuffer srcBuffer, VkBuffer destBuffer, uint32_t regionCount, const VkBufferCopy* pRegions)
1263{
1264    const VkLayerDispatchTable *disp;
1265
1266    disp = loader_get_dispatch(cmdBuffer);
1267
1268    disp->CmdCopyBuffer(cmdBuffer, srcBuffer, destBuffer, regionCount, pRegions);
1269}
1270
1271LOADER_EXPORT void VKAPI vkCmdCopyImage(VkCmdBuffer cmdBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage destImage, VkImageLayout destImageLayout, uint32_t regionCount, const VkImageCopy* pRegions)
1272{
1273    const VkLayerDispatchTable *disp;
1274
1275    disp = loader_get_dispatch(cmdBuffer);
1276
1277    disp->CmdCopyImage(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
1278}
1279
1280LOADER_EXPORT void VKAPI vkCmdBlitImage(VkCmdBuffer cmdBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage destImage, VkImageLayout destImageLayout, uint32_t regionCount, const VkImageBlit* pRegions, VkTexFilter filter)
1281{
1282    const VkLayerDispatchTable *disp;
1283
1284    disp = loader_get_dispatch(cmdBuffer);
1285
1286    disp->CmdBlitImage(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions, filter);
1287}
1288
1289LOADER_EXPORT void VKAPI vkCmdCopyBufferToImage(VkCmdBuffer cmdBuffer, VkBuffer srcBuffer, VkImage destImage, VkImageLayout destImageLayout, uint32_t regionCount, const VkBufferImageCopy* pRegions)
1290{
1291    const VkLayerDispatchTable *disp;
1292
1293    disp = loader_get_dispatch(cmdBuffer);
1294
1295    disp->CmdCopyBufferToImage(cmdBuffer, srcBuffer, destImage, destImageLayout, regionCount, pRegions);
1296}
1297
1298LOADER_EXPORT void VKAPI vkCmdCopyImageToBuffer(VkCmdBuffer cmdBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkBuffer destBuffer, uint32_t regionCount, const VkBufferImageCopy* pRegions)
1299{
1300    const VkLayerDispatchTable *disp;
1301
1302    disp = loader_get_dispatch(cmdBuffer);
1303
1304    disp->CmdCopyImageToBuffer(cmdBuffer, srcImage, srcImageLayout, destBuffer, regionCount, pRegions);
1305}
1306
1307LOADER_EXPORT void VKAPI vkCmdUpdateBuffer(VkCmdBuffer cmdBuffer, VkBuffer destBuffer, VkDeviceSize destOffset, VkDeviceSize dataSize, const uint32_t* pData)
1308{
1309    const VkLayerDispatchTable *disp;
1310
1311    disp = loader_get_dispatch(cmdBuffer);
1312
1313    disp->CmdUpdateBuffer(cmdBuffer, destBuffer, destOffset, dataSize, pData);
1314}
1315
1316LOADER_EXPORT void VKAPI vkCmdFillBuffer(VkCmdBuffer cmdBuffer, VkBuffer destBuffer, VkDeviceSize destOffset, VkDeviceSize fillSize, uint32_t data)
1317{
1318    const VkLayerDispatchTable *disp;
1319
1320    disp = loader_get_dispatch(cmdBuffer);
1321
1322    disp->CmdFillBuffer(cmdBuffer, destBuffer, destOffset, fillSize, data);
1323}
1324
1325LOADER_EXPORT void VKAPI vkCmdClearColorImage(VkCmdBuffer cmdBuffer, VkImage image, VkImageLayout imageLayout, const VkClearColorValue* pColor, uint32_t rangeCount, const VkImageSubresourceRange* pRanges)
1326{
1327    const VkLayerDispatchTable *disp;
1328
1329    disp = loader_get_dispatch(cmdBuffer);
1330
1331    disp->CmdClearColorImage(cmdBuffer, image, imageLayout, pColor, rangeCount, pRanges);
1332}
1333
1334LOADER_EXPORT void VKAPI vkCmdClearDepthStencilImage(VkCmdBuffer cmdBuffer, VkImage image, VkImageLayout imageLayout, const VkClearDepthStencilValue* pDepthStencil, uint32_t rangeCount, const VkImageSubresourceRange* pRanges)
1335{
1336    const VkLayerDispatchTable *disp;
1337
1338    disp = loader_get_dispatch(cmdBuffer);
1339
1340    disp->CmdClearDepthStencilImage(cmdBuffer, image, imageLayout, pDepthStencil, rangeCount, pRanges);
1341}
1342
1343LOADER_EXPORT void VKAPI vkCmdClearAttachments(VkCmdBuffer cmdBuffer, uint32_t attachmentCount, const VkClearAttachment* pAttachments, uint32_t rectCount, const VkRect3D* pRects)
1344{
1345    const VkLayerDispatchTable *disp;
1346
1347    disp = loader_get_dispatch(cmdBuffer);
1348
1349    disp->CmdClearAttachments(cmdBuffer, attachmentCount, pAttachments, rectCount, pRects);
1350}
1351
1352LOADER_EXPORT void VKAPI vkCmdResolveImage(VkCmdBuffer cmdBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage destImage, VkImageLayout destImageLayout, uint32_t regionCount, const VkImageResolve* pRegions)
1353{
1354    const VkLayerDispatchTable *disp;
1355
1356    disp = loader_get_dispatch(cmdBuffer);
1357
1358    disp->CmdResolveImage(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
1359}
1360
1361LOADER_EXPORT void VKAPI vkCmdSetEvent(VkCmdBuffer cmdBuffer, VkEvent event, VkPipelineStageFlags stageMask)
1362{
1363    const VkLayerDispatchTable *disp;
1364
1365    disp = loader_get_dispatch(cmdBuffer);
1366
1367    disp->CmdSetEvent(cmdBuffer, event, stageMask);
1368}
1369
1370LOADER_EXPORT void VKAPI vkCmdResetEvent(VkCmdBuffer cmdBuffer, VkEvent event, VkPipelineStageFlags stageMask)
1371{
1372    const VkLayerDispatchTable *disp;
1373
1374    disp = loader_get_dispatch(cmdBuffer);
1375
1376    disp->CmdResetEvent(cmdBuffer, event, stageMask);
1377}
1378
1379LOADER_EXPORT void VKAPI vkCmdWaitEvents(VkCmdBuffer cmdBuffer, uint32_t eventCount, const VkEvent* pEvents, VkPipelineStageFlags sourceStageMask, VkPipelineStageFlags destStageMask, uint32_t memBarrierCount, const void* const* ppMemBarriers)
1380{
1381    const VkLayerDispatchTable *disp;
1382
1383    disp = loader_get_dispatch(cmdBuffer);
1384
1385    disp->CmdWaitEvents(cmdBuffer, eventCount, pEvents, sourceStageMask, destStageMask, memBarrierCount, ppMemBarriers);
1386}
1387
1388LOADER_EXPORT void VKAPI vkCmdPipelineBarrier(VkCmdBuffer cmdBuffer, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags destStageMask, VkBool32 byRegion, uint32_t memBarrierCount, const void* const* ppMemBarriers)
1389{
1390    const VkLayerDispatchTable *disp;
1391
1392    disp = loader_get_dispatch(cmdBuffer);
1393
1394    disp->CmdPipelineBarrier(cmdBuffer, srcStageMask, destStageMask, byRegion, memBarrierCount, ppMemBarriers);
1395}
1396
1397LOADER_EXPORT void VKAPI vkCmdBeginQuery(VkCmdBuffer cmdBuffer, VkQueryPool queryPool, uint32_t slot, VkFlags flags)
1398{
1399    const VkLayerDispatchTable *disp;
1400
1401    disp = loader_get_dispatch(cmdBuffer);
1402
1403    disp->CmdBeginQuery(cmdBuffer, queryPool, slot, flags);
1404}
1405
1406LOADER_EXPORT void VKAPI vkCmdEndQuery(VkCmdBuffer cmdBuffer, VkQueryPool queryPool, uint32_t slot)
1407{
1408    const VkLayerDispatchTable *disp;
1409
1410    disp = loader_get_dispatch(cmdBuffer);
1411
1412    disp->CmdEndQuery(cmdBuffer, queryPool, slot);
1413}
1414
1415LOADER_EXPORT void VKAPI vkCmdResetQueryPool(VkCmdBuffer cmdBuffer, VkQueryPool queryPool, uint32_t startQuery, uint32_t queryCount)
1416{
1417    const VkLayerDispatchTable *disp;
1418
1419    disp = loader_get_dispatch(cmdBuffer);
1420
1421    disp->CmdResetQueryPool(cmdBuffer, queryPool, startQuery, queryCount);
1422}
1423
1424LOADER_EXPORT void VKAPI vkCmdWriteTimestamp(VkCmdBuffer cmdBuffer, VkTimestampType timestampType, VkBuffer destBuffer, VkDeviceSize destOffset)
1425{
1426    const VkLayerDispatchTable *disp;
1427
1428    disp = loader_get_dispatch(cmdBuffer);
1429
1430    disp->CmdWriteTimestamp(cmdBuffer, timestampType, destBuffer, destOffset);
1431}
1432
1433LOADER_EXPORT void VKAPI vkCmdCopyQueryPoolResults(VkCmdBuffer cmdBuffer, VkQueryPool queryPool, uint32_t startQuery, uint32_t queryCount, VkBuffer destBuffer, VkDeviceSize destOffset, VkDeviceSize destStride, VkFlags flags)
1434{
1435    const VkLayerDispatchTable *disp;
1436
1437    disp = loader_get_dispatch(cmdBuffer);
1438
1439    disp->CmdCopyQueryPoolResults(cmdBuffer, queryPool, startQuery, queryCount, destBuffer, destOffset, destStride, flags);
1440}
1441
1442LOADER_EXPORT void VKAPI vkCmdPushConstants(VkCmdBuffer cmdBuffer, VkPipelineLayout layout, VkShaderStageFlags stageFlags, uint32_t start, uint32_t length, const void* values)
1443{
1444    const VkLayerDispatchTable *disp;
1445
1446    disp = loader_get_dispatch(cmdBuffer);
1447
1448    disp->CmdPushConstants(cmdBuffer, layout, stageFlags, start, length, values);
1449}
1450
1451LOADER_EXPORT void VKAPI vkCmdBeginRenderPass(VkCmdBuffer cmdBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, VkRenderPassContents contents)
1452{
1453    const VkLayerDispatchTable *disp;
1454
1455    disp = loader_get_dispatch(cmdBuffer);
1456
1457    disp->CmdBeginRenderPass(cmdBuffer, pRenderPassBegin, contents);
1458}
1459
1460LOADER_EXPORT void VKAPI vkCmdNextSubpass(VkCmdBuffer cmdBuffer, VkRenderPassContents contents)
1461{
1462    const VkLayerDispatchTable *disp;
1463
1464    disp = loader_get_dispatch(cmdBuffer);
1465
1466    disp->CmdNextSubpass(cmdBuffer, contents);
1467}
1468
1469LOADER_EXPORT void VKAPI vkCmdEndRenderPass(VkCmdBuffer cmdBuffer)
1470{
1471    const VkLayerDispatchTable *disp;
1472
1473    disp = loader_get_dispatch(cmdBuffer);
1474
1475    disp->CmdEndRenderPass(cmdBuffer);
1476}
1477
1478LOADER_EXPORT void VKAPI vkCmdExecuteCommands(VkCmdBuffer cmdBuffer, uint32_t cmdBuffersCount, const VkCmdBuffer* pCmdBuffers)
1479{
1480    const VkLayerDispatchTable *disp;
1481
1482    disp = loader_get_dispatch(cmdBuffer);
1483
1484    disp->CmdExecuteCommands(cmdBuffer, cmdBuffersCount, pCmdBuffers);
1485}
1486