blob: 97326545639af7b4b01e0b8abb206a0058020c48 [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 Ashburn301c5f02015-04-06 10:58:22 -060037static void initLayerTable(const VkBaseLayerObject *gpuw, 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 Ashburn8d8dad02014-12-01 14:22:40 -070039
40/******************************** Layer multi1 functions **************************/
Jon Ashburn301c5f02015-04-06 10:58:22 -060041static std::unordered_map<void *, VkLayerDispatchTable *> tableMap1;
Jon Ashburnd9564002015-05-07 10:27:37 -060042static std::unordered_map<void *, VkLayerInstanceDispatchTable *> tableInstanceMap1;
Jon Ashburn8d8dad02014-12-01 14:22:40 -070043static bool layer1_first_activated = false;
44
Jon Ashburn301c5f02015-04-06 10:58:22 -060045static VkLayerDispatchTable * getLayer1Table(const VkBaseLayerObject *gpuw)
Jon Ashburn8d8dad02014-12-01 14:22:40 -070046{
Jon Ashburn301c5f02015-04-06 10:58:22 -060047 VkLayerDispatchTable *pTable;
Jon Ashburn8d8dad02014-12-01 14:22:40 -070048
49 assert(gpuw);
Jon Ashburn630e44f2015-04-08 21:33:34 -060050 std::unordered_map<void *, VkLayerDispatchTable *>::const_iterator it = tableMap1.find((void *) gpuw->baseObject);
Jon Ashburn8d8dad02014-12-01 14:22:40 -070051 if (it == tableMap1.end())
52 {
Jon Ashburn301c5f02015-04-06 10:58:22 -060053 pTable = new VkLayerDispatchTable;
Jon Ashburn630e44f2015-04-08 21:33:34 -060054 tableMap1[(void *) gpuw->baseObject] = pTable;
Jon Ashburn8d8dad02014-12-01 14:22:40 -070055 initLayerTable(gpuw, pTable, 1);
56 return pTable;
57 } else
58 {
59 return it->second;
60 }
61}
Jon Ashburnd9564002015-05-07 10:27:37 -060062static VkLayerInstanceDispatchTable * getLayer1InstanceTable(const VkBaseLayerObject *instw)
63{
64 VkLayerInstanceDispatchTable *pTable;
65
66 assert(instw);
67 std::unordered_map<void *, VkLayerInstanceDispatchTable *>::const_iterator it = tableInstanceMap1.find((void *) instw->baseObject);
68 if (it == tableInstanceMap1.end())
69 {
70 pTable = new VkLayerInstanceDispatchTable;
71 tableInstanceMap1[(void *) instw->baseObject] = pTable;
72 initLayerInstanceTable(instw, pTable, 1);
73 return pTable;
74 } else
75 {
76 return it->second;
77 }
78}
Jon Ashburn8d8dad02014-12-01 14:22:40 -070079#ifdef __cplusplus
80extern "C" {
81#endif
82
83
Tony Barbour8205d902015-04-16 15:59:00 -060084VK_LAYER_EXPORT VkResult VKAPI multi1CreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo* pCreateInfo,
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -060085 VkDevice* pDevice)
Jon Ashburn8d8dad02014-12-01 14:22:40 -070086{
Jon Ashburn630e44f2015-04-08 21:33:34 -060087 VkLayerDispatchTable* pTable = tableMap1[gpu];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060088 printf("At start of multi1 layer vkCreateDevice()\n");
Jon Ashburn630e44f2015-04-08 21:33:34 -060089 VkResult result = pTable->CreateDevice(gpu, pCreateInfo, pDevice);
Jon Ashburn8d8dad02014-12-01 14:22:40 -070090 // create a mapping for the device object into the dispatch table
91 tableMap1.emplace(*pDevice, pTable);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060092 printf("Completed multi1 layer vkCreateDevice()\n");
Jon Ashburn8d8dad02014-12-01 14:22:40 -070093 return result;
94}
95
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -060096VK_LAYER_EXPORT VkResult VKAPI multi1CreateGraphicsPipeline(VkDevice device, const VkGraphicsPipelineCreateInfo* pCreateInfo,
97 VkPipeline* pPipeline)
Jon Ashburn8d8dad02014-12-01 14:22:40 -070098{
Jon Ashburn301c5f02015-04-06 10:58:22 -060099 VkLayerDispatchTable* pTable = tableMap1[device];
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700100
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600101 printf("At start of multi1 layer vkCreateGraphicsPipeline()\n");
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600102 VkResult result = pTable->CreateGraphicsPipeline(device, pCreateInfo, pPipeline);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700103 // create a mapping for the pipeline object into the dispatch table
104 tableMap1.emplace(*pPipeline, pTable);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600105 printf("Completed multi1 layer vkCreateGraphicsPipeline()\n");
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700106 return result;
107}
108
Mike Stroyan230e6252015-04-17 12:36:38 -0600109VK_LAYER_EXPORT VkResult VKAPI multi1StorePipeline(VkDevice device, VkPipeline pipeline, size_t* pDataSize, void* pData)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700110{
Jon Ashburn301c5f02015-04-06 10:58:22 -0600111 VkLayerDispatchTable* pTable = tableMap1[pipeline];
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700112
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600113 printf("At start of multi1 layer vkStorePipeline()\n");
Mike Stroyan230e6252015-04-17 12:36:38 -0600114 VkResult result = pTable->StorePipeline(device, pipeline, pDataSize, pData);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600115 printf("Completed multi1 layer vkStorePipeline()\n");
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700116 return result;
117}
118
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -0600119VK_LAYER_EXPORT VkResult VKAPI multi1EnumerateLayers(VkPhysicalDevice gpu, size_t maxStringSize,
120 size_t* pLayerCount, char* const* pOutLayers,
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600121 void* pReserved)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700122{
123 if (gpu == NULL)
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -0600124 return vkEnumerateLayers(gpu, maxStringSize, pLayerCount, pOutLayers, pReserved);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700125
Jon Ashburn630e44f2015-04-08 21:33:34 -0600126 VkLayerDispatchTable* pTable = tableMap1[gpu];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600127 printf("At start of multi1 layer vkEnumerateLayers()\n");
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -0600128 VkResult result = pTable->EnumerateLayers(gpu, maxStringSize, pLayerCount, pOutLayers, pReserved);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600129 printf("Completed multi1 layer vkEnumerateLayers()\n");
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700130 return result;
131}
132
Tony Barbour8205d902015-04-16 15:59:00 -0600133VK_LAYER_EXPORT void * VKAPI multi1GetProcAddr(VkPhysicalDevice gpu, const char* pName)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700134{
Jon Ashburn301c5f02015-04-06 10:58:22 -0600135 VkBaseLayerObject* gpuw = (VkBaseLayerObject *) gpu;
Chia-I Wue9ae3882015-01-05 09:41:27 +0800136
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700137 if (gpu == NULL)
138 return NULL;
Chia-I Wue9ae3882015-01-05 09:41:27 +0800139
140 getLayer1Table(gpuw);
141
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600142 if (!strcmp("vkCreateDevice", pName))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600143 return (void *) multi1CreateDevice;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600144 else if (!strcmp("vkEnumerateLayers", pName))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600145 return (void *) multi1EnumerateLayers;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600146 else if (!strcmp("GetGlobalExtensionInfo", pName))
147 return (void*) vkGetGlobalExtensionInfo;
148 else if (!strcmp("vkCreateGraphicsPipeline", pName))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600149 return (void *) multi1CreateGraphicsPipeline;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600150 else if (!strcmp("vkStorePipeline", pName))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600151 return (void *) multi1StorePipeline;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700152 else {
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700153 if (gpuw->pGPA == NULL)
154 return NULL;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600155 return gpuw->pGPA((VkObject) gpuw->nextObject, pName);
156 }
157}
158
Jon Ashburnd9564002015-05-07 10:27:37 -0600159VK_LAYER_EXPORT void * VKAPI multi1GetInstanceProcAddr(VkInstance inst, const char* pName)
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600160{
161 VkBaseLayerObject* instw = (VkBaseLayerObject *) inst;
162
163 if (inst == NULL)
164 return NULL;
165
Jon Ashburnd9564002015-05-07 10:27:37 -0600166 getLayer1InstanceTable(instw);
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600167
168 if (!strcmp("vkCreateDevice", pName))
169 return (void *) multi1CreateDevice;
170 else if (!strcmp("vkEnumerateLayers", pName))
171 return (void *) multi1EnumerateLayers;
172 else if (!strcmp("GetGlobalExtensionInfo", pName))
173 return (void*) vkGetGlobalExtensionInfo;
174 else {
175 if (instw->pGPA == NULL)
176 return NULL;
177 return instw->pGPA((VkObject) instw->nextObject, pName);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700178 }
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700179}
180
181/******************************** Layer multi2 functions **************************/
Jon Ashburn301c5f02015-04-06 10:58:22 -0600182static std::unordered_map<void *, VkLayerDispatchTable *> tableMap2;
Jon Ashburnd9564002015-05-07 10:27:37 -0600183static std::unordered_map<void *, VkLayerInstanceDispatchTable *> tableInstanceMap2;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700184static bool layer2_first_activated = false;
185
Jon Ashburnd9564002015-05-07 10:27:37 -0600186static VkLayerInstanceDispatchTable * getLayer2InstanceTable(const VkBaseLayerObject *instw)
187{
188 VkLayerInstanceDispatchTable *pTable;
189
190 assert(instw);
191 std::unordered_map<void *, VkLayerInstanceDispatchTable *>::const_iterator it = tableInstanceMap2.find((void *) instw->baseObject);
192 if (it == tableInstanceMap2.end())
193 {
194 pTable = new VkLayerInstanceDispatchTable;
195 tableInstanceMap2[(void *) instw->baseObject] = pTable;
196 initLayerInstanceTable(instw, pTable, 2);
197 return pTable;
198 } else
199 {
200 return it->second;
201 }
202}
203
Jon Ashburn301c5f02015-04-06 10:58:22 -0600204static VkLayerDispatchTable * getLayer2Table(const VkBaseLayerObject *gpuw)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700205{
Jon Ashburn301c5f02015-04-06 10:58:22 -0600206 VkLayerDispatchTable *pTable;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700207
208 assert(gpuw);
Jon Ashburn630e44f2015-04-08 21:33:34 -0600209 std::unordered_map<void *, VkLayerDispatchTable *>::const_iterator it = tableMap2.find((void *) gpuw->baseObject);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700210 if (it == tableMap2.end())
211 {
Jon Ashburn301c5f02015-04-06 10:58:22 -0600212 pTable = new VkLayerDispatchTable;
Jon Ashburn630e44f2015-04-08 21:33:34 -0600213 tableMap2[(void *) gpuw->baseObject] = pTable;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700214 initLayerTable(gpuw, pTable, 2);
215 return pTable;
216 } else
217 {
218 return it->second;
219 }
220}
221
Tony Barbour8205d902015-04-16 15:59:00 -0600222VK_LAYER_EXPORT VkResult VKAPI multi2CreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo* pCreateInfo,
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600223 VkDevice* pDevice)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700224{
Jon Ashburn630e44f2015-04-08 21:33:34 -0600225 VkLayerDispatchTable* pTable = tableMap2[gpu];
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700226
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600227 printf("At start of multi2 vkCreateDevice()\n");
Jon Ashburn630e44f2015-04-08 21:33:34 -0600228 VkResult result = pTable->CreateDevice(gpu, pCreateInfo, pDevice);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700229 // create a mapping for the device object into the dispatch table for layer2
230 tableMap2.emplace(*pDevice, pTable);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600231 printf("Completed multi2 layer vkCreateDevice()\n");
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700232 return result;
233}
234
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600235VK_LAYER_EXPORT VkResult VKAPI multi2CreateCommandBuffer(VkDevice device, const VkCmdBufferCreateInfo* pCreateInfo,
236 VkCmdBuffer* pCmdBuffer)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700237{
Jon Ashburn301c5f02015-04-06 10:58:22 -0600238 VkLayerDispatchTable* pTable = tableMap2[device];
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700239
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600240 printf("At start of multi2 layer vkCreateCommandBuffer()\n");
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600241 VkResult result = pTable->CreateCommandBuffer(device, pCreateInfo, pCmdBuffer);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700242 // create a mapping for CmdBuffer object into the dispatch table for layer 2
243 tableMap2.emplace(*pCmdBuffer, pTable);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600244 printf("Completed multi2 layer vkCreateCommandBuffer()\n");
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700245 return result;
246}
247
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600248VK_LAYER_EXPORT VkResult VKAPI multi2BeginCommandBuffer(VkCmdBuffer cmdBuffer, const VkCmdBufferBeginInfo* pBeginInfo)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700249{
Jon Ashburn301c5f02015-04-06 10:58:22 -0600250 VkLayerDispatchTable* pTable = tableMap2[cmdBuffer];
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700251
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600252 printf("At start of multi2 layer vkBeginCommandBuffer()\n");
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600253 VkResult result = pTable->BeginCommandBuffer(cmdBuffer, pBeginInfo);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600254 printf("Completed multi2 layer vkBeginCommandBuffer()\n");
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700255 return result;
256
257}
258
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -0600259VK_LAYER_EXPORT VkResult VKAPI multi2EnumerateLayers(VkPhysicalDevice gpu, size_t maxStringSize,
260 size_t* pLayerCount, char* const* pOutLayers,
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600261 void* pReserved)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700262{
263 if (gpu == NULL)
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -0600264 return vkEnumerateLayers(gpu, maxStringSize, pLayerCount, pOutLayers, pReserved);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700265
Jon Ashburn630e44f2015-04-08 21:33:34 -0600266 VkLayerDispatchTable* pTable = tableMap2[gpu];
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700267
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600268 printf("At start of multi2 layer vkEnumerateLayers()\n");
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -0600269 VkResult result = pTable->EnumerateLayers(gpu, maxStringSize, pLayerCount, pOutLayers, pReserved);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600270 printf("Completed multi2 layer vkEnumerateLayers()\n");
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700271 return result;
272}
273
Tony Barbour8205d902015-04-16 15:59:00 -0600274VK_LAYER_EXPORT void * VKAPI multi2GetProcAddr(VkPhysicalDevice gpu, const char* pName)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700275{
Jon Ashburn301c5f02015-04-06 10:58:22 -0600276 VkBaseLayerObject* gpuw = (VkBaseLayerObject *) gpu;
Chia-I Wue9ae3882015-01-05 09:41:27 +0800277
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700278 if (gpu == NULL)
279 return NULL;
Chia-I Wue9ae3882015-01-05 09:41:27 +0800280
281 getLayer2Table(gpuw);
282
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600283 if (!strcmp("vkCreateDevice", pName))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600284 return (void *) multi2CreateDevice;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600285 else if (!strcmp("vkEnumerateLayers", pName))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600286 return (void *) multi2EnumerateLayers;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600287 else if (!strcmp("GetGlobalExtensionInfo", pName))
288 return (void*) vkGetGlobalExtensionInfo;
289 else if (!strcmp("vkCreateCommandBuffer", pName))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600290 return (void *) multi2CreateCommandBuffer;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600291 else if (!strcmp("vkBeginCommandBuffer", pName))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600292 return (void *) multi2BeginCommandBuffer;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700293 else {
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700294 if (gpuw->pGPA == NULL)
295 return NULL;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600296 return gpuw->pGPA((VkObject) gpuw->nextObject, pName);
297 }
298}
299
Jon Ashburnd9564002015-05-07 10:27:37 -0600300VK_LAYER_EXPORT void * VKAPI multi2GetInstanceProcAddr(VkInstance inst, const char* pName)
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600301{
302 VkBaseLayerObject* instw = (VkBaseLayerObject *) inst;
303
304 if (inst == NULL)
305 return NULL;
306
Jon Ashburnd9564002015-05-07 10:27:37 -0600307 getLayer2InstanceTable(instw);
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600308
309 if (!strcmp("vkCreateDevice", pName))
310 return (void *) multi2CreateDevice;
311 else if (!strcmp("vkEnumerateLayers", pName))
312 return (void *) multi2EnumerateLayers;
313 else if (!strcmp("GetGlobalExtensionInfo", pName))
314 return (void*) vkGetGlobalExtensionInfo;
315 else {
316 if (instw->pGPA == NULL)
317 return NULL;
318 return instw->pGPA((VkObject) instw->nextObject, pName);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700319 }
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700320}
321
322/********************************* Common functions ********************************/
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -0600323VK_LAYER_EXPORT VkResult VKAPI vkEnumerateLayers(VkPhysicalDevice gpu, size_t maxStringSize,
324 size_t* pLayerCount, char* const* pOutLayers,
325 void* pReserved)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700326{
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -0600327 if (pLayerCount == NULL || pOutLayers == NULL || pOutLayers[0] == NULL || pOutLayers[1] == NULL || pReserved == NULL)
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600328 return VK_ERROR_INVALID_POINTER;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700329
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -0600330 if (*pLayerCount < 2)
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600331 return VK_ERROR_INITIALIZATION_FAILED;
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -0600332 *pLayerCount = 2;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700333 strncpy((char *) pOutLayers[0], "multi1", maxStringSize);
334 strncpy((char *) pOutLayers[1], "multi2", maxStringSize);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600335 return VK_SUCCESS;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700336}
337
Jon Ashburneb2728b2015-04-10 14:33:07 -0600338struct extProps {
339 uint32_t version;
340 const char * const name;
341};
342
343#define MULTI_LAYER_EXT_ARRAY_SIZE 2
344static const struct extProps multiExts[MULTI_LAYER_EXT_ARRAY_SIZE] = {
345 // TODO what is the version?
346 0x10, "multi1",
347 0x10, "multi2",
348};
349
350VK_LAYER_EXPORT VkResult VKAPI vkGetGlobalExtensionInfo(
351 VkExtensionInfoType infoType,
352 uint32_t extensionIndex,
353 size_t* pDataSize,
354 void* pData)
355{
Jon Ashburneb2728b2015-04-10 14:33:07 -0600356 /* This entrypoint is NOT going to init it's own dispatch table since loader calls here early */
357 VkExtensionProperties *ext_props;
358 uint32_t *count;
359
360 if (pDataSize == NULL)
361 return VK_ERROR_INVALID_POINTER;
362
363 switch (infoType) {
364 case VK_EXTENSION_INFO_TYPE_COUNT:
365 *pDataSize = sizeof(uint32_t);
366 if (pData == NULL)
367 return VK_SUCCESS;
368 count = (uint32_t *) pData;
369 *count = MULTI_LAYER_EXT_ARRAY_SIZE;
370 break;
371 case VK_EXTENSION_INFO_TYPE_PROPERTIES:
372 *pDataSize = sizeof(VkExtensionProperties);
373 if (pData == NULL)
374 return VK_SUCCESS;
375 if (extensionIndex >= MULTI_LAYER_EXT_ARRAY_SIZE)
376 return VK_ERROR_INVALID_VALUE;
377 ext_props = (VkExtensionProperties *) pData;
378 ext_props->version = multiExts[extensionIndex].version;
379 strncpy(ext_props->extName, multiExts[extensionIndex].name,
380 VK_MAX_EXTENSION_NAME);
381 ext_props->extName[VK_MAX_EXTENSION_NAME - 1] = '\0';
382 break;
383 default:
384 return VK_ERROR_INVALID_VALUE;
385 };
386
387 return VK_SUCCESS;
388}
389
Tony Barbour8205d902015-04-16 15:59:00 -0600390VK_LAYER_EXPORT void * VKAPI vkGetProcAddr(VkPhysicalDevice gpu, const char* pName)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700391{
392 // to find each layers GPA routine Loader will search via "<layerName>GetProcAddr"
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600393 if (!strcmp("multi1GetProcAddr", pName))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600394 return (void *) multi1GetProcAddr;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600395 else if (!strcmp("multi2GetProcAddr", pName))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600396 return (void *) multi2GetProcAddr;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600397 else if (!strcmp("vkGetProcAddr", pName))
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600398 return (void *) vkGetProcAddr;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700399
400 // use first layer activated as GPA dispatch table activation happens in order
401 else if (layer1_first_activated)
402 return multi1GetProcAddr(gpu, pName);
403 else if (layer2_first_activated)
404 return multi2GetProcAddr(gpu, pName);
405 else
406 return NULL;
407
408}
409
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600410VK_LAYER_EXPORT void * VKAPI vkGetInstanceProcAddr(VkInstance inst, const char* pName)
411{
412 // to find each layers GPA routine Loader will search via "<layerName>GetProcAddr"
413 if (!strcmp("multi1GetProcAddr", pName))
414 return (void *) multi1GetProcAddr;
415 else if (!strcmp("multi2GetProcAddr", pName))
416 return (void *) multi2GetProcAddr;
417 else if (!strcmp("vkGetProcAddr", pName))
418 return (void *) vkGetProcAddr;
419 else if (!strcmp("multi1GetInstanceProcAddr", pName))
Jon Ashburnd9564002015-05-07 10:27:37 -0600420 return (void *) multi1GetInstanceProcAddr;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600421 else if (!strcmp("multi2GetInstanceProcAddr", pName))
Jon Ashburnd9564002015-05-07 10:27:37 -0600422 return (void *) multi2GetInstanceProcAddr;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600423 else if (!strcmp("vkGetInstanceProcAddr", pName))
424 return (void *) vkGetProcAddr;
425
426 // use first layer activated as GPA dispatch table activation happens in order
427 else if (layer1_first_activated)
Jon Ashburnd9564002015-05-07 10:27:37 -0600428 return multi1GetInstanceProcAddr(inst, pName);
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600429 else if (layer2_first_activated)
Jon Ashburnd9564002015-05-07 10:27:37 -0600430 return multi2GetInstanceProcAddr(inst, pName);
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600431 else
432 return NULL;
433
434}
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700435#ifdef __cplusplus
436} //extern "C"
437#endif
438
Jon Ashburn301c5f02015-04-06 10:58:22 -0600439static void initLayerTable(const VkBaseLayerObject *gpuw, VkLayerDispatchTable *pTable, const unsigned int layerNum)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700440{
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700441 if (layerNum == 2 && layer1_first_activated == false)
442 layer2_first_activated = true;
443 if (layerNum == 1 && layer2_first_activated == false)
444 layer1_first_activated = true;
445
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600446 layer_initialize_dispatch_table(pTable, (PFN_vkGetProcAddr) gpuw->pGPA, (VkPhysicalDevice) gpuw->nextObject);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700447}
Jon Ashburnd9564002015-05-07 10:27:37 -0600448
449static void initLayerInstanceTable(const VkBaseLayerObject *instw, VkLayerInstanceDispatchTable *pTable, const unsigned int layerNum)
450{
451 if (layerNum == 2 && layer1_first_activated == false)
452 layer2_first_activated = true;
453 if (layerNum == 1 && layer2_first_activated == false)
454 layer1_first_activated = true;
455
456 layer_init_instance_dispatch_table(pTable, (PFN_vkGetInstanceProcAddr) instw->pGPA, (VkInstance) instw->nextObject);
457}