blob: 3a5e4fccf2dc3f7a43450a570267cc103097750e [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 Ashburn79113cc2014-12-01 14:22:40 -0700135 else {
Jon Ashburn79113cc2014-12-01 14:22:40 -0700136 if (gpuw->pGPA == NULL)
137 return NULL;
138 return gpuw->pGPA((XGL_PHYSICAL_GPU) gpuw->nextObject, pName);
139 }
Jon Ashburn79113cc2014-12-01 14:22:40 -0700140}
141
142/******************************** Layer multi2 functions **************************/
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600143static std::unordered_map<void *, XGL_LAYER_DISPATCH_TABLE *> tableMap2;
Jon Ashburn79113cc2014-12-01 14:22:40 -0700144static bool layer2_first_activated = false;
145
146static XGL_LAYER_DISPATCH_TABLE * getLayer2Table(const XGL_BASE_LAYER_OBJECT *gpuw)
147{
148 XGL_LAYER_DISPATCH_TABLE *pTable;
149
150 assert(gpuw);
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600151 std::unordered_map<void *, XGL_LAYER_DISPATCH_TABLE *>::const_iterator it = tableMap2.find((void *) gpuw);
Jon Ashburn79113cc2014-12-01 14:22:40 -0700152 if (it == tableMap2.end())
153 {
154 pTable = new XGL_LAYER_DISPATCH_TABLE;
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600155 tableMap2[(void *) gpuw] = pTable;
Jon Ashburn79113cc2014-12-01 14:22:40 -0700156 initLayerTable(gpuw, pTable, 2);
157 return pTable;
158 } else
159 {
160 return it->second;
161 }
162}
163
164XGL_LAYER_EXPORT XGL_RESULT XGLAPI multi2CreateDevice(XGL_PHYSICAL_GPU gpu, const XGL_DEVICE_CREATE_INFO* pCreateInfo,
165 XGL_DEVICE* pDevice)
166{
167 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
168 XGL_LAYER_DISPATCH_TABLE* pTable = getLayer2Table(gpuw);
169
170 printf("At start of multi2 xglCreateDevice()\n");
171 XGL_RESULT result = pTable->CreateDevice((XGL_PHYSICAL_GPU)gpuw->nextObject, pCreateInfo, pDevice);
172 // create a mapping for the device object into the dispatch table for layer2
173 tableMap2.emplace(*pDevice, pTable);
174 printf("Completed multi2 layer xglCreateDevice()\n");
175 return result;
176}
177
178XGL_LAYER_EXPORT XGL_RESULT XGLAPI multi2CreateCommandBuffer(XGL_DEVICE device, const XGL_CMD_BUFFER_CREATE_INFO* pCreateInfo,
179 XGL_CMD_BUFFER* pCmdBuffer)
180{
181 XGL_LAYER_DISPATCH_TABLE* pTable = tableMap2[device];
182
183 printf("At start of multi2 layer xglCreateCommandBuffer()\n");
184 XGL_RESULT result = pTable->CreateCommandBuffer(device, pCreateInfo, pCmdBuffer);
185 // create a mapping for CmdBuffer object into the dispatch table for layer 2
186 tableMap2.emplace(*pCmdBuffer, pTable);
187 printf("Completed multi2 layer xglCreateCommandBuffer()\n");
188 return result;
189}
190
Tobin Ehlis7e65d752015-01-15 17:51:52 -0700191XGL_LAYER_EXPORT XGL_RESULT XGLAPI multi2BeginCommandBuffer(XGL_CMD_BUFFER cmdBuffer, const XGL_CMD_BUFFER_BEGIN_INFO* pBeginInfo)
Jon Ashburn79113cc2014-12-01 14:22:40 -0700192{
193 XGL_LAYER_DISPATCH_TABLE* pTable = tableMap2[cmdBuffer];
194
195 printf("At start of multi2 layer xglBeginCommandBuffer()\n");
Jon Ashburn86522372014-12-31 17:11:49 -0700196 XGL_RESULT result = pTable->BeginCommandBuffer(cmdBuffer, pBeginInfo);
Jon Ashburn79113cc2014-12-01 14:22:40 -0700197 printf("Completed multi2 layer xglBeginCommandBuffer()\n");
198 return result;
199
200}
201
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600202XGL_LAYER_EXPORT XGL_RESULT XGLAPI multi2EnumerateLayers(XGL_PHYSICAL_GPU gpu, size_t maxLayerCount, size_t maxStringSize,
203 size_t* pOutLayerCount, char* const* pOutLayers,
204 void* pReserved)
Jon Ashburn79113cc2014-12-01 14:22:40 -0700205{
206 if (gpu == NULL)
Mark Lobodzinski391bb6d2015-01-09 15:12:03 -0600207 return xglEnumerateLayers(gpu, maxLayerCount, maxStringSize, pOutLayerCount, pOutLayers, pReserved);
Jon Ashburn79113cc2014-12-01 14:22:40 -0700208
209 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
210 XGL_LAYER_DISPATCH_TABLE* pTable = getLayer2Table(gpuw);
211
212 printf("At start of multi2 layer xglEnumerateLayers()\n");
Mark Lobodzinski391bb6d2015-01-09 15:12:03 -0600213 XGL_RESULT result = pTable->EnumerateLayers((XGL_PHYSICAL_GPU)gpuw->nextObject, maxLayerCount, maxStringSize, pOutLayerCount, pOutLayers, pReserved);
Jon Ashburn79113cc2014-12-01 14:22:40 -0700214 printf("Completed multi2 layer xglEnumerateLayers()\n");
215 return result;
216}
217
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600218XGL_LAYER_EXPORT void * XGLAPI multi2GetProcAddr(XGL_PHYSICAL_GPU gpu, const char* pName)
Jon Ashburn79113cc2014-12-01 14:22:40 -0700219{
220 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
Chia-I Wub665d942015-01-05 09:41:27 +0800221
Jon Ashburn79113cc2014-12-01 14:22:40 -0700222 if (gpu == NULL)
223 return NULL;
Chia-I Wub665d942015-01-05 09:41:27 +0800224
225 getLayer2Table(gpuw);
226
227 if (!strncmp("xglCreateDevice", pName, sizeof ("xglCreateDevice")))
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600228 return (void *) multi2CreateDevice;
Chia-I Wuf1a5a742014-12-27 15:16:07 +0800229 else if (!strncmp("xglEnumerateLayers", pName, sizeof ("xglEnumerateLayers")))
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600230 return (void *) multi2EnumerateLayers;
Chia-I Wuf1a5a742014-12-27 15:16:07 +0800231 else if (!strncmp("xglCreateCommandBuffer", pName, sizeof ("xglCreateCommandBuffer")))
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600232 return (void *) multi2CreateCommandBuffer;
Chia-I Wuf1a5a742014-12-27 15:16:07 +0800233 else if (!strncmp("xglBeginCommandBuffer", pName, sizeof ("xglBeginCommandBuffer")))
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600234 return (void *) multi2BeginCommandBuffer;
Jon Ashburn79113cc2014-12-01 14:22:40 -0700235 else {
Jon Ashburn79113cc2014-12-01 14:22:40 -0700236 if (gpuw->pGPA == NULL)
237 return NULL;
238 return gpuw->pGPA((XGL_PHYSICAL_GPU) gpuw->nextObject, pName);
239 }
Jon Ashburn79113cc2014-12-01 14:22:40 -0700240}
241
242/********************************* Common functions ********************************/
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600243XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglEnumerateLayers(XGL_PHYSICAL_GPU gpu, size_t maxLayerCount, size_t maxStringSize,
244 size_t* pOutLayerCount, char* const* pOutLayers,
245 void* pReserved)
Jon Ashburn79113cc2014-12-01 14:22:40 -0700246{
247 if (pOutLayerCount == NULL || pOutLayers == NULL || pOutLayers[0] == NULL || pOutLayers[1] == NULL || pReserved == NULL)
248 return XGL_ERROR_INVALID_POINTER;
249
250 if (maxLayerCount < 2)
251 return XGL_ERROR_INITIALIZATION_FAILED;
252 *pOutLayerCount = 2;
253 strncpy((char *) pOutLayers[0], "multi1", maxStringSize);
254 strncpy((char *) pOutLayers[1], "multi2", maxStringSize);
255 return XGL_SUCCESS;
256}
257
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600258XGL_LAYER_EXPORT void * XGLAPI xglGetProcAddr(XGL_PHYSICAL_GPU gpu, const char* pName)
Jon Ashburn79113cc2014-12-01 14:22:40 -0700259{
260 // to find each layers GPA routine Loader will search via "<layerName>GetProcAddr"
Chia-I Wuf1a5a742014-12-27 15:16:07 +0800261 if (!strncmp("multi1GetProcAddr", pName, sizeof("multi1GetProcAddr")))
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600262 return (void *) multi1GetProcAddr;
Chia-I Wuf1a5a742014-12-27 15:16:07 +0800263 else if (!strncmp("multi2GetProcAddr", pName, sizeof("multi2GetProcAddr")))
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600264 return (void *) multi2GetProcAddr;
Chia-I Wuf1a5a742014-12-27 15:16:07 +0800265 else if (!strncmp("xglGetProcAddr", pName, sizeof("xglGetProcAddr")))
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600266 return (void *) xglGetProcAddr;
Jon Ashburn79113cc2014-12-01 14:22:40 -0700267
268 // use first layer activated as GPA dispatch table activation happens in order
269 else if (layer1_first_activated)
270 return multi1GetProcAddr(gpu, pName);
271 else if (layer2_first_activated)
272 return multi2GetProcAddr(gpu, pName);
273 else
274 return NULL;
275
276}
277
278#ifdef __cplusplus
279} //extern "C"
280#endif
281
282static void initLayerTable(const XGL_BASE_LAYER_OBJECT *gpuw, XGL_LAYER_DISPATCH_TABLE *pTable, const unsigned int layerNum)
283{
Jon Ashburn79113cc2014-12-01 14:22:40 -0700284 if (layerNum == 2 && layer1_first_activated == false)
285 layer2_first_activated = true;
286 if (layerNum == 1 && layer2_first_activated == false)
287 layer1_first_activated = true;
288
Chia-I Wuaa4121f2015-01-04 23:11:43 +0800289 layer_initialize_dispatch_table(pTable, gpuw->pGPA, (XGL_PHYSICAL_GPU) gpuw->nextObject);
Jon Ashburn79113cc2014-12-01 14:22:40 -0700290}