blob: 36f6d39f3489b2e672a67cf4d68aab9a81eda4b8 [file] [log] [blame]
Jon Ashburn79113cc2014-12-01 14:22:40 -07001/*
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002 * Vulkan
Jon Ashburn79113cc2014-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 Elliott2d4ab1e2015-01-13 17:52:38 -070030#include "loader_platform.h"
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -060031#include "vk_dispatch_table_helper.h"
32#include "vkLayer.h"
Ian Elliott655cad72015-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 Ashburn79113cc2014-12-01 14:22:40 -070036
Jon Ashburn8d1b0b52015-05-18 13:20:15 -060037static void initLayerTable(const VkBaseLayerObject *devw, VkLayerDispatchTable *pTable, const unsigned int layerNum);
Jon Ashburn8c5cbcf2015-05-07 10:27:37 -060038static void initLayerInstanceTable(const VkBaseLayerObject *instw, VkLayerInstanceDispatchTable *pTable, const unsigned int layerNum);
Jon Ashburnfe7ff9c2015-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 Ashburn79113cc2014-12-01 14:22:40 -070046/******************************** Layer multi1 functions **************************/
Jon Ashburnbacb0f52015-04-06 10:58:22 -060047static std::unordered_map<void *, VkLayerDispatchTable *> tableMap1;
Jon Ashburn8c5cbcf2015-05-07 10:27:37 -060048static std::unordered_map<void *, VkLayerInstanceDispatchTable *> tableInstanceMap1;
Jon Ashburn79113cc2014-12-01 14:22:40 -070049static bool layer1_first_activated = false;
50
Jon Ashburnfe7ff9c2015-05-15 16:40:25 -060051static VkLayerDispatchTable *getLayer1Table(const VkBaseLayerObject *devw)
Jon Ashburn79113cc2014-12-01 14:22:40 -070052{
Jon Ashburnbacb0f52015-04-06 10:58:22 -060053 VkLayerDispatchTable *pTable;
Jon Ashburnfe7ff9c2015-05-15 16:40:25 -060054 assert(devw);
55 VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) devw->baseObject;
Jon Ashburn79113cc2014-12-01 14:22:40 -070056
Jon Ashburnfe7ff9c2015-05-15 16:40:25 -060057 std::unordered_map<void *, VkLayerDispatchTable *>::const_iterator it = tableMap1.find((void *) *ppDisp);
Jon Ashburn79113cc2014-12-01 14:22:40 -070058 if (it == tableMap1.end())
59 {
Jon Ashburnbacb0f52015-04-06 10:58:22 -060060 pTable = new VkLayerDispatchTable;
Jon Ashburnfe7ff9c2015-05-15 16:40:25 -060061 tableMap1[(void *) *ppDisp] = pTable;
62 initLayerTable(devw, pTable, 1);
Jon Ashburn79113cc2014-12-01 14:22:40 -070063 return pTable;
64 } else
65 {
66 return it->second;
67 }
68}
Jon Ashburnfe7ff9c2015-05-15 16:40:25 -060069static VkLayerInstanceDispatchTable *getLayer1InstanceTable(const VkBaseLayerObject *instw)
Jon Ashburn8c5cbcf2015-05-07 10:27:37 -060070{
71 VkLayerInstanceDispatchTable *pTable;
Jon Ashburn8c5cbcf2015-05-07 10:27:37 -060072 assert(instw);
Jon Ashburnfe7ff9c2015-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 Ashburn8c5cbcf2015-05-07 10:27:37 -060076 if (it == tableInstanceMap1.end())
77 {
78 pTable = new VkLayerInstanceDispatchTable;
Jon Ashburnfe7ff9c2015-05-15 16:40:25 -060079 tableInstanceMap1[(void *) *ppDisp] = pTable;
Jon Ashburn8c5cbcf2015-05-07 10:27:37 -060080 initLayerInstanceTable(instw, pTable, 1);
81 return pTable;
82 } else
83 {
84 return it->second;
85 }
86}
Jon Ashburn79113cc2014-12-01 14:22:40 -070087#ifdef __cplusplus
88extern "C" {
89#endif
90
Jon Ashburn9a8a2e22015-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 Ashburn95a77ba2015-05-15 15:09:35 -0600111VK_LAYER_EXPORT VkResult VKAPI multi1CreateSampler(VkDevice device, const VkSamplerCreateInfo* pCreateInfo, VkSampler* pSampler)
Jon Ashburn79113cc2014-12-01 14:22:40 -0700112{
Jon Ashburnfe7ff9c2015-05-15 16:40:25 -0600113 VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) device;
114 VkLayerDispatchTable *pTable = tableMap1[*ppDisp];
Jon Ashburn95a77ba2015-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 Ashburn79113cc2014-12-01 14:22:40 -0700119 return result;
120}
121
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600122VK_LAYER_EXPORT VkResult VKAPI multi1CreateGraphicsPipeline(VkDevice device, const VkGraphicsPipelineCreateInfo* pCreateInfo,
123 VkPipeline* pPipeline)
Jon Ashburn79113cc2014-12-01 14:22:40 -0700124{
Jon Ashburnfe7ff9c2015-05-15 16:40:25 -0600125 VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) device;
126 VkLayerDispatchTable *pTable = tableMap1[*ppDisp];
Jon Ashburn79113cc2014-12-01 14:22:40 -0700127
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600128 printf("At start of multi1 layer vkCreateGraphicsPipeline()\n");
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600129 VkResult result = pTable->CreateGraphicsPipeline(device, pCreateInfo, pPipeline);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600130 printf("Completed multi1 layer vkCreateGraphicsPipeline()\n");
Jon Ashburn79113cc2014-12-01 14:22:40 -0700131 return result;
132}
133
Mike Stroyanb050c682015-04-17 12:36:38 -0600134VK_LAYER_EXPORT VkResult VKAPI multi1StorePipeline(VkDevice device, VkPipeline pipeline, size_t* pDataSize, void* pData)
Jon Ashburn79113cc2014-12-01 14:22:40 -0700135{
Jon Ashburnfe7ff9c2015-05-15 16:40:25 -0600136 VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) device;
137 VkLayerDispatchTable *pTable = tableMap1[*ppDisp];
Jon Ashburn79113cc2014-12-01 14:22:40 -0700138
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600139 printf("At start of multi1 layer vkStorePipeline()\n");
Mike Stroyanb050c682015-04-17 12:36:38 -0600140 VkResult result = pTable->StorePipeline(device, pipeline, pDataSize, pData);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600141 printf("Completed multi1 layer vkStorePipeline()\n");
Jon Ashburn79113cc2014-12-01 14:22:40 -0700142 return result;
143}
144
Courtney Goeltzenleuchterd9dc0c72015-04-20 11:04:54 -0600145VK_LAYER_EXPORT VkResult VKAPI multi1EnumerateLayers(VkPhysicalDevice gpu, size_t maxStringSize,
146 size_t* pLayerCount, char* const* pOutLayers,
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600147 void* pReserved)
Jon Ashburn79113cc2014-12-01 14:22:40 -0700148{
149 if (gpu == NULL)
Courtney Goeltzenleuchterd9dc0c72015-04-20 11:04:54 -0600150 return vkEnumerateLayers(gpu, maxStringSize, pLayerCount, pOutLayers, pReserved);
Jon Ashburn79113cc2014-12-01 14:22:40 -0700151
Jon Ashburn95a77ba2015-05-15 15:09:35 -0600152 VkLayerInstanceDispatchTable* pTable = tableInstanceMap1[gpu];
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600153 printf("At start of multi1 layer vkEnumerateLayers()\n");
Courtney Goeltzenleuchterd9dc0c72015-04-20 11:04:54 -0600154 VkResult result = pTable->EnumerateLayers(gpu, maxStringSize, pLayerCount, pOutLayers, pReserved);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600155 printf("Completed multi1 layer vkEnumerateLayers()\n");
Jon Ashburn79113cc2014-12-01 14:22:40 -0700156 return result;
157}
158
Jon Ashburn8d1b0b52015-05-18 13:20:15 -0600159VK_LAYER_EXPORT void * VKAPI multi1GetDeviceProcAddr(VkDevice device, const char* pName)
Jon Ashburn79113cc2014-12-01 14:22:40 -0700160{
Jon Ashburn8d1b0b52015-05-18 13:20:15 -0600161 VkBaseLayerObject* devw = (VkBaseLayerObject *) device;
Chia-I Wub665d942015-01-05 09:41:27 +0800162
Jon Ashburn8d1b0b52015-05-18 13:20:15 -0600163 if (device == NULL)
Jon Ashburn79113cc2014-12-01 14:22:40 -0700164 return NULL;
Chia-I Wub665d942015-01-05 09:41:27 +0800165
Jon Ashburn8d1b0b52015-05-18 13:20:15 -0600166 getLayer1Table(devw);
Chia-I Wub665d942015-01-05 09:41:27 +0800167
Jon Ashburn1c286bb2015-05-19 10:05:54 -0600168 if (!strcmp("vkGetDeviceProcAddr", pName))
169 return (void *) multi1GetDeviceProcAddr;
Jon Ashburn9a8a2e22015-05-19 16:34:53 -0600170 if (!strcmp("vkDestroyDevice", pName))
171 return (void *) multi1DestroyDevice;
Jon Ashburn95a77ba2015-05-15 15:09:35 -0600172 if (!strcmp("vkCreateSampler", pName))
173 return (void *) multi1CreateSampler;
Jon Ashburnf6b33db2015-05-05 14:22:52 -0600174 else if (!strcmp("vkCreateGraphicsPipeline", pName))
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600175 return (void *) multi1CreateGraphicsPipeline;
Jon Ashburnf6b33db2015-05-05 14:22:52 -0600176 else if (!strcmp("vkStorePipeline", pName))
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600177 return (void *) multi1StorePipeline;
Jon Ashburn79113cc2014-12-01 14:22:40 -0700178 else {
Jon Ashburn8d1b0b52015-05-18 13:20:15 -0600179 if (devw->pGPA == NULL)
Jon Ashburn79113cc2014-12-01 14:22:40 -0700180 return NULL;
Jon Ashburn8d1b0b52015-05-18 13:20:15 -0600181 return devw->pGPA((VkObject) devw->nextObject, pName);
Jon Ashburnf6b33db2015-05-05 14:22:52 -0600182 }
183}
184
Jon Ashburn8c5cbcf2015-05-07 10:27:37 -0600185VK_LAYER_EXPORT void * VKAPI multi1GetInstanceProcAddr(VkInstance inst, const char* pName)
Jon Ashburnf6b33db2015-05-05 14:22:52 -0600186{
187 VkBaseLayerObject* instw = (VkBaseLayerObject *) inst;
188
189 if (inst == NULL)
190 return NULL;
191
Jon Ashburn8c5cbcf2015-05-07 10:27:37 -0600192 getLayer1InstanceTable(instw);
Jon Ashburnf6b33db2015-05-05 14:22:52 -0600193
Jon Ashburn1c286bb2015-05-19 10:05:54 -0600194 if (!strcmp("vkGetInstanceProcAddr", pName))
195 return (void *) multi1GetInstanceProcAddr;
Jon Ashburn9a8a2e22015-05-19 16:34:53 -0600196 if (!strcmp("vkDestroyInstance", pName))
197 return (void *) multi1DestroyInstance;
Jon Ashburn95a77ba2015-05-15 15:09:35 -0600198 if (!strcmp("vkEnumerateLayers", pName))
Jon Ashburnf6b33db2015-05-05 14:22:52 -0600199 return (void *) multi1EnumerateLayers;
200 else if (!strcmp("GetGlobalExtensionInfo", pName))
201 return (void*) vkGetGlobalExtensionInfo;
202 else {
203 if (instw->pGPA == NULL)
204 return NULL;
205 return instw->pGPA((VkObject) instw->nextObject, pName);
Jon Ashburn79113cc2014-12-01 14:22:40 -0700206 }
Jon Ashburn79113cc2014-12-01 14:22:40 -0700207}
208
209/******************************** Layer multi2 functions **************************/
Jon Ashburnbacb0f52015-04-06 10:58:22 -0600210static std::unordered_map<void *, VkLayerDispatchTable *> tableMap2;
Jon Ashburn8c5cbcf2015-05-07 10:27:37 -0600211static std::unordered_map<void *, VkLayerInstanceDispatchTable *> tableInstanceMap2;
Jon Ashburn79113cc2014-12-01 14:22:40 -0700212static bool layer2_first_activated = false;
213
Jon Ashburnfe7ff9c2015-05-15 16:40:25 -0600214static VkLayerInstanceDispatchTable *getLayer2InstanceTable(const VkBaseLayerObject *instw)
Jon Ashburn8c5cbcf2015-05-07 10:27:37 -0600215{
216 VkLayerInstanceDispatchTable *pTable;
Jon Ashburn8c5cbcf2015-05-07 10:27:37 -0600217 assert(instw);
Jon Ashburnfe7ff9c2015-05-15 16:40:25 -0600218 VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) instw->baseObject;
219
220 std::unordered_map<void *, VkLayerInstanceDispatchTable *>::const_iterator it = tableInstanceMap2.find((void *) *ppDisp);
Jon Ashburn8c5cbcf2015-05-07 10:27:37 -0600221 if (it == tableInstanceMap2.end())
222 {
223 pTable = new VkLayerInstanceDispatchTable;
Jon Ashburnfe7ff9c2015-05-15 16:40:25 -0600224 tableInstanceMap2[(void *) *ppDisp] = pTable;
Jon Ashburn8c5cbcf2015-05-07 10:27:37 -0600225 initLayerInstanceTable(instw, pTable, 2);
226 return pTable;
227 } else
228 {
229 return it->second;
230 }
231}
232
Jon Ashburnfe7ff9c2015-05-15 16:40:25 -0600233static VkLayerDispatchTable *getLayer2Table(const VkBaseLayerObject *devw)
Jon Ashburn79113cc2014-12-01 14:22:40 -0700234{
Jon Ashburnbacb0f52015-04-06 10:58:22 -0600235 VkLayerDispatchTable *pTable;
Jon Ashburnfe7ff9c2015-05-15 16:40:25 -0600236 assert(devw);
237 VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) devw->baseObject;
Jon Ashburn79113cc2014-12-01 14:22:40 -0700238
Jon Ashburnfe7ff9c2015-05-15 16:40:25 -0600239 std::unordered_map<void *, VkLayerDispatchTable *>::const_iterator it = tableMap2.find((void *) *ppDisp);
Jon Ashburn79113cc2014-12-01 14:22:40 -0700240 if (it == tableMap2.end())
241 {
Jon Ashburnbacb0f52015-04-06 10:58:22 -0600242 pTable = new VkLayerDispatchTable;
Jon Ashburnfe7ff9c2015-05-15 16:40:25 -0600243 tableMap2[(void *) *ppDisp] = pTable;
244 initLayerTable(devw, pTable, 2);
Jon Ashburn79113cc2014-12-01 14:22:40 -0700245 return pTable;
246 } else
247 {
248 return it->second;
249 }
250}
251
Jon Ashburn95a77ba2015-05-15 15:09:35 -0600252VK_LAYER_EXPORT VkResult VKAPI multi2EnumeratePhysicalDevices(
253 VkInstance instance,
254 uint32_t* pPhysicalDeviceCount,
255 VkPhysicalDevice* pPhysicalDevices)
256{
Jon Ashburnfe7ff9c2015-05-15 16:40:25 -0600257 VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) instance;
258 VkLayerInstanceDispatchTable *pInstTable = tableInstanceMap2[*ppDisp];
259
Jon Ashburn95a77ba2015-05-15 15:09:35 -0600260 printf("At start of wrapped multi2 vkEnumeratePhysicalDevices()\n");
261 VkResult result = pInstTable->EnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
Jon Ashburn95a77ba2015-05-15 15:09:35 -0600262 printf("Completed multi2 layer vkEnumeratePhysicalDevices()\n");
263 return result;
264}
265
Jon Ashburn9a8a2e22015-05-19 16:34:53 -0600266/* hook DextroyDevice to remove tableMap entry */
267VK_LAYER_EXPORT VkResult VKAPI multi2DestroyDevice(VkDevice device)
268{
269 VkLayerDispatchTable *pDisp = *(VkLayerDispatchTable **) device;
270 VkLayerDispatchTable *pTable = tableMap2[pDisp];
271 VkResult res = pTable->DestroyDevice(device);
272 tableMap2.erase(pDisp);
273 return res;
274}
275
276/* hook DestroyInstance to remove tableInstanceMap entry */
277VK_LAYER_EXPORT VkResult VKAPI multi2DestroyInstance(VkInstance instance)
278{
279 VkLayerInstanceDispatchTable *pDisp = *(VkLayerInstanceDispatchTable **) instance;
280 VkLayerInstanceDispatchTable *pTable = tableInstanceMap2[pDisp];
281 VkResult res = pTable->DestroyInstance(instance);
282 tableInstanceMap2.erase(pDisp);
283 return res;
284}
285
Tony Barbourd1c35722015-04-16 15:59:00 -0600286VK_LAYER_EXPORT VkResult VKAPI multi2CreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo* pCreateInfo,
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600287 VkDevice* pDevice)
Jon Ashburn79113cc2014-12-01 14:22:40 -0700288{
Jon Ashburnfe7ff9c2015-05-15 16:40:25 -0600289 VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) gpu;
290 VkLayerInstanceDispatchTable *pInstTable = tableInstanceMap2[*ppDisp];
Jon Ashburn79113cc2014-12-01 14:22:40 -0700291
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600292 printf("At start of multi2 vkCreateDevice()\n");
Jon Ashburn95a77ba2015-05-15 15:09:35 -0600293 VkResult result = pInstTable->CreateDevice(gpu, pCreateInfo, pDevice);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600294 printf("Completed multi2 layer vkCreateDevice()\n");
Jon Ashburn79113cc2014-12-01 14:22:40 -0700295 return result;
296}
297
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600298VK_LAYER_EXPORT VkResult VKAPI multi2CreateCommandBuffer(VkDevice device, const VkCmdBufferCreateInfo* pCreateInfo,
299 VkCmdBuffer* pCmdBuffer)
Jon Ashburn79113cc2014-12-01 14:22:40 -0700300{
Jon Ashburnfe7ff9c2015-05-15 16:40:25 -0600301 VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) device;
302 VkLayerDispatchTable *pTable = tableMap2[*ppDisp];
Jon Ashburn79113cc2014-12-01 14:22:40 -0700303
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600304 printf("At start of multi2 layer vkCreateCommandBuffer()\n");
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600305 VkResult result = pTable->CreateCommandBuffer(device, pCreateInfo, pCmdBuffer);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600306 printf("Completed multi2 layer vkCreateCommandBuffer()\n");
Jon Ashburn79113cc2014-12-01 14:22:40 -0700307 return result;
308}
309
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600310VK_LAYER_EXPORT VkResult VKAPI multi2BeginCommandBuffer(VkCmdBuffer cmdBuffer, const VkCmdBufferBeginInfo* pBeginInfo)
Jon Ashburn79113cc2014-12-01 14:22:40 -0700311{
Jon Ashburnfe7ff9c2015-05-15 16:40:25 -0600312 VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) cmdBuffer;
313 VkLayerDispatchTable *pTable = tableMap2[*ppDisp];
Jon Ashburn79113cc2014-12-01 14:22:40 -0700314
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600315 printf("At start of multi2 layer vkBeginCommandBuffer()\n");
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600316 VkResult result = pTable->BeginCommandBuffer(cmdBuffer, pBeginInfo);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600317 printf("Completed multi2 layer vkBeginCommandBuffer()\n");
Jon Ashburn79113cc2014-12-01 14:22:40 -0700318 return result;
319
320}
321
Courtney Goeltzenleuchterd9dc0c72015-04-20 11:04:54 -0600322VK_LAYER_EXPORT VkResult VKAPI multi2EnumerateLayers(VkPhysicalDevice gpu, size_t maxStringSize,
323 size_t* pLayerCount, char* const* pOutLayers,
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600324 void* pReserved)
Jon Ashburn79113cc2014-12-01 14:22:40 -0700325{
326 if (gpu == NULL)
Courtney Goeltzenleuchterd9dc0c72015-04-20 11:04:54 -0600327 return vkEnumerateLayers(gpu, maxStringSize, pLayerCount, pOutLayers, pReserved);
Jon Ashburn79113cc2014-12-01 14:22:40 -0700328
Jon Ashburn95a77ba2015-05-15 15:09:35 -0600329 VkLayerInstanceDispatchTable* pTable = tableInstanceMap2[gpu];
Jon Ashburn79113cc2014-12-01 14:22:40 -0700330
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600331 printf("At start of multi2 layer vkEnumerateLayers()\n");
Courtney Goeltzenleuchterd9dc0c72015-04-20 11:04:54 -0600332 VkResult result = pTable->EnumerateLayers(gpu, maxStringSize, pLayerCount, pOutLayers, pReserved);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600333 printf("Completed multi2 layer vkEnumerateLayers()\n");
Jon Ashburn79113cc2014-12-01 14:22:40 -0700334 return result;
335}
336
Jon Ashburn8d1b0b52015-05-18 13:20:15 -0600337VK_LAYER_EXPORT void * VKAPI multi2GetDeviceProcAddr(VkDevice device, const char* pName)
Jon Ashburn79113cc2014-12-01 14:22:40 -0700338{
Jon Ashburn8d1b0b52015-05-18 13:20:15 -0600339 VkBaseLayerObject* devw = (VkBaseLayerObject *) device;
Chia-I Wub665d942015-01-05 09:41:27 +0800340
Jon Ashburn8d1b0b52015-05-18 13:20:15 -0600341 if (device == NULL)
Jon Ashburn79113cc2014-12-01 14:22:40 -0700342 return NULL;
Chia-I Wub665d942015-01-05 09:41:27 +0800343
Jon Ashburn8d1b0b52015-05-18 13:20:15 -0600344 getLayer2Table(devw);
Chia-I Wub665d942015-01-05 09:41:27 +0800345
Jon Ashburn1c286bb2015-05-19 10:05:54 -0600346 if (!strcmp("vkGetDeviceProcAddr", pName))
347 return (void *) multi2GetDeviceProcAddr;
Jon Ashburn9a8a2e22015-05-19 16:34:53 -0600348 if (!strcmp("vkDestroyDevice", pName))
349 return (void *) multi2DestroyDevice;
Jon Ashburn8d1b0b52015-05-18 13:20:15 -0600350 if (!strcmp("vkCreateCommandBuffer", pName))
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600351 return (void *) multi2CreateCommandBuffer;
Jon Ashburnf6b33db2015-05-05 14:22:52 -0600352 else if (!strcmp("vkBeginCommandBuffer", pName))
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600353 return (void *) multi2BeginCommandBuffer;
Jon Ashburn79113cc2014-12-01 14:22:40 -0700354 else {
Jon Ashburn8d1b0b52015-05-18 13:20:15 -0600355 if (devw->pGPA == NULL)
Jon Ashburn79113cc2014-12-01 14:22:40 -0700356 return NULL;
Jon Ashburn8d1b0b52015-05-18 13:20:15 -0600357 return devw->pGPA((VkObject) devw->nextObject, pName);
Jon Ashburnf6b33db2015-05-05 14:22:52 -0600358 }
359}
360
Jon Ashburn8c5cbcf2015-05-07 10:27:37 -0600361VK_LAYER_EXPORT void * VKAPI multi2GetInstanceProcAddr(VkInstance inst, const char* pName)
Jon Ashburnf6b33db2015-05-05 14:22:52 -0600362{
363 VkBaseLayerObject* instw = (VkBaseLayerObject *) inst;
364
365 if (inst == NULL)
366 return NULL;
367
Jon Ashburn8c5cbcf2015-05-07 10:27:37 -0600368 getLayer2InstanceTable(instw);
Jon Ashburnf6b33db2015-05-05 14:22:52 -0600369
Jon Ashburn1c286bb2015-05-19 10:05:54 -0600370 if (!strcmp("vkGetInstanceProcAddr", pName))
371 return (void *) multi2GetInstanceProcAddr;
Jon Ashburn95a77ba2015-05-15 15:09:35 -0600372 if (!strcmp("vkEnumeratePhysicalDevices", pName))
373 return (void *) multi2EnumeratePhysicalDevices;
Jon Ashburn9a8a2e22015-05-19 16:34:53 -0600374 if (!strcmp("vkDestroyInstance", pName))
375 return (void *) multi2DestroyInstance;
Jon Ashburnf6b33db2015-05-05 14:22:52 -0600376 if (!strcmp("vkCreateDevice", pName))
377 return (void *) multi2CreateDevice;
378 else if (!strcmp("vkEnumerateLayers", pName))
379 return (void *) multi2EnumerateLayers;
380 else if (!strcmp("GetGlobalExtensionInfo", pName))
381 return (void*) vkGetGlobalExtensionInfo;
382 else {
383 if (instw->pGPA == NULL)
384 return NULL;
385 return instw->pGPA((VkObject) instw->nextObject, pName);
Jon Ashburn79113cc2014-12-01 14:22:40 -0700386 }
Jon Ashburn79113cc2014-12-01 14:22:40 -0700387}
388
389/********************************* Common functions ********************************/
Courtney Goeltzenleuchterd9dc0c72015-04-20 11:04:54 -0600390VK_LAYER_EXPORT VkResult VKAPI vkEnumerateLayers(VkPhysicalDevice gpu, size_t maxStringSize,
391 size_t* pLayerCount, char* const* pOutLayers,
392 void* pReserved)
Jon Ashburn79113cc2014-12-01 14:22:40 -0700393{
Courtney Goeltzenleuchterd9dc0c72015-04-20 11:04:54 -0600394 if (pLayerCount == NULL || pOutLayers == NULL || pOutLayers[0] == NULL || pOutLayers[1] == NULL || pReserved == NULL)
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600395 return VK_ERROR_INVALID_POINTER;
Jon Ashburn79113cc2014-12-01 14:22:40 -0700396
Courtney Goeltzenleuchterd9dc0c72015-04-20 11:04:54 -0600397 if (*pLayerCount < 2)
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600398 return VK_ERROR_INITIALIZATION_FAILED;
Courtney Goeltzenleuchterd9dc0c72015-04-20 11:04:54 -0600399 *pLayerCount = 2;
Jon Ashburn79113cc2014-12-01 14:22:40 -0700400 strncpy((char *) pOutLayers[0], "multi1", maxStringSize);
401 strncpy((char *) pOutLayers[1], "multi2", maxStringSize);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600402 return VK_SUCCESS;
Jon Ashburn79113cc2014-12-01 14:22:40 -0700403}
404
Jon Ashburn9fd4cc42015-04-10 14:33:07 -0600405struct extProps {
406 uint32_t version;
407 const char * const name;
408};
409
410#define MULTI_LAYER_EXT_ARRAY_SIZE 2
411static const struct extProps multiExts[MULTI_LAYER_EXT_ARRAY_SIZE] = {
412 // TODO what is the version?
413 0x10, "multi1",
414 0x10, "multi2",
415};
416
417VK_LAYER_EXPORT VkResult VKAPI vkGetGlobalExtensionInfo(
418 VkExtensionInfoType infoType,
419 uint32_t extensionIndex,
420 size_t* pDataSize,
421 void* pData)
422{
Jon Ashburn9fd4cc42015-04-10 14:33:07 -0600423 /* This entrypoint is NOT going to init it's own dispatch table since loader calls here early */
424 VkExtensionProperties *ext_props;
425 uint32_t *count;
426
427 if (pDataSize == NULL)
428 return VK_ERROR_INVALID_POINTER;
429
430 switch (infoType) {
431 case VK_EXTENSION_INFO_TYPE_COUNT:
432 *pDataSize = sizeof(uint32_t);
433 if (pData == NULL)
434 return VK_SUCCESS;
435 count = (uint32_t *) pData;
436 *count = MULTI_LAYER_EXT_ARRAY_SIZE;
437 break;
438 case VK_EXTENSION_INFO_TYPE_PROPERTIES:
439 *pDataSize = sizeof(VkExtensionProperties);
440 if (pData == NULL)
441 return VK_SUCCESS;
442 if (extensionIndex >= MULTI_LAYER_EXT_ARRAY_SIZE)
443 return VK_ERROR_INVALID_VALUE;
444 ext_props = (VkExtensionProperties *) pData;
445 ext_props->version = multiExts[extensionIndex].version;
446 strncpy(ext_props->extName, multiExts[extensionIndex].name,
447 VK_MAX_EXTENSION_NAME);
448 ext_props->extName[VK_MAX_EXTENSION_NAME - 1] = '\0';
449 break;
450 default:
451 return VK_ERROR_INVALID_VALUE;
452 };
453
454 return VK_SUCCESS;
455}
456
Jon Ashburn8d1b0b52015-05-18 13:20:15 -0600457VK_LAYER_EXPORT void * VKAPI vkGetDeviceProcAddr(VkDevice device, const char* pName)
Jon Ashburn79113cc2014-12-01 14:22:40 -0700458{
Jon Ashburn8d1b0b52015-05-18 13:20:15 -0600459 // to find each layers GPA routine Loader will search via "<layerName>GetDeviceProcAddr"
460 if (!strcmp("multi1GetDeviceProcAddr", pName))
461 return (void *) multi1GetDeviceProcAddr;
462 else if (!strcmp("multi2GetDeviceProcAddr", pName))
463 return (void *) multi2GetDeviceProcAddr;
464 else if (!strcmp("vkGetDeviceProcAddr", pName))
465 return (void *) vkGetDeviceProcAddr;
Jon Ashburn79113cc2014-12-01 14:22:40 -0700466
467 // use first layer activated as GPA dispatch table activation happens in order
468 else if (layer1_first_activated)
Jon Ashburn8d1b0b52015-05-18 13:20:15 -0600469 return multi1GetDeviceProcAddr(device, pName);
Jon Ashburn79113cc2014-12-01 14:22:40 -0700470 else if (layer2_first_activated)
Jon Ashburn8d1b0b52015-05-18 13:20:15 -0600471 return multi2GetDeviceProcAddr(device, pName);
Jon Ashburn79113cc2014-12-01 14:22:40 -0700472 else
473 return NULL;
474
475}
476
Jon Ashburnf6b33db2015-05-05 14:22:52 -0600477VK_LAYER_EXPORT void * VKAPI vkGetInstanceProcAddr(VkInstance inst, const char* pName)
478{
Jon Ashburn8d1b0b52015-05-18 13:20:15 -0600479 // to find each layers GPA routine Loader will search via "<layerName>GetInstanceProcAddr"
480 if (!strcmp("multi1GetInstanceProcAddr", pName))
Jon Ashburn8c5cbcf2015-05-07 10:27:37 -0600481 return (void *) multi1GetInstanceProcAddr;
Jon Ashburnf6b33db2015-05-05 14:22:52 -0600482 else if (!strcmp("multi2GetInstanceProcAddr", pName))
Jon Ashburn8c5cbcf2015-05-07 10:27:37 -0600483 return (void *) multi2GetInstanceProcAddr;
Jon Ashburnf6b33db2015-05-05 14:22:52 -0600484 else if (!strcmp("vkGetInstanceProcAddr", pName))
Jon Ashburn8d1b0b52015-05-18 13:20:15 -0600485 return (void *) vkGetInstanceProcAddr;
Jon Ashburnf6b33db2015-05-05 14:22:52 -0600486
487 // use first layer activated as GPA dispatch table activation happens in order
488 else if (layer1_first_activated)
Jon Ashburn8c5cbcf2015-05-07 10:27:37 -0600489 return multi1GetInstanceProcAddr(inst, pName);
Jon Ashburnf6b33db2015-05-05 14:22:52 -0600490 else if (layer2_first_activated)
Jon Ashburn8c5cbcf2015-05-07 10:27:37 -0600491 return multi2GetInstanceProcAddr(inst, pName);
Jon Ashburnf6b33db2015-05-05 14:22:52 -0600492 else
493 return NULL;
494
495}
Jon Ashburn79113cc2014-12-01 14:22:40 -0700496#ifdef __cplusplus
497} //extern "C"
498#endif
499
Jon Ashburn8d1b0b52015-05-18 13:20:15 -0600500static void initLayerTable(const VkBaseLayerObject *devw, VkLayerDispatchTable *pTable, const unsigned int layerNum)
Jon Ashburn79113cc2014-12-01 14:22:40 -0700501{
Jon Ashburn79113cc2014-12-01 14:22:40 -0700502 if (layerNum == 2 && layer1_first_activated == false)
503 layer2_first_activated = true;
504 if (layerNum == 1 && layer2_first_activated == false)
505 layer1_first_activated = true;
506
Jon Ashburn8d1b0b52015-05-18 13:20:15 -0600507 layer_initialize_dispatch_table(pTable, (PFN_vkGetDeviceProcAddr) devw->pGPA, (VkDevice) devw->nextObject);
Jon Ashburn79113cc2014-12-01 14:22:40 -0700508}
Jon Ashburn8c5cbcf2015-05-07 10:27:37 -0600509
510static void initLayerInstanceTable(const VkBaseLayerObject *instw, VkLayerInstanceDispatchTable *pTable, const unsigned int layerNum)
511{
512 if (layerNum == 2 && layer1_first_activated == false)
513 layer2_first_activated = true;
514 if (layerNum == 1 && layer2_first_activated == false)
515 layer1_first_activated = true;
516
517 layer_init_instance_dispatch_table(pTable, (PFN_vkGetInstanceProcAddr) instw->pGPA, (VkInstance) instw->nextObject);
518}