1/*
2 *
3 * Copyright (c) 2015-2016 The Khronos Group Inc.
4 * Copyright (c) 2015-2016 Valve Corporation
5 * Copyright (c) 2015-2016 LunarG, Inc.
6 * Copyright (C) 2016 Google Inc.
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 *     http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 *
20 * Author: Courtney Goeltzenleuchter <courtney@lunarg.com>
21 * Author: Jon Ashburn <jon@lunarg.com>
22 * Author: Ian Elliott <ian@LunarG.com>
23 * Author: Tony Barbour <tony@LunarG.com>
24 */
25
26#include <vulkan/vulkan.h>
27#include <vulkan/vk_layer.h>
28#include <string.h>
29#include "loader.h"
30#include "vk_loader_platform.h"
31
32static VkResult vkDevExtError(VkDevice dev) {
33    struct loader_device *found_dev;
34    struct loader_icd *icd = loader_get_icd_and_device(dev, &found_dev, NULL);
35
36    if (icd)
37        loader_log(icd->this_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
38                   "Bad destination in loader trampoline dispatch,"
39                   "Are layers and extensions that you are calling enabled?");
40    return VK_ERROR_EXTENSION_NOT_PRESENT;
41}
42
43static inline void
44loader_init_device_dispatch_table(struct loader_dev_dispatch_table *dev_table,
45                                  PFN_vkGetDeviceProcAddr gpa, VkDevice dev) {
46    VkLayerDispatchTable *table = &dev_table->core_dispatch;
47    for (uint32_t i = 0; i < MAX_NUM_DEV_EXTS; i++)
48        dev_table->ext_dispatch.dev_ext[i] = (PFN_vkDevExt)vkDevExtError;
49
50    table->GetDeviceProcAddr =
51        (PFN_vkGetDeviceProcAddr)gpa(dev, "vkGetDeviceProcAddr");
52    table->DestroyDevice = (PFN_vkDestroyDevice)gpa(dev, "vkDestroyDevice");
53    table->GetDeviceQueue = (PFN_vkGetDeviceQueue)gpa(dev, "vkGetDeviceQueue");
54    table->QueueSubmit = (PFN_vkQueueSubmit)gpa(dev, "vkQueueSubmit");
55    table->QueueWaitIdle = (PFN_vkQueueWaitIdle)gpa(dev, "vkQueueWaitIdle");
56    table->DeviceWaitIdle = (PFN_vkDeviceWaitIdle)gpa(dev, "vkDeviceWaitIdle");
57    table->AllocateMemory = (PFN_vkAllocateMemory)gpa(dev, "vkAllocateMemory");
58    table->FreeMemory = (PFN_vkFreeMemory)gpa(dev, "vkFreeMemory");
59    table->MapMemory = (PFN_vkMapMemory)gpa(dev, "vkMapMemory");
60    table->UnmapMemory = (PFN_vkUnmapMemory)gpa(dev, "vkUnmapMemory");
61    table->FlushMappedMemoryRanges =
62        (PFN_vkFlushMappedMemoryRanges)gpa(dev, "vkFlushMappedMemoryRanges");
63    table->InvalidateMappedMemoryRanges =
64        (PFN_vkInvalidateMappedMemoryRanges)gpa(
65            dev, "vkInvalidateMappedMemoryRanges");
66    table->GetDeviceMemoryCommitment = (PFN_vkGetDeviceMemoryCommitment)gpa(
67        dev, "vkGetDeviceMemoryCommitment");
68    table->GetImageSparseMemoryRequirements =
69        (PFN_vkGetImageSparseMemoryRequirements)gpa(
70            dev, "vkGetImageSparseMemoryRequirements");
71    table->GetBufferMemoryRequirements = (PFN_vkGetBufferMemoryRequirements)gpa(
72        dev, "vkGetBufferMemoryRequirements");
73    table->GetImageMemoryRequirements = (PFN_vkGetImageMemoryRequirements)gpa(
74        dev, "vkGetImageMemoryRequirements");
75    table->BindBufferMemory =
76        (PFN_vkBindBufferMemory)gpa(dev, "vkBindBufferMemory");
77    table->BindImageMemory =
78        (PFN_vkBindImageMemory)gpa(dev, "vkBindImageMemory");
79    table->QueueBindSparse =
80        (PFN_vkQueueBindSparse)gpa(dev, "vkQueueBindSparse");
81    table->CreateFence = (PFN_vkCreateFence)gpa(dev, "vkCreateFence");
82    table->DestroyFence = (PFN_vkDestroyFence)gpa(dev, "vkDestroyFence");
83    table->ResetFences = (PFN_vkResetFences)gpa(dev, "vkResetFences");
84    table->GetFenceStatus = (PFN_vkGetFenceStatus)gpa(dev, "vkGetFenceStatus");
85    table->WaitForFences = (PFN_vkWaitForFences)gpa(dev, "vkWaitForFences");
86    table->CreateSemaphore =
87        (PFN_vkCreateSemaphore)gpa(dev, "vkCreateSemaphore");
88    table->DestroySemaphore =
89        (PFN_vkDestroySemaphore)gpa(dev, "vkDestroySemaphore");
90    table->CreateEvent = (PFN_vkCreateEvent)gpa(dev, "vkCreateEvent");
91    table->DestroyEvent = (PFN_vkDestroyEvent)gpa(dev, "vkDestroyEvent");
92    table->GetEventStatus = (PFN_vkGetEventStatus)gpa(dev, "vkGetEventStatus");
93    table->SetEvent = (PFN_vkSetEvent)gpa(dev, "vkSetEvent");
94    table->ResetEvent = (PFN_vkResetEvent)gpa(dev, "vkResetEvent");
95    table->CreateQueryPool =
96        (PFN_vkCreateQueryPool)gpa(dev, "vkCreateQueryPool");
97    table->DestroyQueryPool =
98        (PFN_vkDestroyQueryPool)gpa(dev, "vkDestroyQueryPool");
99    table->GetQueryPoolResults =
100        (PFN_vkGetQueryPoolResults)gpa(dev, "vkGetQueryPoolResults");
101    table->CreateBuffer = (PFN_vkCreateBuffer)gpa(dev, "vkCreateBuffer");
102    table->DestroyBuffer = (PFN_vkDestroyBuffer)gpa(dev, "vkDestroyBuffer");
103    table->CreateBufferView =
104        (PFN_vkCreateBufferView)gpa(dev, "vkCreateBufferView");
105    table->DestroyBufferView =
106        (PFN_vkDestroyBufferView)gpa(dev, "vkDestroyBufferView");
107    table->CreateImage = (PFN_vkCreateImage)gpa(dev, "vkCreateImage");
108    table->DestroyImage = (PFN_vkDestroyImage)gpa(dev, "vkDestroyImage");
109    table->GetImageSubresourceLayout = (PFN_vkGetImageSubresourceLayout)gpa(
110        dev, "vkGetImageSubresourceLayout");
111    table->CreateImageView =
112        (PFN_vkCreateImageView)gpa(dev, "vkCreateImageView");
113    table->DestroyImageView =
114        (PFN_vkDestroyImageView)gpa(dev, "vkDestroyImageView");
115    table->CreateShaderModule =
116        (PFN_vkCreateShaderModule)gpa(dev, "vkCreateShaderModule");
117    table->DestroyShaderModule =
118        (PFN_vkDestroyShaderModule)gpa(dev, "vkDestroyShaderModule");
119    table->CreatePipelineCache =
120        (PFN_vkCreatePipelineCache)gpa(dev, "vkCreatePipelineCache");
121    table->DestroyPipelineCache =
122        (PFN_vkDestroyPipelineCache)gpa(dev, "vkDestroyPipelineCache");
123    table->GetPipelineCacheData =
124        (PFN_vkGetPipelineCacheData)gpa(dev, "vkGetPipelineCacheData");
125    table->MergePipelineCaches =
126        (PFN_vkMergePipelineCaches)gpa(dev, "vkMergePipelineCaches");
127    table->CreateGraphicsPipelines =
128        (PFN_vkCreateGraphicsPipelines)gpa(dev, "vkCreateGraphicsPipelines");
129    table->CreateComputePipelines =
130        (PFN_vkCreateComputePipelines)gpa(dev, "vkCreateComputePipelines");
131    table->DestroyPipeline =
132        (PFN_vkDestroyPipeline)gpa(dev, "vkDestroyPipeline");
133    table->CreatePipelineLayout =
134        (PFN_vkCreatePipelineLayout)gpa(dev, "vkCreatePipelineLayout");
135    table->DestroyPipelineLayout =
136        (PFN_vkDestroyPipelineLayout)gpa(dev, "vkDestroyPipelineLayout");
137    table->CreateSampler = (PFN_vkCreateSampler)gpa(dev, "vkCreateSampler");
138    table->DestroySampler = (PFN_vkDestroySampler)gpa(dev, "vkDestroySampler");
139    table->CreateDescriptorSetLayout = (PFN_vkCreateDescriptorSetLayout)gpa(
140        dev, "vkCreateDescriptorSetLayout");
141    table->DestroyDescriptorSetLayout = (PFN_vkDestroyDescriptorSetLayout)gpa(
142        dev, "vkDestroyDescriptorSetLayout");
143    table->CreateDescriptorPool =
144        (PFN_vkCreateDescriptorPool)gpa(dev, "vkCreateDescriptorPool");
145    table->DestroyDescriptorPool =
146        (PFN_vkDestroyDescriptorPool)gpa(dev, "vkDestroyDescriptorPool");
147    table->ResetDescriptorPool =
148        (PFN_vkResetDescriptorPool)gpa(dev, "vkResetDescriptorPool");
149    table->AllocateDescriptorSets =
150        (PFN_vkAllocateDescriptorSets)gpa(dev, "vkAllocateDescriptorSets");
151    table->FreeDescriptorSets =
152        (PFN_vkFreeDescriptorSets)gpa(dev, "vkFreeDescriptorSets");
153    table->UpdateDescriptorSets =
154        (PFN_vkUpdateDescriptorSets)gpa(dev, "vkUpdateDescriptorSets");
155    table->CreateFramebuffer =
156        (PFN_vkCreateFramebuffer)gpa(dev, "vkCreateFramebuffer");
157    table->DestroyFramebuffer =
158        (PFN_vkDestroyFramebuffer)gpa(dev, "vkDestroyFramebuffer");
159    table->CreateRenderPass =
160        (PFN_vkCreateRenderPass)gpa(dev, "vkCreateRenderPass");
161    table->DestroyRenderPass =
162        (PFN_vkDestroyRenderPass)gpa(dev, "vkDestroyRenderPass");
163    table->GetRenderAreaGranularity =
164        (PFN_vkGetRenderAreaGranularity)gpa(dev, "vkGetRenderAreaGranularity");
165    table->CreateCommandPool =
166        (PFN_vkCreateCommandPool)gpa(dev, "vkCreateCommandPool");
167    table->DestroyCommandPool =
168        (PFN_vkDestroyCommandPool)gpa(dev, "vkDestroyCommandPool");
169    table->ResetCommandPool =
170        (PFN_vkResetCommandPool)gpa(dev, "vkResetCommandPool");
171    table->AllocateCommandBuffers =
172        (PFN_vkAllocateCommandBuffers)gpa(dev, "vkAllocateCommandBuffers");
173    table->FreeCommandBuffers =
174        (PFN_vkFreeCommandBuffers)gpa(dev, "vkFreeCommandBuffers");
175    table->BeginCommandBuffer =
176        (PFN_vkBeginCommandBuffer)gpa(dev, "vkBeginCommandBuffer");
177    table->EndCommandBuffer =
178        (PFN_vkEndCommandBuffer)gpa(dev, "vkEndCommandBuffer");
179    table->ResetCommandBuffer =
180        (PFN_vkResetCommandBuffer)gpa(dev, "vkResetCommandBuffer");
181    table->CmdBindPipeline =
182        (PFN_vkCmdBindPipeline)gpa(dev, "vkCmdBindPipeline");
183    table->CmdSetViewport = (PFN_vkCmdSetViewport)gpa(dev, "vkCmdSetViewport");
184    table->CmdSetScissor = (PFN_vkCmdSetScissor)gpa(dev, "vkCmdSetScissor");
185    table->CmdSetLineWidth =
186        (PFN_vkCmdSetLineWidth)gpa(dev, "vkCmdSetLineWidth");
187    table->CmdSetDepthBias =
188        (PFN_vkCmdSetDepthBias)gpa(dev, "vkCmdSetDepthBias");
189    table->CmdSetBlendConstants =
190        (PFN_vkCmdSetBlendConstants)gpa(dev, "vkCmdSetBlendConstants");
191    table->CmdSetDepthBounds =
192        (PFN_vkCmdSetDepthBounds)gpa(dev, "vkCmdSetDepthBounds");
193    table->CmdSetStencilCompareMask =
194        (PFN_vkCmdSetStencilCompareMask)gpa(dev, "vkCmdSetStencilCompareMask");
195    table->CmdSetStencilWriteMask =
196        (PFN_vkCmdSetStencilWriteMask)gpa(dev, "vkCmdSetStencilWriteMask");
197    table->CmdSetStencilReference =
198        (PFN_vkCmdSetStencilReference)gpa(dev, "vkCmdSetStencilReference");
199    table->CmdBindDescriptorSets =
200        (PFN_vkCmdBindDescriptorSets)gpa(dev, "vkCmdBindDescriptorSets");
201    table->CmdBindVertexBuffers =
202        (PFN_vkCmdBindVertexBuffers)gpa(dev, "vkCmdBindVertexBuffers");
203    table->CmdBindIndexBuffer =
204        (PFN_vkCmdBindIndexBuffer)gpa(dev, "vkCmdBindIndexBuffer");
205    table->CmdDraw = (PFN_vkCmdDraw)gpa(dev, "vkCmdDraw");
206    table->CmdDrawIndexed = (PFN_vkCmdDrawIndexed)gpa(dev, "vkCmdDrawIndexed");
207    table->CmdDrawIndirect =
208        (PFN_vkCmdDrawIndirect)gpa(dev, "vkCmdDrawIndirect");
209    table->CmdDrawIndexedIndirect =
210        (PFN_vkCmdDrawIndexedIndirect)gpa(dev, "vkCmdDrawIndexedIndirect");
211    table->CmdDispatch = (PFN_vkCmdDispatch)gpa(dev, "vkCmdDispatch");
212    table->CmdDispatchIndirect =
213        (PFN_vkCmdDispatchIndirect)gpa(dev, "vkCmdDispatchIndirect");
214    table->CmdCopyBuffer = (PFN_vkCmdCopyBuffer)gpa(dev, "vkCmdCopyBuffer");
215    table->CmdCopyImage = (PFN_vkCmdCopyImage)gpa(dev, "vkCmdCopyImage");
216    table->CmdBlitImage = (PFN_vkCmdBlitImage)gpa(dev, "vkCmdBlitImage");
217    table->CmdCopyBufferToImage =
218        (PFN_vkCmdCopyBufferToImage)gpa(dev, "vkCmdCopyBufferToImage");
219    table->CmdCopyImageToBuffer =
220        (PFN_vkCmdCopyImageToBuffer)gpa(dev, "vkCmdCopyImageToBuffer");
221    table->CmdUpdateBuffer =
222        (PFN_vkCmdUpdateBuffer)gpa(dev, "vkCmdUpdateBuffer");
223    table->CmdFillBuffer = (PFN_vkCmdFillBuffer)gpa(dev, "vkCmdFillBuffer");
224    table->CmdClearColorImage =
225        (PFN_vkCmdClearColorImage)gpa(dev, "vkCmdClearColorImage");
226    table->CmdClearDepthStencilImage = (PFN_vkCmdClearDepthStencilImage)gpa(
227        dev, "vkCmdClearDepthStencilImage");
228    table->CmdClearAttachments =
229        (PFN_vkCmdClearAttachments)gpa(dev, "vkCmdClearAttachments");
230    table->CmdResolveImage =
231        (PFN_vkCmdResolveImage)gpa(dev, "vkCmdResolveImage");
232    table->CmdSetEvent = (PFN_vkCmdSetEvent)gpa(dev, "vkCmdSetEvent");
233    table->CmdResetEvent = (PFN_vkCmdResetEvent)gpa(dev, "vkCmdResetEvent");
234    table->CmdWaitEvents = (PFN_vkCmdWaitEvents)gpa(dev, "vkCmdWaitEvents");
235    table->CmdPipelineBarrier =
236        (PFN_vkCmdPipelineBarrier)gpa(dev, "vkCmdPipelineBarrier");
237    table->CmdBeginQuery = (PFN_vkCmdBeginQuery)gpa(dev, "vkCmdBeginQuery");
238    table->CmdEndQuery = (PFN_vkCmdEndQuery)gpa(dev, "vkCmdEndQuery");
239    table->CmdResetQueryPool =
240        (PFN_vkCmdResetQueryPool)gpa(dev, "vkCmdResetQueryPool");
241    table->CmdWriteTimestamp =
242        (PFN_vkCmdWriteTimestamp)gpa(dev, "vkCmdWriteTimestamp");
243    table->CmdCopyQueryPoolResults =
244        (PFN_vkCmdCopyQueryPoolResults)gpa(dev, "vkCmdCopyQueryPoolResults");
245    table->CmdPushConstants =
246        (PFN_vkCmdPushConstants)gpa(dev, "vkCmdPushConstants");
247    table->CmdBeginRenderPass =
248        (PFN_vkCmdBeginRenderPass)gpa(dev, "vkCmdBeginRenderPass");
249    table->CmdNextSubpass = (PFN_vkCmdNextSubpass)gpa(dev, "vkCmdNextSubpass");
250    table->CmdEndRenderPass =
251        (PFN_vkCmdEndRenderPass)gpa(dev, "vkCmdEndRenderPass");
252    table->CmdExecuteCommands =
253        (PFN_vkCmdExecuteCommands)gpa(dev, "vkCmdExecuteCommands");
254}
255
256static inline void loader_init_device_extension_dispatch_table(
257    struct loader_dev_dispatch_table *dev_table, PFN_vkGetDeviceProcAddr gpa,
258    VkDevice dev) {
259    VkLayerDispatchTable *table = &dev_table->core_dispatch;
260    table->AcquireNextImageKHR =
261        (PFN_vkAcquireNextImageKHR)gpa(dev, "vkAcquireNextImageKHR");
262    table->CreateSwapchainKHR =
263        (PFN_vkCreateSwapchainKHR)gpa(dev, "vkCreateSwapchainKHR");
264    table->DestroySwapchainKHR =
265        (PFN_vkDestroySwapchainKHR)gpa(dev, "vkDestroySwapchainKHR");
266    table->GetSwapchainImagesKHR =
267        (PFN_vkGetSwapchainImagesKHR)gpa(dev, "vkGetSwapchainImagesKHR");
268    table->QueuePresentKHR =
269        (PFN_vkQueuePresentKHR)gpa(dev, "vkQueuePresentKHR");
270    table->CmdDrawIndirectCountAMD =
271        (PFN_vkCmdDrawIndirectCountAMD)gpa(dev, "vkCmdDrawIndirectCountAMD");
272    table->CmdDrawIndexedIndirectCountAMD =
273        (PFN_vkCmdDrawIndexedIndirectCountAMD)gpa(
274            dev, "vkCmdDrawIndexedIndirectCountAMD");
275#ifdef VK_USE_PLATFORM_WIN32_KHR
276    table->GetMemoryWin32HandleNV =
277        (PFN_vkGetMemoryWin32HandleNV)gpa(dev, "vkGetMemoryWin32HandleNV");
278#endif // VK_USE_PLATFORM_WIN32_KHR
279    table->CreateSharedSwapchainsKHR =
280        (PFN_vkCreateSharedSwapchainsKHR)gpa(dev, "vkCreateSharedSwapchainsKHR");
281    table->DebugMarkerSetObjectTagEXT =
282        (PFN_vkDebugMarkerSetObjectTagEXT)gpa(dev, "vkDebugMarkerSetObjectTagEXT");
283    table->DebugMarkerSetObjectNameEXT =
284        (PFN_vkDebugMarkerSetObjectNameEXT)gpa(dev, "vkDebugMarkerSetObjectNameEXT");
285    table->CmdDebugMarkerBeginEXT =
286        (PFN_vkCmdDebugMarkerBeginEXT)gpa(dev, "vkCmdDebugMarkerBeginEXT");
287    table->CmdDebugMarkerEndEXT =
288        (PFN_vkCmdDebugMarkerEndEXT)gpa(dev, "vkCmdDebugMarkerEndEXT");
289    table->CmdDebugMarkerInsertEXT =
290        (PFN_vkCmdDebugMarkerInsertEXT)gpa(dev, "vkCmdDebugMarkerInsertEXT");
291}
292
293static inline void *
294loader_lookup_device_dispatch_table(const VkLayerDispatchTable *table,
295                                    const char *name) {
296    if (!name || name[0] != 'v' || name[1] != 'k')
297        return NULL;
298
299    name += 2;
300    if (!strcmp(name, "GetDeviceProcAddr"))
301        return (void *)table->GetDeviceProcAddr;
302    if (!strcmp(name, "DestroyDevice"))
303        return (void *)table->DestroyDevice;
304    if (!strcmp(name, "GetDeviceQueue"))
305        return (void *)table->GetDeviceQueue;
306    if (!strcmp(name, "QueueSubmit"))
307        return (void *)table->QueueSubmit;
308    if (!strcmp(name, "QueueWaitIdle"))
309        return (void *)table->QueueWaitIdle;
310    if (!strcmp(name, "DeviceWaitIdle"))
311        return (void *)table->DeviceWaitIdle;
312    if (!strcmp(name, "AllocateMemory"))
313        return (void *)table->AllocateMemory;
314    if (!strcmp(name, "FreeMemory"))
315        return (void *)table->FreeMemory;
316    if (!strcmp(name, "MapMemory"))
317        return (void *)table->MapMemory;
318    if (!strcmp(name, "UnmapMemory"))
319        return (void *)table->UnmapMemory;
320    if (!strcmp(name, "FlushMappedMemoryRanges"))
321        return (void *)table->FlushMappedMemoryRanges;
322    if (!strcmp(name, "InvalidateMappedMemoryRanges"))
323        return (void *)table->InvalidateMappedMemoryRanges;
324    if (!strcmp(name, "GetDeviceMemoryCommitment"))
325        return (void *)table->GetDeviceMemoryCommitment;
326    if (!strcmp(name, "GetImageSparseMemoryRequirements"))
327        return (void *)table->GetImageSparseMemoryRequirements;
328    if (!strcmp(name, "GetBufferMemoryRequirements"))
329        return (void *)table->GetBufferMemoryRequirements;
330    if (!strcmp(name, "GetImageMemoryRequirements"))
331        return (void *)table->GetImageMemoryRequirements;
332    if (!strcmp(name, "BindBufferMemory"))
333        return (void *)table->BindBufferMemory;
334    if (!strcmp(name, "BindImageMemory"))
335        return (void *)table->BindImageMemory;
336    if (!strcmp(name, "QueueBindSparse"))
337        return (void *)table->QueueBindSparse;
338    if (!strcmp(name, "CreateFence"))
339        return (void *)table->CreateFence;
340    if (!strcmp(name, "DestroyFence"))
341        return (void *)table->DestroyFence;
342    if (!strcmp(name, "ResetFences"))
343        return (void *)table->ResetFences;
344    if (!strcmp(name, "GetFenceStatus"))
345        return (void *)table->GetFenceStatus;
346    if (!strcmp(name, "WaitForFences"))
347        return (void *)table->WaitForFences;
348    if (!strcmp(name, "CreateSemaphore"))
349        return (void *)table->CreateSemaphore;
350    if (!strcmp(name, "DestroySemaphore"))
351        return (void *)table->DestroySemaphore;
352    if (!strcmp(name, "CreateEvent"))
353        return (void *)table->CreateEvent;
354    if (!strcmp(name, "DestroyEvent"))
355        return (void *)table->DestroyEvent;
356    if (!strcmp(name, "GetEventStatus"))
357        return (void *)table->GetEventStatus;
358    if (!strcmp(name, "SetEvent"))
359        return (void *)table->SetEvent;
360    if (!strcmp(name, "ResetEvent"))
361        return (void *)table->ResetEvent;
362    if (!strcmp(name, "CreateQueryPool"))
363        return (void *)table->CreateQueryPool;
364    if (!strcmp(name, "DestroyQueryPool"))
365        return (void *)table->DestroyQueryPool;
366    if (!strcmp(name, "GetQueryPoolResults"))
367        return (void *)table->GetQueryPoolResults;
368    if (!strcmp(name, "CreateBuffer"))
369        return (void *)table->CreateBuffer;
370    if (!strcmp(name, "DestroyBuffer"))
371        return (void *)table->DestroyBuffer;
372    if (!strcmp(name, "CreateBufferView"))
373        return (void *)table->CreateBufferView;
374    if (!strcmp(name, "DestroyBufferView"))
375        return (void *)table->DestroyBufferView;
376    if (!strcmp(name, "CreateImage"))
377        return (void *)table->CreateImage;
378    if (!strcmp(name, "DestroyImage"))
379        return (void *)table->DestroyImage;
380    if (!strcmp(name, "GetImageSubresourceLayout"))
381        return (void *)table->GetImageSubresourceLayout;
382    if (!strcmp(name, "CreateImageView"))
383        return (void *)table->CreateImageView;
384    if (!strcmp(name, "DestroyImageView"))
385        return (void *)table->DestroyImageView;
386    if (!strcmp(name, "CreateShaderModule"))
387        return (void *)table->CreateShaderModule;
388    if (!strcmp(name, "DestroyShaderModule"))
389        return (void *)table->DestroyShaderModule;
390    if (!strcmp(name, "CreatePipelineCache"))
391        return (void *)vkCreatePipelineCache;
392    if (!strcmp(name, "DestroyPipelineCache"))
393        return (void *)vkDestroyPipelineCache;
394    if (!strcmp(name, "GetPipelineCacheData"))
395        return (void *)vkGetPipelineCacheData;
396    if (!strcmp(name, "MergePipelineCaches"))
397        return (void *)vkMergePipelineCaches;
398    if (!strcmp(name, "CreateGraphicsPipelines"))
399        return (void *)vkCreateGraphicsPipelines;
400    if (!strcmp(name, "CreateComputePipelines"))
401        return (void *)vkCreateComputePipelines;
402    if (!strcmp(name, "DestroyPipeline"))
403        return (void *)table->DestroyPipeline;
404    if (!strcmp(name, "CreatePipelineLayout"))
405        return (void *)table->CreatePipelineLayout;
406    if (!strcmp(name, "DestroyPipelineLayout"))
407        return (void *)table->DestroyPipelineLayout;
408    if (!strcmp(name, "CreateSampler"))
409        return (void *)table->CreateSampler;
410    if (!strcmp(name, "DestroySampler"))
411        return (void *)table->DestroySampler;
412    if (!strcmp(name, "CreateDescriptorSetLayout"))
413        return (void *)table->CreateDescriptorSetLayout;
414    if (!strcmp(name, "DestroyDescriptorSetLayout"))
415        return (void *)table->DestroyDescriptorSetLayout;
416    if (!strcmp(name, "CreateDescriptorPool"))
417        return (void *)table->CreateDescriptorPool;
418    if (!strcmp(name, "DestroyDescriptorPool"))
419        return (void *)table->DestroyDescriptorPool;
420    if (!strcmp(name, "ResetDescriptorPool"))
421        return (void *)table->ResetDescriptorPool;
422    if (!strcmp(name, "AllocateDescriptorSets"))
423        return (void *)table->AllocateDescriptorSets;
424    if (!strcmp(name, "FreeDescriptorSets"))
425        return (void *)table->FreeDescriptorSets;
426    if (!strcmp(name, "UpdateDescriptorSets"))
427        return (void *)table->UpdateDescriptorSets;
428    if (!strcmp(name, "CreateFramebuffer"))
429        return (void *)table->CreateFramebuffer;
430    if (!strcmp(name, "DestroyFramebuffer"))
431        return (void *)table->DestroyFramebuffer;
432    if (!strcmp(name, "CreateRenderPass"))
433        return (void *)table->CreateRenderPass;
434    if (!strcmp(name, "DestroyRenderPass"))
435        return (void *)table->DestroyRenderPass;
436    if (!strcmp(name, "GetRenderAreaGranularity"))
437        return (void *)table->GetRenderAreaGranularity;
438    if (!strcmp(name, "CreateCommandPool"))
439        return (void *)table->CreateCommandPool;
440    if (!strcmp(name, "DestroyCommandPool"))
441        return (void *)table->DestroyCommandPool;
442    if (!strcmp(name, "ResetCommandPool"))
443        return (void *)table->ResetCommandPool;
444    if (!strcmp(name, "AllocateCommandBuffers"))
445        return (void *)table->AllocateCommandBuffers;
446    if (!strcmp(name, "FreeCommandBuffers"))
447        return (void *)table->FreeCommandBuffers;
448    if (!strcmp(name, "BeginCommandBuffer"))
449        return (void *)table->BeginCommandBuffer;
450    if (!strcmp(name, "EndCommandBuffer"))
451        return (void *)table->EndCommandBuffer;
452    if (!strcmp(name, "ResetCommandBuffer"))
453        return (void *)table->ResetCommandBuffer;
454    if (!strcmp(name, "CmdBindPipeline"))
455        return (void *)table->CmdBindPipeline;
456    if (!strcmp(name, "CmdSetViewport"))
457        return (void *)table->CmdSetViewport;
458    if (!strcmp(name, "CmdSetScissor"))
459        return (void *)table->CmdSetScissor;
460    if (!strcmp(name, "CmdSetLineWidth"))
461        return (void *)table->CmdSetLineWidth;
462    if (!strcmp(name, "CmdSetDepthBias"))
463        return (void *)table->CmdSetDepthBias;
464    if (!strcmp(name, "CmdSetBlendConstants"))
465        return (void *)table->CmdSetBlendConstants;
466    if (!strcmp(name, "CmdSetDepthBounds"))
467        return (void *)table->CmdSetDepthBounds;
468    if (!strcmp(name, "CmdSetStencilCompareMask"))
469        return (void *)table->CmdSetStencilCompareMask;
470    if (!strcmp(name, "CmdSetStencilwriteMask"))
471        return (void *)table->CmdSetStencilWriteMask;
472    if (!strcmp(name, "CmdSetStencilReference"))
473        return (void *)table->CmdSetStencilReference;
474    if (!strcmp(name, "CmdBindDescriptorSets"))
475        return (void *)table->CmdBindDescriptorSets;
476    if (!strcmp(name, "CmdBindVertexBuffers"))
477        return (void *)table->CmdBindVertexBuffers;
478    if (!strcmp(name, "CmdBindIndexBuffer"))
479        return (void *)table->CmdBindIndexBuffer;
480    if (!strcmp(name, "CmdDraw"))
481        return (void *)table->CmdDraw;
482    if (!strcmp(name, "CmdDrawIndexed"))
483        return (void *)table->CmdDrawIndexed;
484    if (!strcmp(name, "CmdDrawIndirect"))
485        return (void *)table->CmdDrawIndirect;
486    if (!strcmp(name, "CmdDrawIndexedIndirect"))
487        return (void *)table->CmdDrawIndexedIndirect;
488    if (!strcmp(name, "CmdDispatch"))
489        return (void *)table->CmdDispatch;
490    if (!strcmp(name, "CmdDispatchIndirect"))
491        return (void *)table->CmdDispatchIndirect;
492    if (!strcmp(name, "CmdCopyBuffer"))
493        return (void *)table->CmdCopyBuffer;
494    if (!strcmp(name, "CmdCopyImage"))
495        return (void *)table->CmdCopyImage;
496    if (!strcmp(name, "CmdBlitImage"))
497        return (void *)table->CmdBlitImage;
498    if (!strcmp(name, "CmdCopyBufferToImage"))
499        return (void *)table->CmdCopyBufferToImage;
500    if (!strcmp(name, "CmdCopyImageToBuffer"))
501        return (void *)table->CmdCopyImageToBuffer;
502    if (!strcmp(name, "CmdUpdateBuffer"))
503        return (void *)table->CmdUpdateBuffer;
504    if (!strcmp(name, "CmdFillBuffer"))
505        return (void *)table->CmdFillBuffer;
506    if (!strcmp(name, "CmdClearColorImage"))
507        return (void *)table->CmdClearColorImage;
508    if (!strcmp(name, "CmdClearDepthStencilImage"))
509        return (void *)table->CmdClearDepthStencilImage;
510    if (!strcmp(name, "CmdClearAttachments"))
511        return (void *)table->CmdClearAttachments;
512    if (!strcmp(name, "CmdResolveImage"))
513        return (void *)table->CmdResolveImage;
514    if (!strcmp(name, "CmdSetEvent"))
515        return (void *)table->CmdSetEvent;
516    if (!strcmp(name, "CmdResetEvent"))
517        return (void *)table->CmdResetEvent;
518    if (!strcmp(name, "CmdWaitEvents"))
519        return (void *)table->CmdWaitEvents;
520    if (!strcmp(name, "CmdPipelineBarrier"))
521        return (void *)table->CmdPipelineBarrier;
522    if (!strcmp(name, "CmdBeginQuery"))
523        return (void *)table->CmdBeginQuery;
524    if (!strcmp(name, "CmdEndQuery"))
525        return (void *)table->CmdEndQuery;
526    if (!strcmp(name, "CmdResetQueryPool"))
527        return (void *)table->CmdResetQueryPool;
528    if (!strcmp(name, "CmdWriteTimestamp"))
529        return (void *)table->CmdWriteTimestamp;
530    if (!strcmp(name, "CmdCopyQueryPoolResults"))
531        return (void *)table->CmdCopyQueryPoolResults;
532    if (!strcmp(name, "CmdPushConstants"))
533        return (void *)table->CmdPushConstants;
534    if (!strcmp(name, "CmdBeginRenderPass"))
535        return (void *)table->CmdBeginRenderPass;
536    if (!strcmp(name, "CmdNextSubpass"))
537        return (void *)table->CmdNextSubpass;
538    if (!strcmp(name, "CmdEndRenderPass"))
539        return (void *)table->CmdEndRenderPass;
540    if (!strcmp(name, "CmdExecuteCommands"))
541        return (void *)table->CmdExecuteCommands;
542
543    if (!strcmp(name, "CreateSwapchainKHR")) {
544        // For CreateSwapChainKHR we need to use trampoline and terminator
545        // functions to properly unwrap the SurfaceKHR object.
546        return (void *)vkCreateSwapchainKHR;
547    }
548    if (!strcmp(name, "DestroySwapchainKHR"))
549        return (void *)table->DestroySwapchainKHR;
550    if (!strcmp(name, "GetSwapchainImagesKHR"))
551        return (void *)table->GetSwapchainImagesKHR;
552    if (!strcmp(name, "AcquireNextImageKHR"))
553        return (void *)table->AcquireNextImageKHR;
554    if (!strcmp(name, "QueuePresentKHR"))
555        return (void *)table->QueuePresentKHR;
556
557    return NULL;
558}
559
560static inline void
561loader_init_instance_core_dispatch_table(VkLayerInstanceDispatchTable *table,
562                                         PFN_vkGetInstanceProcAddr gpa,
563                                         VkInstance inst) {
564    table->GetInstanceProcAddr =
565        (PFN_vkGetInstanceProcAddr)gpa(inst, "vkGetInstanceProcAddr");
566    table->DestroyInstance =
567        (PFN_vkDestroyInstance)gpa(inst, "vkDestroyInstance");
568    table->EnumeratePhysicalDevices =
569        (PFN_vkEnumeratePhysicalDevices)gpa(inst, "vkEnumeratePhysicalDevices");
570    table->GetPhysicalDeviceFeatures = (PFN_vkGetPhysicalDeviceFeatures)gpa(
571        inst, "vkGetPhysicalDeviceFeatures");
572    table->GetPhysicalDeviceImageFormatProperties =
573        (PFN_vkGetPhysicalDeviceImageFormatProperties)gpa(
574            inst, "vkGetPhysicalDeviceImageFormatProperties");
575    table->GetPhysicalDeviceFormatProperties =
576        (PFN_vkGetPhysicalDeviceFormatProperties)gpa(
577            inst, "vkGetPhysicalDeviceFormatProperties");
578    table->GetPhysicalDeviceSparseImageFormatProperties =
579        (PFN_vkGetPhysicalDeviceSparseImageFormatProperties)gpa(
580            inst, "vkGetPhysicalDeviceSparseImageFormatProperties");
581    table->GetPhysicalDeviceProperties = (PFN_vkGetPhysicalDeviceProperties)gpa(
582        inst, "vkGetPhysicalDeviceProperties");
583    table->GetPhysicalDeviceQueueFamilyProperties =
584        (PFN_vkGetPhysicalDeviceQueueFamilyProperties)gpa(
585            inst, "vkGetPhysicalDeviceQueueFamilyProperties");
586    table->GetPhysicalDeviceMemoryProperties =
587        (PFN_vkGetPhysicalDeviceMemoryProperties)gpa(
588            inst, "vkGetPhysicalDeviceMemoryProperties");
589    table->EnumerateDeviceExtensionProperties =
590        (PFN_vkEnumerateDeviceExtensionProperties)gpa(
591            inst, "vkEnumerateDeviceExtensionProperties");
592    table->EnumerateDeviceLayerProperties =
593        (PFN_vkEnumerateDeviceLayerProperties)gpa(
594            inst, "vkEnumerateDeviceLayerProperties");
595}
596
597static inline void loader_init_instance_extension_dispatch_table(
598    VkLayerInstanceDispatchTable *table, PFN_vkGetInstanceProcAddr gpa,
599    VkInstance inst) {
600    table->DestroySurfaceKHR =
601        (PFN_vkDestroySurfaceKHR)gpa(inst, "vkDestroySurfaceKHR");
602    table->CreateDebugReportCallbackEXT =
603        (PFN_vkCreateDebugReportCallbackEXT)gpa(
604            inst, "vkCreateDebugReportCallbackEXT");
605    table->DestroyDebugReportCallbackEXT =
606        (PFN_vkDestroyDebugReportCallbackEXT)gpa(
607            inst, "vkDestroyDebugReportCallbackEXT");
608    table->DebugReportMessageEXT =
609        (PFN_vkDebugReportMessageEXT)gpa(inst, "vkDebugReportMessageEXT");
610    table->GetPhysicalDeviceSurfaceSupportKHR =
611        (PFN_vkGetPhysicalDeviceSurfaceSupportKHR)gpa(
612            inst, "vkGetPhysicalDeviceSurfaceSupportKHR");
613    table->GetPhysicalDeviceSurfaceCapabilitiesKHR =
614        (PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR)gpa(
615            inst, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR");
616    table->GetPhysicalDeviceSurfaceFormatsKHR =
617        (PFN_vkGetPhysicalDeviceSurfaceFormatsKHR)gpa(
618            inst, "vkGetPhysicalDeviceSurfaceFormatsKHR");
619    table->GetPhysicalDeviceSurfacePresentModesKHR =
620        (PFN_vkGetPhysicalDeviceSurfacePresentModesKHR)gpa(
621            inst, "vkGetPhysicalDeviceSurfacePresentModesKHR");
622    table->GetPhysicalDeviceExternalImageFormatPropertiesNV =
623        (PFN_vkGetPhysicalDeviceExternalImageFormatPropertiesNV)gpa(
624            inst, "vkGetPhysicalDeviceExternalImageFormatPropertiesNV");
625#ifdef VK_USE_PLATFORM_MIR_KHR
626    table->CreateMirSurfaceKHR =
627        (PFN_vkCreateMirSurfaceKHR)gpa(inst, "vkCreateMirSurfaceKHR");
628    table->GetPhysicalDeviceMirPresentationSupportKHR =
629        (PFN_vkGetPhysicalDeviceMirPresentationSupportKHR)gpa(
630            inst, "vkGetPhysicalDeviceMirPresentationSupportKHR");
631#endif
632#ifdef VK_USE_PLATFORM_WAYLAND_KHR
633    table->CreateWaylandSurfaceKHR =
634        (PFN_vkCreateWaylandSurfaceKHR)gpa(inst, "vkCreateWaylandSurfaceKHR");
635    table->GetPhysicalDeviceWaylandPresentationSupportKHR =
636        (PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)gpa(
637            inst, "vkGetPhysicalDeviceWaylandPresentationSupportKHR");
638#endif
639#ifdef VK_USE_PLATFORM_WIN32_KHR
640    table->CreateWin32SurfaceKHR =
641        (PFN_vkCreateWin32SurfaceKHR)gpa(inst, "vkCreateWin32SurfaceKHR");
642    table->GetPhysicalDeviceWin32PresentationSupportKHR =
643        (PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)gpa(
644            inst, "vkGetPhysicalDeviceWin32PresentationSupportKHR");
645#endif
646#ifdef VK_USE_PLATFORM_XCB_KHR
647    table->CreateXcbSurfaceKHR =
648        (PFN_vkCreateXcbSurfaceKHR)gpa(inst, "vkCreateXcbSurfaceKHR");
649    table->GetPhysicalDeviceXcbPresentationSupportKHR =
650        (PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)gpa(
651            inst, "vkGetPhysicalDeviceXcbPresentationSupportKHR");
652#endif
653#ifdef VK_USE_PLATFORM_XLIB_KHR
654    table->CreateXlibSurfaceKHR =
655        (PFN_vkCreateXlibSurfaceKHR)gpa(inst, "vkCreateXlibSurfaceKHR");
656    table->GetPhysicalDeviceXlibPresentationSupportKHR =
657        (PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR)gpa(
658            inst, "vkGetPhysicalDeviceXlibPresentationSupportKHR");
659#endif
660    table->GetPhysicalDeviceDisplayPropertiesKHR =
661        (PFN_vkGetPhysicalDeviceDisplayPropertiesKHR)gpa(
662            inst, "vkGetPhysicalDeviceDisplayPropertiesKHR");
663    table->GetPhysicalDeviceDisplayPlanePropertiesKHR =
664        (PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR)gpa(
665            inst, "vkGetPhysicalDeviceDisplayPlanePropertiesKHR");
666    table->GetDisplayPlaneSupportedDisplaysKHR =
667        (PFN_vkGetDisplayPlaneSupportedDisplaysKHR)gpa(
668            inst, "vkGetDisplayPlaneSupportedDisplaysKHR");
669    table->GetDisplayModePropertiesKHR = (PFN_vkGetDisplayModePropertiesKHR)gpa(
670        inst, "vkGetDisplayModePropertiesKHR");
671    table->CreateDisplayModeKHR =
672        (PFN_vkCreateDisplayModeKHR)gpa(inst, "vkCreateDisplayModeKHR");
673    table->GetDisplayPlaneCapabilitiesKHR =
674        (PFN_vkGetDisplayPlaneCapabilitiesKHR)gpa(
675            inst, "vkGetDisplayPlaneCapabilitiesKHR");
676    table->CreateDisplayPlaneSurfaceKHR =
677        (PFN_vkCreateDisplayPlaneSurfaceKHR)gpa(
678            inst, "vkCreateDisplayPlaneSurfaceKHR");
679}
680
681static inline void *
682loader_lookup_instance_dispatch_table(const VkLayerInstanceDispatchTable *table,
683                                      const char *name, bool *found_name) {
684    if (!name || name[0] != 'v' || name[1] != 'k') {
685        *found_name = false;
686        return NULL;
687    }
688
689    *found_name = true;
690    name += 2;
691    if (!strcmp(name, "DestroyInstance"))
692        return (void *)table->DestroyInstance;
693    if (!strcmp(name, "EnumeratePhysicalDevices"))
694        return (void *)table->EnumeratePhysicalDevices;
695    if (!strcmp(name, "GetPhysicalDeviceFeatures"))
696        return (void *)table->GetPhysicalDeviceFeatures;
697    if (!strcmp(name, "GetPhysicalDeviceImageFormatProperties"))
698        return (void *)table->GetPhysicalDeviceImageFormatProperties;
699    if (!strcmp(name, "GetPhysicalDeviceFormatProperties"))
700        return (void *)table->GetPhysicalDeviceFormatProperties;
701    if (!strcmp(name, "GetPhysicalDeviceSparseImageFormatProperties"))
702        return (void *)table->GetPhysicalDeviceSparseImageFormatProperties;
703    if (!strcmp(name, "GetPhysicalDeviceProperties"))
704        return (void *)table->GetPhysicalDeviceProperties;
705    if (!strcmp(name, "GetPhysicalDeviceQueueFamilyProperties"))
706        return (void *)table->GetPhysicalDeviceQueueFamilyProperties;
707    if (!strcmp(name, "GetPhysicalDeviceMemoryProperties"))
708        return (void *)table->GetPhysicalDeviceMemoryProperties;
709    if (!strcmp(name, "GetInstanceProcAddr"))
710        return (void *)table->GetInstanceProcAddr;
711    if (!strcmp(name, "EnumerateDeviceExtensionProperties"))
712        return (void *)table->EnumerateDeviceExtensionProperties;
713    if (!strcmp(name, "EnumerateDeviceLayerProperties"))
714        return (void *)table->EnumerateDeviceLayerProperties;
715    if (!strcmp(name, "DestroySurfaceKHR"))
716        return (void *)table->DestroySurfaceKHR;
717    if (!strcmp(name, "GetPhysicalDeviceSurfaceSupportKHR"))
718        return (void *)table->GetPhysicalDeviceSurfaceSupportKHR;
719    if (!strcmp(name, "GetPhysicalDeviceSurfaceCapabilitiesKHR"))
720        return (void *)table->GetPhysicalDeviceSurfaceCapabilitiesKHR;
721    if (!strcmp(name, "GetPhysicalDeviceSurfaceFormatsKHR"))
722        return (void *)table->GetPhysicalDeviceSurfaceFormatsKHR;
723    if (!strcmp(name, "GetPhysicalDeviceSurfacePresentModesKHR"))
724        return (void *)table->GetPhysicalDeviceSurfacePresentModesKHR;
725    if (!strcmp(name, "GetPhysicalDeviceExternalImageFormatPropertiesNV"))
726        return (void *)table->GetPhysicalDeviceExternalImageFormatPropertiesNV;
727#ifdef VK_USE_PLATFORM_MIR_KHR
728    if (!strcmp(name, "CreateMirSurfaceKHR"))
729        return (void *)table->CreateMirSurfaceKHR;
730    if (!strcmp(name, "GetPhysicalDeviceMirPresentationSupportKHR"))
731        return (void *)table->GetPhysicalDeviceMirPresentationSupportKHR;
732#endif
733#ifdef VK_USE_PLATFORM_WAYLAND_KHR
734    if (!strcmp(name, "CreateWaylandSurfaceKHR"))
735        return (void *)table->CreateWaylandSurfaceKHR;
736    if (!strcmp(name, "GetPhysicalDeviceWaylandPresentationSupportKHR"))
737        return (void *)table->GetPhysicalDeviceWaylandPresentationSupportKHR;
738#endif
739#ifdef VK_USE_PLATFORM_WIN32_KHR
740    if (!strcmp(name, "CreateWin32SurfaceKHR"))
741        return (void *)table->CreateWin32SurfaceKHR;
742    if (!strcmp(name, "GetPhysicalDeviceWin32PresentationSupportKHR"))
743        return (void *)table->GetPhysicalDeviceWin32PresentationSupportKHR;
744#endif
745#ifdef VK_USE_PLATFORM_XCB_KHR
746    if (!strcmp(name, "CreateXcbSurfaceKHR"))
747        return (void *)table->CreateXcbSurfaceKHR;
748    if (!strcmp(name, "GetPhysicalDeviceXcbPresentationSupportKHR"))
749        return (void *)table->GetPhysicalDeviceXcbPresentationSupportKHR;
750#endif
751#ifdef VK_USE_PLATFORM_XLIB_KHR
752    if (!strcmp(name, "CreateXlibSurfaceKHR"))
753        return (void *)table->CreateXlibSurfaceKHR;
754    if (!strcmp(name, "GetPhysicalDeviceXlibPresentationSupportKHR"))
755        return (void *)table->GetPhysicalDeviceXlibPresentationSupportKHR;
756#endif
757    if (!strcmp(name, "GetPhysicalDeviceDisplayPropertiesKHR"))
758        return (void *)table->GetPhysicalDeviceDisplayPropertiesKHR;
759    if (!strcmp(name, "GetPhysicalDeviceDisplayPlanePropertiesKHR"))
760        return (void *)table->GetPhysicalDeviceDisplayPlanePropertiesKHR;
761    if (!strcmp(name, "GetDisplayPlaneSupportedDisplaysKHR"))
762        return (void *)table->GetDisplayPlaneSupportedDisplaysKHR;
763    if (!strcmp(name, "GetDisplayModePropertiesKHR"))
764        return (void *)table->GetDisplayModePropertiesKHR;
765    if (!strcmp(name, "CreateDisplayModeKHR"))
766        return (void *)table->CreateDisplayModeKHR;
767    if (!strcmp(name, "GetDisplayPlaneCapabilitiesKHR"))
768        return (void *)table->GetDisplayPlaneCapabilitiesKHR;
769    if (!strcmp(name, "CreateDisplayPlaneSurfaceKHR"))
770        return (void *)table->CreateDisplayPlaneSurfaceKHR;
771
772    if (!strcmp(name, "CreateDebugReportCallbackEXT"))
773        return (void *)table->CreateDebugReportCallbackEXT;
774    if (!strcmp(name, "DestroyDebugReportCallbackEXT"))
775        return (void *)table->DestroyDebugReportCallbackEXT;
776    if (!strcmp(name, "DebugReportMessageEXT"))
777        return (void *)table->DebugReportMessageEXT;
778
779    *found_name = false;
780    return NULL;
781}
782