blob: b8c9631c28cedd8721c792201ff7251c2348be0f [file] [log] [blame]
Jon Ashburn8d8dad02014-12-01 14:22:40 -07001/*
2 * XGL
3 *
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>
Chia-I Wu0f65b1e2015-01-04 23:11:43 +080030#include "xgl_dispatch_table_helper.h"
Jon Ashburn8d8dad02014-12-01 14:22:40 -070031#include "xglLayer.h"
32
33static void initLayerTable(const XGL_BASE_LAYER_OBJECT *gpuw, XGL_LAYER_DISPATCH_TABLE *pTable, const unsigned int layerNum);
34
35/******************************** Layer multi1 functions **************************/
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -060036static std::unordered_map<void *, XGL_LAYER_DISPATCH_TABLE *> tableMap1;
Jon Ashburn8d8dad02014-12-01 14:22:40 -070037static bool layer1_first_activated = false;
38
39static XGL_LAYER_DISPATCH_TABLE * getLayer1Table(const XGL_BASE_LAYER_OBJECT *gpuw)
40{
41 XGL_LAYER_DISPATCH_TABLE *pTable;
42
43 assert(gpuw);
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -060044 std::unordered_map<void *, XGL_LAYER_DISPATCH_TABLE *>::const_iterator it = tableMap1.find((void *) gpuw);
Jon Ashburn8d8dad02014-12-01 14:22:40 -070045 if (it == tableMap1.end())
46 {
47 pTable = new XGL_LAYER_DISPATCH_TABLE;
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -060048 tableMap1[(void *) gpuw] = pTable;
Jon Ashburn8d8dad02014-12-01 14:22:40 -070049 initLayerTable(gpuw, pTable, 1);
50 return pTable;
51 } else
52 {
53 return it->second;
54 }
55}
56#ifdef __cplusplus
57extern "C" {
58#endif
59
60
61XGL_LAYER_EXPORT XGL_RESULT XGLAPI multi1CreateDevice(XGL_PHYSICAL_GPU gpu, const XGL_DEVICE_CREATE_INFO* pCreateInfo,
62 XGL_DEVICE* pDevice)
63{
64 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
65 XGL_LAYER_DISPATCH_TABLE* pTable = getLayer1Table(gpuw);
66
67 printf("At start of multi1 layer xglCreateDevice()\n");
68 XGL_RESULT result = pTable->CreateDevice((XGL_PHYSICAL_GPU)gpuw->nextObject, pCreateInfo, pDevice);
69 // create a mapping for the device object into the dispatch table
70 tableMap1.emplace(*pDevice, pTable);
71 printf("Completed multi1 layer xglCreateDevice()\n");
72 return result;
73}
74
75XGL_LAYER_EXPORT XGL_RESULT XGLAPI multi1CreateGraphicsPipeline(XGL_DEVICE device, const XGL_GRAPHICS_PIPELINE_CREATE_INFO* pCreateInfo,
76 XGL_PIPELINE* pPipeline)
77{
78 XGL_LAYER_DISPATCH_TABLE* pTable = tableMap1[device];
79
80 printf("At start of multi1 layer xglCreateGraphicsPipeline()\n");
81 XGL_RESULT result = pTable->CreateGraphicsPipeline(device, pCreateInfo, pPipeline);
82 // create a mapping for the pipeline object into the dispatch table
83 tableMap1.emplace(*pPipeline, pTable);
84 printf("Completed multi1 layer xglCreateGraphicsPipeline()\n");
85 return result;
86}
87
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -060088XGL_LAYER_EXPORT XGL_RESULT XGLAPI multi1StorePipeline(XGL_PIPELINE pipeline, size_t* pDataSize, void* pData)
Jon Ashburn8d8dad02014-12-01 14:22:40 -070089{
90 XGL_LAYER_DISPATCH_TABLE* pTable = tableMap1[pipeline];
91
92 printf("At start of multi1 layer xglStorePipeline()\n");
93 XGL_RESULT result = pTable->StorePipeline(pipeline, pDataSize, pData);
94 printf("Completed multi1 layer xglStorePipeline()\n");
95 return result;
96}
97
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -060098XGL_LAYER_EXPORT XGL_RESULT XGLAPI multi1EnumerateLayers(XGL_PHYSICAL_GPU gpu, size_t maxLayerCount, size_t maxStringSize,
99 size_t* pOutLayerCount, char* const* pOutLayers,
100 void* pReserved)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700101{
102 if (gpu == NULL)
Mark Lobodzinski953a1692015-01-09 15:12:03 -0600103 return xglEnumerateLayers(gpu, maxLayerCount, maxStringSize, pOutLayerCount, pOutLayers, pReserved);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700104
105 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
106 XGL_LAYER_DISPATCH_TABLE* pTable = getLayer1Table(gpuw);
107
108 printf("At start of multi1 layer xglEnumerateLayers()\n");
Mark Lobodzinski953a1692015-01-09 15:12:03 -0600109 XGL_RESULT result = pTable->EnumerateLayers((XGL_PHYSICAL_GPU)gpuw->nextObject, maxLayerCount, maxStringSize, pOutLayerCount, pOutLayers, pReserved);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700110 printf("Completed multi1 layer xglEnumerateLayers()\n");
111 return result;
112}
113
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600114XGL_LAYER_EXPORT void * XGLAPI multi1GetProcAddr(XGL_PHYSICAL_GPU gpu, const char* pName)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700115{
116 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
Chia-I Wue9ae3882015-01-05 09:41:27 +0800117
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700118 if (gpu == NULL)
119 return NULL;
Chia-I Wue9ae3882015-01-05 09:41:27 +0800120
121 getLayer1Table(gpuw);
122
123 if (!strncmp("xglCreateDevice", pName, sizeof ("xglCreateDevice")))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600124 return (void *) multi1CreateDevice;
Chia-I Wu7461fcf2014-12-27 15:16:07 +0800125 else if (!strncmp("xglEnumerateLayers", pName, sizeof ("xglEnumerateLayers")))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600126 return (void *) multi1EnumerateLayers;
Chia-I Wu7461fcf2014-12-27 15:16:07 +0800127 else if (!strncmp("xglCreateGraphicsPipeline", pName, sizeof ("xglCreateGraphicsPipeline")))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600128 return (void *) multi1CreateGraphicsPipeline;
Chia-I Wu7461fcf2014-12-27 15:16:07 +0800129 else if (!strncmp("xglStorePipeline", pName, sizeof ("xglStorePipeline")))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600130 return (void *) multi1StorePipeline;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700131 else {
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700132 if (gpuw->pGPA == NULL)
133 return NULL;
134 return gpuw->pGPA((XGL_PHYSICAL_GPU) gpuw->nextObject, pName);
135 }
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700136}
137
138/******************************** Layer multi2 functions **************************/
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600139static std::unordered_map<void *, XGL_LAYER_DISPATCH_TABLE *> tableMap2;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700140static bool layer2_first_activated = false;
141
142static XGL_LAYER_DISPATCH_TABLE * getLayer2Table(const XGL_BASE_LAYER_OBJECT *gpuw)
143{
144 XGL_LAYER_DISPATCH_TABLE *pTable;
145
146 assert(gpuw);
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600147 std::unordered_map<void *, XGL_LAYER_DISPATCH_TABLE *>::const_iterator it = tableMap2.find((void *) gpuw);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700148 if (it == tableMap2.end())
149 {
150 pTable = new XGL_LAYER_DISPATCH_TABLE;
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600151 tableMap2[(void *) gpuw] = pTable;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700152 initLayerTable(gpuw, pTable, 2);
153 return pTable;
154 } else
155 {
156 return it->second;
157 }
158}
159
160XGL_LAYER_EXPORT XGL_RESULT XGLAPI multi2CreateDevice(XGL_PHYSICAL_GPU gpu, const XGL_DEVICE_CREATE_INFO* pCreateInfo,
161 XGL_DEVICE* pDevice)
162{
163 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
164 XGL_LAYER_DISPATCH_TABLE* pTable = getLayer2Table(gpuw);
165
166 printf("At start of multi2 xglCreateDevice()\n");
167 XGL_RESULT result = pTable->CreateDevice((XGL_PHYSICAL_GPU)gpuw->nextObject, pCreateInfo, pDevice);
168 // create a mapping for the device object into the dispatch table for layer2
169 tableMap2.emplace(*pDevice, pTable);
170 printf("Completed multi2 layer xglCreateDevice()\n");
171 return result;
172}
173
174XGL_LAYER_EXPORT XGL_RESULT XGLAPI multi2CreateCommandBuffer(XGL_DEVICE device, const XGL_CMD_BUFFER_CREATE_INFO* pCreateInfo,
175 XGL_CMD_BUFFER* pCmdBuffer)
176{
177 XGL_LAYER_DISPATCH_TABLE* pTable = tableMap2[device];
178
179 printf("At start of multi2 layer xglCreateCommandBuffer()\n");
180 XGL_RESULT result = pTable->CreateCommandBuffer(device, pCreateInfo, pCmdBuffer);
181 // create a mapping for CmdBuffer object into the dispatch table for layer 2
182 tableMap2.emplace(*pCmdBuffer, pTable);
183 printf("Completed multi2 layer xglCreateCommandBuffer()\n");
184 return result;
185}
186
Jon Ashburn57ba18d2014-12-31 17:11:49 -0700187XGL_LAYER_EXPORT XGL_RESULT XGLAPI multi2BeginCommandBuffer( XGL_CMD_BUFFER cmdBuffer, const XGL_CMD_BUFFER_BEGIN_INFO* pBeginInfo)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700188{
189 XGL_LAYER_DISPATCH_TABLE* pTable = tableMap2[cmdBuffer];
190
191 printf("At start of multi2 layer xglBeginCommandBuffer()\n");
Jon Ashburn57ba18d2014-12-31 17:11:49 -0700192 XGL_RESULT result = pTable->BeginCommandBuffer(cmdBuffer, pBeginInfo);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700193 printf("Completed multi2 layer xglBeginCommandBuffer()\n");
194 return result;
195
196}
197
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600198XGL_LAYER_EXPORT XGL_RESULT XGLAPI multi2EnumerateLayers(XGL_PHYSICAL_GPU gpu, size_t maxLayerCount, size_t maxStringSize,
199 size_t* pOutLayerCount, char* const* pOutLayers,
200 void* pReserved)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700201{
202 if (gpu == NULL)
Mark Lobodzinski953a1692015-01-09 15:12:03 -0600203 return xglEnumerateLayers(gpu, maxLayerCount, maxStringSize, pOutLayerCount, pOutLayers, pReserved);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700204
205 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
206 XGL_LAYER_DISPATCH_TABLE* pTable = getLayer2Table(gpuw);
207
208 printf("At start of multi2 layer xglEnumerateLayers()\n");
Mark Lobodzinski953a1692015-01-09 15:12:03 -0600209 XGL_RESULT result = pTable->EnumerateLayers((XGL_PHYSICAL_GPU)gpuw->nextObject, maxLayerCount, maxStringSize, pOutLayerCount, pOutLayers, pReserved);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700210 printf("Completed multi2 layer xglEnumerateLayers()\n");
211 return result;
212}
213
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600214XGL_LAYER_EXPORT void * XGLAPI multi2GetProcAddr(XGL_PHYSICAL_GPU gpu, const char* pName)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700215{
216 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
Chia-I Wue9ae3882015-01-05 09:41:27 +0800217
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700218 if (gpu == NULL)
219 return NULL;
Chia-I Wue9ae3882015-01-05 09:41:27 +0800220
221 getLayer2Table(gpuw);
222
223 if (!strncmp("xglCreateDevice", pName, sizeof ("xglCreateDevice")))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600224 return (void *) multi2CreateDevice;
Chia-I Wu7461fcf2014-12-27 15:16:07 +0800225 else if (!strncmp("xglEnumerateLayers", pName, sizeof ("xglEnumerateLayers")))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600226 return (void *) multi2EnumerateLayers;
Chia-I Wu7461fcf2014-12-27 15:16:07 +0800227 else if (!strncmp("xglCreateCommandBuffer", pName, sizeof ("xglCreateCommandBuffer")))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600228 return (void *) multi2CreateCommandBuffer;
Chia-I Wu7461fcf2014-12-27 15:16:07 +0800229 else if (!strncmp("xglBeginCommandBuffer", pName, sizeof ("xglBeginCommandBuffer")))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600230 return (void *) multi2BeginCommandBuffer;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700231 else {
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700232 if (gpuw->pGPA == NULL)
233 return NULL;
234 return gpuw->pGPA((XGL_PHYSICAL_GPU) gpuw->nextObject, pName);
235 }
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700236}
237
238/********************************* Common functions ********************************/
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600239XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglEnumerateLayers(XGL_PHYSICAL_GPU gpu, size_t maxLayerCount, size_t maxStringSize,
240 size_t* pOutLayerCount, char* const* pOutLayers,
241 void* pReserved)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700242{
243 if (pOutLayerCount == NULL || pOutLayers == NULL || pOutLayers[0] == NULL || pOutLayers[1] == NULL || pReserved == NULL)
244 return XGL_ERROR_INVALID_POINTER;
245
246 if (maxLayerCount < 2)
247 return XGL_ERROR_INITIALIZATION_FAILED;
248 *pOutLayerCount = 2;
249 strncpy((char *) pOutLayers[0], "multi1", maxStringSize);
250 strncpy((char *) pOutLayers[1], "multi2", maxStringSize);
251 return XGL_SUCCESS;
252}
253
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600254XGL_LAYER_EXPORT void * XGLAPI xglGetProcAddr(XGL_PHYSICAL_GPU gpu, const char* pName)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700255{
256 // to find each layers GPA routine Loader will search via "<layerName>GetProcAddr"
Chia-I Wu7461fcf2014-12-27 15:16:07 +0800257 if (!strncmp("multi1GetProcAddr", pName, sizeof("multi1GetProcAddr")))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600258 return (void *) multi1GetProcAddr;
Chia-I Wu7461fcf2014-12-27 15:16:07 +0800259 else if (!strncmp("multi2GetProcAddr", pName, sizeof("multi2GetProcAddr")))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600260 return (void *) multi2GetProcAddr;
Chia-I Wu7461fcf2014-12-27 15:16:07 +0800261 else if (!strncmp("xglGetProcAddr", pName, sizeof("xglGetProcAddr")))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600262 return (void *) xglGetProcAddr;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700263
264 // use first layer activated as GPA dispatch table activation happens in order
265 else if (layer1_first_activated)
266 return multi1GetProcAddr(gpu, pName);
267 else if (layer2_first_activated)
268 return multi2GetProcAddr(gpu, pName);
269 else
270 return NULL;
271
272}
273
274#ifdef __cplusplus
275} //extern "C"
276#endif
277
278static void initLayerTable(const XGL_BASE_LAYER_OBJECT *gpuw, XGL_LAYER_DISPATCH_TABLE *pTable, const unsigned int layerNum)
279{
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700280 if (layerNum == 2 && layer1_first_activated == false)
281 layer2_first_activated = true;
282 if (layerNum == 1 && layer2_first_activated == false)
283 layer1_first_activated = true;
284
Chia-I Wu0f65b1e2015-01-04 23:11:43 +0800285 layer_initialize_dispatch_table(pTable, gpuw->pGPA, (XGL_PHYSICAL_GPU) gpuw->nextObject);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700286}