blob: b0e8f212131f8a1bbe1bc9c954a7068f65609a4f [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
Chia-I Wue9ae3882015-01-05 09:41:27 +0800152
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600153
154 if (!strcmp("vkGetDeviceProcAddr", pName)) {
155 getLayer1Table(devw);
Jon Ashburn7cb4e0e2015-05-19 10:05:54 -0600156 return (void *) multi1GetDeviceProcAddr;
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600157 }
Jon Ashburn17f37372015-05-19 16:34:53 -0600158 if (!strcmp("vkDestroyDevice", pName))
159 return (void *) multi1DestroyDevice;
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600160 if (!strcmp("vkCreateSampler", pName))
161 return (void *) multi1CreateSampler;
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600162 if (!strcmp("vkCreateGraphicsPipeline", pName))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600163 return (void *) multi1CreateGraphicsPipeline;
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600164 if (!strcmp("vkStorePipeline", pName))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600165 return (void *) multi1StorePipeline;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700166 else {
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600167 VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) device;
168 VkLayerDispatchTable* pTable = tableMap1[*ppDisp];
169 if (pTable->GetDeviceProcAddr == NULL)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700170 return NULL;
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600171 return pTable->GetDeviceProcAddr(device, pName);
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600172 }
173}
174
Jon Ashburnd9564002015-05-07 10:27:37 -0600175VK_LAYER_EXPORT void * VKAPI multi1GetInstanceProcAddr(VkInstance inst, const char* pName)
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600176{
177 VkBaseLayerObject* instw = (VkBaseLayerObject *) inst;
178
179 if (inst == NULL)
180 return NULL;
181
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600182
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600183
184 if (!strcmp("vkGetInstanceProcAddr", pName)) {
185 getLayer1InstanceTable(instw);
Jon Ashburn7cb4e0e2015-05-19 10:05:54 -0600186 return (void *) multi1GetInstanceProcAddr;
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600187 }
Jon Ashburn17f37372015-05-19 16:34:53 -0600188 if (!strcmp("vkDestroyInstance", pName))
189 return (void *) multi1DestroyInstance;
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600190 if (!strcmp("GetGlobalExtensionInfo", pName))
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600191 return (void*) vkGetGlobalExtensionInfo;
192 else {
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600193 VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) inst;
194 VkLayerInstanceDispatchTable* pTable = tableInstanceMap1[*ppDisp];
195 if (pTable->GetInstanceProcAddr == NULL)
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600196 return NULL;
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600197 return pTable->GetInstanceProcAddr(inst, pName);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700198 }
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700199}
200
201/******************************** Layer multi2 functions **************************/
Jon Ashburn301c5f02015-04-06 10:58:22 -0600202static std::unordered_map<void *, VkLayerDispatchTable *> tableMap2;
Jon Ashburnd9564002015-05-07 10:27:37 -0600203static std::unordered_map<void *, VkLayerInstanceDispatchTable *> tableInstanceMap2;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700204static bool layer2_first_activated = false;
205
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600206static VkLayerInstanceDispatchTable *getLayer2InstanceTable(const VkBaseLayerObject *instw)
Jon Ashburnd9564002015-05-07 10:27:37 -0600207{
208 VkLayerInstanceDispatchTable *pTable;
Jon Ashburnd9564002015-05-07 10:27:37 -0600209 assert(instw);
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600210 VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) instw->baseObject;
211
212 std::unordered_map<void *, VkLayerInstanceDispatchTable *>::const_iterator it = tableInstanceMap2.find((void *) *ppDisp);
Jon Ashburnd9564002015-05-07 10:27:37 -0600213 if (it == tableInstanceMap2.end())
214 {
215 pTable = new VkLayerInstanceDispatchTable;
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600216 tableInstanceMap2[(void *) *ppDisp] = pTable;
Jon Ashburnd9564002015-05-07 10:27:37 -0600217 initLayerInstanceTable(instw, pTable, 2);
218 return pTable;
219 } else
220 {
221 return it->second;
222 }
223}
224
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600225static VkLayerDispatchTable *getLayer2Table(const VkBaseLayerObject *devw)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700226{
Jon Ashburn301c5f02015-04-06 10:58:22 -0600227 VkLayerDispatchTable *pTable;
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600228 assert(devw);
229 VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) devw->baseObject;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700230
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600231 std::unordered_map<void *, VkLayerDispatchTable *>::const_iterator it = tableMap2.find((void *) *ppDisp);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700232 if (it == tableMap2.end())
233 {
Jon Ashburn301c5f02015-04-06 10:58:22 -0600234 pTable = new VkLayerDispatchTable;
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600235 tableMap2[(void *) *ppDisp] = pTable;
236 initLayerTable(devw, pTable, 2);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700237 return pTable;
238 } else
239 {
240 return it->second;
241 }
242}
243
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600244VK_LAYER_EXPORT VkResult VKAPI multi2EnumeratePhysicalDevices(
245 VkInstance instance,
246 uint32_t* pPhysicalDeviceCount,
247 VkPhysicalDevice* pPhysicalDevices)
248{
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600249 VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) instance;
250 VkLayerInstanceDispatchTable *pInstTable = tableInstanceMap2[*ppDisp];
251
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600252 printf("At start of wrapped multi2 vkEnumeratePhysicalDevices()\n");
253 VkResult result = pInstTable->EnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600254 printf("Completed multi2 layer vkEnumeratePhysicalDevices()\n");
255 return result;
256}
257
Jon Ashburn17f37372015-05-19 16:34:53 -0600258/* hook DextroyDevice to remove tableMap entry */
259VK_LAYER_EXPORT VkResult VKAPI multi2DestroyDevice(VkDevice device)
260{
261 VkLayerDispatchTable *pDisp = *(VkLayerDispatchTable **) device;
262 VkLayerDispatchTable *pTable = tableMap2[pDisp];
263 VkResult res = pTable->DestroyDevice(device);
264 tableMap2.erase(pDisp);
265 return res;
266}
267
268/* hook DestroyInstance to remove tableInstanceMap entry */
269VK_LAYER_EXPORT VkResult VKAPI multi2DestroyInstance(VkInstance instance)
270{
271 VkLayerInstanceDispatchTable *pDisp = *(VkLayerInstanceDispatchTable **) instance;
272 VkLayerInstanceDispatchTable *pTable = tableInstanceMap2[pDisp];
273 VkResult res = pTable->DestroyInstance(instance);
274 tableInstanceMap2.erase(pDisp);
275 return res;
276}
277
Tony Barbour8205d902015-04-16 15:59:00 -0600278VK_LAYER_EXPORT VkResult VKAPI multi2CreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo* pCreateInfo,
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600279 VkDevice* pDevice)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700280{
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600281 VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) gpu;
282 VkLayerInstanceDispatchTable *pInstTable = tableInstanceMap2[*ppDisp];
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700283
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600284 printf("At start of multi2 vkCreateDevice()\n");
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600285 VkResult result = pInstTable->CreateDevice(gpu, pCreateInfo, pDevice);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600286 printf("Completed multi2 layer vkCreateDevice()\n");
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700287 return result;
288}
289
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600290VK_LAYER_EXPORT VkResult VKAPI multi2CreateCommandBuffer(VkDevice device, const VkCmdBufferCreateInfo* pCreateInfo,
291 VkCmdBuffer* pCmdBuffer)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700292{
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600293 VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) device;
294 VkLayerDispatchTable *pTable = tableMap2[*ppDisp];
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700295
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600296 printf("At start of multi2 layer vkCreateCommandBuffer()\n");
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600297 VkResult result = pTable->CreateCommandBuffer(device, pCreateInfo, pCmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600298 printf("Completed multi2 layer vkCreateCommandBuffer()\n");
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700299 return result;
300}
301
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600302VK_LAYER_EXPORT VkResult VKAPI multi2BeginCommandBuffer(VkCmdBuffer cmdBuffer, const VkCmdBufferBeginInfo* pBeginInfo)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700303{
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600304 VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) cmdBuffer;
305 VkLayerDispatchTable *pTable = tableMap2[*ppDisp];
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700306
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600307 printf("At start of multi2 layer vkBeginCommandBuffer()\n");
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600308 VkResult result = pTable->BeginCommandBuffer(cmdBuffer, pBeginInfo);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600309 printf("Completed multi2 layer vkBeginCommandBuffer()\n");
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700310 return result;
311
312}
313
Jon Ashburn1245cec2015-05-18 13:20:15 -0600314VK_LAYER_EXPORT void * VKAPI multi2GetDeviceProcAddr(VkDevice device, const char* pName)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700315{
Jon Ashburn1245cec2015-05-18 13:20:15 -0600316 VkBaseLayerObject* devw = (VkBaseLayerObject *) device;
Chia-I Wue9ae3882015-01-05 09:41:27 +0800317
Jon Ashburn1245cec2015-05-18 13:20:15 -0600318 if (device == NULL)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700319 return NULL;
Chia-I Wue9ae3882015-01-05 09:41:27 +0800320
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600321 if (!strcmp("vkGetDeviceProcAddr", pName)) {
322 getLayer2Table(devw);
Jon Ashburn7cb4e0e2015-05-19 10:05:54 -0600323 return (void *) multi2GetDeviceProcAddr;
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600324 }
Jon Ashburn17f37372015-05-19 16:34:53 -0600325 if (!strcmp("vkDestroyDevice", pName))
326 return (void *) multi2DestroyDevice;
Jon Ashburn1245cec2015-05-18 13:20:15 -0600327 if (!strcmp("vkCreateCommandBuffer", pName))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600328 return (void *) multi2CreateCommandBuffer;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600329 else if (!strcmp("vkBeginCommandBuffer", pName))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600330 return (void *) multi2BeginCommandBuffer;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700331 else {
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600332 VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) device;
333 VkLayerDispatchTable* pTable = tableMap2[*ppDisp];
334 if (pTable->GetDeviceProcAddr == NULL)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700335 return NULL;
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600336 return pTable->GetDeviceProcAddr(device, pName);
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600337 }
338}
339
Jon Ashburnd9564002015-05-07 10:27:37 -0600340VK_LAYER_EXPORT void * VKAPI multi2GetInstanceProcAddr(VkInstance inst, const char* pName)
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600341{
342 VkBaseLayerObject* instw = (VkBaseLayerObject *) inst;
343
344 if (inst == NULL)
345 return NULL;
346
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600347 if (!strcmp("vkGetInstanceProcAddr", pName)) {
348 getLayer2InstanceTable(instw);
Jon Ashburn7cb4e0e2015-05-19 10:05:54 -0600349 return (void *) multi2GetInstanceProcAddr;
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600350 }
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600351 if (!strcmp("vkEnumeratePhysicalDevices", pName))
352 return (void *) multi2EnumeratePhysicalDevices;
Jon Ashburn17f37372015-05-19 16:34:53 -0600353 if (!strcmp("vkDestroyInstance", pName))
354 return (void *) multi2DestroyInstance;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600355 if (!strcmp("vkCreateDevice", pName))
356 return (void *) multi2CreateDevice;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600357 else if (!strcmp("GetGlobalExtensionInfo", pName))
358 return (void*) vkGetGlobalExtensionInfo;
359 else {
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600360 VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) inst;
361 VkLayerInstanceDispatchTable* pTable = tableInstanceMap2[*ppDisp];
362 if (pTable->GetInstanceProcAddr == NULL)
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600363 return NULL;
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600364 return pTable->GetInstanceProcAddr(inst, pName);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700365 }
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700366}
367
368/********************************* Common functions ********************************/
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700369
Jon Ashburneb2728b2015-04-10 14:33:07 -0600370struct extProps {
371 uint32_t version;
372 const char * const name;
373};
374
375#define MULTI_LAYER_EXT_ARRAY_SIZE 2
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600376static const VkExtensionProperties multiExts[MULTI_LAYER_EXT_ARRAY_SIZE] = {
377 {
378 VK_STRUCTURE_TYPE_EXTENSION_PROPERTIES,
379 "multi1",
380 0x10,
381 "Sample layer: multi",
382// 0,
383// NULL,
384 },
385 {
386 VK_STRUCTURE_TYPE_EXTENSION_PROPERTIES,
387 "multi2",
388 0x10,
389 "Sample layer: multi",
390// 0,
391// NULL,
392 }
Jon Ashburneb2728b2015-04-10 14:33:07 -0600393};
394
395VK_LAYER_EXPORT VkResult VKAPI vkGetGlobalExtensionInfo(
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600396 VkExtensionInfoType infoType,
397 uint32_t extensionIndex,
398 size_t* pDataSize,
399 void* pData)
Jon Ashburneb2728b2015-04-10 14:33:07 -0600400{
Jon Ashburneb2728b2015-04-10 14:33:07 -0600401 /* This entrypoint is NOT going to init it's own dispatch table since loader calls here early */
Jon Ashburneb2728b2015-04-10 14:33:07 -0600402 uint32_t *count;
403
404 if (pDataSize == NULL)
405 return VK_ERROR_INVALID_POINTER;
406
407 switch (infoType) {
408 case VK_EXTENSION_INFO_TYPE_COUNT:
409 *pDataSize = sizeof(uint32_t);
410 if (pData == NULL)
411 return VK_SUCCESS;
412 count = (uint32_t *) pData;
413 *count = MULTI_LAYER_EXT_ARRAY_SIZE;
414 break;
415 case VK_EXTENSION_INFO_TYPE_PROPERTIES:
416 *pDataSize = sizeof(VkExtensionProperties);
417 if (pData == NULL)
418 return VK_SUCCESS;
419 if (extensionIndex >= MULTI_LAYER_EXT_ARRAY_SIZE)
420 return VK_ERROR_INVALID_VALUE;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600421 memcpy((VkExtensionProperties *) pData, &multiExts[extensionIndex], sizeof(VkExtensionProperties));
Jon Ashburneb2728b2015-04-10 14:33:07 -0600422 break;
423 default:
424 return VK_ERROR_INVALID_VALUE;
425 };
426
427 return VK_SUCCESS;
428}
429
Jon Ashburn1245cec2015-05-18 13:20:15 -0600430VK_LAYER_EXPORT void * VKAPI vkGetDeviceProcAddr(VkDevice device, const char* pName)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700431{
Jon Ashburn1245cec2015-05-18 13:20:15 -0600432 // to find each layers GPA routine Loader will search via "<layerName>GetDeviceProcAddr"
433 if (!strcmp("multi1GetDeviceProcAddr", pName))
434 return (void *) multi1GetDeviceProcAddr;
435 else if (!strcmp("multi2GetDeviceProcAddr", pName))
436 return (void *) multi2GetDeviceProcAddr;
437 else if (!strcmp("vkGetDeviceProcAddr", pName))
438 return (void *) vkGetDeviceProcAddr;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700439
440 // use first layer activated as GPA dispatch table activation happens in order
441 else if (layer1_first_activated)
Jon Ashburn1245cec2015-05-18 13:20:15 -0600442 return multi1GetDeviceProcAddr(device, pName);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700443 else if (layer2_first_activated)
Jon Ashburn1245cec2015-05-18 13:20:15 -0600444 return multi2GetDeviceProcAddr(device, pName);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700445 else
446 return NULL;
447
448}
449
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600450VK_LAYER_EXPORT void * VKAPI vkGetInstanceProcAddr(VkInstance inst, const char* pName)
451{
Jon Ashburn1245cec2015-05-18 13:20:15 -0600452 // to find each layers GPA routine Loader will search via "<layerName>GetInstanceProcAddr"
453 if (!strcmp("multi1GetInstanceProcAddr", pName))
Jon Ashburnd9564002015-05-07 10:27:37 -0600454 return (void *) multi1GetInstanceProcAddr;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600455 else if (!strcmp("multi2GetInstanceProcAddr", pName))
Jon Ashburnd9564002015-05-07 10:27:37 -0600456 return (void *) multi2GetInstanceProcAddr;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600457 else if (!strcmp("vkGetInstanceProcAddr", pName))
Jon Ashburn1245cec2015-05-18 13:20:15 -0600458 return (void *) vkGetInstanceProcAddr;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600459
460 // use first layer activated as GPA dispatch table activation happens in order
461 else if (layer1_first_activated)
Jon Ashburnd9564002015-05-07 10:27:37 -0600462 return multi1GetInstanceProcAddr(inst, pName);
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600463 else if (layer2_first_activated)
Jon Ashburnd9564002015-05-07 10:27:37 -0600464 return multi2GetInstanceProcAddr(inst, pName);
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600465 else
466 return NULL;
467
468}
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700469#ifdef __cplusplus
470} //extern "C"
471#endif
472
Jon Ashburn1245cec2015-05-18 13:20:15 -0600473static void initLayerTable(const VkBaseLayerObject *devw, VkLayerDispatchTable *pTable, const unsigned int layerNum)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700474{
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700475 if (layerNum == 2 && layer1_first_activated == false)
476 layer2_first_activated = true;
477 if (layerNum == 1 && layer2_first_activated == false)
478 layer1_first_activated = true;
479
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600480 layer_initialize_dispatch_table(pTable, devw);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700481}
Jon Ashburnd9564002015-05-07 10:27:37 -0600482
483static void initLayerInstanceTable(const VkBaseLayerObject *instw, VkLayerInstanceDispatchTable *pTable, const unsigned int layerNum)
484{
485 if (layerNum == 2 && layer1_first_activated == false)
486 layer2_first_activated = true;
487 if (layerNum == 1 && layer2_first_activated == false)
488 layer1_first_activated = true;
489
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600490 layer_init_instance_dispatch_table(pTable, instw);
Jon Ashburnd9564002015-05-07 10:27:37 -0600491}