blob: acdfaf6b12677c7ed6ab657f29b0b722a2af05f1 [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>
Tobin Ehlis7a51d902015-07-03 10:34:49 -060030#include "vk_loader_platform.h"
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060031#include "vk_dispatch_table_helper.h"
Tobin Ehlis2d1d9702015-07-03 09:42:57 -060032#include "vk_layer.h"
Ian Elliott20f06872015-02-12 17:08:34 -070033// The following is #included again to catch certain OS-specific functions
34// being used:
Tobin Ehlis7a51d902015-07-03 10:34:49 -060035#include "vk_loader_platform.h"
Courtney Goeltzenleuchter142c9c22015-07-06 21:32:03 -060036#include "vk_layer_extension_utils.h"
Jon Ashburn8d8dad02014-12-01 14:22:40 -070037
Jon Ashburn1245cec2015-05-18 13:20:15 -060038static void initLayerTable(const VkBaseLayerObject *devw, VkLayerDispatchTable *pTable, const unsigned int layerNum);
Jon Ashburnd9564002015-05-07 10:27:37 -060039static void initLayerInstanceTable(const VkBaseLayerObject *instw, VkLayerInstanceDispatchTable *pTable, const unsigned int layerNum);
Jon Ashburnd25a78e2015-05-15 16:40:25 -060040/* Various dispatchable objects will use the same underlying dispatch table if they
41 * are created from that "parent" object. Thus use pointer to dispatch table
42 * as the key to table maps (tableMap1, tableInstanceMap1, tableMap2, tableInstanceMap2.
43 * Instance -> PhysicalDevice
44 * Device -> CmdBuffer or Queue
45 * If use the object themselves as key to map then implies Create entrypoints have to be intercepted
46 * and a new key inserted into map */
Jon Ashburn8d8dad02014-12-01 14:22:40 -070047/******************************** Layer multi1 functions **************************/
Jon Ashburn301c5f02015-04-06 10:58:22 -060048static std::unordered_map<void *, VkLayerDispatchTable *> tableMap1;
Jon Ashburnd9564002015-05-07 10:27:37 -060049static std::unordered_map<void *, VkLayerInstanceDispatchTable *> tableInstanceMap1;
Jon Ashburn8d8dad02014-12-01 14:22:40 -070050static bool layer1_first_activated = false;
51
Jon Ashburn5a10d212015-06-01 10:02:09 -060052// Map lookup must be thread safe
53static inline VkLayerDispatchTable *device_dispatch_table1(VkObject object)
54{
55 VkLayerDispatchTable *pDisp = *(VkLayerDispatchTable **) object;
56 std::unordered_map<void *, VkLayerDispatchTable *>::const_iterator it = tableMap1.find((void *) pDisp);
57 assert(it != tableMap1.end() && "Not able to find device dispatch entry");
58 return it->second;
59}
60
61static inline VkLayerInstanceDispatchTable *instance_dispatch_table1(VkObject object)
62{
63 VkLayerInstanceDispatchTable *pDisp = *(VkLayerInstanceDispatchTable **) object;
64 std::unordered_map<void *, VkLayerInstanceDispatchTable *>::const_iterator it = tableInstanceMap1.find((void *) pDisp);
65 assert(it != tableInstanceMap1.end() && "Not able to find instance dispatch entry");
66 return it->second;
67}
68
Jon Ashburnd25a78e2015-05-15 16:40:25 -060069static VkLayerDispatchTable *getLayer1Table(const VkBaseLayerObject *devw)
Jon Ashburn8d8dad02014-12-01 14:22:40 -070070{
Jon Ashburn301c5f02015-04-06 10:58:22 -060071 VkLayerDispatchTable *pTable;
Jon Ashburnd25a78e2015-05-15 16:40:25 -060072 assert(devw);
73 VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) devw->baseObject;
Jon Ashburn8d8dad02014-12-01 14:22:40 -070074
Jon Ashburnd25a78e2015-05-15 16:40:25 -060075 std::unordered_map<void *, VkLayerDispatchTable *>::const_iterator it = tableMap1.find((void *) *ppDisp);
Jon Ashburn8d8dad02014-12-01 14:22:40 -070076 if (it == tableMap1.end())
77 {
Jon Ashburn301c5f02015-04-06 10:58:22 -060078 pTable = new VkLayerDispatchTable;
Jon Ashburnd25a78e2015-05-15 16:40:25 -060079 tableMap1[(void *) *ppDisp] = pTable;
80 initLayerTable(devw, pTable, 1);
Jon Ashburn8d8dad02014-12-01 14:22:40 -070081 return pTable;
82 } else
83 {
84 return it->second;
85 }
86}
Jon Ashburnd25a78e2015-05-15 16:40:25 -060087static VkLayerInstanceDispatchTable *getLayer1InstanceTable(const VkBaseLayerObject *instw)
Jon Ashburnd9564002015-05-07 10:27:37 -060088{
89 VkLayerInstanceDispatchTable *pTable;
Jon Ashburnd9564002015-05-07 10:27:37 -060090 assert(instw);
Jon Ashburnd25a78e2015-05-15 16:40:25 -060091 VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) instw->baseObject;
92
93 std::unordered_map<void *, VkLayerInstanceDispatchTable *>::const_iterator it = tableInstanceMap1.find((void *) *ppDisp);
Jon Ashburnd9564002015-05-07 10:27:37 -060094 if (it == tableInstanceMap1.end())
95 {
96 pTable = new VkLayerInstanceDispatchTable;
Jon Ashburnd25a78e2015-05-15 16:40:25 -060097 tableInstanceMap1[(void *) *ppDisp] = pTable;
Jon Ashburnd9564002015-05-07 10:27:37 -060098 initLayerInstanceTable(instw, pTable, 1);
99 return pTable;
100 } else
101 {
102 return it->second;
103 }
104}
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700105#ifdef __cplusplus
106extern "C" {
107#endif
108
Courtney Goeltzenleuchter142c9c22015-07-06 21:32:03 -0600109/* hook DestroyDevice to remove tableMap entry */
Jon Ashburn17f37372015-05-19 16:34:53 -0600110VK_LAYER_EXPORT VkResult VKAPI multi1DestroyDevice(VkDevice device)
111{
112 VkLayerDispatchTable *pDisp = *(VkLayerDispatchTable **) device;
Jon Ashburn5a10d212015-06-01 10:02:09 -0600113 VkResult res = device_dispatch_table1(device)->DestroyDevice(device);
Jon Ashburn17f37372015-05-19 16:34:53 -0600114 tableMap1.erase(pDisp);
115 return res;
116}
117
118/* hook DestroyInstance to remove tableInstanceMap entry */
119VK_LAYER_EXPORT VkResult VKAPI multi1DestroyInstance(VkInstance instance)
120{
121 VkLayerInstanceDispatchTable *pDisp = *(VkLayerInstanceDispatchTable **) instance;
Jon Ashburn5a10d212015-06-01 10:02:09 -0600122 VkResult res = instance_dispatch_table1(instance)->DestroyInstance(instance);
Jon Ashburn17f37372015-05-19 16:34:53 -0600123 tableInstanceMap1.erase(pDisp);
124 return res;
125}
126
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600127VK_LAYER_EXPORT VkResult VKAPI multi1CreateSampler(VkDevice device, const VkSamplerCreateInfo* pCreateInfo, VkSampler* pSampler)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700128{
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600129 VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) device;
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600130
131 printf("At start of multi1 layer vkCreateSampler()\n");
Jon Ashburn5a10d212015-06-01 10:02:09 -0600132 VkResult result = device_dispatch_table1(device)->CreateSampler(device, pCreateInfo, pSampler);
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600133 printf("Completed multi1 layer vkCreateSampler()\n");
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700134 return result;
135}
136
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600137VK_LAYER_EXPORT VkResult VKAPI multi1CreateGraphicsPipeline(VkDevice device, const VkGraphicsPipelineCreateInfo* pCreateInfo,
138 VkPipeline* pPipeline)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700139{
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600140 VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) device;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700141
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600142 printf("At start of multi1 layer vkCreateGraphicsPipeline()\n");
Jon Ashburn5a10d212015-06-01 10:02:09 -0600143 VkResult result = device_dispatch_table1(device)->CreateGraphicsPipeline(device, pCreateInfo, pPipeline);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600144 printf("Completed multi1 layer vkCreateGraphicsPipeline()\n");
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700145 return result;
146}
147
Mike Stroyan230e6252015-04-17 12:36:38 -0600148VK_LAYER_EXPORT VkResult VKAPI multi1StorePipeline(VkDevice device, VkPipeline pipeline, size_t* pDataSize, void* pData)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700149{
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600150 VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) device;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700151
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600152 printf("At start of multi1 layer vkStorePipeline()\n");
Jon Ashburn5a10d212015-06-01 10:02:09 -0600153 VkResult result = device_dispatch_table1(device)->StorePipeline(device, pipeline, pDataSize, pData);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600154 printf("Completed multi1 layer vkStorePipeline()\n");
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700155 return result;
156}
157
Jon Ashburn1245cec2015-05-18 13:20:15 -0600158VK_LAYER_EXPORT void * VKAPI multi1GetDeviceProcAddr(VkDevice device, const char* pName)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700159{
Jon Ashburn1245cec2015-05-18 13:20:15 -0600160 VkBaseLayerObject* devw = (VkBaseLayerObject *) device;
Chia-I Wue9ae3882015-01-05 09:41:27 +0800161
Jon Ashburn1245cec2015-05-18 13:20:15 -0600162 if (device == NULL)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700163 return NULL;
Chia-I Wue9ae3882015-01-05 09:41:27 +0800164
Chia-I Wue9ae3882015-01-05 09:41:27 +0800165
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600166
167 if (!strcmp("vkGetDeviceProcAddr", pName)) {
168 getLayer1Table(devw);
Jon Ashburn7cb4e0e2015-05-19 10:05:54 -0600169 return (void *) multi1GetDeviceProcAddr;
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600170 }
Jon Ashburn17f37372015-05-19 16:34:53 -0600171 if (!strcmp("vkDestroyDevice", pName))
172 return (void *) multi1DestroyDevice;
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600173 if (!strcmp("vkCreateSampler", pName))
174 return (void *) multi1CreateSampler;
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600175 if (!strcmp("vkCreateGraphicsPipeline", pName))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600176 return (void *) multi1CreateGraphicsPipeline;
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600177 if (!strcmp("vkStorePipeline", pName))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600178 return (void *) multi1StorePipeline;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700179 else {
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600180 VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) device;
Jon Ashburn5a10d212015-06-01 10:02:09 -0600181 VkLayerDispatchTable* pTable = device_dispatch_table1(device);
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600182 if (pTable->GetDeviceProcAddr == NULL)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700183 return NULL;
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600184 return pTable->GetDeviceProcAddr(device, pName);
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600185 }
186}
187
Jon Ashburnd9564002015-05-07 10:27:37 -0600188VK_LAYER_EXPORT void * VKAPI multi1GetInstanceProcAddr(VkInstance inst, const char* pName)
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600189{
190 VkBaseLayerObject* instw = (VkBaseLayerObject *) inst;
191
192 if (inst == NULL)
193 return NULL;
194
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600195
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600196
197 if (!strcmp("vkGetInstanceProcAddr", pName)) {
198 getLayer1InstanceTable(instw);
Jon Ashburn7cb4e0e2015-05-19 10:05:54 -0600199 return (void *) multi1GetInstanceProcAddr;
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600200 }
Jon Ashburn17f37372015-05-19 16:34:53 -0600201 if (!strcmp("vkDestroyInstance", pName))
202 return (void *) multi1DestroyInstance;
Tony Barbour426b9052015-06-24 16:06:58 -0600203 if (!strcmp("GetGlobalExtensionProperties", pName))
204 return (void*) vkGetGlobalExtensionProperties;
Courtney Goeltzenleuchter142c9c22015-07-06 21:32:03 -0600205 if (!strcmp("GetGlobalLayerProperties", pName))
206 return (void*) vkGetGlobalLayerProperties;
207 if (!strcmp("GetPhysicalDeviceExtensionProperties", pName))
208 return (void*) vkGetPhysicalDeviceExtensionProperties;
209 if (!strcmp("GetPhysicalDeviceLayerProperties", pName))
210 return (void*) vkGetPhysicalDeviceLayerProperties;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600211 else {
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600212 VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) inst;
Jon Ashburn5a10d212015-06-01 10:02:09 -0600213 VkLayerInstanceDispatchTable* pTable = instance_dispatch_table1(inst);
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600214 if (pTable->GetInstanceProcAddr == NULL)
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600215 return NULL;
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600216 return pTable->GetInstanceProcAddr(inst, pName);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700217 }
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700218}
219
220/******************************** Layer multi2 functions **************************/
Jon Ashburn301c5f02015-04-06 10:58:22 -0600221static std::unordered_map<void *, VkLayerDispatchTable *> tableMap2;
Jon Ashburnd9564002015-05-07 10:27:37 -0600222static std::unordered_map<void *, VkLayerInstanceDispatchTable *> tableInstanceMap2;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700223static bool layer2_first_activated = false;
224
Jon Ashburn5a10d212015-06-01 10:02:09 -0600225// Map lookup must be thread safe
226static inline VkLayerDispatchTable *device_dispatch_table2(VkObject object)
227{
228 VkLayerDispatchTable *pDisp = *(VkLayerDispatchTable **) object;
229 std::unordered_map<void *, VkLayerDispatchTable *>::const_iterator it = tableMap2.find((void *) pDisp);
230 assert(it != tableMap2.end() && "Not able to find device dispatch entry");
231 return it->second;
232}
233
234static inline VkLayerInstanceDispatchTable *instance_dispatch_table2(VkObject object)
235{
236 VkLayerInstanceDispatchTable *pDisp = *(VkLayerInstanceDispatchTable **) object;
237 std::unordered_map<void *, VkLayerInstanceDispatchTable *>::const_iterator it = tableInstanceMap2.find((void *) pDisp);
238 assert(it != tableInstanceMap2.end() && "Not able to find instance dispatch entry");
239 return it->second;
240}
241
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600242static VkLayerInstanceDispatchTable *getLayer2InstanceTable(const VkBaseLayerObject *instw)
Jon Ashburnd9564002015-05-07 10:27:37 -0600243{
244 VkLayerInstanceDispatchTable *pTable;
Jon Ashburnd9564002015-05-07 10:27:37 -0600245 assert(instw);
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600246 VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) instw->baseObject;
247
248 std::unordered_map<void *, VkLayerInstanceDispatchTable *>::const_iterator it = tableInstanceMap2.find((void *) *ppDisp);
Jon Ashburnd9564002015-05-07 10:27:37 -0600249 if (it == tableInstanceMap2.end())
250 {
251 pTable = new VkLayerInstanceDispatchTable;
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600252 tableInstanceMap2[(void *) *ppDisp] = pTable;
Jon Ashburnd9564002015-05-07 10:27:37 -0600253 initLayerInstanceTable(instw, pTable, 2);
254 return pTable;
255 } else
256 {
257 return it->second;
258 }
259}
260
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600261static VkLayerDispatchTable *getLayer2Table(const VkBaseLayerObject *devw)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700262{
Jon Ashburn301c5f02015-04-06 10:58:22 -0600263 VkLayerDispatchTable *pTable;
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600264 assert(devw);
265 VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) devw->baseObject;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700266
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600267 std::unordered_map<void *, VkLayerDispatchTable *>::const_iterator it = tableMap2.find((void *) *ppDisp);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700268 if (it == tableMap2.end())
269 {
Jon Ashburn301c5f02015-04-06 10:58:22 -0600270 pTable = new VkLayerDispatchTable;
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600271 tableMap2[(void *) *ppDisp] = pTable;
272 initLayerTable(devw, pTable, 2);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700273 return pTable;
274 } else
275 {
276 return it->second;
277 }
278}
279
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600280VK_LAYER_EXPORT VkResult VKAPI multi2EnumeratePhysicalDevices(
281 VkInstance instance,
282 uint32_t* pPhysicalDeviceCount,
283 VkPhysicalDevice* pPhysicalDevices)
284{
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600285 VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) instance;
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600286
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600287 printf("At start of wrapped multi2 vkEnumeratePhysicalDevices()\n");
Jon Ashburn5a10d212015-06-01 10:02:09 -0600288 VkResult result = instance_dispatch_table2(instance)->EnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600289 printf("Completed multi2 layer vkEnumeratePhysicalDevices()\n");
290 return result;
291}
292
Jon Ashburn17f37372015-05-19 16:34:53 -0600293/* hook DextroyDevice to remove tableMap entry */
294VK_LAYER_EXPORT VkResult VKAPI multi2DestroyDevice(VkDevice device)
295{
296 VkLayerDispatchTable *pDisp = *(VkLayerDispatchTable **) device;
Jon Ashburn5a10d212015-06-01 10:02:09 -0600297 VkResult res = device_dispatch_table2(device)->DestroyDevice(device);
Jon Ashburn17f37372015-05-19 16:34:53 -0600298 tableMap2.erase(pDisp);
299 return res;
300}
301
302/* hook DestroyInstance to remove tableInstanceMap entry */
303VK_LAYER_EXPORT VkResult VKAPI multi2DestroyInstance(VkInstance instance)
304{
305 VkLayerInstanceDispatchTable *pDisp = *(VkLayerInstanceDispatchTable **) instance;
Jon Ashburn5a10d212015-06-01 10:02:09 -0600306 VkResult res = instance_dispatch_table2(instance)->DestroyInstance(instance);
Jon Ashburn17f37372015-05-19 16:34:53 -0600307 tableInstanceMap2.erase(pDisp);
308 return res;
309}
310
Tony Barbour8205d902015-04-16 15:59:00 -0600311VK_LAYER_EXPORT VkResult VKAPI multi2CreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo* pCreateInfo,
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600312 VkDevice* pDevice)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700313{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600314 printf("At start of multi2 vkCreateDevice()\n");
Courtney Goeltzenleuchterbe637992015-06-25 18:01:43 -0600315 VkResult result = device_dispatch_table2(*pDevice)->CreateDevice(gpu, pCreateInfo, pDevice);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600316 printf("Completed multi2 layer vkCreateDevice()\n");
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700317 return result;
318}
319
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600320VK_LAYER_EXPORT VkResult VKAPI multi2CreateCommandBuffer(VkDevice device, const VkCmdBufferCreateInfo* pCreateInfo,
321 VkCmdBuffer* pCmdBuffer)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700322{
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600323 VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) device;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700324
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600325 printf("At start of multi2 layer vkCreateCommandBuffer()\n");
Jon Ashburn5a10d212015-06-01 10:02:09 -0600326 VkResult result = device_dispatch_table2(device)->CreateCommandBuffer(device, pCreateInfo, pCmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600327 printf("Completed multi2 layer vkCreateCommandBuffer()\n");
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700328 return result;
329}
330
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600331VK_LAYER_EXPORT VkResult VKAPI multi2BeginCommandBuffer(VkCmdBuffer cmdBuffer, const VkCmdBufferBeginInfo* pBeginInfo)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700332{
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600333 VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) cmdBuffer;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700334
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600335 printf("At start of multi2 layer vkBeginCommandBuffer()\n");
Jon Ashburn5a10d212015-06-01 10:02:09 -0600336 VkResult result = device_dispatch_table2(cmdBuffer)->BeginCommandBuffer(cmdBuffer, pBeginInfo);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600337 printf("Completed multi2 layer vkBeginCommandBuffer()\n");
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700338 return result;
339
340}
341
Jon Ashburn1245cec2015-05-18 13:20:15 -0600342VK_LAYER_EXPORT void * VKAPI multi2GetDeviceProcAddr(VkDevice device, const char* pName)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700343{
Jon Ashburn1245cec2015-05-18 13:20:15 -0600344 VkBaseLayerObject* devw = (VkBaseLayerObject *) device;
Chia-I Wue9ae3882015-01-05 09:41:27 +0800345
Jon Ashburn1245cec2015-05-18 13:20:15 -0600346 if (device == NULL)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700347 return NULL;
Chia-I Wue9ae3882015-01-05 09:41:27 +0800348
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600349 if (!strcmp("vkGetDeviceProcAddr", pName)) {
350 getLayer2Table(devw);
Jon Ashburn7cb4e0e2015-05-19 10:05:54 -0600351 return (void *) multi2GetDeviceProcAddr;
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600352 }
Courtney Goeltzenleuchterbe637992015-06-25 18:01:43 -0600353 if (!strcmp("vkCreateDevice", pName))
354 return (void *) multi2CreateDevice;
Jon Ashburn17f37372015-05-19 16:34:53 -0600355 if (!strcmp("vkDestroyDevice", pName))
356 return (void *) multi2DestroyDevice;
Jon Ashburn1245cec2015-05-18 13:20:15 -0600357 if (!strcmp("vkCreateCommandBuffer", pName))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600358 return (void *) multi2CreateCommandBuffer;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600359 else if (!strcmp("vkBeginCommandBuffer", pName))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600360 return (void *) multi2BeginCommandBuffer;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700361 else {
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600362 VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) device;
Jon Ashburn5a10d212015-06-01 10:02:09 -0600363 VkLayerDispatchTable* pTable = device_dispatch_table2(device);
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600364 if (pTable->GetDeviceProcAddr == NULL)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700365 return NULL;
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600366 return pTable->GetDeviceProcAddr(device, pName);
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600367 }
368}
369
Jon Ashburnd9564002015-05-07 10:27:37 -0600370VK_LAYER_EXPORT void * VKAPI multi2GetInstanceProcAddr(VkInstance inst, const char* pName)
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600371{
372 VkBaseLayerObject* instw = (VkBaseLayerObject *) inst;
373
374 if (inst == NULL)
375 return NULL;
376
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600377 if (!strcmp("vkGetInstanceProcAddr", pName)) {
378 getLayer2InstanceTable(instw);
Jon Ashburn7cb4e0e2015-05-19 10:05:54 -0600379 return (void *) multi2GetInstanceProcAddr;
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600380 }
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600381 if (!strcmp("vkEnumeratePhysicalDevices", pName))
382 return (void *) multi2EnumeratePhysicalDevices;
Jon Ashburn17f37372015-05-19 16:34:53 -0600383 if (!strcmp("vkDestroyInstance", pName))
384 return (void *) multi2DestroyInstance;
Courtney Goeltzenleuchter142c9c22015-07-06 21:32:03 -0600385 if (!strcmp("GetGlobalExtensionProperties", pName))
Tony Barbour426b9052015-06-24 16:06:58 -0600386 return (void*) vkGetGlobalExtensionProperties;
Courtney Goeltzenleuchter142c9c22015-07-06 21:32:03 -0600387 if (!strcmp("GetGlobalLayerProperties", pName))
388 return (void*) vkGetGlobalLayerProperties;
389 if (!strcmp("GetPhysicalDeviceExtensionProperties", pName))
390 return (void*) vkGetPhysicalDeviceExtensionProperties;
391 if (!strcmp("GetPhysicalDeviceLayerProperties", pName))
392 return (void*) vkGetPhysicalDeviceLayerProperties;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600393 else {
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600394 VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) inst;
Jon Ashburn5a10d212015-06-01 10:02:09 -0600395 VkLayerInstanceDispatchTable* pTable = instance_dispatch_table2(inst);
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600396 if (pTable->GetInstanceProcAddr == NULL)
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600397 return NULL;
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600398 return pTable->GetInstanceProcAddr(inst, pName);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700399 }
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700400}
401
402/********************************* Common functions ********************************/
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700403
Jon Ashburneb2728b2015-04-10 14:33:07 -0600404struct extProps {
405 uint32_t version;
406 const char * const name;
407};
408
Courtney Goeltzenleuchter142c9c22015-07-06 21:32:03 -0600409VK_LAYER_EXPORT VkResult VKAPI vkGetGlobalExtensionProperties(
410 const char *pLayerName,
411 uint32_t *pCount,
412 VkExtensionProperties* pProperties)
413{
414 /* multi does not have any global extensions */
415 return util_GetExtensionProperties(0, NULL, pCount, pProperties);
416}
417
418VK_LAYER_EXPORT VkResult VKAPI vkGetGlobalLayerProperties(
419 uint32_t *pCount,
420 VkLayerProperties* pProperties)
421{
422 /* multi does not have any global layers */
423 return util_GetLayerProperties(0, NULL, pCount, pProperties);
424}
425
426#define MULTI_LAYER_ARRAY_SIZE 1
427static const VkLayerProperties multi_device_layers[MULTI_LAYER_ARRAY_SIZE] = {
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600428 {
Courtney Goeltzenleuchter142c9c22015-07-06 21:32:03 -0600429 "Multi1",
430 VK_API_VERSION,
431 VK_MAKE_VERSION(0, 1, 0),
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600432 "Sample layer: multi",
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600433 }
Jon Ashburneb2728b2015-04-10 14:33:07 -0600434};
435
Courtney Goeltzenleuchter142c9c22015-07-06 21:32:03 -0600436VK_LAYER_EXPORT VkResult VKAPI vkGetPhysicalDeviceExtensionProperties(
437 VkPhysicalDevice physicalDevice,
438 const char* pLayerName,
439 uint32_t* pCount,
440 VkExtensionProperties* pProperties)
Tony Barbour426b9052015-06-24 16:06:58 -0600441{
Courtney Goeltzenleuchter142c9c22015-07-06 21:32:03 -0600442 /* Multi does not have any physical device extensions */
443 return util_GetExtensionProperties(0, NULL, pCount, pProperties);
Tony Barbour426b9052015-06-24 16:06:58 -0600444}
445
Courtney Goeltzenleuchter142c9c22015-07-06 21:32:03 -0600446VK_LAYER_EXPORT VkResult VKAPI vkGetPhysicalDeviceLayerProperties(
447 VkPhysicalDevice physicalDevice,
448 uint32_t* pCount,
449 VkLayerProperties* pProperties)
Jon Ashburneb2728b2015-04-10 14:33:07 -0600450{
Courtney Goeltzenleuchter142c9c22015-07-06 21:32:03 -0600451 return util_GetLayerProperties(MULTI_LAYER_ARRAY_SIZE, multi_device_layers,
452 pCount, pProperties);
Jon Ashburneb2728b2015-04-10 14:33:07 -0600453}
454
Jon Ashburn1245cec2015-05-18 13:20:15 -0600455VK_LAYER_EXPORT void * VKAPI vkGetDeviceProcAddr(VkDevice device, const char* pName)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700456{
Jon Ashburn1245cec2015-05-18 13:20:15 -0600457 // to find each layers GPA routine Loader will search via "<layerName>GetDeviceProcAddr"
458 if (!strcmp("multi1GetDeviceProcAddr", pName))
459 return (void *) multi1GetDeviceProcAddr;
460 else if (!strcmp("multi2GetDeviceProcAddr", pName))
461 return (void *) multi2GetDeviceProcAddr;
462 else if (!strcmp("vkGetDeviceProcAddr", pName))
463 return (void *) vkGetDeviceProcAddr;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700464
465 // use first layer activated as GPA dispatch table activation happens in order
466 else if (layer1_first_activated)
Jon Ashburn1245cec2015-05-18 13:20:15 -0600467 return multi1GetDeviceProcAddr(device, pName);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700468 else if (layer2_first_activated)
Jon Ashburn1245cec2015-05-18 13:20:15 -0600469 return multi2GetDeviceProcAddr(device, pName);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700470 else
471 return NULL;
472
473}
474
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600475VK_LAYER_EXPORT void * VKAPI vkGetInstanceProcAddr(VkInstance inst, const char* pName)
476{
Jon Ashburn1245cec2015-05-18 13:20:15 -0600477 // to find each layers GPA routine Loader will search via "<layerName>GetInstanceProcAddr"
478 if (!strcmp("multi1GetInstanceProcAddr", pName))
Jon Ashburnd9564002015-05-07 10:27:37 -0600479 return (void *) multi1GetInstanceProcAddr;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600480 else if (!strcmp("multi2GetInstanceProcAddr", pName))
Jon Ashburnd9564002015-05-07 10:27:37 -0600481 return (void *) multi2GetInstanceProcAddr;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600482 else if (!strcmp("vkGetInstanceProcAddr", pName))
Jon Ashburn1245cec2015-05-18 13:20:15 -0600483 return (void *) vkGetInstanceProcAddr;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600484
485 // use first layer activated as GPA dispatch table activation happens in order
486 else if (layer1_first_activated)
Jon Ashburnd9564002015-05-07 10:27:37 -0600487 return multi1GetInstanceProcAddr(inst, pName);
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600488 else if (layer2_first_activated)
Jon Ashburnd9564002015-05-07 10:27:37 -0600489 return multi2GetInstanceProcAddr(inst, pName);
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600490 else
491 return NULL;
492
493}
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700494#ifdef __cplusplus
495} //extern "C"
496#endif
497
Jon Ashburn1245cec2015-05-18 13:20:15 -0600498static void initLayerTable(const VkBaseLayerObject *devw, VkLayerDispatchTable *pTable, const unsigned int layerNum)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700499{
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700500 if (layerNum == 2 && layer1_first_activated == false)
501 layer2_first_activated = true;
502 if (layerNum == 1 && layer2_first_activated == false)
503 layer1_first_activated = true;
504
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600505 layer_initialize_dispatch_table(pTable, devw);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700506}
Jon Ashburnd9564002015-05-07 10:27:37 -0600507
508static void initLayerInstanceTable(const VkBaseLayerObject *instw, VkLayerInstanceDispatchTable *pTable, const unsigned int layerNum)
509{
510 if (layerNum == 2 && layer1_first_activated == false)
511 layer2_first_activated = true;
512 if (layerNum == 1 && layer2_first_activated == false)
513 layer1_first_activated = true;
514
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600515 layer_init_instance_dispatch_table(pTable, instw);
Jon Ashburnd9564002015-05-07 10:27:37 -0600516}