1 /*
2  *
3  * Copyright (c) 2015 The Khronos Group Inc.
4  * Copyright (c) 2015 Valve Corporation
5  * Copyright (c) 2015 LunarG, Inc.
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy
8  * of this software and/or associated documentation files (the "Materials"), to
9  * deal in the Materials without restriction, including without limitation the
10  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11  * sell copies of the Materials, and to permit persons to whom the Materials are
12  * furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice(s) and this permission notice shall be included in
15  * all copies or substantial portions of the Materials.
16  *
17  * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20  *
21  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
22  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
24  * USE OR OTHER DEALINGS IN THE MATERIALS.
25  *
26  * Author: Jon Ashburn <jon@lunarg.com>
27  */
28 
29 #include <string.h>
30 #include "debug_report.h"
31 #include "wsi.h"
32 
trampolineGetProcAddr(struct loader_instance * inst,const char * funcName)33 static inline void *trampolineGetProcAddr(struct loader_instance *inst,
34                                           const char *funcName) {
35     // Don't include or check global functions
36     if (!strcmp(funcName, "vkGetInstanceProcAddr"))
37         return (PFN_vkVoidFunction)vkGetInstanceProcAddr;
38     if (!strcmp(funcName, "vkDestroyInstance"))
39         return (PFN_vkVoidFunction)vkDestroyInstance;
40     if (!strcmp(funcName, "vkEnumeratePhysicalDevices"))
41         return (PFN_vkVoidFunction)vkEnumeratePhysicalDevices;
42     if (!strcmp(funcName, "vkGetPhysicalDeviceFeatures"))
43         return (PFN_vkVoidFunction)vkGetPhysicalDeviceFeatures;
44     if (!strcmp(funcName, "vkGetPhysicalDeviceFormatProperties"))
45         return (PFN_vkVoidFunction)vkGetPhysicalDeviceFormatProperties;
46     if (!strcmp(funcName, "vkGetPhysicalDeviceImageFormatProperties"))
47         return (PFN_vkVoidFunction)vkGetPhysicalDeviceImageFormatProperties;
48     if (!strcmp(funcName, "vkGetPhysicalDeviceSparseImageFormatProperties"))
49         return (
50             PFN_vkVoidFunction)vkGetPhysicalDeviceSparseImageFormatProperties;
51     if (!strcmp(funcName, "vkGetPhysicalDeviceProperties"))
52         return (PFN_vkVoidFunction)vkGetPhysicalDeviceProperties;
53     if (!strcmp(funcName, "vkGetPhysicalDeviceQueueFamilyProperties"))
54         return (PFN_vkVoidFunction)vkGetPhysicalDeviceQueueFamilyProperties;
55     if (!strcmp(funcName, "vkGetPhysicalDeviceMemoryProperties"))
56         return (PFN_vkVoidFunction)vkGetPhysicalDeviceMemoryProperties;
57     if (!strcmp(funcName, "vkEnumerateDeviceLayerProperties"))
58         return (PFN_vkVoidFunction)vkEnumerateDeviceLayerProperties;
59     if (!strcmp(funcName, "vkEnumerateDeviceExtensionProperties"))
60         return (PFN_vkVoidFunction)vkEnumerateDeviceExtensionProperties;
61     if (!strcmp(funcName, "vkCreateDevice"))
62         return (PFN_vkVoidFunction)vkCreateDevice;
63     if (!strcmp(funcName, "vkGetDeviceProcAddr"))
64         return (PFN_vkVoidFunction)vkGetDeviceProcAddr;
65     if (!strcmp(funcName, "vkDestroyDevice"))
66         return (PFN_vkVoidFunction)vkDestroyDevice;
67     if (!strcmp(funcName, "vkGetDeviceQueue"))
68         return (PFN_vkVoidFunction)vkGetDeviceQueue;
69     if (!strcmp(funcName, "vkQueueSubmit"))
70         return (PFN_vkVoidFunction)vkQueueSubmit;
71     if (!strcmp(funcName, "vkQueueWaitIdle"))
72         return (PFN_vkVoidFunction)vkQueueWaitIdle;
73     if (!strcmp(funcName, "vkDeviceWaitIdle"))
74         return (PFN_vkVoidFunction)vkDeviceWaitIdle;
75     if (!strcmp(funcName, "vkAllocateMemory"))
76         return (PFN_vkVoidFunction)vkAllocateMemory;
77     if (!strcmp(funcName, "vkFreeMemory"))
78         return (PFN_vkVoidFunction)vkFreeMemory;
79     if (!strcmp(funcName, "vkMapMemory"))
80         return (PFN_vkVoidFunction)vkMapMemory;
81     if (!strcmp(funcName, "vkUnmapMemory"))
82         return (PFN_vkVoidFunction)vkUnmapMemory;
83     if (!strcmp(funcName, "vkFlushMappedMemoryRanges"))
84         return (PFN_vkVoidFunction)vkFlushMappedMemoryRanges;
85     if (!strcmp(funcName, "vkInvalidateMappedMemoryRanges"))
86         return (PFN_vkVoidFunction)vkInvalidateMappedMemoryRanges;
87     if (!strcmp(funcName, "vkGetDeviceMemoryCommitment"))
88         return (PFN_vkVoidFunction)vkGetDeviceMemoryCommitment;
89     if (!strcmp(funcName, "vkGetImageSparseMemoryRequirements"))
90         return (PFN_vkVoidFunction)vkGetImageSparseMemoryRequirements;
91     if (!strcmp(funcName, "vkGetImageMemoryRequirements"))
92         return (PFN_vkVoidFunction)vkGetImageMemoryRequirements;
93     if (!strcmp(funcName, "vkGetBufferMemoryRequirements"))
94         return (PFN_vkVoidFunction)vkGetBufferMemoryRequirements;
95     if (!strcmp(funcName, "vkBindImageMemory"))
96         return (PFN_vkVoidFunction)vkBindImageMemory;
97     if (!strcmp(funcName, "vkBindBufferMemory"))
98         return (PFN_vkVoidFunction)vkBindBufferMemory;
99     if (!strcmp(funcName, "vkQueueBindSparse"))
100         return (PFN_vkVoidFunction)vkQueueBindSparse;
101     if (!strcmp(funcName, "vkCreateFence"))
102         return (PFN_vkVoidFunction)vkCreateFence;
103     if (!strcmp(funcName, "vkDestroyFence"))
104         return (PFN_vkVoidFunction)vkDestroyFence;
105     if (!strcmp(funcName, "vkGetFenceStatus"))
106         return (PFN_vkVoidFunction)vkGetFenceStatus;
107     if (!strcmp(funcName, "vkResetFences"))
108         return (PFN_vkVoidFunction)vkResetFences;
109     if (!strcmp(funcName, "vkWaitForFences"))
110         return (PFN_vkVoidFunction)vkWaitForFences;
111     if (!strcmp(funcName, "vkCreateSemaphore"))
112         return (PFN_vkVoidFunction)vkCreateSemaphore;
113     if (!strcmp(funcName, "vkDestroySemaphore"))
114         return (PFN_vkVoidFunction)vkDestroySemaphore;
115     if (!strcmp(funcName, "vkCreateEvent"))
116         return (PFN_vkVoidFunction)vkCreateEvent;
117     if (!strcmp(funcName, "vkDestroyEvent"))
118         return (PFN_vkVoidFunction)vkDestroyEvent;
119     if (!strcmp(funcName, "vkGetEventStatus"))
120         return (PFN_vkVoidFunction)vkGetEventStatus;
121     if (!strcmp(funcName, "vkSetEvent"))
122         return (PFN_vkVoidFunction)vkSetEvent;
123     if (!strcmp(funcName, "vkResetEvent"))
124         return (PFN_vkVoidFunction)vkResetEvent;
125     if (!strcmp(funcName, "vkCreateQueryPool"))
126         return (PFN_vkVoidFunction)vkCreateQueryPool;
127     if (!strcmp(funcName, "vkDestroyQueryPool"))
128         return (PFN_vkVoidFunction)vkDestroyQueryPool;
129     if (!strcmp(funcName, "vkGetQueryPoolResults"))
130         return (PFN_vkVoidFunction)vkGetQueryPoolResults;
131     if (!strcmp(funcName, "vkCreateBuffer"))
132         return (PFN_vkVoidFunction)vkCreateBuffer;
133     if (!strcmp(funcName, "vkDestroyBuffer"))
134         return (PFN_vkVoidFunction)vkDestroyBuffer;
135     if (!strcmp(funcName, "vkCreateBufferView"))
136         return (PFN_vkVoidFunction)vkCreateBufferView;
137     if (!strcmp(funcName, "vkDestroyBufferView"))
138         return (PFN_vkVoidFunction)vkDestroyBufferView;
139     if (!strcmp(funcName, "vkCreateImage"))
140         return (PFN_vkVoidFunction)vkCreateImage;
141     if (!strcmp(funcName, "vkDestroyImage"))
142         return (PFN_vkVoidFunction)vkDestroyImage;
143     if (!strcmp(funcName, "vkGetImageSubresourceLayout"))
144         return (PFN_vkVoidFunction)vkGetImageSubresourceLayout;
145     if (!strcmp(funcName, "vkCreateImageView"))
146         return (PFN_vkVoidFunction)vkCreateImageView;
147     if (!strcmp(funcName, "vkDestroyImageView"))
148         return (PFN_vkVoidFunction)vkDestroyImageView;
149     if (!strcmp(funcName, "vkCreateShaderModule"))
150         return (PFN_vkVoidFunction)vkCreateShaderModule;
151     if (!strcmp(funcName, "vkDestroyShaderModule"))
152         return (PFN_vkVoidFunction)vkDestroyShaderModule;
153     if (!strcmp(funcName, "vkCreatePipelineCache"))
154         return (PFN_vkVoidFunction)vkCreatePipelineCache;
155     if (!strcmp(funcName, "vkDestroyPipelineCache"))
156         return (PFN_vkVoidFunction)vkDestroyPipelineCache;
157     if (!strcmp(funcName, "vkGetPipelineCacheData"))
158         return (PFN_vkVoidFunction)vkGetPipelineCacheData;
159     if (!strcmp(funcName, "vkMergePipelineCaches"))
160         return (PFN_vkVoidFunction)vkMergePipelineCaches;
161     if (!strcmp(funcName, "vkCreateGraphicsPipelines"))
162         return (PFN_vkVoidFunction)vkCreateGraphicsPipelines;
163     if (!strcmp(funcName, "vkCreateComputePipelines"))
164         return (PFN_vkVoidFunction)vkCreateComputePipelines;
165     if (!strcmp(funcName, "vkDestroyPipeline"))
166         return (PFN_vkVoidFunction)vkDestroyPipeline;
167     if (!strcmp(funcName, "vkCreatePipelineLayout"))
168         return (PFN_vkVoidFunction)vkCreatePipelineLayout;
169     if (!strcmp(funcName, "vkDestroyPipelineLayout"))
170         return (PFN_vkVoidFunction)vkDestroyPipelineLayout;
171     if (!strcmp(funcName, "vkCreateSampler"))
172         return (PFN_vkVoidFunction)vkCreateSampler;
173     if (!strcmp(funcName, "vkDestroySampler"))
174         return (PFN_vkVoidFunction)vkDestroySampler;
175     if (!strcmp(funcName, "vkCreateDescriptorSetLayout"))
176         return (PFN_vkVoidFunction)vkCreateDescriptorSetLayout;
177     if (!strcmp(funcName, "vkDestroyDescriptorSetLayout"))
178         return (PFN_vkVoidFunction)vkDestroyDescriptorSetLayout;
179     if (!strcmp(funcName, "vkCreateDescriptorPool"))
180         return (PFN_vkVoidFunction)vkCreateDescriptorPool;
181     if (!strcmp(funcName, "vkDestroyDescriptorPool"))
182         return (PFN_vkVoidFunction)vkDestroyDescriptorPool;
183     if (!strcmp(funcName, "vkResetDescriptorPool"))
184         return (PFN_vkVoidFunction)vkResetDescriptorPool;
185     if (!strcmp(funcName, "vkAllocateDescriptorSets"))
186         return (PFN_vkVoidFunction)vkAllocateDescriptorSets;
187     if (!strcmp(funcName, "vkFreeDescriptorSets"))
188         return (PFN_vkVoidFunction)vkFreeDescriptorSets;
189     if (!strcmp(funcName, "vkUpdateDescriptorSets"))
190         return (PFN_vkVoidFunction)vkUpdateDescriptorSets;
191     if (!strcmp(funcName, "vkCreateFramebuffer"))
192         return (PFN_vkVoidFunction)vkCreateFramebuffer;
193     if (!strcmp(funcName, "vkDestroyFramebuffer"))
194         return (PFN_vkVoidFunction)vkDestroyFramebuffer;
195     if (!strcmp(funcName, "vkCreateRenderPass"))
196         return (PFN_vkVoidFunction)vkCreateRenderPass;
197     if (!strcmp(funcName, "vkDestroyRenderPass"))
198         return (PFN_vkVoidFunction)vkDestroyRenderPass;
199     if (!strcmp(funcName, "vkGetRenderAreaGranularity"))
200         return (PFN_vkVoidFunction)vkGetRenderAreaGranularity;
201     if (!strcmp(funcName, "vkCreateCommandPool"))
202         return (PFN_vkVoidFunction)vkCreateCommandPool;
203     if (!strcmp(funcName, "vkDestroyCommandPool"))
204         return (PFN_vkVoidFunction)vkDestroyCommandPool;
205     if (!strcmp(funcName, "vkResetCommandPool"))
206         return (PFN_vkVoidFunction)vkResetCommandPool;
207     if (!strcmp(funcName, "vkAllocateCommandBuffers"))
208         return (PFN_vkVoidFunction)vkAllocateCommandBuffers;
209     if (!strcmp(funcName, "vkFreeCommandBuffers"))
210         return (PFN_vkVoidFunction)vkFreeCommandBuffers;
211     if (!strcmp(funcName, "vkBeginCommandBuffer"))
212         return (PFN_vkVoidFunction)vkBeginCommandBuffer;
213     if (!strcmp(funcName, "vkEndCommandBuffer"))
214         return (PFN_vkVoidFunction)vkEndCommandBuffer;
215     if (!strcmp(funcName, "vkResetCommandBuffer"))
216         return (PFN_vkVoidFunction)vkResetCommandBuffer;
217     if (!strcmp(funcName, "vkCmdBindPipeline"))
218         return (PFN_vkVoidFunction)vkCmdBindPipeline;
219     if (!strcmp(funcName, "vkCmdBindDescriptorSets"))
220         return (PFN_vkVoidFunction)vkCmdBindDescriptorSets;
221     if (!strcmp(funcName, "vkCmdBindVertexBuffers"))
222         return (PFN_vkVoidFunction)vkCmdBindVertexBuffers;
223     if (!strcmp(funcName, "vkCmdBindIndexBuffer"))
224         return (PFN_vkVoidFunction)vkCmdBindIndexBuffer;
225     if (!strcmp(funcName, "vkCmdSetViewport"))
226         return (PFN_vkVoidFunction)vkCmdSetViewport;
227     if (!strcmp(funcName, "vkCmdSetScissor"))
228         return (PFN_vkVoidFunction)vkCmdSetScissor;
229     if (!strcmp(funcName, "vkCmdSetLineWidth"))
230         return (PFN_vkVoidFunction)vkCmdSetLineWidth;
231     if (!strcmp(funcName, "vkCmdSetDepthBias"))
232         return (PFN_vkVoidFunction)vkCmdSetDepthBias;
233     if (!strcmp(funcName, "vkCmdSetBlendConstants"))
234         return (PFN_vkVoidFunction)vkCmdSetBlendConstants;
235     if (!strcmp(funcName, "vkCmdSetDepthBounds"))
236         return (PFN_vkVoidFunction)vkCmdSetDepthBounds;
237     if (!strcmp(funcName, "vkCmdSetStencilCompareMask"))
238         return (PFN_vkVoidFunction)vkCmdSetStencilCompareMask;
239     if (!strcmp(funcName, "vkCmdSetStencilWriteMask"))
240         return (PFN_vkVoidFunction)vkCmdSetStencilWriteMask;
241     if (!strcmp(funcName, "vkCmdSetStencilReference"))
242         return (PFN_vkVoidFunction)vkCmdSetStencilReference;
243     if (!strcmp(funcName, "vkCmdDraw"))
244         return (PFN_vkVoidFunction)vkCmdDraw;
245     if (!strcmp(funcName, "vkCmdDrawIndexed"))
246         return (PFN_vkVoidFunction)vkCmdDrawIndexed;
247     if (!strcmp(funcName, "vkCmdDrawIndirect"))
248         return (PFN_vkVoidFunction)vkCmdDrawIndirect;
249     if (!strcmp(funcName, "vkCmdDrawIndexedIndirect"))
250         return (PFN_vkVoidFunction)vkCmdDrawIndexedIndirect;
251     if (!strcmp(funcName, "vkCmdDispatch"))
252         return (PFN_vkVoidFunction)vkCmdDispatch;
253     if (!strcmp(funcName, "vkCmdDispatchIndirect"))
254         return (PFN_vkVoidFunction)vkCmdDispatchIndirect;
255     if (!strcmp(funcName, "vkCmdCopyBuffer"))
256         return (PFN_vkVoidFunction)vkCmdCopyBuffer;
257     if (!strcmp(funcName, "vkCmdCopyImage"))
258         return (PFN_vkVoidFunction)vkCmdCopyImage;
259     if (!strcmp(funcName, "vkCmdBlitImage"))
260         return (PFN_vkVoidFunction)vkCmdBlitImage;
261     if (!strcmp(funcName, "vkCmdCopyBufferToImage"))
262         return (PFN_vkVoidFunction)vkCmdCopyBufferToImage;
263     if (!strcmp(funcName, "vkCmdCopyImageToBuffer"))
264         return (PFN_vkVoidFunction)vkCmdCopyImageToBuffer;
265     if (!strcmp(funcName, "vkCmdUpdateBuffer"))
266         return (PFN_vkVoidFunction)vkCmdUpdateBuffer;
267     if (!strcmp(funcName, "vkCmdFillBuffer"))
268         return (PFN_vkVoidFunction)vkCmdFillBuffer;
269     if (!strcmp(funcName, "vkCmdClearColorImage"))
270         return (PFN_vkVoidFunction)vkCmdClearColorImage;
271     if (!strcmp(funcName, "vkCmdClearDepthStencilImage"))
272         return (PFN_vkVoidFunction)vkCmdClearDepthStencilImage;
273     if (!strcmp(funcName, "vkCmdClearAttachments"))
274         return (PFN_vkVoidFunction)vkCmdClearAttachments;
275     if (!strcmp(funcName, "vkCmdResolveImage"))
276         return (PFN_vkVoidFunction)vkCmdResolveImage;
277     if (!strcmp(funcName, "vkCmdSetEvent"))
278         return (PFN_vkVoidFunction)vkCmdSetEvent;
279     if (!strcmp(funcName, "vkCmdResetEvent"))
280         return (PFN_vkVoidFunction)vkCmdResetEvent;
281     if (!strcmp(funcName, "vkCmdWaitEvents"))
282         return (PFN_vkVoidFunction)vkCmdWaitEvents;
283     if (!strcmp(funcName, "vkCmdPipelineBarrier"))
284         return (PFN_vkVoidFunction)vkCmdPipelineBarrier;
285     if (!strcmp(funcName, "vkCmdBeginQuery"))
286         return (PFN_vkVoidFunction)vkCmdBeginQuery;
287     if (!strcmp(funcName, "vkCmdEndQuery"))
288         return (PFN_vkVoidFunction)vkCmdEndQuery;
289     if (!strcmp(funcName, "vkCmdResetQueryPool"))
290         return (PFN_vkVoidFunction)vkCmdResetQueryPool;
291     if (!strcmp(funcName, "vkCmdWriteTimestamp"))
292         return (PFN_vkVoidFunction)vkCmdWriteTimestamp;
293     if (!strcmp(funcName, "vkCmdCopyQueryPoolResults"))
294         return (PFN_vkVoidFunction)vkCmdCopyQueryPoolResults;
295     if (!strcmp(funcName, "vkCmdPushConstants"))
296         return (PFN_vkVoidFunction)vkCmdPushConstants;
297     if (!strcmp(funcName, "vkCmdBeginRenderPass"))
298         return (PFN_vkVoidFunction)vkCmdBeginRenderPass;
299     if (!strcmp(funcName, "vkCmdNextSubpass"))
300         return (PFN_vkVoidFunction)vkCmdNextSubpass;
301     if (!strcmp(funcName, "vkCmdEndRenderPass"))
302         return (PFN_vkVoidFunction)vkCmdEndRenderPass;
303     if (!strcmp(funcName, "vkCmdExecuteCommands"))
304         return (PFN_vkVoidFunction)vkCmdExecuteCommands;
305 
306     // Instance extensions
307     void *addr;
308     if (debug_report_instance_gpa(inst, funcName, &addr))
309         return addr;
310 
311     if (wsi_swapchain_instance_gpa(inst, funcName, &addr))
312         return addr;
313 
314     addr = loader_dev_ext_gpa(inst, funcName);
315     return addr;
316 }
317 
globalGetProcAddr(const char * name)318 static inline void *globalGetProcAddr(const char *name) {
319     if (!name || name[0] != 'v' || name[1] != 'k')
320         return NULL;
321 
322     name += 2;
323     if (!strcmp(name, "CreateInstance"))
324         return (void *)vkCreateInstance;
325     if (!strcmp(name, "EnumerateInstanceExtensionProperties"))
326         return (void *)vkEnumerateInstanceExtensionProperties;
327     if (!strcmp(name, "EnumerateInstanceLayerProperties"))
328         return (void *)vkEnumerateInstanceLayerProperties;
329 
330     return NULL;
331 }
332 
333 /* These functions require special handling by the loader.
334 *  They are not just generic trampoline code entrypoints.
335 *  Thus GPA must return loader entrypoint for these instead of first function
336 *  in the chain. */
loader_non_passthrough_gipa(const char * name)337 static inline void *loader_non_passthrough_gipa(const char *name) {
338     if (!name || name[0] != 'v' || name[1] != 'k')
339         return NULL;
340 
341     name += 2;
342     if (!strcmp(name, "CreateInstance"))
343         return (void *)vkCreateInstance;
344     if (!strcmp(name, "DestroyInstance"))
345         return (void *)vkDestroyInstance;
346     if (!strcmp(name, "GetDeviceProcAddr"))
347         return (void *)vkGetDeviceProcAddr;
348     // remove once no longer locks
349     if (!strcmp(name, "EnumeratePhysicalDevices"))
350         return (void *)vkEnumeratePhysicalDevices;
351     if (!strcmp(name, "EnumerateDeviceExtensionProperties"))
352         return (void *)vkEnumerateDeviceExtensionProperties;
353     if (!strcmp(name, "EnumerateDeviceLayerProperties"))
354         return (void *)vkEnumerateDeviceLayerProperties;
355     if (!strcmp(name, "GetInstanceProcAddr"))
356         return (void *)vkGetInstanceProcAddr;
357     if (!strcmp(name, "CreateDevice"))
358         return (void *)vkCreateDevice;
359 
360     return NULL;
361 }
362 
loader_non_passthrough_gdpa(const char * name)363 static inline void *loader_non_passthrough_gdpa(const char *name) {
364     if (!name || name[0] != 'v' || name[1] != 'k')
365         return NULL;
366 
367     name += 2;
368 
369     if (!strcmp(name, "GetDeviceProcAddr"))
370         return (void *)vkGetDeviceProcAddr;
371     if (!strcmp(name, "DestroyDevice"))
372         return (void *)vkDestroyDevice;
373     if (!strcmp(name, "GetDeviceQueue"))
374         return (void *)vkGetDeviceQueue;
375     if (!strcmp(name, "AllocateCommandBuffers"))
376         return (void *)vkAllocateCommandBuffers;
377 
378     return NULL;
379 }
380