trampoline.c revision b480085ea933d5049ffac15b95f61483b0d22a8b
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#include <stdlib.h>
25#include <string.h>
26
27#include "loader_platform.h"
28#include "loader.h"
29#include "wsi_lunarg.h"
30#include "debug_report.h"
31
32#if defined(WIN32)
33// On Windows need to disable global optimization for function entrypoints or
34//  else mhook will not be able to hook all of them
35#pragma optimize( "g", off )
36#endif
37
38/* Trampoline entrypoints */
39LOADER_EXPORT VkResult VKAPI vkCreateInstance(
40        const VkInstanceCreateInfo* pCreateInfo,
41        VkInstance* pInstance)
42{
43    struct loader_instance *ptr_instance = NULL;
44
45    VkResult res = VK_ERROR_INITIALIZATION_FAILED;
46
47    /* Scan/discover all ICD libraries in a single-threaded manner */
48    loader_platform_thread_once(&once_icd, loader_icd_scan);
49
50    /* get layer libraries in a single-threaded manner */
51    loader_platform_thread_once(&once_layer, layer_lib_scan);
52
53    /* merge any duplicate extensions */
54    loader_platform_thread_once(&once_exts, loader_coalesce_extensions);
55
56    ptr_instance = (struct loader_instance*) malloc(sizeof(struct loader_instance));
57    if (ptr_instance == NULL) {
58        return VK_ERROR_OUT_OF_HOST_MEMORY;
59    }
60    loader_platform_thread_lock_mutex(&loader_lock);
61    memset(ptr_instance, 0, sizeof(struct loader_instance));
62    ptr_instance->app_extension_count = pCreateInfo->extensionCount;
63    ptr_instance->app_extension_props = (ptr_instance->app_extension_count > 0) ?
64                malloc(sizeof (VkExtensionProperties) * ptr_instance->app_extension_count) : NULL;
65    if (ptr_instance->app_extension_props == NULL && (ptr_instance->app_extension_count > 0)) {
66        loader_platform_thread_unlock_mutex(&loader_lock);
67        return VK_ERROR_OUT_OF_HOST_MEMORY;
68    }
69
70    /*
71     * Make local copy of extension properties indicated by application.
72     */
73    if (ptr_instance->app_extension_props) {
74        memcpy(ptr_instance->app_extension_props,
75               pCreateInfo->pEnabledExtensions,
76               sizeof(VkExtensionProperties) * ptr_instance->app_extension_count);
77    }
78
79    ptr_instance->disp = malloc(sizeof(VkLayerInstanceDispatchTable));
80    if (ptr_instance->disp == NULL) {
81        loader_platform_thread_unlock_mutex(&loader_lock);
82        return VK_ERROR_OUT_OF_HOST_MEMORY;
83    }
84    memcpy(ptr_instance->disp, &instance_disp, sizeof(instance_disp));
85    ptr_instance->next = loader.instances;
86    loader.instances = ptr_instance;
87
88    loader_enable_instance_layers(ptr_instance);
89
90    debug_report_create_instance(ptr_instance);
91    wsi_lunarg_create_instance(ptr_instance);
92
93    /* enable any layers on instance chain */
94    loader_activate_instance_layers(ptr_instance);
95
96    *pInstance = (VkInstance) ptr_instance;
97
98    res = ptr_instance->disp->CreateInstance(pCreateInfo, pInstance);
99
100    /*
101     * Finally have the layers in place and everyone has seen
102     * the CreateInstance command go by. This allows the layer's
103     * GetInstanceProcAddr functions to return valid extension functions
104     * if enabled.
105     */
106    loader_activate_instance_layer_extensions(ptr_instance);
107
108    loader_platform_thread_unlock_mutex(&loader_lock);
109
110    return res;
111}
112
113LOADER_EXPORT VkResult VKAPI vkDestroyInstance(
114                                            VkInstance instance)
115{
116    const VkLayerInstanceDispatchTable *disp;
117    VkResult res;
118    disp = loader_get_instance_dispatch(instance);
119
120    loader_platform_thread_lock_mutex(&loader_lock);
121
122    res = disp->DestroyInstance(instance);
123
124    struct loader_instance *ptr_instance = loader_instance(instance);
125    loader_deactivate_instance_layers(ptr_instance);
126    loader_destroy_ext_list(&ptr_instance->enabled_instance_extensions);
127
128    free(ptr_instance);
129
130    loader_platform_thread_unlock_mutex(&loader_lock);
131
132    return res;
133}
134
135LOADER_EXPORT VkResult VKAPI vkEnumeratePhysicalDevices(
136                                            VkInstance instance,
137                                            uint32_t* pPhysicalDeviceCount,
138                                            VkPhysicalDevice* pPhysicalDevices)
139{
140    const VkLayerInstanceDispatchTable *disp;
141    VkResult res;
142    disp = loader_get_instance_dispatch(instance);
143
144    loader_platform_thread_lock_mutex(&loader_lock);
145    res = disp->EnumeratePhysicalDevices(instance, pPhysicalDeviceCount,
146                                         pPhysicalDevices);
147    loader_platform_thread_unlock_mutex(&loader_lock);
148    return res;
149}
150
151LOADER_EXPORT VkResult VKAPI vkGetPhysicalDeviceInfo(
152                                            VkPhysicalDevice gpu,
153                                            VkPhysicalDeviceInfoType infoType,
154                                            size_t* pDataSize,
155                                            void* pData)
156{
157    const VkLayerInstanceDispatchTable *disp;
158    VkResult res;
159
160    disp = loader_get_instance_dispatch(gpu);
161
162    loader_platform_thread_lock_mutex(&loader_lock);
163    res = disp->GetPhysicalDeviceInfo(gpu, infoType, pDataSize, pData);
164    //TODO add check for extension enabled
165    loader_platform_thread_unlock_mutex(&loader_lock);
166    if (infoType == VK_PHYSICAL_DEVICE_INFO_TYPE_DISPLAY_PROPERTIES_WSI && pData && res == VK_SUCCESS) {
167        VkDisplayPropertiesWSI *info = pData;
168        size_t count = *pDataSize / sizeof(*info), i;
169        for (i = 0; i < count; i++) {
170            loader_set_dispatch(info[i].display, disp);
171        }
172    }
173
174    return res;
175}
176
177LOADER_EXPORT VkResult VKAPI vkCreateDevice(
178                                        VkPhysicalDevice gpu,
179                                        const VkDeviceCreateInfo* pCreateInfo,
180                                        VkDevice* pDevice)
181{
182    const VkLayerInstanceDispatchTable *disp;
183    VkResult res;
184
185    disp = loader_get_instance_dispatch(gpu);
186
187    loader_platform_thread_lock_mutex(&loader_lock);
188    // CreateDevice is dispatched on the instance chain
189    res = disp->CreateDevice(gpu, pCreateInfo, pDevice);
190    loader_platform_thread_unlock_mutex(&loader_lock);
191    return res;
192}
193
194LOADER_EXPORT VkResult VKAPI vkDestroyDevice(VkDevice device)
195{
196    const VkLayerDispatchTable *disp;
197    VkResult res;
198
199    disp = loader_get_dispatch(device);
200
201    loader_platform_thread_lock_mutex(&loader_lock);
202    res =  disp->DestroyDevice(device);
203    loader_remove_logical_device(device);
204    loader_platform_thread_unlock_mutex(&loader_lock);
205    return res;
206}
207
208LOADER_EXPORT VkResult VKAPI vkGetPhysicalDeviceExtensionInfo(
209                                                VkPhysicalDevice gpu,
210                                                VkExtensionInfoType infoType,
211                                                uint32_t extensionIndex,
212                                                size_t* pDataSize,
213                                                void* pData)
214{
215    VkResult res;
216
217    loader_platform_thread_lock_mutex(&loader_lock);
218    res = loader_GetPhysicalDeviceExtensionInfo(gpu, infoType, extensionIndex, pDataSize, pData);
219    loader_platform_thread_unlock_mutex(&loader_lock);
220    return res;
221}
222
223LOADER_EXPORT VkResult VKAPI vkGetDeviceQueue(VkDevice device, uint32_t queueNodeIndex, uint32_t queueIndex, VkQueue* pQueue)
224{
225    const VkLayerDispatchTable *disp;
226    VkResult res;
227
228    disp = loader_get_dispatch(device);
229
230    res = disp->GetDeviceQueue(device, queueNodeIndex, queueIndex, pQueue);
231    if (res == VK_SUCCESS) {
232        loader_set_dispatch(*pQueue, disp);
233    }
234
235    return res;
236}
237
238LOADER_EXPORT VkResult VKAPI vkQueueSubmit(VkQueue queue, uint32_t cmdBufferCount, const VkCmdBuffer* pCmdBuffers, VkFence fence)
239{
240    const VkLayerDispatchTable *disp;
241
242    disp = loader_get_dispatch(queue);
243
244    return disp->QueueSubmit(queue, cmdBufferCount, pCmdBuffers, fence);
245}
246
247LOADER_EXPORT VkResult VKAPI vkQueueWaitIdle(VkQueue queue)
248{
249    const VkLayerDispatchTable *disp;
250
251    disp = loader_get_dispatch(queue);
252
253    return disp->QueueWaitIdle(queue);
254}
255
256LOADER_EXPORT VkResult VKAPI vkDeviceWaitIdle(VkDevice device)
257{
258    const VkLayerDispatchTable *disp;
259
260    disp = loader_get_dispatch(device);
261
262    return disp->DeviceWaitIdle(device);
263}
264
265LOADER_EXPORT VkResult VKAPI vkAllocMemory(VkDevice device, const VkMemoryAllocInfo* pAllocInfo, VkDeviceMemory* pMem)
266{
267    const VkLayerDispatchTable *disp;
268
269    disp = loader_get_dispatch(device);
270
271    return disp->AllocMemory(device, pAllocInfo, pMem);
272}
273
274LOADER_EXPORT VkResult VKAPI vkFreeMemory(VkDevice device, VkDeviceMemory mem)
275{
276    const VkLayerDispatchTable *disp;
277
278    disp = loader_get_dispatch(device);
279
280    return disp->FreeMemory(device, mem);
281}
282
283LOADER_EXPORT VkResult VKAPI vkMapMemory(VkDevice device, VkDeviceMemory mem, VkDeviceSize offset, VkDeviceSize size, VkFlags flags, void** ppData)
284{
285    const VkLayerDispatchTable *disp;
286
287    disp = loader_get_dispatch(device);
288
289    return disp->MapMemory(device, mem, offset, size, flags, ppData);
290}
291
292LOADER_EXPORT VkResult VKAPI vkUnmapMemory(VkDevice device, VkDeviceMemory mem)
293{
294    const VkLayerDispatchTable *disp;
295
296    disp = loader_get_dispatch(device);
297
298    return disp->UnmapMemory(device, mem);
299}
300
301LOADER_EXPORT VkResult VKAPI vkFlushMappedMemoryRanges(VkDevice device, uint32_t memRangeCount, const VkMappedMemoryRange* pMemRanges)
302{
303    const VkLayerDispatchTable *disp;
304
305    disp = loader_get_dispatch(device);
306
307    return disp->FlushMappedMemoryRanges(device, memRangeCount, pMemRanges);
308}
309
310LOADER_EXPORT VkResult VKAPI vkInvalidateMappedMemoryRanges(VkDevice device, uint32_t memRangeCount, const VkMappedMemoryRange* pMemRanges)
311{
312    const VkLayerDispatchTable *disp;
313
314    disp = loader_get_dispatch(device);
315
316    return disp->InvalidateMappedMemoryRanges(device, memRangeCount, pMemRanges);
317}
318
319LOADER_EXPORT VkResult VKAPI vkGetMultiDeviceCompatibility(VkPhysicalDevice gpu0, VkPhysicalDevice gpu1, VkPhysicalDeviceCompatibilityInfo* pInfo)
320{
321    const VkLayerInstanceDispatchTable *disp;
322    VkResult res;
323
324    disp = loader_get_instance_dispatch(gpu0);
325
326    loader_platform_thread_lock_mutex(&loader_lock);
327    res = disp->GetMultiDeviceCompatibility(gpu0, gpu1, pInfo);
328    loader_platform_thread_unlock_mutex(&loader_lock);
329    return res;
330}
331
332LOADER_EXPORT VkResult VKAPI vkOpenSharedMemory(VkDevice device, const VkMemoryOpenInfo* pOpenInfo, VkDeviceMemory* pMem)
333{
334    const VkLayerDispatchTable *disp;
335
336    disp = loader_get_dispatch(device);
337
338    return disp->OpenSharedMemory(device, pOpenInfo, pMem);
339}
340
341LOADER_EXPORT VkResult VKAPI vkOpenSharedSemaphore(VkDevice device, const VkSemaphoreOpenInfo* pOpenInfo, VkSemaphore* pSemaphore)
342{
343    const VkLayerDispatchTable *disp;
344
345    disp = loader_get_dispatch(device);
346
347    return disp->OpenSharedSemaphore(device, pOpenInfo, pSemaphore);
348}
349
350LOADER_EXPORT VkResult VKAPI vkOpenPeerMemory(VkDevice device, const VkPeerMemoryOpenInfo* pOpenInfo, VkDeviceMemory* pMem)
351{
352    const VkLayerDispatchTable *disp;
353
354    disp = loader_get_dispatch(device);
355
356    return disp->OpenPeerMemory(device, pOpenInfo, pMem);
357}
358
359LOADER_EXPORT VkResult VKAPI vkOpenPeerImage(VkDevice device, const VkPeerImageOpenInfo* pOpenInfo, VkImage* pImage, VkDeviceMemory* pMem)
360{
361    const VkLayerDispatchTable *disp;
362
363    disp = loader_get_dispatch(device);
364
365    return disp->OpenPeerImage(device, pOpenInfo, pImage, pMem);
366}
367
368LOADER_EXPORT VkResult VKAPI vkDestroyObject(VkDevice device, VkObjectType objType, VkObject object)
369{
370    const VkLayerDispatchTable *disp;
371
372    disp = loader_get_dispatch(device);
373
374    return disp->DestroyObject(device, objType, object);
375}
376
377LOADER_EXPORT VkResult VKAPI vkGetObjectInfo(VkDevice device, VkObjectType objType, VkObject object, VkObjectInfoType infoType, size_t* pDataSize, void* pData)
378{
379    const VkLayerDispatchTable *disp;
380
381    disp = loader_get_dispatch(device);
382
383    return disp->GetObjectInfo(device, objType, object, infoType, pDataSize, pData);
384}
385
386LOADER_EXPORT VkResult VKAPI vkBindObjectMemory(VkDevice device, VkObjectType objType, VkObject object, VkDeviceMemory mem, VkDeviceSize offset)
387{
388    const VkLayerDispatchTable *disp;
389
390    disp = loader_get_dispatch(device);
391
392    return disp->BindObjectMemory(device, objType, object, mem, offset);
393}
394
395LOADER_EXPORT VkResult VKAPI vkQueueBindSparseBufferMemory(VkQueue queue, VkBuffer buffer, VkDeviceSize rangeOffset, VkDeviceSize rangeSize, VkDeviceMemory mem, VkDeviceSize memOffset)
396{
397    const VkLayerDispatchTable *disp;
398
399    disp = loader_get_dispatch(queue);
400
401    return disp->QueueBindSparseBufferMemory(queue, buffer, rangeOffset, rangeSize, mem, memOffset);
402}
403
404LOADER_EXPORT VkResult VKAPI vkQueueBindSparseImageMemory(VkQueue queue, VkImage image, const VkImageMemoryBindInfo* pBindInfo, VkDeviceMemory mem, VkDeviceSize memOffset)
405{
406    const VkLayerDispatchTable *disp;
407
408    disp = loader_get_dispatch(queue);
409
410    return disp->QueueBindSparseImageMemory(queue, image, pBindInfo, mem, memOffset);
411}
412
413LOADER_EXPORT VkResult VKAPI vkCreateFence(VkDevice device, const VkFenceCreateInfo* pCreateInfo, VkFence* pFence)
414{
415    const VkLayerDispatchTable *disp;
416
417    disp = loader_get_dispatch(device);
418
419    return disp->CreateFence(device, pCreateInfo, pFence);
420}
421
422LOADER_EXPORT VkResult VKAPI vkResetFences(VkDevice device, uint32_t fenceCount, VkFence* pFences)
423{
424    const VkLayerDispatchTable *disp;
425
426    disp = loader_get_dispatch(device);
427
428    return disp->ResetFences(device, fenceCount, pFences);
429}
430
431LOADER_EXPORT VkResult VKAPI vkGetFenceStatus(VkDevice device, VkFence fence)
432{
433    const VkLayerDispatchTable *disp;
434
435    disp = loader_get_dispatch(device);
436
437    return disp->GetFenceStatus(device, fence);
438}
439
440LOADER_EXPORT VkResult VKAPI vkWaitForFences(VkDevice device, uint32_t fenceCount, const VkFence* pFences, bool32_t waitAll, uint64_t timeout)
441{
442    const VkLayerDispatchTable *disp;
443
444    disp = loader_get_dispatch(device);
445
446    return disp->WaitForFences(device, fenceCount, pFences, waitAll, timeout);
447}
448
449LOADER_EXPORT VkResult VKAPI vkCreateSemaphore(VkDevice device, const VkSemaphoreCreateInfo* pCreateInfo, VkSemaphore* pSemaphore)
450{
451    const VkLayerDispatchTable *disp;
452
453    disp = loader_get_dispatch(device);
454
455    return disp->CreateSemaphore(device, pCreateInfo, pSemaphore);
456}
457
458LOADER_EXPORT VkResult VKAPI vkQueueSignalSemaphore(VkQueue queue, VkSemaphore semaphore)
459{
460    const VkLayerDispatchTable *disp;
461
462    disp = loader_get_dispatch(queue);
463
464    return disp->QueueSignalSemaphore(queue, semaphore);
465}
466
467LOADER_EXPORT VkResult VKAPI vkQueueWaitSemaphore(VkQueue queue, VkSemaphore semaphore)
468{
469    const VkLayerDispatchTable *disp;
470
471    disp = loader_get_dispatch(queue);
472
473    return disp->QueueWaitSemaphore(queue, semaphore);
474}
475
476LOADER_EXPORT VkResult VKAPI vkCreateEvent(VkDevice device, const VkEventCreateInfo* pCreateInfo, VkEvent* pEvent)
477{
478    const VkLayerDispatchTable *disp;
479
480    disp = loader_get_dispatch(device);
481
482    return disp->CreateEvent(device, pCreateInfo, pEvent);
483}
484
485LOADER_EXPORT VkResult VKAPI vkGetEventStatus(VkDevice device, VkEvent event)
486{
487    const VkLayerDispatchTable *disp;
488
489    disp = loader_get_dispatch(device);
490
491    return disp->GetEventStatus(device, event);
492}
493
494LOADER_EXPORT VkResult VKAPI vkSetEvent(VkDevice device, VkEvent event)
495{
496    const VkLayerDispatchTable *disp;
497
498    disp = loader_get_dispatch(device);
499
500    return disp->SetEvent(device, event);
501}
502
503LOADER_EXPORT VkResult VKAPI vkResetEvent(VkDevice device, VkEvent event)
504{
505    const VkLayerDispatchTable *disp;
506
507    disp = loader_get_dispatch(device);
508
509    return disp->ResetEvent(device, event);
510}
511
512LOADER_EXPORT VkResult VKAPI vkCreateQueryPool(VkDevice device, const VkQueryPoolCreateInfo* pCreateInfo, VkQueryPool* pQueryPool)
513{
514    const VkLayerDispatchTable *disp;
515
516    disp = loader_get_dispatch(device);
517
518    return disp->CreateQueryPool(device, pCreateInfo, pQueryPool);
519}
520
521LOADER_EXPORT VkResult VKAPI vkGetQueryPoolResults(VkDevice device, VkQueryPool queryPool, uint32_t startQuery, uint32_t queryCount, size_t* pDataSize, void* pData, VkQueryResultFlags flags)
522{
523    const VkLayerDispatchTable *disp;
524
525    disp = loader_get_dispatch(device);
526
527    return disp->GetQueryPoolResults(device, queryPool, startQuery, queryCount, pDataSize, pData, flags);
528}
529
530LOADER_EXPORT VkResult VKAPI vkGetFormatInfo(VkDevice device, VkFormat format, VkFormatInfoType infoType, size_t* pDataSize, void* pData)
531{
532    const VkLayerDispatchTable *disp;
533
534    disp = loader_get_dispatch(device);
535
536    return disp->GetFormatInfo(device, format, infoType, pDataSize, pData);
537}
538
539LOADER_EXPORT VkResult VKAPI vkCreateBuffer(VkDevice device, const VkBufferCreateInfo* pCreateInfo, VkBuffer* pBuffer)
540{
541    const VkLayerDispatchTable *disp;
542
543    disp = loader_get_dispatch(device);
544
545    return disp->CreateBuffer(device, pCreateInfo, pBuffer);
546}
547
548LOADER_EXPORT VkResult VKAPI vkCreateBufferView(VkDevice device, const VkBufferViewCreateInfo* pCreateInfo, VkBufferView* pView)
549{
550    const VkLayerDispatchTable *disp;
551
552    disp = loader_get_dispatch(device);
553
554    return disp->CreateBufferView(device, pCreateInfo, pView);
555}
556
557LOADER_EXPORT VkResult VKAPI vkCreateImage(VkDevice device, const VkImageCreateInfo* pCreateInfo, VkImage* pImage)
558{
559    const VkLayerDispatchTable *disp;
560
561    disp = loader_get_dispatch(device);
562
563    return disp->CreateImage(device, pCreateInfo, pImage);
564}
565
566LOADER_EXPORT VkResult VKAPI vkGetImageSubresourceInfo(VkDevice device, VkImage image, const VkImageSubresource* pSubresource, VkSubresourceInfoType infoType, size_t* pDataSize, void* pData)
567{
568    const VkLayerDispatchTable *disp;
569
570    disp = loader_get_dispatch(device);
571
572    return disp->GetImageSubresourceInfo(device, image, pSubresource, infoType, pDataSize, pData);
573}
574
575LOADER_EXPORT VkResult VKAPI vkCreateImageView(VkDevice device, const VkImageViewCreateInfo* pCreateInfo, VkImageView* pView)
576{
577    const VkLayerDispatchTable *disp;
578
579    disp = loader_get_dispatch(device);
580
581    return disp->CreateImageView(device, pCreateInfo, pView);
582}
583
584LOADER_EXPORT VkResult VKAPI vkCreateColorAttachmentView(VkDevice device, const VkColorAttachmentViewCreateInfo* pCreateInfo, VkColorAttachmentView* pView)
585{
586    const VkLayerDispatchTable *disp;
587
588    disp = loader_get_dispatch(device);
589
590    return disp->CreateColorAttachmentView(device, pCreateInfo, pView);
591}
592
593LOADER_EXPORT VkResult VKAPI vkCreateDepthStencilView(VkDevice device, const VkDepthStencilViewCreateInfo* pCreateInfo, VkDepthStencilView* pView)
594{
595    const VkLayerDispatchTable *disp;
596
597    disp = loader_get_dispatch(device);
598
599    return disp->CreateDepthStencilView(device, pCreateInfo, pView);
600}
601
602LOADER_EXPORT VkResult VKAPI vkCreateShader(VkDevice device, const VkShaderCreateInfo* pCreateInfo, VkShader* pShader)
603{
604    const VkLayerDispatchTable *disp;
605
606    disp = loader_get_dispatch(device);
607
608    return disp->CreateShader(device, pCreateInfo, pShader);
609}
610
611LOADER_EXPORT VkResult VKAPI vkCreateGraphicsPipeline(VkDevice device, const VkGraphicsPipelineCreateInfo* pCreateInfo, VkPipeline* pPipeline)
612{
613    const VkLayerDispatchTable *disp;
614
615    disp = loader_get_dispatch(device);
616
617    return disp->CreateGraphicsPipeline(device, pCreateInfo, pPipeline);
618}
619
620LOADER_EXPORT VkResult VKAPI vkCreateGraphicsPipelineDerivative(VkDevice device, const VkGraphicsPipelineCreateInfo* pCreateInfo, VkPipeline basePipeline, VkPipeline* pPipeline)
621{
622    const VkLayerDispatchTable *disp;
623
624    disp = loader_get_dispatch(device);
625
626    return disp->CreateGraphicsPipelineDerivative(device, pCreateInfo, basePipeline, pPipeline);
627}
628
629LOADER_EXPORT VkResult VKAPI vkCreateComputePipeline(VkDevice device, const VkComputePipelineCreateInfo* pCreateInfo, VkPipeline* pPipeline)
630{
631    const VkLayerDispatchTable *disp;
632
633    disp = loader_get_dispatch(device);
634
635    return disp->CreateComputePipeline(device, pCreateInfo, pPipeline);
636}
637
638LOADER_EXPORT VkResult VKAPI vkStorePipeline(VkDevice device, VkPipeline pipeline, size_t* pDataSize, void* pData)
639{
640    const VkLayerDispatchTable *disp;
641
642    disp = loader_get_dispatch(device);
643
644    return disp->StorePipeline(device, pipeline, pDataSize, pData);
645}
646
647LOADER_EXPORT VkResult VKAPI vkLoadPipeline(VkDevice device, size_t dataSize, const void* pData, VkPipeline* pPipeline)
648{
649    const VkLayerDispatchTable *disp;
650
651    disp = loader_get_dispatch(device);
652
653    return disp->LoadPipeline(device, dataSize, pData, pPipeline);
654}
655
656LOADER_EXPORT VkResult VKAPI vkLoadPipelineDerivative(VkDevice device, size_t dataSize, const void* pData, VkPipeline basePipeline, VkPipeline* pPipeline)
657{
658    const VkLayerDispatchTable *disp;
659
660    disp = loader_get_dispatch(device);
661
662    return disp->LoadPipelineDerivative(device, dataSize, pData, basePipeline, pPipeline);
663}
664
665LOADER_EXPORT VkResult VKAPI vkCreatePipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo* pCreateInfo, VkPipelineLayout* pPipelineLayout)
666{
667    const VkLayerDispatchTable *disp;
668
669    disp = loader_get_dispatch(device);
670
671    return disp->CreatePipelineLayout(device, pCreateInfo, pPipelineLayout);
672}
673
674LOADER_EXPORT VkResult VKAPI vkCreateSampler(VkDevice device, const VkSamplerCreateInfo* pCreateInfo, VkSampler* pSampler)
675{
676    const VkLayerDispatchTable *disp;
677
678    disp = loader_get_dispatch(device);
679
680    return disp->CreateSampler(device, pCreateInfo, pSampler);
681}
682
683LOADER_EXPORT VkResult VKAPI vkCreateDescriptorSetLayout(VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, VkDescriptorSetLayout* pSetLayout)
684{
685    const VkLayerDispatchTable *disp;
686
687    disp = loader_get_dispatch(device);
688
689    return disp->CreateDescriptorSetLayout(device, pCreateInfo, pSetLayout);
690}
691
692LOADER_EXPORT VkResult VKAPI vkCreateDescriptorPool(VkDevice device, VkDescriptorPoolUsage poolUsage, uint32_t maxSets, const VkDescriptorPoolCreateInfo* pCreateInfo, VkDescriptorPool* pDescriptorPool)
693{
694    const VkLayerDispatchTable *disp;
695
696    disp = loader_get_dispatch(device);
697
698    return disp->CreateDescriptorPool(device, poolUsage, maxSets, pCreateInfo, pDescriptorPool);
699}
700
701LOADER_EXPORT VkResult VKAPI vkResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool)
702{
703    const VkLayerDispatchTable *disp;
704
705    disp = loader_get_dispatch(device);
706
707    return disp->ResetDescriptorPool(device, descriptorPool);
708}
709
710LOADER_EXPORT VkResult VKAPI vkAllocDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorSetUsage setUsage, uint32_t count, const VkDescriptorSetLayout* pSetLayouts, VkDescriptorSet* pDescriptorSets, uint32_t* pCount)
711{
712    const VkLayerDispatchTable *disp;
713
714    disp = loader_get_dispatch(device);
715
716    return disp->AllocDescriptorSets(device, descriptorPool, setUsage, count, pSetLayouts, pDescriptorSets, pCount);
717}
718
719LOADER_EXPORT VkResult VKAPI vkUpdateDescriptorSets(VkDevice device, uint32_t writeCount, const VkWriteDescriptorSet* pDescriptorWrites, uint32_t copyCount, const VkCopyDescriptorSet* pDescriptorCopies)
720{
721    const VkLayerDispatchTable *disp;
722
723    disp = loader_get_dispatch(device);
724
725    return disp->UpdateDescriptorSets(device, writeCount, pDescriptorWrites, copyCount, pDescriptorCopies);
726}
727
728LOADER_EXPORT VkResult VKAPI vkCreateDynamicViewportState(VkDevice device, const VkDynamicVpStateCreateInfo* pCreateInfo, VkDynamicVpState* pState)
729{
730    const VkLayerDispatchTable *disp;
731
732    disp = loader_get_dispatch(device);
733
734    return disp->CreateDynamicViewportState(device, pCreateInfo, pState);
735}
736
737LOADER_EXPORT VkResult VKAPI vkCreateDynamicRasterState(VkDevice device, const VkDynamicRsStateCreateInfo* pCreateInfo, VkDynamicRsState* pState)
738{
739    const VkLayerDispatchTable *disp;
740
741    disp = loader_get_dispatch(device);
742
743    return disp->CreateDynamicRasterState(device, pCreateInfo, pState);
744}
745
746LOADER_EXPORT VkResult VKAPI vkCreateDynamicColorBlendState(VkDevice device, const VkDynamicCbStateCreateInfo* pCreateInfo, VkDynamicCbState* pState)
747{
748    const VkLayerDispatchTable *disp;
749
750    disp = loader_get_dispatch(device);
751
752    return disp->CreateDynamicColorBlendState(device, pCreateInfo, pState);
753}
754
755LOADER_EXPORT VkResult VKAPI vkCreateDynamicDepthStencilState(VkDevice device, const VkDynamicDsStateCreateInfo* pCreateInfo, VkDynamicDsState* pState)
756{
757    const VkLayerDispatchTable *disp;
758
759    disp = loader_get_dispatch(device);
760
761    return disp->CreateDynamicDepthStencilState(device, pCreateInfo, pState);
762}
763
764LOADER_EXPORT VkResult VKAPI vkCreateCommandBuffer(VkDevice device, const VkCmdBufferCreateInfo* pCreateInfo, VkCmdBuffer* pCmdBuffer)
765{
766    const VkLayerDispatchTable *disp;
767    VkResult res;
768
769    disp = loader_get_dispatch(device);
770
771    res = disp->CreateCommandBuffer(device, pCreateInfo, pCmdBuffer);
772    if (res == VK_SUCCESS) {
773        loader_init_dispatch(*pCmdBuffer, disp);
774    }
775
776    return res;
777}
778
779LOADER_EXPORT VkResult VKAPI vkBeginCommandBuffer(VkCmdBuffer cmdBuffer, const VkCmdBufferBeginInfo* pBeginInfo)
780{
781    const VkLayerDispatchTable *disp;
782
783    disp = loader_get_dispatch(cmdBuffer);
784
785    return disp->BeginCommandBuffer(cmdBuffer, pBeginInfo);
786}
787
788LOADER_EXPORT VkResult VKAPI vkEndCommandBuffer(VkCmdBuffer cmdBuffer)
789{
790    const VkLayerDispatchTable *disp;
791
792    disp = loader_get_dispatch(cmdBuffer);
793
794    return disp->EndCommandBuffer(cmdBuffer);
795}
796
797LOADER_EXPORT VkResult VKAPI vkResetCommandBuffer(VkCmdBuffer cmdBuffer)
798{
799    const VkLayerDispatchTable *disp;
800
801    disp = loader_get_dispatch(cmdBuffer);
802
803    return disp->ResetCommandBuffer(cmdBuffer);
804}
805
806LOADER_EXPORT void VKAPI vkCmdBindPipeline(VkCmdBuffer cmdBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline)
807{
808    const VkLayerDispatchTable *disp;
809
810    disp = loader_get_dispatch(cmdBuffer);
811
812    disp->CmdBindPipeline(cmdBuffer, pipelineBindPoint, pipeline);
813}
814
815LOADER_EXPORT void VKAPI vkCmdBindDynamicStateObject(VkCmdBuffer cmdBuffer, VkStateBindPoint stateBindPoint, VkDynamicStateObject state)
816{
817    const VkLayerDispatchTable *disp;
818
819    disp = loader_get_dispatch(cmdBuffer);
820
821    disp->CmdBindDynamicStateObject(cmdBuffer, stateBindPoint, state);
822}
823
824LOADER_EXPORT void VKAPI vkCmdBindDescriptorSets(VkCmdBuffer cmdBuffer, VkPipelineBindPoint pipelineBindPoint, uint32_t firstSet, uint32_t setCount, const VkDescriptorSet* pDescriptorSets, uint32_t dynamicOffsetCount, const uint32_t* pDynamicOffsets)
825{
826    const VkLayerDispatchTable *disp;
827
828    disp = loader_get_dispatch(cmdBuffer);
829
830    disp->CmdBindDescriptorSets(cmdBuffer, pipelineBindPoint, firstSet, setCount, pDescriptorSets, dynamicOffsetCount, pDynamicOffsets);
831}
832
833LOADER_EXPORT void VKAPI vkCmdBindVertexBuffers(VkCmdBuffer cmdBuffer, uint32_t startBinding, uint32_t bindingCount, const VkBuffer* pBuffers, const VkDeviceSize* pOffsets)
834{
835    const VkLayerDispatchTable *disp;
836
837    disp = loader_get_dispatch(cmdBuffer);
838
839    disp->CmdBindVertexBuffers(cmdBuffer, startBinding, bindingCount, pBuffers, pOffsets);
840}
841
842LOADER_EXPORT void VKAPI vkCmdBindIndexBuffer(VkCmdBuffer cmdBuffer, VkBuffer buffer, VkDeviceSize offset, VkIndexType indexType)
843{
844    const VkLayerDispatchTable *disp;
845
846    disp = loader_get_dispatch(cmdBuffer);
847
848    disp->CmdBindIndexBuffer(cmdBuffer, buffer, offset, indexType);
849}
850
851LOADER_EXPORT void VKAPI vkCmdDraw(VkCmdBuffer cmdBuffer, uint32_t firstVertex, uint32_t vertexCount, uint32_t firstInstance, uint32_t instanceCount)
852{
853    const VkLayerDispatchTable *disp;
854
855    disp = loader_get_dispatch(cmdBuffer);
856
857    disp->CmdDraw(cmdBuffer, firstVertex, vertexCount, firstInstance, instanceCount);
858}
859
860LOADER_EXPORT void VKAPI vkCmdDrawIndexed(VkCmdBuffer cmdBuffer, uint32_t firstIndex, uint32_t indexCount, int32_t vertexOffset, uint32_t firstInstance, uint32_t instanceCount)
861{
862    const VkLayerDispatchTable *disp;
863
864    disp = loader_get_dispatch(cmdBuffer);
865
866    disp->CmdDrawIndexed(cmdBuffer, firstIndex, indexCount, vertexOffset, firstInstance, instanceCount);
867}
868
869LOADER_EXPORT void VKAPI vkCmdDrawIndirect(VkCmdBuffer cmdBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count, uint32_t stride)
870{
871    const VkLayerDispatchTable *disp;
872
873    disp = loader_get_dispatch(cmdBuffer);
874
875    disp->CmdDrawIndirect(cmdBuffer, buffer, offset, count, stride);
876}
877
878LOADER_EXPORT void VKAPI vkCmdDrawIndexedIndirect(VkCmdBuffer cmdBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count, uint32_t stride)
879{
880    const VkLayerDispatchTable *disp;
881
882    disp = loader_get_dispatch(cmdBuffer);
883
884    disp->CmdDrawIndexedIndirect(cmdBuffer, buffer, offset, count, stride);
885}
886
887LOADER_EXPORT void VKAPI vkCmdDispatch(VkCmdBuffer cmdBuffer, uint32_t x, uint32_t y, uint32_t z)
888{
889    const VkLayerDispatchTable *disp;
890
891    disp = loader_get_dispatch(cmdBuffer);
892
893    disp->CmdDispatch(cmdBuffer, x, y, z);
894}
895
896LOADER_EXPORT void VKAPI vkCmdDispatchIndirect(VkCmdBuffer cmdBuffer, VkBuffer buffer, VkDeviceSize offset)
897{
898    const VkLayerDispatchTable *disp;
899
900    disp = loader_get_dispatch(cmdBuffer);
901
902    disp->CmdDispatchIndirect(cmdBuffer, buffer, offset);
903}
904
905LOADER_EXPORT void VKAPI vkCmdCopyBuffer(VkCmdBuffer cmdBuffer, VkBuffer srcBuffer, VkBuffer destBuffer, uint32_t regionCount, const VkBufferCopy* pRegions)
906{
907    const VkLayerDispatchTable *disp;
908
909    disp = loader_get_dispatch(cmdBuffer);
910
911    disp->CmdCopyBuffer(cmdBuffer, srcBuffer, destBuffer, regionCount, pRegions);
912}
913
914LOADER_EXPORT void VKAPI vkCmdCopyImage(VkCmdBuffer cmdBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage destImage, VkImageLayout destImageLayout, uint32_t regionCount, const VkImageCopy* pRegions)
915{
916    const VkLayerDispatchTable *disp;
917
918    disp = loader_get_dispatch(cmdBuffer);
919
920    disp->CmdCopyImage(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
921}
922
923LOADER_EXPORT void VKAPI vkCmdBlitImage(VkCmdBuffer cmdBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage destImage, VkImageLayout destImageLayout, uint32_t regionCount, const VkImageBlit* pRegions, VkTexFilter filter)
924{
925    const VkLayerDispatchTable *disp;
926
927    disp = loader_get_dispatch(cmdBuffer);
928
929    disp->CmdBlitImage(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions, filter);
930}
931
932LOADER_EXPORT void VKAPI vkCmdCopyBufferToImage(VkCmdBuffer cmdBuffer, VkBuffer srcBuffer, VkImage destImage, VkImageLayout destImageLayout, uint32_t regionCount, const VkBufferImageCopy* pRegions)
933{
934    const VkLayerDispatchTable *disp;
935
936    disp = loader_get_dispatch(cmdBuffer);
937
938    disp->CmdCopyBufferToImage(cmdBuffer, srcBuffer, destImage, destImageLayout, regionCount, pRegions);
939}
940
941LOADER_EXPORT void VKAPI vkCmdCopyImageToBuffer(VkCmdBuffer cmdBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkBuffer destBuffer, uint32_t regionCount, const VkBufferImageCopy* pRegions)
942{
943    const VkLayerDispatchTable *disp;
944
945    disp = loader_get_dispatch(cmdBuffer);
946
947    disp->CmdCopyImageToBuffer(cmdBuffer, srcImage, srcImageLayout, destBuffer, regionCount, pRegions);
948}
949
950LOADER_EXPORT void VKAPI vkCmdUpdateBuffer(VkCmdBuffer cmdBuffer, VkBuffer destBuffer, VkDeviceSize destOffset, VkDeviceSize dataSize, const uint32_t* pData)
951{
952    const VkLayerDispatchTable *disp;
953
954    disp = loader_get_dispatch(cmdBuffer);
955
956    disp->CmdUpdateBuffer(cmdBuffer, destBuffer, destOffset, dataSize, pData);
957}
958
959LOADER_EXPORT void VKAPI vkCmdFillBuffer(VkCmdBuffer cmdBuffer, VkBuffer destBuffer, VkDeviceSize destOffset, VkDeviceSize fillSize, uint32_t data)
960{
961    const VkLayerDispatchTable *disp;
962
963    disp = loader_get_dispatch(cmdBuffer);
964
965    disp->CmdFillBuffer(cmdBuffer, destBuffer, destOffset, fillSize, data);
966}
967
968LOADER_EXPORT void VKAPI vkCmdClearColorImage(VkCmdBuffer cmdBuffer, VkImage image, VkImageLayout imageLayout, const VkClearColor* pColor, uint32_t rangeCount, const VkImageSubresourceRange* pRanges)
969{
970    const VkLayerDispatchTable *disp;
971
972    disp = loader_get_dispatch(cmdBuffer);
973
974    disp->CmdClearColorImage(cmdBuffer, image, imageLayout, pColor, rangeCount, pRanges);
975}
976
977LOADER_EXPORT void VKAPI vkCmdClearDepthStencil(VkCmdBuffer cmdBuffer, VkImage image, VkImageLayout imageLayout, float depth, uint32_t stencil, uint32_t rangeCount, const VkImageSubresourceRange* pRanges)
978{
979    const VkLayerDispatchTable *disp;
980
981    disp = loader_get_dispatch(cmdBuffer);
982
983    disp->CmdClearDepthStencil(cmdBuffer, image, imageLayout, depth, stencil, rangeCount, pRanges);
984}
985
986LOADER_EXPORT void VKAPI vkCmdResolveImage(VkCmdBuffer cmdBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage destImage, VkImageLayout destImageLayout, uint32_t regionCount, const VkImageResolve* pRegions)
987{
988    const VkLayerDispatchTable *disp;
989
990    disp = loader_get_dispatch(cmdBuffer);
991
992    disp->CmdResolveImage(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
993}
994
995LOADER_EXPORT void VKAPI vkCmdSetEvent(VkCmdBuffer cmdBuffer, VkEvent event, VkPipeEvent pipeEvent)
996{
997    const VkLayerDispatchTable *disp;
998
999    disp = loader_get_dispatch(cmdBuffer);
1000
1001    disp->CmdSetEvent(cmdBuffer, event, pipeEvent);
1002}
1003
1004LOADER_EXPORT void VKAPI vkCmdResetEvent(VkCmdBuffer cmdBuffer, VkEvent event, VkPipeEvent pipeEvent)
1005{
1006    const VkLayerDispatchTable *disp;
1007
1008    disp = loader_get_dispatch(cmdBuffer);
1009
1010    disp->CmdResetEvent(cmdBuffer, event, pipeEvent);
1011}
1012
1013LOADER_EXPORT void VKAPI vkCmdWaitEvents(VkCmdBuffer cmdBuffer, VkWaitEvent waitEvent, uint32_t eventCount, const VkEvent* pEvents, uint32_t memBarrierCount, const void** ppMemBarriers)
1014{
1015    const VkLayerDispatchTable *disp;
1016
1017    disp = loader_get_dispatch(cmdBuffer);
1018
1019    disp->CmdWaitEvents(cmdBuffer, waitEvent, eventCount, pEvents, memBarrierCount, ppMemBarriers);
1020}
1021
1022LOADER_EXPORT void VKAPI vkCmdPipelineBarrier(VkCmdBuffer cmdBuffer, VkWaitEvent waitEvent, uint32_t pipeEventCount, const VkPipeEvent* pPipeEvents, uint32_t memBarrierCount, const void** ppMemBarriers)
1023{
1024    const VkLayerDispatchTable *disp;
1025
1026    disp = loader_get_dispatch(cmdBuffer);
1027
1028    disp->CmdPipelineBarrier(cmdBuffer, waitEvent, pipeEventCount, pPipeEvents, memBarrierCount, ppMemBarriers);
1029}
1030
1031LOADER_EXPORT void VKAPI vkCmdBeginQuery(VkCmdBuffer cmdBuffer, VkQueryPool queryPool, uint32_t slot, VkFlags flags)
1032{
1033    const VkLayerDispatchTable *disp;
1034
1035    disp = loader_get_dispatch(cmdBuffer);
1036
1037    disp->CmdBeginQuery(cmdBuffer, queryPool, slot, flags);
1038}
1039
1040LOADER_EXPORT void VKAPI vkCmdEndQuery(VkCmdBuffer cmdBuffer, VkQueryPool queryPool, uint32_t slot)
1041{
1042    const VkLayerDispatchTable *disp;
1043
1044    disp = loader_get_dispatch(cmdBuffer);
1045
1046    disp->CmdEndQuery(cmdBuffer, queryPool, slot);
1047}
1048
1049LOADER_EXPORT void VKAPI vkCmdResetQueryPool(VkCmdBuffer cmdBuffer, VkQueryPool queryPool, uint32_t startQuery, uint32_t queryCount)
1050{
1051    const VkLayerDispatchTable *disp;
1052
1053    disp = loader_get_dispatch(cmdBuffer);
1054
1055    disp->CmdResetQueryPool(cmdBuffer, queryPool, startQuery, queryCount);
1056}
1057
1058LOADER_EXPORT void VKAPI vkCmdWriteTimestamp(VkCmdBuffer cmdBuffer, VkTimestampType timestampType, VkBuffer destBuffer, VkDeviceSize destOffset)
1059{
1060    const VkLayerDispatchTable *disp;
1061
1062    disp = loader_get_dispatch(cmdBuffer);
1063
1064    disp->CmdWriteTimestamp(cmdBuffer, timestampType, destBuffer, destOffset);
1065}
1066
1067LOADER_EXPORT void VKAPI vkCmdCopyQueryPoolResults(VkCmdBuffer cmdBuffer, VkQueryPool queryPool, uint32_t startQuery, uint32_t queryCount, VkBuffer destBuffer, VkDeviceSize destOffset, VkDeviceSize destStride, VkFlags flags)
1068{
1069    const VkLayerDispatchTable *disp;
1070
1071    disp = loader_get_dispatch(cmdBuffer);
1072
1073    disp->CmdCopyQueryPoolResults(cmdBuffer, queryPool, startQuery, queryCount, destBuffer, destOffset, destStride, flags);
1074}
1075
1076LOADER_EXPORT void VKAPI vkCmdInitAtomicCounters(VkCmdBuffer cmdBuffer, VkPipelineBindPoint pipelineBindPoint, uint32_t startCounter, uint32_t counterCount, const uint32_t* pData)
1077{
1078    const VkLayerDispatchTable *disp;
1079
1080    disp = loader_get_dispatch(cmdBuffer);
1081
1082    disp->CmdInitAtomicCounters(cmdBuffer, pipelineBindPoint, startCounter, counterCount, pData);
1083}
1084
1085LOADER_EXPORT void VKAPI vkCmdLoadAtomicCounters(VkCmdBuffer cmdBuffer, VkPipelineBindPoint pipelineBindPoint, uint32_t startCounter, uint32_t counterCount, VkBuffer srcBuffer, VkDeviceSize srcOffset)
1086{
1087    const VkLayerDispatchTable *disp;
1088
1089    disp = loader_get_dispatch(cmdBuffer);
1090
1091    disp->CmdLoadAtomicCounters(cmdBuffer, pipelineBindPoint, startCounter, counterCount, srcBuffer, srcOffset);
1092}
1093
1094LOADER_EXPORT void VKAPI vkCmdSaveAtomicCounters(VkCmdBuffer cmdBuffer, VkPipelineBindPoint pipelineBindPoint, uint32_t startCounter, uint32_t counterCount, VkBuffer destBuffer, VkDeviceSize destOffset)
1095{
1096    const VkLayerDispatchTable *disp;
1097
1098    disp = loader_get_dispatch(cmdBuffer);
1099
1100    disp->CmdSaveAtomicCounters(cmdBuffer, pipelineBindPoint, startCounter, counterCount, destBuffer, destOffset);
1101}
1102
1103LOADER_EXPORT VkResult VKAPI vkCreateFramebuffer(VkDevice device, const VkFramebufferCreateInfo* pCreateInfo, VkFramebuffer* pFramebuffer)
1104{
1105    const VkLayerDispatchTable *disp;
1106
1107    disp = loader_get_dispatch(device);
1108
1109    return disp->CreateFramebuffer(device, pCreateInfo, pFramebuffer);
1110}
1111
1112LOADER_EXPORT VkResult VKAPI vkCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo* pCreateInfo, VkRenderPass* pRenderPass)
1113{
1114    const VkLayerDispatchTable *disp;
1115
1116    disp = loader_get_dispatch(device);
1117
1118    return disp->CreateRenderPass(device, pCreateInfo, pRenderPass);
1119}
1120
1121LOADER_EXPORT void VKAPI vkCmdBeginRenderPass(VkCmdBuffer cmdBuffer, const VkRenderPassBegin* pRenderPassBegin)
1122{
1123    const VkLayerDispatchTable *disp;
1124
1125    disp = loader_get_dispatch(cmdBuffer);
1126
1127    disp->CmdBeginRenderPass(cmdBuffer, pRenderPassBegin);
1128}
1129
1130LOADER_EXPORT void VKAPI vkCmdEndRenderPass(VkCmdBuffer cmdBuffer, VkRenderPass renderPass)
1131{
1132    const VkLayerDispatchTable *disp;
1133
1134    disp = loader_get_dispatch(cmdBuffer);
1135
1136    disp->CmdEndRenderPass(cmdBuffer, renderPass);
1137}
1138