blob: 95514928a27a20b41b55753cf6fa3bfcf909b4eb [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>
Ian Elliott81ac44c2015-01-13 17:52:38 -070030#include "loader_platform.h"
Chia-I Wu0f65b1e2015-01-04 23:11:43 +080031#include "xgl_dispatch_table_helper.h"
Jon Ashburn8d8dad02014-12-01 14:22:40 -070032#include "xglLayer.h"
33
34static void initLayerTable(const XGL_BASE_LAYER_OBJECT *gpuw, XGL_LAYER_DISPATCH_TABLE *pTable, const unsigned int layerNum);
35
36/******************************** Layer multi1 functions **************************/
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -060037static std::unordered_map<void *, XGL_LAYER_DISPATCH_TABLE *> tableMap1;
Jon Ashburn8d8dad02014-12-01 14:22:40 -070038static bool layer1_first_activated = false;
39
40static XGL_LAYER_DISPATCH_TABLE * getLayer1Table(const XGL_BASE_LAYER_OBJECT *gpuw)
41{
42 XGL_LAYER_DISPATCH_TABLE *pTable;
43
44 assert(gpuw);
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -060045 std::unordered_map<void *, XGL_LAYER_DISPATCH_TABLE *>::const_iterator it = tableMap1.find((void *) gpuw);
Jon Ashburn8d8dad02014-12-01 14:22:40 -070046 if (it == tableMap1.end())
47 {
48 pTable = new XGL_LAYER_DISPATCH_TABLE;
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -060049 tableMap1[(void *) gpuw] = pTable;
Jon Ashburn8d8dad02014-12-01 14:22:40 -070050 initLayerTable(gpuw, pTable, 1);
51 return pTable;
52 } else
53 {
54 return it->second;
55 }
56}
57#ifdef __cplusplus
58extern "C" {
59#endif
60
61
62XGL_LAYER_EXPORT XGL_RESULT XGLAPI multi1CreateDevice(XGL_PHYSICAL_GPU gpu, const XGL_DEVICE_CREATE_INFO* pCreateInfo,
63 XGL_DEVICE* pDevice)
64{
65 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
66 XGL_LAYER_DISPATCH_TABLE* pTable = getLayer1Table(gpuw);
67
68 printf("At start of multi1 layer xglCreateDevice()\n");
69 XGL_RESULT result = pTable->CreateDevice((XGL_PHYSICAL_GPU)gpuw->nextObject, pCreateInfo, pDevice);
70 // create a mapping for the device object into the dispatch table
71 tableMap1.emplace(*pDevice, pTable);
72 printf("Completed multi1 layer xglCreateDevice()\n");
73 return result;
74}
75
76XGL_LAYER_EXPORT XGL_RESULT XGLAPI multi1CreateGraphicsPipeline(XGL_DEVICE device, const XGL_GRAPHICS_PIPELINE_CREATE_INFO* pCreateInfo,
77 XGL_PIPELINE* pPipeline)
78{
79 XGL_LAYER_DISPATCH_TABLE* pTable = tableMap1[device];
80
81 printf("At start of multi1 layer xglCreateGraphicsPipeline()\n");
82 XGL_RESULT result = pTable->CreateGraphicsPipeline(device, pCreateInfo, pPipeline);
83 // create a mapping for the pipeline object into the dispatch table
84 tableMap1.emplace(*pPipeline, pTable);
85 printf("Completed multi1 layer xglCreateGraphicsPipeline()\n");
86 return result;
87}
88
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -060089XGL_LAYER_EXPORT XGL_RESULT XGLAPI multi1StorePipeline(XGL_PIPELINE pipeline, size_t* pDataSize, void* pData)
Jon Ashburn8d8dad02014-12-01 14:22:40 -070090{
91 XGL_LAYER_DISPATCH_TABLE* pTable = tableMap1[pipeline];
92
93 printf("At start of multi1 layer xglStorePipeline()\n");
94 XGL_RESULT result = pTable->StorePipeline(pipeline, pDataSize, pData);
95 printf("Completed multi1 layer xglStorePipeline()\n");
96 return result;
97}
98
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -060099XGL_LAYER_EXPORT XGL_RESULT XGLAPI multi1EnumerateLayers(XGL_PHYSICAL_GPU gpu, size_t maxLayerCount, size_t maxStringSize,
100 size_t* pOutLayerCount, char* const* pOutLayers,
101 void* pReserved)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700102{
103 if (gpu == NULL)
Mark Lobodzinski953a1692015-01-09 15:12:03 -0600104 return xglEnumerateLayers(gpu, maxLayerCount, maxStringSize, pOutLayerCount, pOutLayers, pReserved);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700105
106 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
107 XGL_LAYER_DISPATCH_TABLE* pTable = getLayer1Table(gpuw);
108
109 printf("At start of multi1 layer xglEnumerateLayers()\n");
Mark Lobodzinski953a1692015-01-09 15:12:03 -0600110 XGL_RESULT result = pTable->EnumerateLayers((XGL_PHYSICAL_GPU)gpuw->nextObject, maxLayerCount, maxStringSize, pOutLayerCount, pOutLayers, pReserved);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700111 printf("Completed multi1 layer xglEnumerateLayers()\n");
112 return result;
113}
114
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600115XGL_LAYER_EXPORT void * XGLAPI multi1GetProcAddr(XGL_PHYSICAL_GPU gpu, const char* pName)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700116{
117 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
Chia-I Wue9ae3882015-01-05 09:41:27 +0800118
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700119 if (gpu == NULL)
120 return NULL;
Chia-I Wue9ae3882015-01-05 09:41:27 +0800121
122 getLayer1Table(gpuw);
123
124 if (!strncmp("xglCreateDevice", pName, sizeof ("xglCreateDevice")))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600125 return (void *) multi1CreateDevice;
Chia-I Wu7461fcf2014-12-27 15:16:07 +0800126 else if (!strncmp("xglEnumerateLayers", pName, sizeof ("xglEnumerateLayers")))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600127 return (void *) multi1EnumerateLayers;
Chia-I Wu7461fcf2014-12-27 15:16:07 +0800128 else if (!strncmp("xglCreateGraphicsPipeline", pName, sizeof ("xglCreateGraphicsPipeline")))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600129 return (void *) multi1CreateGraphicsPipeline;
Chia-I Wu7461fcf2014-12-27 15:16:07 +0800130 else if (!strncmp("xglStorePipeline", pName, sizeof ("xglStorePipeline")))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600131 return (void *) multi1StorePipeline;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700132 else {
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700133 if (gpuw->pGPA == NULL)
134 return NULL;
135 return gpuw->pGPA((XGL_PHYSICAL_GPU) gpuw->nextObject, pName);
136 }
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700137}
138
139/******************************** Layer multi2 functions **************************/
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600140static std::unordered_map<void *, XGL_LAYER_DISPATCH_TABLE *> tableMap2;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700141static bool layer2_first_activated = false;
142
143static XGL_LAYER_DISPATCH_TABLE * getLayer2Table(const XGL_BASE_LAYER_OBJECT *gpuw)
144{
145 XGL_LAYER_DISPATCH_TABLE *pTable;
146
147 assert(gpuw);
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600148 std::unordered_map<void *, XGL_LAYER_DISPATCH_TABLE *>::const_iterator it = tableMap2.find((void *) gpuw);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700149 if (it == tableMap2.end())
150 {
151 pTable = new XGL_LAYER_DISPATCH_TABLE;
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600152 tableMap2[(void *) gpuw] = pTable;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700153 initLayerTable(gpuw, pTable, 2);
154 return pTable;
155 } else
156 {
157 return it->second;
158 }
159}
160
161XGL_LAYER_EXPORT XGL_RESULT XGLAPI multi2CreateDevice(XGL_PHYSICAL_GPU gpu, const XGL_DEVICE_CREATE_INFO* pCreateInfo,
162 XGL_DEVICE* pDevice)
163{
164 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
165 XGL_LAYER_DISPATCH_TABLE* pTable = getLayer2Table(gpuw);
166
167 printf("At start of multi2 xglCreateDevice()\n");
168 XGL_RESULT result = pTable->CreateDevice((XGL_PHYSICAL_GPU)gpuw->nextObject, pCreateInfo, pDevice);
169 // create a mapping for the device object into the dispatch table for layer2
170 tableMap2.emplace(*pDevice, pTable);
171 printf("Completed multi2 layer xglCreateDevice()\n");
172 return result;
173}
174
175XGL_LAYER_EXPORT XGL_RESULT XGLAPI multi2CreateCommandBuffer(XGL_DEVICE device, const XGL_CMD_BUFFER_CREATE_INFO* pCreateInfo,
176 XGL_CMD_BUFFER* pCmdBuffer)
177{
178 XGL_LAYER_DISPATCH_TABLE* pTable = tableMap2[device];
179
180 printf("At start of multi2 layer xglCreateCommandBuffer()\n");
181 XGL_RESULT result = pTable->CreateCommandBuffer(device, pCreateInfo, pCmdBuffer);
182 // create a mapping for CmdBuffer object into the dispatch table for layer 2
183 tableMap2.emplace(*pCmdBuffer, pTable);
184 printf("Completed multi2 layer xglCreateCommandBuffer()\n");
185 return result;
186}
187
Tobin Ehlis2f3726c2015-01-15 17:51:52 -0700188XGL_LAYER_EXPORT XGL_RESULT XGLAPI multi2BeginCommandBuffer(XGL_CMD_BUFFER cmdBuffer, const XGL_CMD_BUFFER_BEGIN_INFO* pBeginInfo)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700189{
190 XGL_LAYER_DISPATCH_TABLE* pTable = tableMap2[cmdBuffer];
191
192 printf("At start of multi2 layer xglBeginCommandBuffer()\n");
Jon Ashburn57ba18d2014-12-31 17:11:49 -0700193 XGL_RESULT result = pTable->BeginCommandBuffer(cmdBuffer, pBeginInfo);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700194 printf("Completed multi2 layer xglBeginCommandBuffer()\n");
195 return result;
196
197}
198
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600199XGL_LAYER_EXPORT XGL_RESULT XGLAPI multi2EnumerateLayers(XGL_PHYSICAL_GPU gpu, size_t maxLayerCount, size_t maxStringSize,
200 size_t* pOutLayerCount, char* const* pOutLayers,
201 void* pReserved)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700202{
203 if (gpu == NULL)
Mark Lobodzinski953a1692015-01-09 15:12:03 -0600204 return xglEnumerateLayers(gpu, maxLayerCount, maxStringSize, pOutLayerCount, pOutLayers, pReserved);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700205
206 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
207 XGL_LAYER_DISPATCH_TABLE* pTable = getLayer2Table(gpuw);
208
209 printf("At start of multi2 layer xglEnumerateLayers()\n");
Mark Lobodzinski953a1692015-01-09 15:12:03 -0600210 XGL_RESULT result = pTable->EnumerateLayers((XGL_PHYSICAL_GPU)gpuw->nextObject, maxLayerCount, maxStringSize, pOutLayerCount, pOutLayers, pReserved);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700211 printf("Completed multi2 layer xglEnumerateLayers()\n");
212 return result;
213}
214
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600215XGL_LAYER_EXPORT void * XGLAPI multi2GetProcAddr(XGL_PHYSICAL_GPU gpu, const char* pName)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700216{
217 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
Chia-I Wue9ae3882015-01-05 09:41:27 +0800218
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700219 if (gpu == NULL)
220 return NULL;
Chia-I Wue9ae3882015-01-05 09:41:27 +0800221
222 getLayer2Table(gpuw);
223
224 if (!strncmp("xglCreateDevice", pName, sizeof ("xglCreateDevice")))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600225 return (void *) multi2CreateDevice;
Chia-I Wu7461fcf2014-12-27 15:16:07 +0800226 else if (!strncmp("xglEnumerateLayers", pName, sizeof ("xglEnumerateLayers")))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600227 return (void *) multi2EnumerateLayers;
Chia-I Wu7461fcf2014-12-27 15:16:07 +0800228 else if (!strncmp("xglCreateCommandBuffer", pName, sizeof ("xglCreateCommandBuffer")))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600229 return (void *) multi2CreateCommandBuffer;
Chia-I Wu7461fcf2014-12-27 15:16:07 +0800230 else if (!strncmp("xglBeginCommandBuffer", pName, sizeof ("xglBeginCommandBuffer")))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600231 return (void *) multi2BeginCommandBuffer;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700232 else {
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700233 if (gpuw->pGPA == NULL)
234 return NULL;
235 return gpuw->pGPA((XGL_PHYSICAL_GPU) gpuw->nextObject, pName);
236 }
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700237}
238
239/********************************* Common functions ********************************/
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600240XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglEnumerateLayers(XGL_PHYSICAL_GPU gpu, size_t maxLayerCount, size_t maxStringSize,
241 size_t* pOutLayerCount, char* const* pOutLayers,
242 void* pReserved)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700243{
244 if (pOutLayerCount == NULL || pOutLayers == NULL || pOutLayers[0] == NULL || pOutLayers[1] == NULL || pReserved == NULL)
245 return XGL_ERROR_INVALID_POINTER;
246
247 if (maxLayerCount < 2)
248 return XGL_ERROR_INITIALIZATION_FAILED;
249 *pOutLayerCount = 2;
250 strncpy((char *) pOutLayers[0], "multi1", maxStringSize);
251 strncpy((char *) pOutLayers[1], "multi2", maxStringSize);
252 return XGL_SUCCESS;
253}
254
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600255XGL_LAYER_EXPORT void * XGLAPI xglGetProcAddr(XGL_PHYSICAL_GPU gpu, const char* pName)
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700256{
257 // to find each layers GPA routine Loader will search via "<layerName>GetProcAddr"
Chia-I Wu7461fcf2014-12-27 15:16:07 +0800258 if (!strncmp("multi1GetProcAddr", pName, sizeof("multi1GetProcAddr")))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600259 return (void *) multi1GetProcAddr;
Chia-I Wu7461fcf2014-12-27 15:16:07 +0800260 else if (!strncmp("multi2GetProcAddr", pName, sizeof("multi2GetProcAddr")))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600261 return (void *) multi2GetProcAddr;
Chia-I Wu7461fcf2014-12-27 15:16:07 +0800262 else if (!strncmp("xglGetProcAddr", pName, sizeof("xglGetProcAddr")))
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600263 return (void *) xglGetProcAddr;
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700264
265 // use first layer activated as GPA dispatch table activation happens in order
266 else if (layer1_first_activated)
267 return multi1GetProcAddr(gpu, pName);
268 else if (layer2_first_activated)
269 return multi2GetProcAddr(gpu, pName);
270 else
271 return NULL;
272
273}
274
275#ifdef __cplusplus
276} //extern "C"
277#endif
278
279static void initLayerTable(const XGL_BASE_LAYER_OBJECT *gpuw, XGL_LAYER_DISPATCH_TABLE *pTable, const unsigned int layerNum)
280{
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700281 if (layerNum == 2 && layer1_first_activated == false)
282 layer2_first_activated = true;
283 if (layerNum == 1 && layer2_first_activated == false)
284 layer1_first_activated = true;
285
Chia-I Wu0f65b1e2015-01-04 23:11:43 +0800286 layer_initialize_dispatch_table(pTable, gpuw->pGPA, (XGL_PHYSICAL_GPU) gpuw->nextObject);
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700287}