blob: 605a642077555bc392d196c2d18843e8b343bca0 [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
Jon Ashburn2666e2f2015-05-15 15:09:35 -060083VK_LAYER_EXPORT VkResult VKAPI multi1CreateSampler(VkDevice device, const VkSamplerCreateInfo* pCreateInfo, VkSampler* pSampler)
Jon Ashburn8d8dad02014-12-01 14:22:40 -070084{
Jon Ashburn2666e2f2015-05-15 15:09:35 -060085 VkLayerDispatchTable* pTable = tableMap1[device];
86
87 printf("At start of multi1 layer vkCreateSampler()\n");
88 VkResult result = pTable->CreateSampler(device, pCreateInfo, pSampler);
89 printf("Completed multi1 layer vkCreateSampler()\n");
Jon Ashburn8d8dad02014-12-01 14:22:40 -070090 return result;
91}
92
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -060093VK_LAYER_EXPORT VkResult VKAPI multi1CreateGraphicsPipeline(VkDevice device, const VkGraphicsPipelineCreateInfo* pCreateInfo,
94 VkPipeline* pPipeline)
Jon Ashburn8d8dad02014-12-01 14:22:40 -070095{
Jon Ashburn301c5f02015-04-06 10:58:22 -060096 VkLayerDispatchTable* pTable = tableMap1[device];
Jon Ashburn8d8dad02014-12-01 14:22:40 -070097
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060098 printf("At start of multi1 layer vkCreateGraphicsPipeline()\n");
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -060099 VkResult result = pTable->CreateGraphicsPipeline(device, pCreateInfo, pPipeline);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700100 // create a mapping for the pipeline object into the dispatch table
101 tableMap1.emplace(*pPipeline, pTable);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600102 printf("Completed multi1 layer vkCreateGraphicsPipeline()\n");
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700103 return result;
104}
105
Mike Stroyan230e6252015-04-17 12:36:38 -0600106VK_LAYER_EXPORT VkResult VKAPI multi1StorePipeline(VkDevice device, VkPipeline pipeline, size_t* pDataSize, void* pData)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700107{
Jon Ashburn301c5f02015-04-06 10:58:22 -0600108 VkLayerDispatchTable* pTable = tableMap1[pipeline];
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700109
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600110 printf("At start of multi1 layer vkStorePipeline()\n");
Mike Stroyan230e6252015-04-17 12:36:38 -0600111 VkResult result = pTable->StorePipeline(device, pipeline, pDataSize, pData);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600112 printf("Completed multi1 layer vkStorePipeline()\n");
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700113 return result;
114}
115
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -0600116VK_LAYER_EXPORT VkResult VKAPI multi1EnumerateLayers(VkPhysicalDevice gpu, size_t maxStringSize,
117 size_t* pLayerCount, char* const* pOutLayers,
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600118 void* pReserved)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700119{
120 if (gpu == NULL)
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -0600121 return vkEnumerateLayers(gpu, maxStringSize, pLayerCount, pOutLayers, pReserved);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700122
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600123 VkLayerInstanceDispatchTable* pTable = tableInstanceMap1[gpu];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600124 printf("At start of multi1 layer vkEnumerateLayers()\n");
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -0600125 VkResult result = pTable->EnumerateLayers(gpu, maxStringSize, pLayerCount, pOutLayers, pReserved);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600126 printf("Completed multi1 layer vkEnumerateLayers()\n");
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700127 return result;
128}
129
Tony Barbour8205d902015-04-16 15:59:00 -0600130VK_LAYER_EXPORT void * VKAPI multi1GetProcAddr(VkPhysicalDevice gpu, const char* pName)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700131{
Jon Ashburn301c5f02015-04-06 10:58:22 -0600132 VkBaseLayerObject* gpuw = (VkBaseLayerObject *) gpu;
Chia-I Wue9ae3882015-01-05 09:41:27 +0800133
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700134 if (gpu == NULL)
135 return NULL;
Chia-I Wue9ae3882015-01-05 09:41:27 +0800136
137 getLayer1Table(gpuw);
138
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600139 if (!strcmp("vkCreateSampler", pName))
140 return (void *) multi1CreateSampler;
141 if (!strcmp("vkEnumerateLayers", pName))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600142 return (void *) multi1EnumerateLayers;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600143 else if (!strcmp("GetGlobalExtensionInfo", pName))
144 return (void*) vkGetGlobalExtensionInfo;
145 else if (!strcmp("vkCreateGraphicsPipeline", pName))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600146 return (void *) multi1CreateGraphicsPipeline;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600147 else if (!strcmp("vkStorePipeline", pName))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600148 return (void *) multi1StorePipeline;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700149 else {
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700150 if (gpuw->pGPA == NULL)
151 return NULL;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600152 return gpuw->pGPA((VkObject) gpuw->nextObject, pName);
153 }
154}
155
Jon Ashburnd9564002015-05-07 10:27:37 -0600156VK_LAYER_EXPORT void * VKAPI multi1GetInstanceProcAddr(VkInstance inst, const char* pName)
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600157{
158 VkBaseLayerObject* instw = (VkBaseLayerObject *) inst;
159
160 if (inst == NULL)
161 return NULL;
162
Jon Ashburnd9564002015-05-07 10:27:37 -0600163 getLayer1InstanceTable(instw);
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600164
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600165 if (!strcmp("vkCreateSampler", pName))
166 return (void *) multi1CreateSampler;
167 if (!strcmp("vkEnumerateLayers", pName))
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600168 return (void *) multi1EnumerateLayers;
169 else if (!strcmp("GetGlobalExtensionInfo", pName))
170 return (void*) vkGetGlobalExtensionInfo;
171 else {
172 if (instw->pGPA == NULL)
173 return NULL;
174 return instw->pGPA((VkObject) instw->nextObject, pName);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700175 }
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700176}
177
178/******************************** Layer multi2 functions **************************/
Jon Ashburn301c5f02015-04-06 10:58:22 -0600179static std::unordered_map<void *, VkLayerDispatchTable *> tableMap2;
Jon Ashburnd9564002015-05-07 10:27:37 -0600180static std::unordered_map<void *, VkLayerInstanceDispatchTable *> tableInstanceMap2;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700181static bool layer2_first_activated = false;
182
Jon Ashburnd9564002015-05-07 10:27:37 -0600183static VkLayerInstanceDispatchTable * getLayer2InstanceTable(const VkBaseLayerObject *instw)
184{
185 VkLayerInstanceDispatchTable *pTable;
186
187 assert(instw);
188 std::unordered_map<void *, VkLayerInstanceDispatchTable *>::const_iterator it = tableInstanceMap2.find((void *) instw->baseObject);
189 if (it == tableInstanceMap2.end())
190 {
191 pTable = new VkLayerInstanceDispatchTable;
192 tableInstanceMap2[(void *) instw->baseObject] = pTable;
193 initLayerInstanceTable(instw, pTable, 2);
194 return pTable;
195 } else
196 {
197 return it->second;
198 }
199}
200
Jon Ashburn301c5f02015-04-06 10:58:22 -0600201static VkLayerDispatchTable * getLayer2Table(const VkBaseLayerObject *gpuw)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700202{
Jon Ashburn301c5f02015-04-06 10:58:22 -0600203 VkLayerDispatchTable *pTable;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700204
205 assert(gpuw);
Jon Ashburn630e44f2015-04-08 21:33:34 -0600206 std::unordered_map<void *, VkLayerDispatchTable *>::const_iterator it = tableMap2.find((void *) gpuw->baseObject);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700207 if (it == tableMap2.end())
208 {
Jon Ashburn301c5f02015-04-06 10:58:22 -0600209 pTable = new VkLayerDispatchTable;
Jon Ashburn630e44f2015-04-08 21:33:34 -0600210 tableMap2[(void *) gpuw->baseObject] = pTable;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700211 initLayerTable(gpuw, pTable, 2);
212 return pTable;
213 } else
214 {
215 return it->second;
216 }
217}
218
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600219VK_LAYER_EXPORT VkResult VKAPI multi2EnumeratePhysicalDevices(
220 VkInstance instance,
221 uint32_t* pPhysicalDeviceCount,
222 VkPhysicalDevice* pPhysicalDevices)
223{
224 /* Need to intercept this entrypoint to add the physDev objects to instance map */
225 VkLayerInstanceDispatchTable* pInstTable = tableInstanceMap2[instance];
226 printf("At start of wrapped multi2 vkEnumeratePhysicalDevices()\n");
227 VkResult result = pInstTable->EnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
228 if (pPhysicalDevices)
229 {
230 // create a mapping for the objects into the dispatch table
231 for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++)
232 {
233 tableInstanceMap2.emplace(*(pPhysicalDevices + i), pInstTable);
234 }
235 }
236 printf("Completed multi2 layer vkEnumeratePhysicalDevices()\n");
237 return result;
238}
239
Tony Barbour8205d902015-04-16 15:59:00 -0600240VK_LAYER_EXPORT VkResult VKAPI multi2CreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo* pCreateInfo,
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600241 VkDevice* pDevice)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700242{
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600243 VkLayerInstanceDispatchTable* pInstTable = tableInstanceMap2[gpu];
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700244
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600245 printf("At start of multi2 vkCreateDevice()\n");
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600246 VkResult result = pInstTable->CreateDevice(gpu, pCreateInfo, pDevice);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600247 printf("Completed multi2 layer vkCreateDevice()\n");
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700248 return result;
249}
250
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600251VK_LAYER_EXPORT VkResult VKAPI multi2CreateCommandBuffer(VkDevice device, const VkCmdBufferCreateInfo* pCreateInfo,
252 VkCmdBuffer* pCmdBuffer)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700253{
Jon Ashburn301c5f02015-04-06 10:58:22 -0600254 VkLayerDispatchTable* pTable = tableMap2[device];
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700255
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600256 printf("At start of multi2 layer vkCreateCommandBuffer()\n");
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600257 VkResult result = pTable->CreateCommandBuffer(device, pCreateInfo, pCmdBuffer);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700258 // create a mapping for CmdBuffer object into the dispatch table for layer 2
259 tableMap2.emplace(*pCmdBuffer, pTable);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600260 printf("Completed multi2 layer vkCreateCommandBuffer()\n");
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700261 return result;
262}
263
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600264VK_LAYER_EXPORT VkResult VKAPI multi2BeginCommandBuffer(VkCmdBuffer cmdBuffer, const VkCmdBufferBeginInfo* pBeginInfo)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700265{
Jon Ashburn301c5f02015-04-06 10:58:22 -0600266 VkLayerDispatchTable* pTable = tableMap2[cmdBuffer];
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700267
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600268 printf("At start of multi2 layer vkBeginCommandBuffer()\n");
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600269 VkResult result = pTable->BeginCommandBuffer(cmdBuffer, pBeginInfo);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600270 printf("Completed multi2 layer vkBeginCommandBuffer()\n");
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700271 return result;
272
273}
274
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -0600275VK_LAYER_EXPORT VkResult VKAPI multi2EnumerateLayers(VkPhysicalDevice gpu, size_t maxStringSize,
276 size_t* pLayerCount, char* const* pOutLayers,
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600277 void* pReserved)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700278{
279 if (gpu == NULL)
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -0600280 return vkEnumerateLayers(gpu, maxStringSize, pLayerCount, pOutLayers, pReserved);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700281
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600282 VkLayerInstanceDispatchTable* pTable = tableInstanceMap2[gpu];
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700283
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600284 printf("At start of multi2 layer vkEnumerateLayers()\n");
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -0600285 VkResult result = pTable->EnumerateLayers(gpu, maxStringSize, pLayerCount, pOutLayers, pReserved);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600286 printf("Completed multi2 layer vkEnumerateLayers()\n");
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700287 return result;
288}
289
Tony Barbour8205d902015-04-16 15:59:00 -0600290VK_LAYER_EXPORT void * VKAPI multi2GetProcAddr(VkPhysicalDevice gpu, const char* pName)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700291{
Jon Ashburn301c5f02015-04-06 10:58:22 -0600292 VkBaseLayerObject* gpuw = (VkBaseLayerObject *) gpu;
Chia-I Wue9ae3882015-01-05 09:41:27 +0800293
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700294 if (gpu == NULL)
295 return NULL;
Chia-I Wue9ae3882015-01-05 09:41:27 +0800296
297 getLayer2Table(gpuw);
298
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600299 if (!strcmp("vkEnumeratePhysicalDevices", pName))
300 return (void *) multi2EnumeratePhysicalDevices;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600301 if (!strcmp("vkCreateDevice", pName))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600302 return (void *) multi2CreateDevice;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600303 else if (!strcmp("vkEnumerateLayers", pName))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600304 return (void *) multi2EnumerateLayers;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600305 else if (!strcmp("GetGlobalExtensionInfo", pName))
306 return (void*) vkGetGlobalExtensionInfo;
307 else if (!strcmp("vkCreateCommandBuffer", pName))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600308 return (void *) multi2CreateCommandBuffer;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600309 else if (!strcmp("vkBeginCommandBuffer", pName))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600310 return (void *) multi2BeginCommandBuffer;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700311 else {
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700312 if (gpuw->pGPA == NULL)
313 return NULL;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600314 return gpuw->pGPA((VkObject) gpuw->nextObject, pName);
315 }
316}
317
Jon Ashburnd9564002015-05-07 10:27:37 -0600318VK_LAYER_EXPORT void * VKAPI multi2GetInstanceProcAddr(VkInstance inst, const char* pName)
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600319{
320 VkBaseLayerObject* instw = (VkBaseLayerObject *) inst;
321
322 if (inst == NULL)
323 return NULL;
324
Jon Ashburnd9564002015-05-07 10:27:37 -0600325 getLayer2InstanceTable(instw);
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600326
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600327 if (!strcmp("vkEnumeratePhysicalDevices", pName))
328 return (void *) multi2EnumeratePhysicalDevices;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600329 if (!strcmp("vkCreateDevice", pName))
330 return (void *) multi2CreateDevice;
331 else if (!strcmp("vkEnumerateLayers", pName))
332 return (void *) multi2EnumerateLayers;
333 else if (!strcmp("GetGlobalExtensionInfo", pName))
334 return (void*) vkGetGlobalExtensionInfo;
335 else {
336 if (instw->pGPA == NULL)
337 return NULL;
338 return instw->pGPA((VkObject) instw->nextObject, pName);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700339 }
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700340}
341
342/********************************* Common functions ********************************/
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -0600343VK_LAYER_EXPORT VkResult VKAPI vkEnumerateLayers(VkPhysicalDevice gpu, size_t maxStringSize,
344 size_t* pLayerCount, char* const* pOutLayers,
345 void* pReserved)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700346{
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -0600347 if (pLayerCount == NULL || pOutLayers == NULL || pOutLayers[0] == NULL || pOutLayers[1] == NULL || pReserved == NULL)
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600348 return VK_ERROR_INVALID_POINTER;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700349
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -0600350 if (*pLayerCount < 2)
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600351 return VK_ERROR_INITIALIZATION_FAILED;
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -0600352 *pLayerCount = 2;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700353 strncpy((char *) pOutLayers[0], "multi1", maxStringSize);
354 strncpy((char *) pOutLayers[1], "multi2", maxStringSize);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600355 return VK_SUCCESS;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700356}
357
Jon Ashburneb2728b2015-04-10 14:33:07 -0600358struct extProps {
359 uint32_t version;
360 const char * const name;
361};
362
363#define MULTI_LAYER_EXT_ARRAY_SIZE 2
364static const struct extProps multiExts[MULTI_LAYER_EXT_ARRAY_SIZE] = {
365 // TODO what is the version?
366 0x10, "multi1",
367 0x10, "multi2",
368};
369
370VK_LAYER_EXPORT VkResult VKAPI vkGetGlobalExtensionInfo(
371 VkExtensionInfoType infoType,
372 uint32_t extensionIndex,
373 size_t* pDataSize,
374 void* pData)
375{
Jon Ashburneb2728b2015-04-10 14:33:07 -0600376 /* This entrypoint is NOT going to init it's own dispatch table since loader calls here early */
377 VkExtensionProperties *ext_props;
378 uint32_t *count;
379
380 if (pDataSize == NULL)
381 return VK_ERROR_INVALID_POINTER;
382
383 switch (infoType) {
384 case VK_EXTENSION_INFO_TYPE_COUNT:
385 *pDataSize = sizeof(uint32_t);
386 if (pData == NULL)
387 return VK_SUCCESS;
388 count = (uint32_t *) pData;
389 *count = MULTI_LAYER_EXT_ARRAY_SIZE;
390 break;
391 case VK_EXTENSION_INFO_TYPE_PROPERTIES:
392 *pDataSize = sizeof(VkExtensionProperties);
393 if (pData == NULL)
394 return VK_SUCCESS;
395 if (extensionIndex >= MULTI_LAYER_EXT_ARRAY_SIZE)
396 return VK_ERROR_INVALID_VALUE;
397 ext_props = (VkExtensionProperties *) pData;
398 ext_props->version = multiExts[extensionIndex].version;
399 strncpy(ext_props->extName, multiExts[extensionIndex].name,
400 VK_MAX_EXTENSION_NAME);
401 ext_props->extName[VK_MAX_EXTENSION_NAME - 1] = '\0';
402 break;
403 default:
404 return VK_ERROR_INVALID_VALUE;
405 };
406
407 return VK_SUCCESS;
408}
409
Tony Barbour8205d902015-04-16 15:59:00 -0600410VK_LAYER_EXPORT void * VKAPI vkGetProcAddr(VkPhysicalDevice gpu, const char* pName)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700411{
412 // to find each layers GPA routine Loader will search via "<layerName>GetProcAddr"
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600413 if (!strcmp("multi1GetProcAddr", pName))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600414 return (void *) multi1GetProcAddr;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600415 else if (!strcmp("multi2GetProcAddr", pName))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600416 return (void *) multi2GetProcAddr;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600417 else if (!strcmp("vkGetProcAddr", pName))
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600418 return (void *) vkGetProcAddr;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700419
420 // use first layer activated as GPA dispatch table activation happens in order
421 else if (layer1_first_activated)
422 return multi1GetProcAddr(gpu, pName);
423 else if (layer2_first_activated)
424 return multi2GetProcAddr(gpu, pName);
425 else
426 return NULL;
427
428}
429
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600430VK_LAYER_EXPORT void * VKAPI vkGetInstanceProcAddr(VkInstance inst, const char* pName)
431{
432 // to find each layers GPA routine Loader will search via "<layerName>GetProcAddr"
433 if (!strcmp("multi1GetProcAddr", pName))
434 return (void *) multi1GetProcAddr;
435 else if (!strcmp("multi2GetProcAddr", pName))
436 return (void *) multi2GetProcAddr;
437 else if (!strcmp("vkGetProcAddr", pName))
438 return (void *) vkGetProcAddr;
439 else if (!strcmp("multi1GetInstanceProcAddr", pName))
Jon Ashburnd9564002015-05-07 10:27:37 -0600440 return (void *) multi1GetInstanceProcAddr;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600441 else if (!strcmp("multi2GetInstanceProcAddr", pName))
Jon Ashburnd9564002015-05-07 10:27:37 -0600442 return (void *) multi2GetInstanceProcAddr;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600443 else if (!strcmp("vkGetInstanceProcAddr", pName))
444 return (void *) vkGetProcAddr;
445
446 // use first layer activated as GPA dispatch table activation happens in order
447 else if (layer1_first_activated)
Jon Ashburnd9564002015-05-07 10:27:37 -0600448 return multi1GetInstanceProcAddr(inst, pName);
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600449 else if (layer2_first_activated)
Jon Ashburnd9564002015-05-07 10:27:37 -0600450 return multi2GetInstanceProcAddr(inst, pName);
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600451 else
452 return NULL;
453
454}
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700455#ifdef __cplusplus
456} //extern "C"
457#endif
458
Jon Ashburn301c5f02015-04-06 10:58:22 -0600459static void initLayerTable(const VkBaseLayerObject *gpuw, VkLayerDispatchTable *pTable, const unsigned int layerNum)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700460{
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700461 if (layerNum == 2 && layer1_first_activated == false)
462 layer2_first_activated = true;
463 if (layerNum == 1 && layer2_first_activated == false)
464 layer1_first_activated = true;
465
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600466 layer_initialize_dispatch_table(pTable, (PFN_vkGetProcAddr) gpuw->pGPA, (VkPhysicalDevice) gpuw->nextObject);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700467}
Jon Ashburnd9564002015-05-07 10:27:37 -0600468
469static void initLayerInstanceTable(const VkBaseLayerObject *instw, VkLayerInstanceDispatchTable *pTable, const unsigned int layerNum)
470{
471 if (layerNum == 2 && layer1_first_activated == false)
472 layer2_first_activated = true;
473 if (layerNum == 1 && layer2_first_activated == false)
474 layer1_first_activated = true;
475
476 layer_init_instance_dispatch_table(pTable, (PFN_vkGetInstanceProcAddr) instw->pGPA, (VkInstance) instw->nextObject);
477}