blob: 2cc9e0c49d3c0404424d419d7458dc33fc4453b3 [file] [log] [blame]
Jon Ashburn8d8dad02014-12-01 14:22:40 -07001/*
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002 * Vulkan
Jon Ashburn8d8dad02014-12-01 14:22:40 -07003 *
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 */
25
26#include <string.h>
27#include <stdlib.h>
28#include <assert.h>
29#include <unordered_map>
Ian Elliott81ac44c2015-01-13 17:52:38 -070030#include "loader_platform.h"
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060031#include "vk_dispatch_table_helper.h"
32#include "vkLayer.h"
Ian Elliott20f06872015-02-12 17:08:34 -070033// The following is #included again to catch certain OS-specific functions
34// being used:
35#include "loader_platform.h"
Jon Ashburn8d8dad02014-12-01 14:22:40 -070036
Jon Ashburn1245cec2015-05-18 13:20:15 -060037static void initLayerTable(const VkBaseLayerObject *devw, VkLayerDispatchTable *pTable, const unsigned int layerNum);
Jon Ashburnd9564002015-05-07 10:27:37 -060038static void initLayerInstanceTable(const VkBaseLayerObject *instw, VkLayerInstanceDispatchTable *pTable, const unsigned int layerNum);
Jon Ashburnd25a78e2015-05-15 16:40:25 -060039/* Various dispatchable objects will use the same underlying dispatch table if they
40 * are created from that "parent" object. Thus use pointer to dispatch table
41 * as the key to table maps (tableMap1, tableInstanceMap1, tableMap2, tableInstanceMap2.
42 * Instance -> PhysicalDevice
43 * Device -> CmdBuffer or Queue
44 * If use the object themselves as key to map then implies Create entrypoints have to be intercepted
45 * and a new key inserted into map */
Jon Ashburn8d8dad02014-12-01 14:22:40 -070046/******************************** Layer multi1 functions **************************/
Jon Ashburn301c5f02015-04-06 10:58:22 -060047static std::unordered_map<void *, VkLayerDispatchTable *> tableMap1;
Jon Ashburnd9564002015-05-07 10:27:37 -060048static std::unordered_map<void *, VkLayerInstanceDispatchTable *> tableInstanceMap1;
Jon Ashburn8d8dad02014-12-01 14:22:40 -070049static bool layer1_first_activated = false;
50
Jon Ashburnd25a78e2015-05-15 16:40:25 -060051static VkLayerDispatchTable *getLayer1Table(const VkBaseLayerObject *devw)
Jon Ashburn8d8dad02014-12-01 14:22:40 -070052{
Jon Ashburn301c5f02015-04-06 10:58:22 -060053 VkLayerDispatchTable *pTable;
Jon Ashburnd25a78e2015-05-15 16:40:25 -060054 assert(devw);
55 VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) devw->baseObject;
Jon Ashburn8d8dad02014-12-01 14:22:40 -070056
Jon Ashburnd25a78e2015-05-15 16:40:25 -060057 std::unordered_map<void *, VkLayerDispatchTable *>::const_iterator it = tableMap1.find((void *) *ppDisp);
Jon Ashburn8d8dad02014-12-01 14:22:40 -070058 if (it == tableMap1.end())
59 {
Jon Ashburn301c5f02015-04-06 10:58:22 -060060 pTable = new VkLayerDispatchTable;
Jon Ashburnd25a78e2015-05-15 16:40:25 -060061 tableMap1[(void *) *ppDisp] = pTable;
62 initLayerTable(devw, pTable, 1);
Jon Ashburn8d8dad02014-12-01 14:22:40 -070063 return pTable;
64 } else
65 {
66 return it->second;
67 }
68}
Jon Ashburnd25a78e2015-05-15 16:40:25 -060069static VkLayerInstanceDispatchTable *getLayer1InstanceTable(const VkBaseLayerObject *instw)
Jon Ashburnd9564002015-05-07 10:27:37 -060070{
71 VkLayerInstanceDispatchTable *pTable;
Jon Ashburnd9564002015-05-07 10:27:37 -060072 assert(instw);
Jon Ashburnd25a78e2015-05-15 16:40:25 -060073 VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) instw->baseObject;
74
75 std::unordered_map<void *, VkLayerInstanceDispatchTable *>::const_iterator it = tableInstanceMap1.find((void *) *ppDisp);
Jon Ashburnd9564002015-05-07 10:27:37 -060076 if (it == tableInstanceMap1.end())
77 {
78 pTable = new VkLayerInstanceDispatchTable;
Jon Ashburnd25a78e2015-05-15 16:40:25 -060079 tableInstanceMap1[(void *) *ppDisp] = pTable;
Jon Ashburnd9564002015-05-07 10:27:37 -060080 initLayerInstanceTable(instw, pTable, 1);
81 return pTable;
82 } else
83 {
84 return it->second;
85 }
86}
Jon Ashburn8d8dad02014-12-01 14:22:40 -070087#ifdef __cplusplus
88extern "C" {
89#endif
90
Jon Ashburn17f37372015-05-19 16:34:53 -060091/* hook DextroyDevice to remove tableMap entry */
92VK_LAYER_EXPORT VkResult VKAPI multi1DestroyDevice(VkDevice device)
93{
94 VkLayerDispatchTable *pDisp = *(VkLayerDispatchTable **) device;
95 VkLayerDispatchTable *pTable = tableMap1[pDisp];
96 VkResult res = pTable->DestroyDevice(device);
97 tableMap1.erase(pDisp);
98 return res;
99}
100
101/* hook DestroyInstance to remove tableInstanceMap entry */
102VK_LAYER_EXPORT VkResult VKAPI multi1DestroyInstance(VkInstance instance)
103{
104 VkLayerInstanceDispatchTable *pDisp = *(VkLayerInstanceDispatchTable **) instance;
105 VkLayerInstanceDispatchTable *pTable = tableInstanceMap1[pDisp];
106 VkResult res = pTable->DestroyInstance(instance);
107 tableInstanceMap1.erase(pDisp);
108 return res;
109}
110
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600111VK_LAYER_EXPORT VkResult VKAPI multi1CreateSampler(VkDevice device, const VkSamplerCreateInfo* pCreateInfo, VkSampler* pSampler)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700112{
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600113 VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) device;
114 VkLayerDispatchTable *pTable = tableMap1[*ppDisp];
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600115
116 printf("At start of multi1 layer vkCreateSampler()\n");
117 VkResult result = pTable->CreateSampler(device, pCreateInfo, pSampler);
118 printf("Completed multi1 layer vkCreateSampler()\n");
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700119 return result;
120}
121
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600122VK_LAYER_EXPORT VkResult VKAPI multi1CreateGraphicsPipeline(VkDevice device, const VkGraphicsPipelineCreateInfo* pCreateInfo,
123 VkPipeline* pPipeline)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700124{
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600125 VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) device;
126 VkLayerDispatchTable *pTable = tableMap1[*ppDisp];
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700127
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600128 printf("At start of multi1 layer vkCreateGraphicsPipeline()\n");
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600129 VkResult result = pTable->CreateGraphicsPipeline(device, pCreateInfo, pPipeline);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600130 printf("Completed multi1 layer vkCreateGraphicsPipeline()\n");
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700131 return result;
132}
133
Mike Stroyan230e6252015-04-17 12:36:38 -0600134VK_LAYER_EXPORT VkResult VKAPI multi1StorePipeline(VkDevice device, VkPipeline pipeline, size_t* pDataSize, void* pData)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700135{
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600136 VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) device;
137 VkLayerDispatchTable *pTable = tableMap1[*ppDisp];
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700138
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600139 printf("At start of multi1 layer vkStorePipeline()\n");
Mike Stroyan230e6252015-04-17 12:36:38 -0600140 VkResult result = pTable->StorePipeline(device, pipeline, pDataSize, pData);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600141 printf("Completed multi1 layer vkStorePipeline()\n");
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700142 return result;
143}
144
Jon Ashburn1245cec2015-05-18 13:20:15 -0600145VK_LAYER_EXPORT void * VKAPI multi1GetDeviceProcAddr(VkDevice device, const char* pName)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700146{
Jon Ashburn1245cec2015-05-18 13:20:15 -0600147 VkBaseLayerObject* devw = (VkBaseLayerObject *) device;
Chia-I Wue9ae3882015-01-05 09:41:27 +0800148
Jon Ashburn1245cec2015-05-18 13:20:15 -0600149 if (device == NULL)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700150 return NULL;
Chia-I Wue9ae3882015-01-05 09:41:27 +0800151
Jon Ashburn1245cec2015-05-18 13:20:15 -0600152 getLayer1Table(devw);
Chia-I Wue9ae3882015-01-05 09:41:27 +0800153
Jon Ashburn7cb4e0e2015-05-19 10:05:54 -0600154 if (!strcmp("vkGetDeviceProcAddr", pName))
155 return (void *) multi1GetDeviceProcAddr;
Jon Ashburn17f37372015-05-19 16:34:53 -0600156 if (!strcmp("vkDestroyDevice", pName))
157 return (void *) multi1DestroyDevice;
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600158 if (!strcmp("vkCreateSampler", pName))
159 return (void *) multi1CreateSampler;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600160 else if (!strcmp("vkCreateGraphicsPipeline", pName))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600161 return (void *) multi1CreateGraphicsPipeline;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600162 else if (!strcmp("vkStorePipeline", pName))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600163 return (void *) multi1StorePipeline;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700164 else {
Jon Ashburn1245cec2015-05-18 13:20:15 -0600165 if (devw->pGPA == NULL)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700166 return NULL;
Jon Ashburn1245cec2015-05-18 13:20:15 -0600167 return devw->pGPA((VkObject) devw->nextObject, pName);
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600168 }
169}
170
Jon Ashburnd9564002015-05-07 10:27:37 -0600171VK_LAYER_EXPORT void * VKAPI multi1GetInstanceProcAddr(VkInstance inst, const char* pName)
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600172{
173 VkBaseLayerObject* instw = (VkBaseLayerObject *) inst;
174
175 if (inst == NULL)
176 return NULL;
177
Jon Ashburnd9564002015-05-07 10:27:37 -0600178 getLayer1InstanceTable(instw);
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600179
Jon Ashburn7cb4e0e2015-05-19 10:05:54 -0600180 if (!strcmp("vkGetInstanceProcAddr", pName))
181 return (void *) multi1GetInstanceProcAddr;
Jon Ashburn17f37372015-05-19 16:34:53 -0600182 if (!strcmp("vkDestroyInstance", pName))
183 return (void *) multi1DestroyInstance;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600184 else if (!strcmp("GetGlobalExtensionInfo", pName))
185 return (void*) vkGetGlobalExtensionInfo;
186 else {
187 if (instw->pGPA == NULL)
188 return NULL;
189 return instw->pGPA((VkObject) instw->nextObject, pName);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700190 }
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700191}
192
193/******************************** Layer multi2 functions **************************/
Jon Ashburn301c5f02015-04-06 10:58:22 -0600194static std::unordered_map<void *, VkLayerDispatchTable *> tableMap2;
Jon Ashburnd9564002015-05-07 10:27:37 -0600195static std::unordered_map<void *, VkLayerInstanceDispatchTable *> tableInstanceMap2;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700196static bool layer2_first_activated = false;
197
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600198static VkLayerInstanceDispatchTable *getLayer2InstanceTable(const VkBaseLayerObject *instw)
Jon Ashburnd9564002015-05-07 10:27:37 -0600199{
200 VkLayerInstanceDispatchTable *pTable;
Jon Ashburnd9564002015-05-07 10:27:37 -0600201 assert(instw);
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600202 VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) instw->baseObject;
203
204 std::unordered_map<void *, VkLayerInstanceDispatchTable *>::const_iterator it = tableInstanceMap2.find((void *) *ppDisp);
Jon Ashburnd9564002015-05-07 10:27:37 -0600205 if (it == tableInstanceMap2.end())
206 {
207 pTable = new VkLayerInstanceDispatchTable;
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600208 tableInstanceMap2[(void *) *ppDisp] = pTable;
Jon Ashburnd9564002015-05-07 10:27:37 -0600209 initLayerInstanceTable(instw, pTable, 2);
210 return pTable;
211 } else
212 {
213 return it->second;
214 }
215}
216
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600217static VkLayerDispatchTable *getLayer2Table(const VkBaseLayerObject *devw)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700218{
Jon Ashburn301c5f02015-04-06 10:58:22 -0600219 VkLayerDispatchTable *pTable;
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600220 assert(devw);
221 VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) devw->baseObject;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700222
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600223 std::unordered_map<void *, VkLayerDispatchTable *>::const_iterator it = tableMap2.find((void *) *ppDisp);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700224 if (it == tableMap2.end())
225 {
Jon Ashburn301c5f02015-04-06 10:58:22 -0600226 pTable = new VkLayerDispatchTable;
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600227 tableMap2[(void *) *ppDisp] = pTable;
228 initLayerTable(devw, pTable, 2);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700229 return pTable;
230 } else
231 {
232 return it->second;
233 }
234}
235
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600236VK_LAYER_EXPORT VkResult VKAPI multi2EnumeratePhysicalDevices(
237 VkInstance instance,
238 uint32_t* pPhysicalDeviceCount,
239 VkPhysicalDevice* pPhysicalDevices)
240{
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600241 VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) instance;
242 VkLayerInstanceDispatchTable *pInstTable = tableInstanceMap2[*ppDisp];
243
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600244 printf("At start of wrapped multi2 vkEnumeratePhysicalDevices()\n");
245 VkResult result = pInstTable->EnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600246 printf("Completed multi2 layer vkEnumeratePhysicalDevices()\n");
247 return result;
248}
249
Jon Ashburn17f37372015-05-19 16:34:53 -0600250/* hook DextroyDevice to remove tableMap entry */
251VK_LAYER_EXPORT VkResult VKAPI multi2DestroyDevice(VkDevice device)
252{
253 VkLayerDispatchTable *pDisp = *(VkLayerDispatchTable **) device;
254 VkLayerDispatchTable *pTable = tableMap2[pDisp];
255 VkResult res = pTable->DestroyDevice(device);
256 tableMap2.erase(pDisp);
257 return res;
258}
259
260/* hook DestroyInstance to remove tableInstanceMap entry */
261VK_LAYER_EXPORT VkResult VKAPI multi2DestroyInstance(VkInstance instance)
262{
263 VkLayerInstanceDispatchTable *pDisp = *(VkLayerInstanceDispatchTable **) instance;
264 VkLayerInstanceDispatchTable *pTable = tableInstanceMap2[pDisp];
265 VkResult res = pTable->DestroyInstance(instance);
266 tableInstanceMap2.erase(pDisp);
267 return res;
268}
269
Tony Barbour8205d902015-04-16 15:59:00 -0600270VK_LAYER_EXPORT VkResult VKAPI multi2CreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo* pCreateInfo,
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600271 VkDevice* pDevice)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700272{
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600273 VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) gpu;
274 VkLayerInstanceDispatchTable *pInstTable = tableInstanceMap2[*ppDisp];
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700275
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600276 printf("At start of multi2 vkCreateDevice()\n");
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600277 VkResult result = pInstTable->CreateDevice(gpu, pCreateInfo, pDevice);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600278 printf("Completed multi2 layer vkCreateDevice()\n");
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700279 return result;
280}
281
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600282VK_LAYER_EXPORT VkResult VKAPI multi2CreateCommandBuffer(VkDevice device, const VkCmdBufferCreateInfo* pCreateInfo,
283 VkCmdBuffer* pCmdBuffer)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700284{
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600285 VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) device;
286 VkLayerDispatchTable *pTable = tableMap2[*ppDisp];
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700287
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600288 printf("At start of multi2 layer vkCreateCommandBuffer()\n");
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600289 VkResult result = pTable->CreateCommandBuffer(device, pCreateInfo, pCmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600290 printf("Completed multi2 layer vkCreateCommandBuffer()\n");
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700291 return result;
292}
293
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600294VK_LAYER_EXPORT VkResult VKAPI multi2BeginCommandBuffer(VkCmdBuffer cmdBuffer, const VkCmdBufferBeginInfo* pBeginInfo)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700295{
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600296 VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) cmdBuffer;
297 VkLayerDispatchTable *pTable = tableMap2[*ppDisp];
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700298
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600299 printf("At start of multi2 layer vkBeginCommandBuffer()\n");
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600300 VkResult result = pTable->BeginCommandBuffer(cmdBuffer, pBeginInfo);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600301 printf("Completed multi2 layer vkBeginCommandBuffer()\n");
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700302 return result;
303
304}
305
Jon Ashburn1245cec2015-05-18 13:20:15 -0600306VK_LAYER_EXPORT void * VKAPI multi2GetDeviceProcAddr(VkDevice device, const char* pName)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700307{
Jon Ashburn1245cec2015-05-18 13:20:15 -0600308 VkBaseLayerObject* devw = (VkBaseLayerObject *) device;
Chia-I Wue9ae3882015-01-05 09:41:27 +0800309
Jon Ashburn1245cec2015-05-18 13:20:15 -0600310 if (device == NULL)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700311 return NULL;
Chia-I Wue9ae3882015-01-05 09:41:27 +0800312
Jon Ashburn1245cec2015-05-18 13:20:15 -0600313 getLayer2Table(devw);
Chia-I Wue9ae3882015-01-05 09:41:27 +0800314
Jon Ashburn7cb4e0e2015-05-19 10:05:54 -0600315 if (!strcmp("vkGetDeviceProcAddr", pName))
316 return (void *) multi2GetDeviceProcAddr;
Jon Ashburn17f37372015-05-19 16:34:53 -0600317 if (!strcmp("vkDestroyDevice", pName))
318 return (void *) multi2DestroyDevice;
Jon Ashburn1245cec2015-05-18 13:20:15 -0600319 if (!strcmp("vkCreateCommandBuffer", pName))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600320 return (void *) multi2CreateCommandBuffer;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600321 else if (!strcmp("vkBeginCommandBuffer", pName))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600322 return (void *) multi2BeginCommandBuffer;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700323 else {
Jon Ashburn1245cec2015-05-18 13:20:15 -0600324 if (devw->pGPA == NULL)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700325 return NULL;
Jon Ashburn1245cec2015-05-18 13:20:15 -0600326 return devw->pGPA((VkObject) devw->nextObject, pName);
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600327 }
328}
329
Jon Ashburnd9564002015-05-07 10:27:37 -0600330VK_LAYER_EXPORT void * VKAPI multi2GetInstanceProcAddr(VkInstance inst, const char* pName)
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600331{
332 VkBaseLayerObject* instw = (VkBaseLayerObject *) inst;
333
334 if (inst == NULL)
335 return NULL;
336
Jon Ashburnd9564002015-05-07 10:27:37 -0600337 getLayer2InstanceTable(instw);
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600338
Jon Ashburn7cb4e0e2015-05-19 10:05:54 -0600339 if (!strcmp("vkGetInstanceProcAddr", pName))
340 return (void *) multi2GetInstanceProcAddr;
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600341 if (!strcmp("vkEnumeratePhysicalDevices", pName))
342 return (void *) multi2EnumeratePhysicalDevices;
Jon Ashburn17f37372015-05-19 16:34:53 -0600343 if (!strcmp("vkDestroyInstance", pName))
344 return (void *) multi2DestroyInstance;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600345 if (!strcmp("vkCreateDevice", pName))
346 return (void *) multi2CreateDevice;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600347 else if (!strcmp("GetGlobalExtensionInfo", pName))
348 return (void*) vkGetGlobalExtensionInfo;
349 else {
350 if (instw->pGPA == NULL)
351 return NULL;
352 return instw->pGPA((VkObject) instw->nextObject, pName);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700353 }
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700354}
355
356/********************************* Common functions ********************************/
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -0600357VK_LAYER_EXPORT VkResult VKAPI vkEnumerateLayers(VkPhysicalDevice gpu, size_t maxStringSize,
358 size_t* pLayerCount, char* const* pOutLayers,
359 void* pReserved)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700360{
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -0600361 if (pLayerCount == NULL || pOutLayers == NULL || pOutLayers[0] == NULL || pOutLayers[1] == NULL || pReserved == NULL)
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600362 return VK_ERROR_INVALID_POINTER;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700363
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -0600364 if (*pLayerCount < 2)
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600365 return VK_ERROR_INITIALIZATION_FAILED;
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -0600366 *pLayerCount = 2;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700367 strncpy((char *) pOutLayers[0], "multi1", maxStringSize);
368 strncpy((char *) pOutLayers[1], "multi2", maxStringSize);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600369 return VK_SUCCESS;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700370}
371
Jon Ashburneb2728b2015-04-10 14:33:07 -0600372struct extProps {
373 uint32_t version;
374 const char * const name;
375};
376
377#define MULTI_LAYER_EXT_ARRAY_SIZE 2
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600378static const VkExtensionProperties multiExts[MULTI_LAYER_EXT_ARRAY_SIZE] = {
379 {
380 VK_STRUCTURE_TYPE_EXTENSION_PROPERTIES,
381 "multi1",
382 0x10,
383 "Sample layer: multi",
384// 0,
385// NULL,
386 },
387 {
388 VK_STRUCTURE_TYPE_EXTENSION_PROPERTIES,
389 "multi2",
390 0x10,
391 "Sample layer: multi",
392// 0,
393// NULL,
394 }
Jon Ashburneb2728b2015-04-10 14:33:07 -0600395};
396
397VK_LAYER_EXPORT VkResult VKAPI vkGetGlobalExtensionInfo(
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600398 VkExtensionInfoType infoType,
399 uint32_t extensionIndex,
400 size_t* pDataSize,
401 void* pData)
Jon Ashburneb2728b2015-04-10 14:33:07 -0600402{
Jon Ashburneb2728b2015-04-10 14:33:07 -0600403 /* This entrypoint is NOT going to init it's own dispatch table since loader calls here early */
Jon Ashburneb2728b2015-04-10 14:33:07 -0600404 uint32_t *count;
405
406 if (pDataSize == NULL)
407 return VK_ERROR_INVALID_POINTER;
408
409 switch (infoType) {
410 case VK_EXTENSION_INFO_TYPE_COUNT:
411 *pDataSize = sizeof(uint32_t);
412 if (pData == NULL)
413 return VK_SUCCESS;
414 count = (uint32_t *) pData;
415 *count = MULTI_LAYER_EXT_ARRAY_SIZE;
416 break;
417 case VK_EXTENSION_INFO_TYPE_PROPERTIES:
418 *pDataSize = sizeof(VkExtensionProperties);
419 if (pData == NULL)
420 return VK_SUCCESS;
421 if (extensionIndex >= MULTI_LAYER_EXT_ARRAY_SIZE)
422 return VK_ERROR_INVALID_VALUE;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600423 memcpy((VkExtensionProperties *) pData, &multiExts[extensionIndex], sizeof(VkExtensionProperties));
Jon Ashburneb2728b2015-04-10 14:33:07 -0600424 break;
425 default:
426 return VK_ERROR_INVALID_VALUE;
427 };
428
429 return VK_SUCCESS;
430}
431
Jon Ashburn1245cec2015-05-18 13:20:15 -0600432VK_LAYER_EXPORT void * VKAPI vkGetDeviceProcAddr(VkDevice device, const char* pName)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700433{
Jon Ashburn1245cec2015-05-18 13:20:15 -0600434 // to find each layers GPA routine Loader will search via "<layerName>GetDeviceProcAddr"
435 if (!strcmp("multi1GetDeviceProcAddr", pName))
436 return (void *) multi1GetDeviceProcAddr;
437 else if (!strcmp("multi2GetDeviceProcAddr", pName))
438 return (void *) multi2GetDeviceProcAddr;
439 else if (!strcmp("vkGetDeviceProcAddr", pName))
440 return (void *) vkGetDeviceProcAddr;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700441
442 // use first layer activated as GPA dispatch table activation happens in order
443 else if (layer1_first_activated)
Jon Ashburn1245cec2015-05-18 13:20:15 -0600444 return multi1GetDeviceProcAddr(device, pName);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700445 else if (layer2_first_activated)
Jon Ashburn1245cec2015-05-18 13:20:15 -0600446 return multi2GetDeviceProcAddr(device, pName);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700447 else
448 return NULL;
449
450}
451
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600452VK_LAYER_EXPORT void * VKAPI vkGetInstanceProcAddr(VkInstance inst, const char* pName)
453{
Jon Ashburn1245cec2015-05-18 13:20:15 -0600454 // to find each layers GPA routine Loader will search via "<layerName>GetInstanceProcAddr"
455 if (!strcmp("multi1GetInstanceProcAddr", pName))
Jon Ashburnd9564002015-05-07 10:27:37 -0600456 return (void *) multi1GetInstanceProcAddr;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600457 else if (!strcmp("multi2GetInstanceProcAddr", pName))
Jon Ashburnd9564002015-05-07 10:27:37 -0600458 return (void *) multi2GetInstanceProcAddr;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600459 else if (!strcmp("vkGetInstanceProcAddr", pName))
Jon Ashburn1245cec2015-05-18 13:20:15 -0600460 return (void *) vkGetInstanceProcAddr;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600461
462 // use first layer activated as GPA dispatch table activation happens in order
463 else if (layer1_first_activated)
Jon Ashburnd9564002015-05-07 10:27:37 -0600464 return multi1GetInstanceProcAddr(inst, pName);
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600465 else if (layer2_first_activated)
Jon Ashburnd9564002015-05-07 10:27:37 -0600466 return multi2GetInstanceProcAddr(inst, pName);
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600467 else
468 return NULL;
469
470}
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700471#ifdef __cplusplus
472} //extern "C"
473#endif
474
Jon Ashburn1245cec2015-05-18 13:20:15 -0600475static void initLayerTable(const VkBaseLayerObject *devw, VkLayerDispatchTable *pTable, const unsigned int layerNum)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700476{
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700477 if (layerNum == 2 && layer1_first_activated == false)
478 layer2_first_activated = true;
479 if (layerNum == 1 && layer2_first_activated == false)
480 layer1_first_activated = true;
481
Jon Ashburn1245cec2015-05-18 13:20:15 -0600482 layer_initialize_dispatch_table(pTable, (PFN_vkGetDeviceProcAddr) devw->pGPA, (VkDevice) devw->nextObject);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700483}
Jon Ashburnd9564002015-05-07 10:27:37 -0600484
485static void initLayerInstanceTable(const VkBaseLayerObject *instw, VkLayerInstanceDispatchTable *pTable, const unsigned int layerNum)
486{
487 if (layerNum == 2 && layer1_first_activated == false)
488 layer2_first_activated = true;
489 if (layerNum == 1 && layer2_first_activated == false)
490 layer1_first_activated = true;
491
492 layer_init_instance_dispatch_table(pTable, (PFN_vkGetInstanceProcAddr) instw->pGPA, (VkInstance) instw->nextObject);
493}