blob: e706bb39c1f772510e9946938f17e199bc6dc450 [file] [log] [blame]
Jon Ashburn79113cc2014-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 Wuaa4121f2015-01-04 23:11:43 +080030#include "xgl_dispatch_table_helper.h"
Jon Ashburn79113cc2014-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 **************************/
36static std::unordered_map<XGL_VOID *, XGL_LAYER_DISPATCH_TABLE *> tableMap1;
37static 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);
44 std::unordered_map<XGL_VOID *, XGL_LAYER_DISPATCH_TABLE *>::const_iterator it = tableMap1.find((XGL_VOID *) gpuw);
45 if (it == tableMap1.end())
46 {
47 pTable = new XGL_LAYER_DISPATCH_TABLE;
48 tableMap1[(XGL_VOID *) gpuw] = pTable;
49 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
88XGL_LAYER_EXPORT XGL_RESULT XGLAPI multi1StorePipeline(XGL_PIPELINE pipeline, XGL_SIZE* pDataSize, XGL_VOID* pData)
89{
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
98XGL_LAYER_EXPORT XGL_RESULT XGLAPI multi1EnumerateLayers(XGL_PHYSICAL_GPU gpu, XGL_SIZE maxLayerCount, XGL_SIZE maxStringSize,
Mark Lobodzinski391bb6d2015-01-09 15:12:03 -060099 XGL_SIZE* pOutLayerCount, XGL_CHAR* const* pOutLayers,
Jon Ashburn79113cc2014-12-01 14:22:40 -0700100 XGL_VOID* pReserved)
101{
102 if (gpu == NULL)
Mark Lobodzinski391bb6d2015-01-09 15:12:03 -0600103 return xglEnumerateLayers(gpu, maxLayerCount, maxStringSize, pOutLayerCount, pOutLayers, pReserved);
Jon Ashburn79113cc2014-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 Lobodzinski391bb6d2015-01-09 15:12:03 -0600109 XGL_RESULT result = pTable->EnumerateLayers((XGL_PHYSICAL_GPU)gpuw->nextObject, maxLayerCount, maxStringSize, pOutLayerCount, pOutLayers, pReserved);
Jon Ashburn79113cc2014-12-01 14:22:40 -0700110 printf("Completed multi1 layer xglEnumerateLayers()\n");
111 return result;
112}
113
114XGL_LAYER_EXPORT XGL_VOID * XGLAPI multi1GetProcAddr(XGL_PHYSICAL_GPU gpu, const XGL_CHAR* pName)
115{
116 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
Chia-I Wub665d942015-01-05 09:41:27 +0800117
Jon Ashburn79113cc2014-12-01 14:22:40 -0700118 if (gpu == NULL)
119 return NULL;
Chia-I Wub665d942015-01-05 09:41:27 +0800120
121 getLayer1Table(gpuw);
122
123 if (!strncmp("xglCreateDevice", pName, sizeof ("xglCreateDevice")))
Jon Ashburn79113cc2014-12-01 14:22:40 -0700124 return (XGL_VOID *) multi1CreateDevice;
Chia-I Wuf1a5a742014-12-27 15:16:07 +0800125 else if (!strncmp("xglEnumerateLayers", pName, sizeof ("xglEnumerateLayers")))
Jon Ashburn79113cc2014-12-01 14:22:40 -0700126 return (XGL_VOID *) multi1EnumerateLayers;
Chia-I Wuf1a5a742014-12-27 15:16:07 +0800127 else if (!strncmp("xglCreateGraphicsPipeline", pName, sizeof ("xglCreateGraphicsPipeline")))
Jon Ashburn79113cc2014-12-01 14:22:40 -0700128 return (XGL_VOID *) multi1CreateGraphicsPipeline;
Chia-I Wuf1a5a742014-12-27 15:16:07 +0800129 else if (!strncmp("xglStorePipeline", pName, sizeof ("xglStorePipeline")))
Jon Ashburn79113cc2014-12-01 14:22:40 -0700130 return (XGL_VOID *) multi1StorePipeline;
Jon Ashburn79113cc2014-12-01 14:22:40 -0700131 else {
Jon Ashburn79113cc2014-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 Ashburn79113cc2014-12-01 14:22:40 -0700136}
137
138/******************************** Layer multi2 functions **************************/
139static std::unordered_map<XGL_VOID *, XGL_LAYER_DISPATCH_TABLE *> tableMap2;
140static 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);
147 std::unordered_map<XGL_VOID *, XGL_LAYER_DISPATCH_TABLE *>::const_iterator it = tableMap2.find((XGL_VOID *) gpuw);
148 if (it == tableMap2.end())
149 {
150 pTable = new XGL_LAYER_DISPATCH_TABLE;
151 tableMap2[(XGL_VOID *) gpuw] = pTable;
152 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 Ashburn86522372014-12-31 17:11:49 -0700187XGL_LAYER_EXPORT XGL_RESULT XGLAPI multi2BeginCommandBuffer( XGL_CMD_BUFFER cmdBuffer, const XGL_CMD_BUFFER_BEGIN_INFO* pBeginInfo)
Jon Ashburn79113cc2014-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 Ashburn86522372014-12-31 17:11:49 -0700192 XGL_RESULT result = pTable->BeginCommandBuffer(cmdBuffer, pBeginInfo);
Jon Ashburn79113cc2014-12-01 14:22:40 -0700193 printf("Completed multi2 layer xglBeginCommandBuffer()\n");
194 return result;
195
196}
197
198XGL_LAYER_EXPORT XGL_RESULT XGLAPI multi2EnumerateLayers(XGL_PHYSICAL_GPU gpu, XGL_SIZE maxLayerCount, XGL_SIZE maxStringSize,
Mark Lobodzinski391bb6d2015-01-09 15:12:03 -0600199 XGL_SIZE* pOutLayerCount, XGL_CHAR* const* pOutLayers,
Jon Ashburn79113cc2014-12-01 14:22:40 -0700200 XGL_VOID* pReserved)
201{
202 if (gpu == NULL)
Mark Lobodzinski391bb6d2015-01-09 15:12:03 -0600203 return xglEnumerateLayers(gpu, maxLayerCount, maxStringSize, pOutLayerCount, pOutLayers, pReserved);
Jon Ashburn79113cc2014-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 Lobodzinski391bb6d2015-01-09 15:12:03 -0600209 XGL_RESULT result = pTable->EnumerateLayers((XGL_PHYSICAL_GPU)gpuw->nextObject, maxLayerCount, maxStringSize, pOutLayerCount, pOutLayers, pReserved);
Jon Ashburn79113cc2014-12-01 14:22:40 -0700210 printf("Completed multi2 layer xglEnumerateLayers()\n");
211 return result;
212}
213
214XGL_LAYER_EXPORT XGL_VOID * XGLAPI multi2GetProcAddr(XGL_PHYSICAL_GPU gpu, const XGL_CHAR* pName)
215{
216 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
Chia-I Wub665d942015-01-05 09:41:27 +0800217
Jon Ashburn79113cc2014-12-01 14:22:40 -0700218 if (gpu == NULL)
219 return NULL;
Chia-I Wub665d942015-01-05 09:41:27 +0800220
221 getLayer2Table(gpuw);
222
223 if (!strncmp("xglCreateDevice", pName, sizeof ("xglCreateDevice")))
Jon Ashburn79113cc2014-12-01 14:22:40 -0700224 return (XGL_VOID *) multi2CreateDevice;
Chia-I Wuf1a5a742014-12-27 15:16:07 +0800225 else if (!strncmp("xglEnumerateLayers", pName, sizeof ("xglEnumerateLayers")))
Jon Ashburn79113cc2014-12-01 14:22:40 -0700226 return (XGL_VOID *) multi2EnumerateLayers;
Chia-I Wuf1a5a742014-12-27 15:16:07 +0800227 else if (!strncmp("xglCreateCommandBuffer", pName, sizeof ("xglCreateCommandBuffer")))
Jon Ashburn79113cc2014-12-01 14:22:40 -0700228 return (XGL_VOID *) multi2CreateCommandBuffer;
Chia-I Wuf1a5a742014-12-27 15:16:07 +0800229 else if (!strncmp("xglBeginCommandBuffer", pName, sizeof ("xglBeginCommandBuffer")))
Jon Ashburn79113cc2014-12-01 14:22:40 -0700230 return (XGL_VOID *) multi2BeginCommandBuffer;
Jon Ashburn79113cc2014-12-01 14:22:40 -0700231 else {
Jon Ashburn79113cc2014-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 Ashburn79113cc2014-12-01 14:22:40 -0700236}
237
238/********************************* Common functions ********************************/
239XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglEnumerateLayers(XGL_PHYSICAL_GPU gpu, XGL_SIZE maxLayerCount, XGL_SIZE maxStringSize,
Mark Lobodzinski391bb6d2015-01-09 15:12:03 -0600240 XGL_SIZE* pOutLayerCount, XGL_CHAR* const* pOutLayers,
Jon Ashburn79113cc2014-12-01 14:22:40 -0700241 XGL_VOID* pReserved)
242{
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
254XGL_LAYER_EXPORT XGL_VOID * XGLAPI xglGetProcAddr(XGL_PHYSICAL_GPU gpu, const XGL_CHAR* pName)
255{
256 // to find each layers GPA routine Loader will search via "<layerName>GetProcAddr"
Chia-I Wuf1a5a742014-12-27 15:16:07 +0800257 if (!strncmp("multi1GetProcAddr", pName, sizeof("multi1GetProcAddr")))
Jon Ashburn79113cc2014-12-01 14:22:40 -0700258 return (XGL_VOID *) multi1GetProcAddr;
Chia-I Wuf1a5a742014-12-27 15:16:07 +0800259 else if (!strncmp("multi2GetProcAddr", pName, sizeof("multi2GetProcAddr")))
Jon Ashburn79113cc2014-12-01 14:22:40 -0700260 return (XGL_VOID *) multi2GetProcAddr;
Chia-I Wuf1a5a742014-12-27 15:16:07 +0800261 else if (!strncmp("xglGetProcAddr", pName, sizeof("xglGetProcAddr")))
Jon Ashburn79113cc2014-12-01 14:22:40 -0700262 return (XGL_VOID *) xglGetProcAddr;
263
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 Ashburn79113cc2014-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 Wuaa4121f2015-01-04 23:11:43 +0800285 layer_initialize_dispatch_table(pTable, gpuw->pGPA, (XGL_PHYSICAL_GPU) gpuw->nextObject);
Jon Ashburn79113cc2014-12-01 14:22:40 -0700286}