blob: 90f7b90bd92182ad1e59bd21c9d563cbdba7b803 [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 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 Ashburn2666e2f2015-05-15 15:09:35 -060091VK_LAYER_EXPORT VkResult VKAPI multi1CreateSampler(VkDevice device, const VkSamplerCreateInfo* pCreateInfo, VkSampler* pSampler)
Jon Ashburn8d8dad02014-12-01 14:22:40 -070092{
Jon Ashburnd25a78e2015-05-15 16:40:25 -060093 VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) device;
94 VkLayerDispatchTable *pTable = tableMap1[*ppDisp];
Jon Ashburn2666e2f2015-05-15 15:09:35 -060095
96 printf("At start of multi1 layer vkCreateSampler()\n");
97 VkResult result = pTable->CreateSampler(device, pCreateInfo, pSampler);
98 printf("Completed multi1 layer vkCreateSampler()\n");
Jon Ashburn8d8dad02014-12-01 14:22:40 -070099 return result;
100}
101
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600102VK_LAYER_EXPORT VkResult VKAPI multi1CreateGraphicsPipeline(VkDevice device, const VkGraphicsPipelineCreateInfo* pCreateInfo,
103 VkPipeline* pPipeline)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700104{
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600105 VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) device;
106 VkLayerDispatchTable *pTable = tableMap1[*ppDisp];
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700107
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600108 printf("At start of multi1 layer vkCreateGraphicsPipeline()\n");
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600109 VkResult result = pTable->CreateGraphicsPipeline(device, pCreateInfo, pPipeline);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600110 printf("Completed multi1 layer vkCreateGraphicsPipeline()\n");
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700111 return result;
112}
113
Mike Stroyan230e6252015-04-17 12:36:38 -0600114VK_LAYER_EXPORT VkResult VKAPI multi1StorePipeline(VkDevice device, VkPipeline pipeline, size_t* pDataSize, void* pData)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700115{
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600116 VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) device;
117 VkLayerDispatchTable *pTable = tableMap1[*ppDisp];
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700118
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600119 printf("At start of multi1 layer vkStorePipeline()\n");
Mike Stroyan230e6252015-04-17 12:36:38 -0600120 VkResult result = pTable->StorePipeline(device, pipeline, pDataSize, pData);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600121 printf("Completed multi1 layer vkStorePipeline()\n");
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700122 return result;
123}
124
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -0600125VK_LAYER_EXPORT VkResult VKAPI multi1EnumerateLayers(VkPhysicalDevice gpu, size_t maxStringSize,
126 size_t* pLayerCount, char* const* pOutLayers,
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600127 void* pReserved)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700128{
129 if (gpu == NULL)
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -0600130 return vkEnumerateLayers(gpu, maxStringSize, pLayerCount, pOutLayers, pReserved);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700131
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600132 VkLayerInstanceDispatchTable* pTable = tableInstanceMap1[gpu];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600133 printf("At start of multi1 layer vkEnumerateLayers()\n");
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -0600134 VkResult result = pTable->EnumerateLayers(gpu, maxStringSize, pLayerCount, pOutLayers, pReserved);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600135 printf("Completed multi1 layer vkEnumerateLayers()\n");
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700136 return result;
137}
138
Tony Barbour8205d902015-04-16 15:59:00 -0600139VK_LAYER_EXPORT void * VKAPI multi1GetProcAddr(VkPhysicalDevice gpu, const char* pName)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700140{
Jon Ashburn301c5f02015-04-06 10:58:22 -0600141 VkBaseLayerObject* gpuw = (VkBaseLayerObject *) gpu;
Chia-I Wue9ae3882015-01-05 09:41:27 +0800142
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700143 if (gpu == NULL)
144 return NULL;
Chia-I Wue9ae3882015-01-05 09:41:27 +0800145
146 getLayer1Table(gpuw);
147
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600148 if (!strcmp("vkCreateSampler", pName))
149 return (void *) multi1CreateSampler;
150 if (!strcmp("vkEnumerateLayers", pName))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600151 return (void *) multi1EnumerateLayers;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600152 else if (!strcmp("GetGlobalExtensionInfo", pName))
153 return (void*) vkGetGlobalExtensionInfo;
154 else if (!strcmp("vkCreateGraphicsPipeline", pName))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600155 return (void *) multi1CreateGraphicsPipeline;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600156 else if (!strcmp("vkStorePipeline", pName))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600157 return (void *) multi1StorePipeline;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700158 else {
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700159 if (gpuw->pGPA == NULL)
160 return NULL;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600161 return gpuw->pGPA((VkObject) gpuw->nextObject, pName);
162 }
163}
164
Jon Ashburnd9564002015-05-07 10:27:37 -0600165VK_LAYER_EXPORT void * VKAPI multi1GetInstanceProcAddr(VkInstance inst, const char* pName)
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600166{
167 VkBaseLayerObject* instw = (VkBaseLayerObject *) inst;
168
169 if (inst == NULL)
170 return NULL;
171
Jon Ashburnd9564002015-05-07 10:27:37 -0600172 getLayer1InstanceTable(instw);
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600173
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600174 if (!strcmp("vkCreateSampler", pName))
175 return (void *) multi1CreateSampler;
176 if (!strcmp("vkEnumerateLayers", pName))
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600177 return (void *) multi1EnumerateLayers;
178 else if (!strcmp("GetGlobalExtensionInfo", pName))
179 return (void*) vkGetGlobalExtensionInfo;
180 else {
181 if (instw->pGPA == NULL)
182 return NULL;
183 return instw->pGPA((VkObject) instw->nextObject, pName);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700184 }
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700185}
186
187/******************************** Layer multi2 functions **************************/
Jon Ashburn301c5f02015-04-06 10:58:22 -0600188static std::unordered_map<void *, VkLayerDispatchTable *> tableMap2;
Jon Ashburnd9564002015-05-07 10:27:37 -0600189static std::unordered_map<void *, VkLayerInstanceDispatchTable *> tableInstanceMap2;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700190static bool layer2_first_activated = false;
191
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600192static VkLayerInstanceDispatchTable *getLayer2InstanceTable(const VkBaseLayerObject *instw)
Jon Ashburnd9564002015-05-07 10:27:37 -0600193{
194 VkLayerInstanceDispatchTable *pTable;
Jon Ashburnd9564002015-05-07 10:27:37 -0600195 assert(instw);
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600196 VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) instw->baseObject;
197
198 std::unordered_map<void *, VkLayerInstanceDispatchTable *>::const_iterator it = tableInstanceMap2.find((void *) *ppDisp);
Jon Ashburnd9564002015-05-07 10:27:37 -0600199 if (it == tableInstanceMap2.end())
200 {
201 pTable = new VkLayerInstanceDispatchTable;
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600202 tableInstanceMap2[(void *) *ppDisp] = pTable;
Jon Ashburnd9564002015-05-07 10:27:37 -0600203 initLayerInstanceTable(instw, pTable, 2);
204 return pTable;
205 } else
206 {
207 return it->second;
208 }
209}
210
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600211static VkLayerDispatchTable *getLayer2Table(const VkBaseLayerObject *devw)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700212{
Jon Ashburn301c5f02015-04-06 10:58:22 -0600213 VkLayerDispatchTable *pTable;
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600214 assert(devw);
215 VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) devw->baseObject;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700216
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600217 std::unordered_map<void *, VkLayerDispatchTable *>::const_iterator it = tableMap2.find((void *) *ppDisp);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700218 if (it == tableMap2.end())
219 {
Jon Ashburn301c5f02015-04-06 10:58:22 -0600220 pTable = new VkLayerDispatchTable;
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600221 tableMap2[(void *) *ppDisp] = pTable;
222 initLayerTable(devw, pTable, 2);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700223 return pTable;
224 } else
225 {
226 return it->second;
227 }
228}
229
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600230VK_LAYER_EXPORT VkResult VKAPI multi2EnumeratePhysicalDevices(
231 VkInstance instance,
232 uint32_t* pPhysicalDeviceCount,
233 VkPhysicalDevice* pPhysicalDevices)
234{
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600235 VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) instance;
236 VkLayerInstanceDispatchTable *pInstTable = tableInstanceMap2[*ppDisp];
237
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600238 printf("At start of wrapped multi2 vkEnumeratePhysicalDevices()\n");
239 VkResult result = pInstTable->EnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600240 printf("Completed multi2 layer vkEnumeratePhysicalDevices()\n");
241 return result;
242}
243
Tony Barbour8205d902015-04-16 15:59:00 -0600244VK_LAYER_EXPORT VkResult VKAPI multi2CreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo* pCreateInfo,
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600245 VkDevice* pDevice)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700246{
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600247 VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) gpu;
248 VkLayerInstanceDispatchTable *pInstTable = tableInstanceMap2[*ppDisp];
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700249
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600250 printf("At start of multi2 vkCreateDevice()\n");
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600251 VkResult result = pInstTable->CreateDevice(gpu, pCreateInfo, pDevice);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600252 printf("Completed multi2 layer vkCreateDevice()\n");
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700253 return result;
254}
255
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600256VK_LAYER_EXPORT VkResult VKAPI multi2CreateCommandBuffer(VkDevice device, const VkCmdBufferCreateInfo* pCreateInfo,
257 VkCmdBuffer* pCmdBuffer)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700258{
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600259 VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) device;
260 VkLayerDispatchTable *pTable = tableMap2[*ppDisp];
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700261
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600262 printf("At start of multi2 layer vkCreateCommandBuffer()\n");
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600263 VkResult result = pTable->CreateCommandBuffer(device, pCreateInfo, pCmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600264 printf("Completed multi2 layer vkCreateCommandBuffer()\n");
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700265 return result;
266}
267
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600268VK_LAYER_EXPORT VkResult VKAPI multi2BeginCommandBuffer(VkCmdBuffer cmdBuffer, const VkCmdBufferBeginInfo* pBeginInfo)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700269{
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600270 VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) cmdBuffer;
271 VkLayerDispatchTable *pTable = tableMap2[*ppDisp];
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700272
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600273 printf("At start of multi2 layer vkBeginCommandBuffer()\n");
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600274 VkResult result = pTable->BeginCommandBuffer(cmdBuffer, pBeginInfo);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600275 printf("Completed multi2 layer vkBeginCommandBuffer()\n");
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700276 return result;
277
278}
279
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -0600280VK_LAYER_EXPORT VkResult VKAPI multi2EnumerateLayers(VkPhysicalDevice gpu, size_t maxStringSize,
281 size_t* pLayerCount, char* const* pOutLayers,
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600282 void* pReserved)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700283{
284 if (gpu == NULL)
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -0600285 return vkEnumerateLayers(gpu, maxStringSize, pLayerCount, pOutLayers, pReserved);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700286
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600287 VkLayerInstanceDispatchTable* pTable = tableInstanceMap2[gpu];
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700288
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600289 printf("At start of multi2 layer vkEnumerateLayers()\n");
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -0600290 VkResult result = pTable->EnumerateLayers(gpu, maxStringSize, pLayerCount, pOutLayers, pReserved);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600291 printf("Completed multi2 layer vkEnumerateLayers()\n");
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700292 return result;
293}
294
Tony Barbour8205d902015-04-16 15:59:00 -0600295VK_LAYER_EXPORT void * VKAPI multi2GetProcAddr(VkPhysicalDevice gpu, const char* pName)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700296{
Jon Ashburn301c5f02015-04-06 10:58:22 -0600297 VkBaseLayerObject* gpuw = (VkBaseLayerObject *) gpu;
Chia-I Wue9ae3882015-01-05 09:41:27 +0800298
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700299 if (gpu == NULL)
300 return NULL;
Chia-I Wue9ae3882015-01-05 09:41:27 +0800301
302 getLayer2Table(gpuw);
303
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600304 if (!strcmp("vkEnumeratePhysicalDevices", pName))
305 return (void *) multi2EnumeratePhysicalDevices;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600306 if (!strcmp("vkCreateDevice", pName))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600307 return (void *) multi2CreateDevice;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600308 else if (!strcmp("vkEnumerateLayers", pName))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600309 return (void *) multi2EnumerateLayers;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600310 else if (!strcmp("GetGlobalExtensionInfo", pName))
311 return (void*) vkGetGlobalExtensionInfo;
312 else if (!strcmp("vkCreateCommandBuffer", pName))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600313 return (void *) multi2CreateCommandBuffer;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600314 else if (!strcmp("vkBeginCommandBuffer", pName))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600315 return (void *) multi2BeginCommandBuffer;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700316 else {
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700317 if (gpuw->pGPA == NULL)
318 return NULL;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600319 return gpuw->pGPA((VkObject) gpuw->nextObject, pName);
320 }
321}
322
Jon Ashburnd9564002015-05-07 10:27:37 -0600323VK_LAYER_EXPORT void * VKAPI multi2GetInstanceProcAddr(VkInstance inst, const char* pName)
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600324{
325 VkBaseLayerObject* instw = (VkBaseLayerObject *) inst;
326
327 if (inst == NULL)
328 return NULL;
329
Jon Ashburnd9564002015-05-07 10:27:37 -0600330 getLayer2InstanceTable(instw);
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600331
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600332 if (!strcmp("vkEnumeratePhysicalDevices", pName))
333 return (void *) multi2EnumeratePhysicalDevices;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600334 if (!strcmp("vkCreateDevice", pName))
335 return (void *) multi2CreateDevice;
336 else if (!strcmp("vkEnumerateLayers", pName))
337 return (void *) multi2EnumerateLayers;
338 else if (!strcmp("GetGlobalExtensionInfo", pName))
339 return (void*) vkGetGlobalExtensionInfo;
340 else {
341 if (instw->pGPA == NULL)
342 return NULL;
343 return instw->pGPA((VkObject) instw->nextObject, pName);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700344 }
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700345}
346
347/********************************* Common functions ********************************/
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -0600348VK_LAYER_EXPORT VkResult VKAPI vkEnumerateLayers(VkPhysicalDevice gpu, size_t maxStringSize,
349 size_t* pLayerCount, char* const* pOutLayers,
350 void* pReserved)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700351{
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -0600352 if (pLayerCount == NULL || pOutLayers == NULL || pOutLayers[0] == NULL || pOutLayers[1] == NULL || pReserved == NULL)
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600353 return VK_ERROR_INVALID_POINTER;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700354
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -0600355 if (*pLayerCount < 2)
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600356 return VK_ERROR_INITIALIZATION_FAILED;
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -0600357 *pLayerCount = 2;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700358 strncpy((char *) pOutLayers[0], "multi1", maxStringSize);
359 strncpy((char *) pOutLayers[1], "multi2", maxStringSize);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600360 return VK_SUCCESS;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700361}
362
Jon Ashburneb2728b2015-04-10 14:33:07 -0600363struct extProps {
364 uint32_t version;
365 const char * const name;
366};
367
368#define MULTI_LAYER_EXT_ARRAY_SIZE 2
369static const struct extProps multiExts[MULTI_LAYER_EXT_ARRAY_SIZE] = {
370 // TODO what is the version?
371 0x10, "multi1",
372 0x10, "multi2",
373};
374
375VK_LAYER_EXPORT VkResult VKAPI vkGetGlobalExtensionInfo(
376 VkExtensionInfoType infoType,
377 uint32_t extensionIndex,
378 size_t* pDataSize,
379 void* pData)
380{
Jon Ashburneb2728b2015-04-10 14:33:07 -0600381 /* This entrypoint is NOT going to init it's own dispatch table since loader calls here early */
382 VkExtensionProperties *ext_props;
383 uint32_t *count;
384
385 if (pDataSize == NULL)
386 return VK_ERROR_INVALID_POINTER;
387
388 switch (infoType) {
389 case VK_EXTENSION_INFO_TYPE_COUNT:
390 *pDataSize = sizeof(uint32_t);
391 if (pData == NULL)
392 return VK_SUCCESS;
393 count = (uint32_t *) pData;
394 *count = MULTI_LAYER_EXT_ARRAY_SIZE;
395 break;
396 case VK_EXTENSION_INFO_TYPE_PROPERTIES:
397 *pDataSize = sizeof(VkExtensionProperties);
398 if (pData == NULL)
399 return VK_SUCCESS;
400 if (extensionIndex >= MULTI_LAYER_EXT_ARRAY_SIZE)
401 return VK_ERROR_INVALID_VALUE;
402 ext_props = (VkExtensionProperties *) pData;
403 ext_props->version = multiExts[extensionIndex].version;
404 strncpy(ext_props->extName, multiExts[extensionIndex].name,
405 VK_MAX_EXTENSION_NAME);
406 ext_props->extName[VK_MAX_EXTENSION_NAME - 1] = '\0';
407 break;
408 default:
409 return VK_ERROR_INVALID_VALUE;
410 };
411
412 return VK_SUCCESS;
413}
414
Tony Barbour8205d902015-04-16 15:59:00 -0600415VK_LAYER_EXPORT void * VKAPI vkGetProcAddr(VkPhysicalDevice gpu, const char* pName)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700416{
417 // to find each layers GPA routine Loader will search via "<layerName>GetProcAddr"
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600418 if (!strcmp("multi1GetProcAddr", pName))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600419 return (void *) multi1GetProcAddr;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600420 else if (!strcmp("multi2GetProcAddr", pName))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600421 return (void *) multi2GetProcAddr;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600422 else if (!strcmp("vkGetProcAddr", pName))
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600423 return (void *) vkGetProcAddr;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700424
425 // use first layer activated as GPA dispatch table activation happens in order
426 else if (layer1_first_activated)
427 return multi1GetProcAddr(gpu, pName);
428 else if (layer2_first_activated)
429 return multi2GetProcAddr(gpu, pName);
430 else
431 return NULL;
432
433}
434
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600435VK_LAYER_EXPORT void * VKAPI vkGetInstanceProcAddr(VkInstance inst, const char* pName)
436{
437 // to find each layers GPA routine Loader will search via "<layerName>GetProcAddr"
438 if (!strcmp("multi1GetProcAddr", pName))
439 return (void *) multi1GetProcAddr;
440 else if (!strcmp("multi2GetProcAddr", pName))
441 return (void *) multi2GetProcAddr;
442 else if (!strcmp("vkGetProcAddr", pName))
443 return (void *) vkGetProcAddr;
444 else if (!strcmp("multi1GetInstanceProcAddr", pName))
Jon Ashburnd9564002015-05-07 10:27:37 -0600445 return (void *) multi1GetInstanceProcAddr;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600446 else if (!strcmp("multi2GetInstanceProcAddr", pName))
Jon Ashburnd9564002015-05-07 10:27:37 -0600447 return (void *) multi2GetInstanceProcAddr;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600448 else if (!strcmp("vkGetInstanceProcAddr", pName))
449 return (void *) vkGetProcAddr;
450
451 // use first layer activated as GPA dispatch table activation happens in order
452 else if (layer1_first_activated)
Jon Ashburnd9564002015-05-07 10:27:37 -0600453 return multi1GetInstanceProcAddr(inst, pName);
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600454 else if (layer2_first_activated)
Jon Ashburnd9564002015-05-07 10:27:37 -0600455 return multi2GetInstanceProcAddr(inst, pName);
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600456 else
457 return NULL;
458
459}
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700460#ifdef __cplusplus
461} //extern "C"
462#endif
463
Jon Ashburn301c5f02015-04-06 10:58:22 -0600464static void initLayerTable(const VkBaseLayerObject *gpuw, VkLayerDispatchTable *pTable, const unsigned int layerNum)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700465{
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700466 if (layerNum == 2 && layer1_first_activated == false)
467 layer2_first_activated = true;
468 if (layerNum == 1 && layer2_first_activated == false)
469 layer1_first_activated = true;
470
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600471 layer_initialize_dispatch_table(pTable, (PFN_vkGetProcAddr) gpuw->pGPA, (VkPhysicalDevice) gpuw->nextObject);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700472}
Jon Ashburnd9564002015-05-07 10:27:37 -0600473
474static void initLayerInstanceTable(const VkBaseLayerObject *instw, VkLayerInstanceDispatchTable *pTable, const unsigned int layerNum)
475{
476 if (layerNum == 2 && layer1_first_activated == false)
477 layer2_first_activated = true;
478 if (layerNum == 1 && layer2_first_activated == false)
479 layer1_first_activated = true;
480
481 layer_init_instance_dispatch_table(pTable, (PFN_vkGetInstanceProcAddr) instw->pGPA, (VkInstance) instw->nextObject);
482}