blob: 1d6764b8504335d30547386bb1080c458b54d05b [file] [log] [blame]
Jon Ashburn8d8dad02014-12-01 14:22:40 -07001/*
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002 * Vulkan
Jon Ashburn8d8dad02014-12-01 14:22:40 -07003 *
4 * Copyright (C) 2014 LunarG, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *
24 */
25
26#include <string.h>
27#include <stdlib.h>
28#include <assert.h>
29#include <unordered_map>
Ian Elliott81ac44c2015-01-13 17:52:38 -070030#include "loader_platform.h"
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060031#include "vk_dispatch_table_helper.h"
32#include "vkLayer.h"
Ian Elliott20f06872015-02-12 17:08:34 -070033// The following is #included again to catch certain OS-specific functions
34// being used:
35#include "loader_platform.h"
Jon Ashburn8d8dad02014-12-01 14:22:40 -070036
Jon Ashburn1245cec2015-05-18 13:20:15 -060037static void initLayerTable(const VkBaseLayerObject *devw, VkLayerDispatchTable *pTable, const unsigned int layerNum);
Jon Ashburnd9564002015-05-07 10:27:37 -060038static void initLayerInstanceTable(const VkBaseLayerObject *instw, VkLayerInstanceDispatchTable *pTable, const unsigned int layerNum);
Jon Ashburnd25a78e2015-05-15 16:40:25 -060039/* Various dispatchable objects will use the same underlying dispatch table if they
40 * are created from that "parent" object. Thus use pointer to dispatch table
41 * as the key to table maps (tableMap1, tableInstanceMap1, tableMap2, tableInstanceMap2.
42 * Instance -> PhysicalDevice
43 * Device -> CmdBuffer or Queue
44 * If use the object themselves as key to map then implies Create entrypoints have to be intercepted
45 * and a new key inserted into map */
Jon Ashburn8d8dad02014-12-01 14:22:40 -070046/******************************** Layer multi1 functions **************************/
Jon Ashburn301c5f02015-04-06 10:58:22 -060047static std::unordered_map<void *, VkLayerDispatchTable *> tableMap1;
Jon Ashburnd9564002015-05-07 10:27:37 -060048static std::unordered_map<void *, VkLayerInstanceDispatchTable *> tableInstanceMap1;
Jon Ashburn8d8dad02014-12-01 14:22:40 -070049static bool layer1_first_activated = false;
50
Jon Ashburnd25a78e2015-05-15 16:40:25 -060051static VkLayerDispatchTable *getLayer1Table(const VkBaseLayerObject *devw)
Jon Ashburn8d8dad02014-12-01 14:22:40 -070052{
Jon Ashburn301c5f02015-04-06 10:58:22 -060053 VkLayerDispatchTable *pTable;
Jon Ashburnd25a78e2015-05-15 16:40:25 -060054 assert(devw);
55 VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) devw->baseObject;
Jon Ashburn8d8dad02014-12-01 14:22:40 -070056
Jon Ashburnd25a78e2015-05-15 16:40:25 -060057 std::unordered_map<void *, VkLayerDispatchTable *>::const_iterator it = tableMap1.find((void *) *ppDisp);
Jon Ashburn8d8dad02014-12-01 14:22:40 -070058 if (it == tableMap1.end())
59 {
Jon Ashburn301c5f02015-04-06 10:58:22 -060060 pTable = new VkLayerDispatchTable;
Jon Ashburnd25a78e2015-05-15 16:40:25 -060061 tableMap1[(void *) *ppDisp] = pTable;
62 initLayerTable(devw, pTable, 1);
Jon Ashburn8d8dad02014-12-01 14:22:40 -070063 return pTable;
64 } else
65 {
66 return it->second;
67 }
68}
Jon Ashburnd25a78e2015-05-15 16:40:25 -060069static VkLayerInstanceDispatchTable *getLayer1InstanceTable(const VkBaseLayerObject *instw)
Jon Ashburnd9564002015-05-07 10:27:37 -060070{
71 VkLayerInstanceDispatchTable *pTable;
Jon Ashburnd9564002015-05-07 10:27:37 -060072 assert(instw);
Jon Ashburnd25a78e2015-05-15 16:40:25 -060073 VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) instw->baseObject;
74
75 std::unordered_map<void *, VkLayerInstanceDispatchTable *>::const_iterator it = tableInstanceMap1.find((void *) *ppDisp);
Jon Ashburnd9564002015-05-07 10:27:37 -060076 if (it == tableInstanceMap1.end())
77 {
78 pTable = new VkLayerInstanceDispatchTable;
Jon Ashburnd25a78e2015-05-15 16:40:25 -060079 tableInstanceMap1[(void *) *ppDisp] = pTable;
Jon Ashburnd9564002015-05-07 10:27:37 -060080 initLayerInstanceTable(instw, pTable, 1);
81 return pTable;
82 } else
83 {
84 return it->second;
85 }
86}
Jon Ashburn8d8dad02014-12-01 14:22:40 -070087#ifdef __cplusplus
88extern "C" {
89#endif
90
Jon 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
Jon Ashburn1245cec2015-05-18 13:20:15 -0600139VK_LAYER_EXPORT void * VKAPI multi1GetDeviceProcAddr(VkDevice device, const char* pName)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700140{
Jon Ashburn1245cec2015-05-18 13:20:15 -0600141 VkBaseLayerObject* devw = (VkBaseLayerObject *) device;
Chia-I Wue9ae3882015-01-05 09:41:27 +0800142
Jon Ashburn1245cec2015-05-18 13:20:15 -0600143 if (device == NULL)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700144 return NULL;
Chia-I Wue9ae3882015-01-05 09:41:27 +0800145
Jon Ashburn1245cec2015-05-18 13:20:15 -0600146 getLayer1Table(devw);
Chia-I Wue9ae3882015-01-05 09:41:27 +0800147
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600148 if (!strcmp("vkCreateSampler", pName))
149 return (void *) multi1CreateSampler;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600150 else if (!strcmp("vkCreateGraphicsPipeline", pName))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600151 return (void *) multi1CreateGraphicsPipeline;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600152 else if (!strcmp("vkStorePipeline", pName))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600153 return (void *) multi1StorePipeline;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700154 else {
Jon Ashburn1245cec2015-05-18 13:20:15 -0600155 if (devw->pGPA == NULL)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700156 return NULL;
Jon Ashburn1245cec2015-05-18 13:20:15 -0600157 return devw->pGPA((VkObject) devw->nextObject, pName);
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600158 }
159}
160
Jon Ashburnd9564002015-05-07 10:27:37 -0600161VK_LAYER_EXPORT void * VKAPI multi1GetInstanceProcAddr(VkInstance inst, const char* pName)
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600162{
163 VkBaseLayerObject* instw = (VkBaseLayerObject *) inst;
164
165 if (inst == NULL)
166 return NULL;
167
Jon Ashburnd9564002015-05-07 10:27:37 -0600168 getLayer1InstanceTable(instw);
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600169
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600170 if (!strcmp("vkEnumerateLayers", pName))
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600171 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 Ashburnd25a78e2015-05-15 16:40:25 -0600186static VkLayerInstanceDispatchTable *getLayer2InstanceTable(const VkBaseLayerObject *instw)
Jon Ashburnd9564002015-05-07 10:27:37 -0600187{
188 VkLayerInstanceDispatchTable *pTable;
Jon Ashburnd9564002015-05-07 10:27:37 -0600189 assert(instw);
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600190 VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) instw->baseObject;
191
192 std::unordered_map<void *, VkLayerInstanceDispatchTable *>::const_iterator it = tableInstanceMap2.find((void *) *ppDisp);
Jon Ashburnd9564002015-05-07 10:27:37 -0600193 if (it == tableInstanceMap2.end())
194 {
195 pTable = new VkLayerInstanceDispatchTable;
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600196 tableInstanceMap2[(void *) *ppDisp] = pTable;
Jon Ashburnd9564002015-05-07 10:27:37 -0600197 initLayerInstanceTable(instw, pTable, 2);
198 return pTable;
199 } else
200 {
201 return it->second;
202 }
203}
204
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600205static VkLayerDispatchTable *getLayer2Table(const VkBaseLayerObject *devw)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700206{
Jon Ashburn301c5f02015-04-06 10:58:22 -0600207 VkLayerDispatchTable *pTable;
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600208 assert(devw);
209 VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) devw->baseObject;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700210
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600211 std::unordered_map<void *, VkLayerDispatchTable *>::const_iterator it = tableMap2.find((void *) *ppDisp);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700212 if (it == tableMap2.end())
213 {
Jon Ashburn301c5f02015-04-06 10:58:22 -0600214 pTable = new VkLayerDispatchTable;
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600215 tableMap2[(void *) *ppDisp] = pTable;
216 initLayerTable(devw, pTable, 2);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700217 return pTable;
218 } else
219 {
220 return it->second;
221 }
222}
223
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600224VK_LAYER_EXPORT VkResult VKAPI multi2EnumeratePhysicalDevices(
225 VkInstance instance,
226 uint32_t* pPhysicalDeviceCount,
227 VkPhysicalDevice* pPhysicalDevices)
228{
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600229 VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) instance;
230 VkLayerInstanceDispatchTable *pInstTable = tableInstanceMap2[*ppDisp];
231
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600232 printf("At start of wrapped multi2 vkEnumeratePhysicalDevices()\n");
233 VkResult result = pInstTable->EnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600234 printf("Completed multi2 layer vkEnumeratePhysicalDevices()\n");
235 return result;
236}
237
Tony Barbour8205d902015-04-16 15:59:00 -0600238VK_LAYER_EXPORT VkResult VKAPI multi2CreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo* pCreateInfo,
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600239 VkDevice* pDevice)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700240{
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600241 VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) gpu;
242 VkLayerInstanceDispatchTable *pInstTable = tableInstanceMap2[*ppDisp];
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700243
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600244 printf("At start of multi2 vkCreateDevice()\n");
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600245 VkResult result = pInstTable->CreateDevice(gpu, pCreateInfo, pDevice);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600246 printf("Completed multi2 layer vkCreateDevice()\n");
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700247 return result;
248}
249
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600250VK_LAYER_EXPORT VkResult VKAPI multi2CreateCommandBuffer(VkDevice device, const VkCmdBufferCreateInfo* pCreateInfo,
251 VkCmdBuffer* pCmdBuffer)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700252{
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600253 VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) device;
254 VkLayerDispatchTable *pTable = tableMap2[*ppDisp];
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);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600258 printf("Completed multi2 layer vkCreateCommandBuffer()\n");
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700259 return result;
260}
261
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600262VK_LAYER_EXPORT VkResult VKAPI multi2BeginCommandBuffer(VkCmdBuffer cmdBuffer, const VkCmdBufferBeginInfo* pBeginInfo)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700263{
Jon Ashburnd25a78e2015-05-15 16:40:25 -0600264 VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) cmdBuffer;
265 VkLayerDispatchTable *pTable = tableMap2[*ppDisp];
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700266
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600267 printf("At start of multi2 layer vkBeginCommandBuffer()\n");
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600268 VkResult result = pTable->BeginCommandBuffer(cmdBuffer, pBeginInfo);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600269 printf("Completed multi2 layer vkBeginCommandBuffer()\n");
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700270 return result;
271
272}
273
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -0600274VK_LAYER_EXPORT VkResult VKAPI multi2EnumerateLayers(VkPhysicalDevice gpu, size_t maxStringSize,
275 size_t* pLayerCount, char* const* pOutLayers,
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600276 void* pReserved)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700277{
278 if (gpu == NULL)
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -0600279 return vkEnumerateLayers(gpu, maxStringSize, pLayerCount, pOutLayers, pReserved);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700280
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600281 VkLayerInstanceDispatchTable* pTable = tableInstanceMap2[gpu];
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700282
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600283 printf("At start of multi2 layer vkEnumerateLayers()\n");
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -0600284 VkResult result = pTable->EnumerateLayers(gpu, maxStringSize, pLayerCount, pOutLayers, pReserved);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600285 printf("Completed multi2 layer vkEnumerateLayers()\n");
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700286 return result;
287}
288
Jon Ashburn1245cec2015-05-18 13:20:15 -0600289VK_LAYER_EXPORT void * VKAPI multi2GetDeviceProcAddr(VkDevice device, const char* pName)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700290{
Jon Ashburn1245cec2015-05-18 13:20:15 -0600291 VkBaseLayerObject* devw = (VkBaseLayerObject *) device;
Chia-I Wue9ae3882015-01-05 09:41:27 +0800292
Jon Ashburn1245cec2015-05-18 13:20:15 -0600293 if (device == NULL)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700294 return NULL;
Chia-I Wue9ae3882015-01-05 09:41:27 +0800295
Jon Ashburn1245cec2015-05-18 13:20:15 -0600296 getLayer2Table(devw);
Chia-I Wue9ae3882015-01-05 09:41:27 +0800297
Jon Ashburn1245cec2015-05-18 13:20:15 -0600298 if (!strcmp("vkCreateCommandBuffer", pName))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600299 return (void *) multi2CreateCommandBuffer;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600300 else if (!strcmp("vkBeginCommandBuffer", pName))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600301 return (void *) multi2BeginCommandBuffer;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700302 else {
Jon Ashburn1245cec2015-05-18 13:20:15 -0600303 if (devw->pGPA == NULL)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700304 return NULL;
Jon Ashburn1245cec2015-05-18 13:20:15 -0600305 return devw->pGPA((VkObject) devw->nextObject, pName);
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600306 }
307}
308
Jon Ashburnd9564002015-05-07 10:27:37 -0600309VK_LAYER_EXPORT void * VKAPI multi2GetInstanceProcAddr(VkInstance inst, const char* pName)
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600310{
311 VkBaseLayerObject* instw = (VkBaseLayerObject *) inst;
312
313 if (inst == NULL)
314 return NULL;
315
Jon Ashburnd9564002015-05-07 10:27:37 -0600316 getLayer2InstanceTable(instw);
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600317
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600318 if (!strcmp("vkEnumeratePhysicalDevices", pName))
319 return (void *) multi2EnumeratePhysicalDevices;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600320 if (!strcmp("vkCreateDevice", pName))
321 return (void *) multi2CreateDevice;
322 else if (!strcmp("vkEnumerateLayers", pName))
323 return (void *) multi2EnumerateLayers;
324 else if (!strcmp("GetGlobalExtensionInfo", pName))
325 return (void*) vkGetGlobalExtensionInfo;
326 else {
327 if (instw->pGPA == NULL)
328 return NULL;
329 return instw->pGPA((VkObject) instw->nextObject, pName);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700330 }
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700331}
332
333/********************************* Common functions ********************************/
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -0600334VK_LAYER_EXPORT VkResult VKAPI vkEnumerateLayers(VkPhysicalDevice gpu, size_t maxStringSize,
335 size_t* pLayerCount, char* const* pOutLayers,
336 void* pReserved)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700337{
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -0600338 if (pLayerCount == NULL || pOutLayers == NULL || pOutLayers[0] == NULL || pOutLayers[1] == NULL || pReserved == NULL)
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600339 return VK_ERROR_INVALID_POINTER;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700340
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -0600341 if (*pLayerCount < 2)
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600342 return VK_ERROR_INITIALIZATION_FAILED;
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -0600343 *pLayerCount = 2;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700344 strncpy((char *) pOutLayers[0], "multi1", maxStringSize);
345 strncpy((char *) pOutLayers[1], "multi2", maxStringSize);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600346 return VK_SUCCESS;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700347}
348
Jon Ashburneb2728b2015-04-10 14:33:07 -0600349struct extProps {
350 uint32_t version;
351 const char * const name;
352};
353
354#define MULTI_LAYER_EXT_ARRAY_SIZE 2
355static const struct extProps multiExts[MULTI_LAYER_EXT_ARRAY_SIZE] = {
356 // TODO what is the version?
357 0x10, "multi1",
358 0x10, "multi2",
359};
360
361VK_LAYER_EXPORT VkResult VKAPI vkGetGlobalExtensionInfo(
362 VkExtensionInfoType infoType,
363 uint32_t extensionIndex,
364 size_t* pDataSize,
365 void* pData)
366{
Jon Ashburneb2728b2015-04-10 14:33:07 -0600367 /* This entrypoint is NOT going to init it's own dispatch table since loader calls here early */
368 VkExtensionProperties *ext_props;
369 uint32_t *count;
370
371 if (pDataSize == NULL)
372 return VK_ERROR_INVALID_POINTER;
373
374 switch (infoType) {
375 case VK_EXTENSION_INFO_TYPE_COUNT:
376 *pDataSize = sizeof(uint32_t);
377 if (pData == NULL)
378 return VK_SUCCESS;
379 count = (uint32_t *) pData;
380 *count = MULTI_LAYER_EXT_ARRAY_SIZE;
381 break;
382 case VK_EXTENSION_INFO_TYPE_PROPERTIES:
383 *pDataSize = sizeof(VkExtensionProperties);
384 if (pData == NULL)
385 return VK_SUCCESS;
386 if (extensionIndex >= MULTI_LAYER_EXT_ARRAY_SIZE)
387 return VK_ERROR_INVALID_VALUE;
388 ext_props = (VkExtensionProperties *) pData;
389 ext_props->version = multiExts[extensionIndex].version;
390 strncpy(ext_props->extName, multiExts[extensionIndex].name,
391 VK_MAX_EXTENSION_NAME);
392 ext_props->extName[VK_MAX_EXTENSION_NAME - 1] = '\0';
393 break;
394 default:
395 return VK_ERROR_INVALID_VALUE;
396 };
397
398 return VK_SUCCESS;
399}
400
Jon Ashburn1245cec2015-05-18 13:20:15 -0600401VK_LAYER_EXPORT void * VKAPI vkGetDeviceProcAddr(VkDevice device, const char* pName)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700402{
Jon Ashburn1245cec2015-05-18 13:20:15 -0600403 // to find each layers GPA routine Loader will search via "<layerName>GetDeviceProcAddr"
404 if (!strcmp("multi1GetDeviceProcAddr", pName))
405 return (void *) multi1GetDeviceProcAddr;
406 else if (!strcmp("multi2GetDeviceProcAddr", pName))
407 return (void *) multi2GetDeviceProcAddr;
408 else if (!strcmp("vkGetDeviceProcAddr", pName))
409 return (void *) vkGetDeviceProcAddr;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700410
411 // use first layer activated as GPA dispatch table activation happens in order
412 else if (layer1_first_activated)
Jon Ashburn1245cec2015-05-18 13:20:15 -0600413 return multi1GetDeviceProcAddr(device, pName);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700414 else if (layer2_first_activated)
Jon Ashburn1245cec2015-05-18 13:20:15 -0600415 return multi2GetDeviceProcAddr(device, pName);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700416 else
417 return NULL;
418
419}
420
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600421VK_LAYER_EXPORT void * VKAPI vkGetInstanceProcAddr(VkInstance inst, const char* pName)
422{
Jon Ashburn1245cec2015-05-18 13:20:15 -0600423 // to find each layers GPA routine Loader will search via "<layerName>GetInstanceProcAddr"
424 if (!strcmp("multi1GetInstanceProcAddr", pName))
Jon Ashburnd9564002015-05-07 10:27:37 -0600425 return (void *) multi1GetInstanceProcAddr;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600426 else if (!strcmp("multi2GetInstanceProcAddr", pName))
Jon Ashburnd9564002015-05-07 10:27:37 -0600427 return (void *) multi2GetInstanceProcAddr;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600428 else if (!strcmp("vkGetInstanceProcAddr", pName))
Jon Ashburn1245cec2015-05-18 13:20:15 -0600429 return (void *) vkGetInstanceProcAddr;
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600430
431 // use first layer activated as GPA dispatch table activation happens in order
432 else if (layer1_first_activated)
Jon Ashburnd9564002015-05-07 10:27:37 -0600433 return multi1GetInstanceProcAddr(inst, pName);
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600434 else if (layer2_first_activated)
Jon Ashburnd9564002015-05-07 10:27:37 -0600435 return multi2GetInstanceProcAddr(inst, pName);
Jon Ashburn79b78ac2015-05-05 14:22:52 -0600436 else
437 return NULL;
438
439}
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700440#ifdef __cplusplus
441} //extern "C"
442#endif
443
Jon Ashburn1245cec2015-05-18 13:20:15 -0600444static void initLayerTable(const VkBaseLayerObject *devw, VkLayerDispatchTable *pTable, const unsigned int layerNum)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700445{
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700446 if (layerNum == 2 && layer1_first_activated == false)
447 layer2_first_activated = true;
448 if (layerNum == 1 && layer2_first_activated == false)
449 layer1_first_activated = true;
450
Jon Ashburn1245cec2015-05-18 13:20:15 -0600451 layer_initialize_dispatch_table(pTable, (PFN_vkGetDeviceProcAddr) devw->pGPA, (VkDevice) devw->nextObject);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700452}
Jon Ashburnd9564002015-05-07 10:27:37 -0600453
454static void initLayerInstanceTable(const VkBaseLayerObject *instw, VkLayerInstanceDispatchTable *pTable, const unsigned int layerNum)
455{
456 if (layerNum == 2 && layer1_first_activated == false)
457 layer2_first_activated = true;
458 if (layerNum == 1 && layer2_first_activated == false)
459 layer1_first_activated = true;
460
461 layer_init_instance_dispatch_table(pTable, (PFN_vkGetInstanceProcAddr) instw->pGPA, (VkInstance) instw->nextObject);
462}