blob: f8c2bc9ffd2b18bd12653bde1a78548a9935873d [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>
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070030#include "loader_platform.h"
Chia-I Wuaa4121f2015-01-04 23:11:43 +080031#include "xgl_dispatch_table_helper.h"
Jon Ashburn79113cc2014-12-01 14:22:40 -070032#include "xglLayer.h"
Ian Elliott655cad72015-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 Ashburn79113cc2014-12-01 14:22:40 -070036
37static void initLayerTable(const XGL_BASE_LAYER_OBJECT *gpuw, XGL_LAYER_DISPATCH_TABLE *pTable, const unsigned int layerNum);
38
39/******************************** Layer multi1 functions **************************/
Mark Lobodzinski17caf572015-01-29 08:55:56 -060040static std::unordered_map<void *, XGL_LAYER_DISPATCH_TABLE *> tableMap1;
Jon Ashburn79113cc2014-12-01 14:22:40 -070041static bool layer1_first_activated = false;
42
43static XGL_LAYER_DISPATCH_TABLE * getLayer1Table(const XGL_BASE_LAYER_OBJECT *gpuw)
44{
45 XGL_LAYER_DISPATCH_TABLE *pTable;
46
47 assert(gpuw);
Mark Lobodzinski17caf572015-01-29 08:55:56 -060048 std::unordered_map<void *, XGL_LAYER_DISPATCH_TABLE *>::const_iterator it = tableMap1.find((void *) gpuw);
Jon Ashburn79113cc2014-12-01 14:22:40 -070049 if (it == tableMap1.end())
50 {
51 pTable = new XGL_LAYER_DISPATCH_TABLE;
Mark Lobodzinski17caf572015-01-29 08:55:56 -060052 tableMap1[(void *) gpuw] = pTable;
Jon Ashburn79113cc2014-12-01 14:22:40 -070053 initLayerTable(gpuw, pTable, 1);
54 return pTable;
55 } else
56 {
57 return it->second;
58 }
59}
60#ifdef __cplusplus
61extern "C" {
62#endif
63
64
65XGL_LAYER_EXPORT XGL_RESULT XGLAPI multi1CreateDevice(XGL_PHYSICAL_GPU gpu, const XGL_DEVICE_CREATE_INFO* pCreateInfo,
66 XGL_DEVICE* pDevice)
67{
68 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
69 XGL_LAYER_DISPATCH_TABLE* pTable = getLayer1Table(gpuw);
70
71 printf("At start of multi1 layer xglCreateDevice()\n");
72 XGL_RESULT result = pTable->CreateDevice((XGL_PHYSICAL_GPU)gpuw->nextObject, pCreateInfo, pDevice);
73 // create a mapping for the device object into the dispatch table
74 tableMap1.emplace(*pDevice, pTable);
75 printf("Completed multi1 layer xglCreateDevice()\n");
76 return result;
77}
78
79XGL_LAYER_EXPORT XGL_RESULT XGLAPI multi1CreateGraphicsPipeline(XGL_DEVICE device, const XGL_GRAPHICS_PIPELINE_CREATE_INFO* pCreateInfo,
80 XGL_PIPELINE* pPipeline)
81{
82 XGL_LAYER_DISPATCH_TABLE* pTable = tableMap1[device];
83
84 printf("At start of multi1 layer xglCreateGraphicsPipeline()\n");
85 XGL_RESULT result = pTable->CreateGraphicsPipeline(device, pCreateInfo, pPipeline);
86 // create a mapping for the pipeline object into the dispatch table
87 tableMap1.emplace(*pPipeline, pTable);
88 printf("Completed multi1 layer xglCreateGraphicsPipeline()\n");
89 return result;
90}
91
Mark Lobodzinski17caf572015-01-29 08:55:56 -060092XGL_LAYER_EXPORT XGL_RESULT XGLAPI multi1StorePipeline(XGL_PIPELINE pipeline, size_t* pDataSize, void* pData)
Jon Ashburn79113cc2014-12-01 14:22:40 -070093{
94 XGL_LAYER_DISPATCH_TABLE* pTable = tableMap1[pipeline];
95
96 printf("At start of multi1 layer xglStorePipeline()\n");
97 XGL_RESULT result = pTable->StorePipeline(pipeline, pDataSize, pData);
98 printf("Completed multi1 layer xglStorePipeline()\n");
99 return result;
100}
101
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600102XGL_LAYER_EXPORT XGL_RESULT XGLAPI multi1EnumerateLayers(XGL_PHYSICAL_GPU gpu, size_t maxLayerCount, size_t maxStringSize,
103 size_t* pOutLayerCount, char* const* pOutLayers,
104 void* pReserved)
Jon Ashburn79113cc2014-12-01 14:22:40 -0700105{
106 if (gpu == NULL)
Mark Lobodzinski391bb6d2015-01-09 15:12:03 -0600107 return xglEnumerateLayers(gpu, maxLayerCount, maxStringSize, pOutLayerCount, pOutLayers, pReserved);
Jon Ashburn79113cc2014-12-01 14:22:40 -0700108
109 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
110 XGL_LAYER_DISPATCH_TABLE* pTable = getLayer1Table(gpuw);
111
112 printf("At start of multi1 layer xglEnumerateLayers()\n");
Mark Lobodzinski391bb6d2015-01-09 15:12:03 -0600113 XGL_RESULT result = pTable->EnumerateLayers((XGL_PHYSICAL_GPU)gpuw->nextObject, maxLayerCount, maxStringSize, pOutLayerCount, pOutLayers, pReserved);
Jon Ashburn79113cc2014-12-01 14:22:40 -0700114 printf("Completed multi1 layer xglEnumerateLayers()\n");
115 return result;
116}
117
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600118XGL_LAYER_EXPORT void * XGLAPI multi1GetProcAddr(XGL_PHYSICAL_GPU gpu, const char* pName)
Jon Ashburn79113cc2014-12-01 14:22:40 -0700119{
120 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
Chia-I Wub665d942015-01-05 09:41:27 +0800121
Jon Ashburn79113cc2014-12-01 14:22:40 -0700122 if (gpu == NULL)
123 return NULL;
Chia-I Wub665d942015-01-05 09:41:27 +0800124
125 getLayer1Table(gpuw);
126
127 if (!strncmp("xglCreateDevice", pName, sizeof ("xglCreateDevice")))
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600128 return (void *) multi1CreateDevice;
Chia-I Wuf1a5a742014-12-27 15:16:07 +0800129 else if (!strncmp("xglEnumerateLayers", pName, sizeof ("xglEnumerateLayers")))
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600130 return (void *) multi1EnumerateLayers;
Chia-I Wuf1a5a742014-12-27 15:16:07 +0800131 else if (!strncmp("xglCreateGraphicsPipeline", pName, sizeof ("xglCreateGraphicsPipeline")))
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600132 return (void *) multi1CreateGraphicsPipeline;
Chia-I Wuf1a5a742014-12-27 15:16:07 +0800133 else if (!strncmp("xglStorePipeline", pName, sizeof ("xglStorePipeline")))
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600134 return (void *) multi1StorePipeline;
Jon Ashburn5f3960e2015-04-02 12:06:28 -0600135 else if (!strncmp("xglGetExtensionSupport", pName, sizeof ("xglGetExtensionSupport")))
136 return (void *) xglGetExtensionSupport;
Jon Ashburn79113cc2014-12-01 14:22:40 -0700137 else {
Jon Ashburn79113cc2014-12-01 14:22:40 -0700138 if (gpuw->pGPA == NULL)
139 return NULL;
140 return gpuw->pGPA((XGL_PHYSICAL_GPU) gpuw->nextObject, pName);
141 }
Jon Ashburn79113cc2014-12-01 14:22:40 -0700142}
143
144/******************************** Layer multi2 functions **************************/
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600145static std::unordered_map<void *, XGL_LAYER_DISPATCH_TABLE *> tableMap2;
Jon Ashburn79113cc2014-12-01 14:22:40 -0700146static bool layer2_first_activated = false;
147
148static XGL_LAYER_DISPATCH_TABLE * getLayer2Table(const XGL_BASE_LAYER_OBJECT *gpuw)
149{
150 XGL_LAYER_DISPATCH_TABLE *pTable;
151
152 assert(gpuw);
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600153 std::unordered_map<void *, XGL_LAYER_DISPATCH_TABLE *>::const_iterator it = tableMap2.find((void *) gpuw);
Jon Ashburn79113cc2014-12-01 14:22:40 -0700154 if (it == tableMap2.end())
155 {
156 pTable = new XGL_LAYER_DISPATCH_TABLE;
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600157 tableMap2[(void *) gpuw] = pTable;
Jon Ashburn79113cc2014-12-01 14:22:40 -0700158 initLayerTable(gpuw, pTable, 2);
159 return pTable;
160 } else
161 {
162 return it->second;
163 }
164}
165
166XGL_LAYER_EXPORT XGL_RESULT XGLAPI multi2CreateDevice(XGL_PHYSICAL_GPU gpu, const XGL_DEVICE_CREATE_INFO* pCreateInfo,
167 XGL_DEVICE* pDevice)
168{
169 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
170 XGL_LAYER_DISPATCH_TABLE* pTable = getLayer2Table(gpuw);
171
172 printf("At start of multi2 xglCreateDevice()\n");
173 XGL_RESULT result = pTable->CreateDevice((XGL_PHYSICAL_GPU)gpuw->nextObject, pCreateInfo, pDevice);
174 // create a mapping for the device object into the dispatch table for layer2
175 tableMap2.emplace(*pDevice, pTable);
176 printf("Completed multi2 layer xglCreateDevice()\n");
177 return result;
178}
179
180XGL_LAYER_EXPORT XGL_RESULT XGLAPI multi2CreateCommandBuffer(XGL_DEVICE device, const XGL_CMD_BUFFER_CREATE_INFO* pCreateInfo,
181 XGL_CMD_BUFFER* pCmdBuffer)
182{
183 XGL_LAYER_DISPATCH_TABLE* pTable = tableMap2[device];
184
185 printf("At start of multi2 layer xglCreateCommandBuffer()\n");
186 XGL_RESULT result = pTable->CreateCommandBuffer(device, pCreateInfo, pCmdBuffer);
187 // create a mapping for CmdBuffer object into the dispatch table for layer 2
188 tableMap2.emplace(*pCmdBuffer, pTable);
189 printf("Completed multi2 layer xglCreateCommandBuffer()\n");
190 return result;
191}
192
Tobin Ehlis7e65d752015-01-15 17:51:52 -0700193XGL_LAYER_EXPORT XGL_RESULT XGLAPI multi2BeginCommandBuffer(XGL_CMD_BUFFER cmdBuffer, const XGL_CMD_BUFFER_BEGIN_INFO* pBeginInfo)
Jon Ashburn79113cc2014-12-01 14:22:40 -0700194{
195 XGL_LAYER_DISPATCH_TABLE* pTable = tableMap2[cmdBuffer];
196
197 printf("At start of multi2 layer xglBeginCommandBuffer()\n");
Jon Ashburn86522372014-12-31 17:11:49 -0700198 XGL_RESULT result = pTable->BeginCommandBuffer(cmdBuffer, pBeginInfo);
Jon Ashburn79113cc2014-12-01 14:22:40 -0700199 printf("Completed multi2 layer xglBeginCommandBuffer()\n");
200 return result;
201
202}
203
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600204XGL_LAYER_EXPORT XGL_RESULT XGLAPI multi2EnumerateLayers(XGL_PHYSICAL_GPU gpu, size_t maxLayerCount, size_t maxStringSize,
205 size_t* pOutLayerCount, char* const* pOutLayers,
206 void* pReserved)
Jon Ashburn79113cc2014-12-01 14:22:40 -0700207{
208 if (gpu == NULL)
Mark Lobodzinski391bb6d2015-01-09 15:12:03 -0600209 return xglEnumerateLayers(gpu, maxLayerCount, maxStringSize, pOutLayerCount, pOutLayers, pReserved);
Jon Ashburn79113cc2014-12-01 14:22:40 -0700210
211 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
212 XGL_LAYER_DISPATCH_TABLE* pTable = getLayer2Table(gpuw);
213
214 printf("At start of multi2 layer xglEnumerateLayers()\n");
Mark Lobodzinski391bb6d2015-01-09 15:12:03 -0600215 XGL_RESULT result = pTable->EnumerateLayers((XGL_PHYSICAL_GPU)gpuw->nextObject, maxLayerCount, maxStringSize, pOutLayerCount, pOutLayers, pReserved);
Jon Ashburn79113cc2014-12-01 14:22:40 -0700216 printf("Completed multi2 layer xglEnumerateLayers()\n");
217 return result;
218}
219
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600220XGL_LAYER_EXPORT void * XGLAPI multi2GetProcAddr(XGL_PHYSICAL_GPU gpu, const char* pName)
Jon Ashburn79113cc2014-12-01 14:22:40 -0700221{
222 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
Chia-I Wub665d942015-01-05 09:41:27 +0800223
Jon Ashburn79113cc2014-12-01 14:22:40 -0700224 if (gpu == NULL)
225 return NULL;
Chia-I Wub665d942015-01-05 09:41:27 +0800226
227 getLayer2Table(gpuw);
228
229 if (!strncmp("xglCreateDevice", pName, sizeof ("xglCreateDevice")))
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600230 return (void *) multi2CreateDevice;
Chia-I Wuf1a5a742014-12-27 15:16:07 +0800231 else if (!strncmp("xglEnumerateLayers", pName, sizeof ("xglEnumerateLayers")))
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600232 return (void *) multi2EnumerateLayers;
Chia-I Wuf1a5a742014-12-27 15:16:07 +0800233 else if (!strncmp("xglCreateCommandBuffer", pName, sizeof ("xglCreateCommandBuffer")))
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600234 return (void *) multi2CreateCommandBuffer;
Chia-I Wuf1a5a742014-12-27 15:16:07 +0800235 else if (!strncmp("xglBeginCommandBuffer", pName, sizeof ("xglBeginCommandBuffer")))
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600236 return (void *) multi2BeginCommandBuffer;
Jon Ashburn5f3960e2015-04-02 12:06:28 -0600237 else if (!strncmp("xglGetExtensionSupport", pName, sizeof ("xglGetExtensionSupport")))
238 return (void *) xglGetExtensionSupport;
Jon Ashburn79113cc2014-12-01 14:22:40 -0700239 else {
Jon Ashburn79113cc2014-12-01 14:22:40 -0700240 if (gpuw->pGPA == NULL)
241 return NULL;
242 return gpuw->pGPA((XGL_PHYSICAL_GPU) gpuw->nextObject, pName);
243 }
Jon Ashburn79113cc2014-12-01 14:22:40 -0700244}
245
246/********************************* Common functions ********************************/
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600247XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglEnumerateLayers(XGL_PHYSICAL_GPU gpu, size_t maxLayerCount, size_t maxStringSize,
248 size_t* pOutLayerCount, char* const* pOutLayers,
249 void* pReserved)
Jon Ashburn79113cc2014-12-01 14:22:40 -0700250{
251 if (pOutLayerCount == NULL || pOutLayers == NULL || pOutLayers[0] == NULL || pOutLayers[1] == NULL || pReserved == NULL)
252 return XGL_ERROR_INVALID_POINTER;
253
254 if (maxLayerCount < 2)
255 return XGL_ERROR_INITIALIZATION_FAILED;
256 *pOutLayerCount = 2;
257 strncpy((char *) pOutLayers[0], "multi1", maxStringSize);
258 strncpy((char *) pOutLayers[1], "multi2", maxStringSize);
259 return XGL_SUCCESS;
260}
261
Jon Ashburn5f3960e2015-04-02 12:06:28 -0600262XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglGetExtensionSupport(XGL_PHYSICAL_GPU gpu, const char* pExtName)
263{
264 XGL_RESULT result;
265 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
266
267 /* This entrypoint is NOT going to init it's own dispatch table since loader calls here early */
268 if (!strncmp(pExtName, "multi1", strlen("multi1")))
269 {
270 result = XGL_SUCCESS;
271 } else if (!strncmp(pExtName, "multi2", strlen("multi2")))
272 {
273 result = XGL_SUCCESS;
274 } else if (!tableMap1.empty() && (tableMap1.find(gpuw) != tableMap1.end()))
275 {
276 XGL_LAYER_DISPATCH_TABLE* pTable = tableMap1[gpuw];
277 result = pTable->GetExtensionSupport((XGL_PHYSICAL_GPU)gpuw->nextObject, pExtName);
278 } else if (!tableMap2.empty() && (tableMap2.find(gpuw) != tableMap2.end()))
279 {
280 XGL_LAYER_DISPATCH_TABLE* pTable = tableMap2[gpuw];
281 result = pTable->GetExtensionSupport((XGL_PHYSICAL_GPU)gpuw->nextObject, pExtName);
282 } else
283 {
284 result = XGL_ERROR_INVALID_EXTENSION;
285 }
286 return result;
287}
288
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600289XGL_LAYER_EXPORT void * XGLAPI xglGetProcAddr(XGL_PHYSICAL_GPU gpu, const char* pName)
Jon Ashburn79113cc2014-12-01 14:22:40 -0700290{
291 // to find each layers GPA routine Loader will search via "<layerName>GetProcAddr"
Chia-I Wuf1a5a742014-12-27 15:16:07 +0800292 if (!strncmp("multi1GetProcAddr", pName, sizeof("multi1GetProcAddr")))
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600293 return (void *) multi1GetProcAddr;
Chia-I Wuf1a5a742014-12-27 15:16:07 +0800294 else if (!strncmp("multi2GetProcAddr", pName, sizeof("multi2GetProcAddr")))
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600295 return (void *) multi2GetProcAddr;
Chia-I Wuf1a5a742014-12-27 15:16:07 +0800296 else if (!strncmp("xglGetProcAddr", pName, sizeof("xglGetProcAddr")))
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600297 return (void *) xglGetProcAddr;
Jon Ashburn79113cc2014-12-01 14:22:40 -0700298
299 // use first layer activated as GPA dispatch table activation happens in order
300 else if (layer1_first_activated)
301 return multi1GetProcAddr(gpu, pName);
302 else if (layer2_first_activated)
303 return multi2GetProcAddr(gpu, pName);
304 else
305 return NULL;
306
307}
308
309#ifdef __cplusplus
310} //extern "C"
311#endif
312
313static void initLayerTable(const XGL_BASE_LAYER_OBJECT *gpuw, XGL_LAYER_DISPATCH_TABLE *pTable, const unsigned int layerNum)
314{
Jon Ashburn79113cc2014-12-01 14:22:40 -0700315 if (layerNum == 2 && layer1_first_activated == false)
316 layer2_first_activated = true;
317 if (layerNum == 1 && layer2_first_activated == false)
318 layer1_first_activated = true;
319
Chia-I Wuaa4121f2015-01-04 23:11:43 +0800320 layer_initialize_dispatch_table(pTable, gpuw->pGPA, (XGL_PHYSICAL_GPU) gpuw->nextObject);
Jon Ashburn79113cc2014-12-01 14:22:40 -0700321}