blob: de9d71c5407816cd143d69c50322f0c16c75ec93 [file] [log] [blame]
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001/*
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#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
Ian Elliott81ac44c2015-01-13 17:52:38 -070028#include "loader_platform.h"
Chia-I Wu0f65b1e2015-01-04 23:11:43 +080029#include "xgl_dispatch_table_helper.h"
Chia-I Wu706533e2015-01-05 13:18:57 +080030#include "xgl_generic_intercept_proc_helper.h"
Tobin Ehlisb8154982014-10-27 14:53:17 -060031#include "xgl_struct_string_helper.h"
Tobin Ehlisa701ef02014-11-27 15:43:39 -070032#include "xgl_struct_graphviz_helper.h"
Tobin Ehlise79df942014-11-18 16:38:08 -070033#include "draw_state.h"
Jon Ashburn2e9b5612014-12-22 13:38:27 -070034#include "layers_config.h"
Ian Elliott20f06872015-02-12 17:08:34 -070035// The following is #included again to catch certain OS-specific functions
36// being used:
37#include "loader_platform.h"
Jon Ashburn5a7be202015-02-16 08:46:53 -070038#include "layers_msg.h"
Tobin Ehlis8726b9f2014-10-24 12:01:45 -060039static XGL_LAYER_DISPATCH_TABLE nextTable;
40static XGL_BASE_LAYER_OBJECT *pCurObj;
Ian Elliott81ac44c2015-01-13 17:52:38 -070041static LOADER_PLATFORM_THREAD_ONCE_DECLARATION(g_initOnce);
Tobin Ehlisfb1ef942015-02-20 09:30:06 -070042// TODO : This can be much smarter, using separate locks for separate global data
Ian Elliott81ac44c2015-01-13 17:52:38 -070043static int globalLockInitialized = 0;
44static loader_platform_thread_mutex globalLock;
Tobin Ehlis8614b8d2015-02-17 16:27:03 -070045#define ALLOC_DEBUG 0
46#if ALLOC_DEBUG
47static uint64_t g_alloc_count = 0;
48static uint64_t g_free_count = 0;
49#endif
Tobin Ehlis45662712015-02-23 09:06:28 -070050#define MAX_TID 513
51static loader_platform_thread_id tidMapping[MAX_TID] = {0};
52static uint32_t g_maxTID = 0;
53// Map actual TID to an index value and return that index
54// This keeps TIDs in range from 0-MAX_TID and simplifies compares between runs
55static uint32_t getTIDIndex() {
56 loader_platform_thread_id tid = loader_platform_get_thread_id();
57 for (uint32_t i = 0; i < g_maxTID; i++) {
58 if (tid == tidMapping[i])
59 return i;
60 }
61 // Don't yet have mapping, set it and return newly set index
62 uint32_t retVal = (uint32_t) g_maxTID;
63 tidMapping[g_maxTID++] = tid;
64 assert(g_maxTID < MAX_TID);
65 return retVal;
66}
Tobin Ehlis26092022014-11-20 09:49:17 -070067// Return the size of the underlying struct based on struct type
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -060068static size_t sTypeStructSize(XGL_STRUCTURE_TYPE sType)
Tobin Ehlis26092022014-11-20 09:49:17 -070069{
70 switch (sType)
71 {
72 case XGL_STRUCTURE_TYPE_APPLICATION_INFO:
73 return sizeof(XGL_APPLICATION_INFO);
74 case XGL_STRUCTURE_TYPE_DEVICE_CREATE_INFO:
75 return sizeof(XGL_DEVICE_CREATE_INFO);
76 case XGL_STRUCTURE_TYPE_MEMORY_ALLOC_INFO:
77 return sizeof(XGL_MEMORY_ALLOC_INFO);
78 case XGL_STRUCTURE_TYPE_MEMORY_OPEN_INFO:
79 return sizeof(XGL_MEMORY_OPEN_INFO);
80 case XGL_STRUCTURE_TYPE_PEER_MEMORY_OPEN_INFO:
81 return sizeof(XGL_PEER_MEMORY_OPEN_INFO);
Tobin Ehlis2f3726c2015-01-15 17:51:52 -070082 case XGL_STRUCTURE_TYPE_BUFFER_VIEW_ATTACH_INFO:
83 return sizeof(XGL_BUFFER_VIEW_ATTACH_INFO);
Tobin Ehlis26092022014-11-20 09:49:17 -070084 case XGL_STRUCTURE_TYPE_IMAGE_VIEW_ATTACH_INFO:
85 return sizeof(XGL_IMAGE_VIEW_ATTACH_INFO);
Tobin Ehlis2f3726c2015-01-15 17:51:52 -070086 case XGL_STRUCTURE_TYPE_EVENT_WAIT_INFO:
87 return sizeof(XGL_EVENT_WAIT_INFO);
Tobin Ehlis26092022014-11-20 09:49:17 -070088 case XGL_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO:
89 return sizeof(XGL_IMAGE_VIEW_CREATE_INFO);
90 case XGL_STRUCTURE_TYPE_COLOR_ATTACHMENT_VIEW_CREATE_INFO:
91 return sizeof(XGL_COLOR_ATTACHMENT_VIEW_CREATE_INFO);
92 case XGL_STRUCTURE_TYPE_DEPTH_STENCIL_VIEW_CREATE_INFO:
93 return sizeof(XGL_DEPTH_STENCIL_VIEW_CREATE_INFO);
94 case XGL_STRUCTURE_TYPE_SHADER_CREATE_INFO:
95 return sizeof(XGL_SHADER_CREATE_INFO);
96 case XGL_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO:
97 return sizeof(XGL_COMPUTE_PIPELINE_CREATE_INFO);
98 case XGL_STRUCTURE_TYPE_SAMPLER_CREATE_INFO:
99 return sizeof(XGL_SAMPLER_CREATE_INFO);
Tobin Ehlis2f3726c2015-01-15 17:51:52 -0700100 case XGL_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO:
101 return sizeof(XGL_DESCRIPTOR_SET_LAYOUT_CREATE_INFO);
102 case XGL_STRUCTURE_TYPE_DYNAMIC_VP_STATE_CREATE_INFO:
103 return sizeof(XGL_DYNAMIC_VP_STATE_CREATE_INFO);
104 case XGL_STRUCTURE_TYPE_DYNAMIC_RS_STATE_CREATE_INFO:
105 return sizeof(XGL_DYNAMIC_RS_STATE_CREATE_INFO);
106 case XGL_STRUCTURE_TYPE_DYNAMIC_CB_STATE_CREATE_INFO:
107 return sizeof(XGL_DYNAMIC_CB_STATE_CREATE_INFO);
108 case XGL_STRUCTURE_TYPE_DYNAMIC_DS_STATE_CREATE_INFO:
109 return sizeof(XGL_DYNAMIC_DS_STATE_CREATE_INFO);
Tobin Ehlis26092022014-11-20 09:49:17 -0700110 case XGL_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO:
111 return sizeof(XGL_CMD_BUFFER_CREATE_INFO);
112 case XGL_STRUCTURE_TYPE_EVENT_CREATE_INFO:
113 return sizeof(XGL_EVENT_CREATE_INFO);
114 case XGL_STRUCTURE_TYPE_FENCE_CREATE_INFO:
115 return sizeof(XGL_FENCE_CREATE_INFO);
Mark Lobodzinski4eca6972015-01-26 10:34:00 -0600116 case XGL_STRUCTURE_TYPE_QUEUE_SEMAPHORE_CREATE_INFO:
Tobin Ehlis26092022014-11-20 09:49:17 -0700117 return sizeof(XGL_QUEUE_SEMAPHORE_CREATE_INFO);
Mark Lobodzinski4eca6972015-01-26 10:34:00 -0600118 case XGL_STRUCTURE_TYPE_QUEUE_SEMAPHORE_OPEN_INFO:
Tobin Ehlis26092022014-11-20 09:49:17 -0700119 return sizeof(XGL_QUEUE_SEMAPHORE_OPEN_INFO);
120 case XGL_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO:
121 return sizeof(XGL_QUERY_POOL_CREATE_INFO);
122 case XGL_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO:
123 return sizeof(XGL_PIPELINE_SHADER_STAGE_CREATE_INFO);
124 case XGL_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO:
125 return sizeof(XGL_GRAPHICS_PIPELINE_CREATE_INFO);
Tobin Ehlis26092022014-11-20 09:49:17 -0700126 case XGL_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_CREATE_INFO:
127 return sizeof(XGL_PIPELINE_VERTEX_INPUT_CREATE_INFO);
Tobin Ehlis2f3726c2015-01-15 17:51:52 -0700128 case XGL_STRUCTURE_TYPE_PIPELINE_IA_STATE_CREATE_INFO:
129 return sizeof(XGL_PIPELINE_IA_STATE_CREATE_INFO);
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700130 case XGL_STRUCTURE_TYPE_PIPELINE_TESS_STATE_CREATE_INFO:
131 return sizeof(XGL_PIPELINE_TESS_STATE_CREATE_INFO);
Tobin Ehlis2f3726c2015-01-15 17:51:52 -0700132 case XGL_STRUCTURE_TYPE_PIPELINE_VP_STATE_CREATE_INFO:
133 return sizeof(XGL_PIPELINE_VP_STATE_CREATE_INFO);
Tobin Ehlis2f3726c2015-01-15 17:51:52 -0700134 case XGL_STRUCTURE_TYPE_PIPELINE_RS_STATE_CREATE_INFO:
135 return sizeof(XGL_PIPELINE_RS_STATE_CREATE_INFO);
136 case XGL_STRUCTURE_TYPE_PIPELINE_MS_STATE_CREATE_INFO:
137 return sizeof(XGL_PIPELINE_MS_STATE_CREATE_INFO);
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700138 case XGL_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO:
139 return sizeof(XGL_PIPELINE_CB_STATE_CREATE_INFO);
Tobin Ehlis2f3726c2015-01-15 17:51:52 -0700140 case XGL_STRUCTURE_TYPE_PIPELINE_DS_STATE_CREATE_INFO:
141 return sizeof(XGL_PIPELINE_DS_STATE_CREATE_INFO);
142 case XGL_STRUCTURE_TYPE_IMAGE_CREATE_INFO:
143 return sizeof(XGL_IMAGE_CREATE_INFO);
144 case XGL_STRUCTURE_TYPE_BUFFER_CREATE_INFO:
145 return sizeof(XGL_BUFFER_CREATE_INFO);
146 case XGL_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO:
147 return sizeof(XGL_BUFFER_VIEW_CREATE_INFO);
148 case XGL_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO:
149 return sizeof(XGL_FRAMEBUFFER_CREATE_INFO);
150 case XGL_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO:
151 return sizeof(XGL_CMD_BUFFER_BEGIN_INFO);
152 case XGL_STRUCTURE_TYPE_CMD_BUFFER_GRAPHICS_BEGIN_INFO:
153 return sizeof(XGL_CMD_BUFFER_GRAPHICS_BEGIN_INFO);
154 case XGL_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO:
155 return sizeof(XGL_RENDER_PASS_CREATE_INFO);
Tobin Ehlis26092022014-11-20 09:49:17 -0700156 case XGL_STRUCTURE_TYPE_LAYER_CREATE_INFO:
157 return sizeof(XGL_LAYER_CREATE_INFO);
Tobin Ehlis2f3726c2015-01-15 17:51:52 -0700158 case XGL_STRUCTURE_TYPE_PIPELINE_BARRIER:
159 return sizeof(XGL_PIPELINE_BARRIER);
160 case XGL_STRUCTURE_TYPE_MEMORY_BARRIER:
161 return sizeof(XGL_MEMORY_BARRIER);
162 case XGL_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER:
163 return sizeof(XGL_BUFFER_MEMORY_BARRIER);
164 case XGL_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER:
165 return sizeof(XGL_IMAGE_MEMORY_BARRIER);
166 case XGL_STRUCTURE_TYPE_DESCRIPTOR_REGION_CREATE_INFO:
167 return sizeof(XGL_DESCRIPTOR_REGION_CREATE_INFO);
168 case XGL_STRUCTURE_TYPE_UPDATE_SAMPLERS:
169 return sizeof(XGL_UPDATE_SAMPLERS);
170 case XGL_STRUCTURE_TYPE_UPDATE_SAMPLER_TEXTURES:
171 return sizeof(XGL_UPDATE_SAMPLER_TEXTURES);
172 case XGL_STRUCTURE_TYPE_UPDATE_IMAGES:
173 return sizeof(XGL_UPDATE_IMAGES);
174 case XGL_STRUCTURE_TYPE_UPDATE_BUFFERS:
175 return sizeof(XGL_UPDATE_BUFFERS);
176 case XGL_STRUCTURE_TYPE_UPDATE_AS_COPY:
177 return sizeof(XGL_UPDATE_AS_COPY);
178 case XGL_STRUCTURE_TYPE_MEMORY_ALLOC_BUFFER_INFO:
179 return sizeof(XGL_MEMORY_ALLOC_BUFFER_INFO);
180 case XGL_STRUCTURE_TYPE_MEMORY_ALLOC_IMAGE_INFO:
181 return sizeof(XGL_MEMORY_ALLOC_IMAGE_INFO);
Tobin Ehlis26092022014-11-20 09:49:17 -0700182 default:
183 return 0;
184 }
185}
Tobin Ehlis84c521c2015-01-19 08:42:29 -0700186// Return the size of the underlying struct based on sType
187static size_t dynStateCreateInfoSize(XGL_STRUCTURE_TYPE sType)
Tobin Ehlis56a61072014-11-21 08:58:46 -0700188{
189 switch (sType)
190 {
Tobin Ehlis84c521c2015-01-19 08:42:29 -0700191 case XGL_STRUCTURE_TYPE_DYNAMIC_VP_STATE_CREATE_INFO:
192 return sizeof(XGL_DYNAMIC_VP_STATE_CREATE_INFO);
193 case XGL_STRUCTURE_TYPE_DYNAMIC_RS_STATE_CREATE_INFO:
194 return sizeof(XGL_DYNAMIC_RS_STATE_CREATE_INFO);
195 case XGL_STRUCTURE_TYPE_DYNAMIC_DS_STATE_CREATE_INFO:
196 return sizeof(XGL_DYNAMIC_DS_STATE_CREATE_INFO);
197 case XGL_STRUCTURE_TYPE_DYNAMIC_CB_STATE_CREATE_INFO:
198 return sizeof(XGL_DYNAMIC_CB_STATE_CREATE_INFO);
Tobin Ehlis56a61072014-11-21 08:58:46 -0700199 default:
200 return 0;
201 }
202}
Tobin Ehlisd092d232015-02-13 13:30:07 -0700203// Return a string representation of CMD_TYPE enum
204static char* cmdTypeToString(CMD_TYPE cmd)
205{
206 switch (cmd)
207 {
208 case CMD_BINDPIPELINE:
209 return "CMD_BINDPIPELINE";
210 case CMD_BINDPIPELINEDELTA:
211 return "CMD_BINDPIPELINEDELTA";
212 case CMD_BINDDYNAMICSTATEOBJECT:
213 return "CMD_BINDDYNAMICSTATEOBJECT";
214 case CMD_BINDDESCRIPTORSET:
215 return "CMD_BINDDESCRIPTORSET";
216 case CMD_BINDINDEXBUFFER:
217 return "CMD_BINDINDEXBUFFER";
218 case CMD_BINDVERTEXBUFFER:
219 return "CMD_BINDVERTEXBUFFER";
220 case CMD_DRAW:
221 return "CMD_DRAW";
222 case CMD_DRAWINDEXED:
223 return "CMD_DRAWINDEXED";
224 case CMD_DRAWINDIRECT:
225 return "CMD_DRAWINDIRECT";
226 case CMD_DRAWINDEXEDINDIRECT:
227 return "CMD_DRAWINDEXEDINDIRECT";
228 case CMD_DISPATCH:
229 return "CMD_DISPATCH";
230 case CMD_DISPATCHINDIRECT:
231 return "CMD_DISPATCHINDIRECT";
232 case CMD_COPYBUFFER:
233 return "CMD_COPYBUFFER";
234 case CMD_COPYIMAGE:
235 return "CMD_COPYIMAGE";
236 case CMD_COPYBUFFERTOIMAGE:
237 return "CMD_COPYBUFFERTOIMAGE";
238 case CMD_COPYIMAGETOBUFFER:
239 return "CMD_COPYIMAGETOBUFFER";
240 case CMD_CLONEIMAGEDATA:
241 return "CMD_CLONEIMAGEDATA";
242 case CMD_UPDATEBUFFER:
243 return "CMD_UPDATEBUFFER";
244 case CMD_FILLBUFFER:
245 return "CMD_FILLBUFFER";
246 case CMD_CLEARCOLORIMAGE:
247 return "CMD_CLEARCOLORIMAGE";
248 case CMD_CLEARCOLORIMAGERAW:
249 return "CMD_CLEARCOLORIMAGERAW";
250 case CMD_CLEARDEPTHSTENCIL:
251 return "CMD_CLEARDEPTHSTENCIL";
252 case CMD_RESOLVEIMAGE:
253 return "CMD_RESOLVEIMAGE";
254 case CMD_SETEVENT:
255 return "CMD_SETEVENT";
256 case CMD_RESETEVENT:
257 return "CMD_RESETEVENT";
258 case CMD_WAITEVENTS:
259 return "CMD_WAITEVENTS";
260 case CMD_PIPELINEBARRIER:
261 return "CMD_PIPELINEBARRIER";
262 case CMD_BEGINQUERY:
263 return "CMD_BEGINQUERY";
264 case CMD_ENDQUERY:
265 return "CMD_ENDQUERY";
266 case CMD_RESETQUERYPOOL:
267 return "CMD_RESETQUERYPOOL";
268 case CMD_WRITETIMESTAMP:
269 return "CMD_WRITETIMESTAMP";
270 case CMD_INITATOMICCOUNTERS:
271 return "CMD_INITATOMICCOUNTERS";
272 case CMD_LOADATOMICCOUNTERS:
273 return "CMD_LOADATOMICCOUNTERS";
274 case CMD_SAVEATOMICCOUNTERS:
275 return "CMD_SAVEATOMICCOUNTERS";
276 case CMD_BEGINRENDERPASS:
277 return "CMD_BEGINRENDERPASS";
278 case CMD_ENDRENDERPASS:
279 return "CMD_ENDRENDERPASS";
280 default:
281 return "UNKNOWN";
282 }
283}
Tobin Ehlis8726b9f2014-10-24 12:01:45 -0600284// Block of code at start here for managing/tracking Pipeline state that this layer cares about
285// Just track 2 shaders for now
Tobin Ehlis26092022014-11-20 09:49:17 -0700286#define XGL_NUM_GRAPHICS_SHADERS XGL_SHADER_STAGE_COMPUTE
Tobin Ehlis8726b9f2014-10-24 12:01:45 -0600287#define MAX_SLOTS 2048
Tobin Ehlisb8154982014-10-27 14:53:17 -0600288
Tobin Ehlis8cced212015-02-13 10:26:14 -0700289static uint64_t g_drawCount[NUM_DRAW_TYPES] = {0, 0, 0, 0};
290
Tobin Ehlis56a61072014-11-21 08:58:46 -0700291// TODO : Should be tracking lastBound per cmdBuffer and when draws occur, report based on that cmd buffer lastBound
Tobin Ehlisa701ef02014-11-27 15:43:39 -0700292// Then need to synchronize the accesses based on cmd buffer so that if I'm reading state on one cmd buffer, updates
293// to that same cmd buffer by separate thread are not changing state from underneath us
Tobin Ehlis8cced212015-02-13 10:26:14 -0700294static PIPELINE_NODE* g_pPipelineHead = NULL;
295static SAMPLER_NODE* g_pSamplerHead = NULL;
296static IMAGE_NODE* g_pImageHead = NULL;
297static BUFFER_NODE* g_pBufferHead = NULL;
298static GLOBAL_CB_NODE* g_pCmdBufferHead = NULL;
Tobin Ehlis45662712015-02-23 09:06:28 -0700299static XGL_CMD_BUFFER g_lastCmdBuffer[MAX_TID] = {NULL};
Tobin Ehlis8cced212015-02-13 10:26:14 -0700300#define MAX_BINDING 0xFFFFFFFF // Default vtxBinding value in CB Node to identify if no vtxBinding set
Tobin Ehlis8726b9f2014-10-24 12:01:45 -0600301
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700302static DYNAMIC_STATE_NODE* g_pDynamicStateHead[XGL_NUM_STATE_BIND_POINT] = {0};
Tobin Ehlis56a61072014-11-21 08:58:46 -0700303
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700304static void insertDynamicState(const XGL_DYNAMIC_STATE_OBJECT state, const GENERIC_HEADER* pCreateInfo, XGL_STATE_BIND_POINT bindPoint)
Tobin Ehlis56a61072014-11-21 08:58:46 -0700305{
Ian Elliott81ac44c2015-01-13 17:52:38 -0700306 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis56a61072014-11-21 08:58:46 -0700307 // Insert new node at head of appropriate LL
308 DYNAMIC_STATE_NODE* pStateNode = (DYNAMIC_STATE_NODE*)malloc(sizeof(DYNAMIC_STATE_NODE));
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700309#if ALLOC_DEBUG
310 printf("Alloc1 #%lu pStateNode addr(%p)\n", ++g_alloc_count, (void*)pStateNode);
311#endif
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700312 pStateNode->pNext = g_pDynamicStateHead[bindPoint];
313 g_pDynamicStateHead[bindPoint] = pStateNode;
Tobin Ehlis56a61072014-11-21 08:58:46 -0700314 pStateNode->stateObj = state;
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700315 pStateNode->pCreateInfo = (GENERIC_HEADER*)malloc(dynStateCreateInfoSize(pCreateInfo->sType));
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700316#if ALLOC_DEBUG
317 printf("Alloc2 #%lu pStateNode->pCreateInfo addr(%p)\n", ++g_alloc_count, (void*)pStateNode->pCreateInfo);
318#endif
Tobin Ehlis84c521c2015-01-19 08:42:29 -0700319 memcpy(pStateNode->pCreateInfo, pCreateInfo, dynStateCreateInfoSize(pCreateInfo->sType));
Tobin Ehlis83ebbef2015-02-10 15:35:23 -0700320 // VP has embedded ptr so need to handle that as special case
321 if (XGL_STRUCTURE_TYPE_DYNAMIC_VP_STATE_CREATE_INFO == pCreateInfo->sType) {
322 XGL_DYNAMIC_VP_STATE_CREATE_INFO* pVPCI = (XGL_DYNAMIC_VP_STATE_CREATE_INFO*)pStateNode->pCreateInfo;
323 XGL_VIEWPORT** ppViewports = (XGL_VIEWPORT**)&pVPCI->pViewports;
Courtney Goeltzenleuchterc6e32f92015-02-11 14:13:34 -0700324 size_t vpSize = sizeof(XGL_VIEWPORT) * pVPCI->viewportAndScissorCount;
Tobin Ehlis83ebbef2015-02-10 15:35:23 -0700325 if (vpSize) {
326 *ppViewports = (XGL_VIEWPORT*)malloc(vpSize);
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700327#if ALLOC_DEBUG
328 printf("Alloc3 #%lu *ppViewports addr(%p)\n", ++g_alloc_count, (void*)*ppViewports);
329#endif
Tobin Ehlis83ebbef2015-02-10 15:35:23 -0700330 memcpy(*ppViewports, ((XGL_DYNAMIC_VP_STATE_CREATE_INFO*)pCreateInfo)->pViewports, vpSize);
331 }
332 XGL_RECT** ppScissors = (XGL_RECT**)&pVPCI->pScissors;
Courtney Goeltzenleuchterc6e32f92015-02-11 14:13:34 -0700333 size_t scSize = sizeof(XGL_RECT) * pVPCI->viewportAndScissorCount;
Tobin Ehlis83ebbef2015-02-10 15:35:23 -0700334 if (scSize) {
335 *ppScissors = (XGL_RECT*)malloc(scSize);
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700336#if ALLOC_DEBUG
337 printf("Alloc4 #%lu *ppScissors addr(%p)\n", ++g_alloc_count, (void*)*ppScissors);
338#endif
Tobin Ehlis83ebbef2015-02-10 15:35:23 -0700339 memcpy(*ppScissors, ((XGL_DYNAMIC_VP_STATE_CREATE_INFO*)pCreateInfo)->pScissors, scSize);
340 }
341 }
Ian Elliott81ac44c2015-01-13 17:52:38 -0700342 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis56a61072014-11-21 08:58:46 -0700343}
Tobin Ehlisefa84162015-02-17 09:54:13 -0700344// Free all allocated nodes for Dynamic State objs
345static void freeDynamicState()
346{
347 for (uint32_t i = 0; i < XGL_NUM_STATE_BIND_POINT; i++) {
348 DYNAMIC_STATE_NODE* pStateNode = g_pDynamicStateHead[i];
349 DYNAMIC_STATE_NODE* pFreeMe = pStateNode;
350 while (pStateNode) {
351 pFreeMe = pStateNode;
352 pStateNode = pStateNode->pNext;
353 assert(pFreeMe->pCreateInfo);
354 if (XGL_STRUCTURE_TYPE_DYNAMIC_VP_STATE_CREATE_INFO == pFreeMe->pCreateInfo->sType) {
355 XGL_DYNAMIC_VP_STATE_CREATE_INFO* pVPCI = (XGL_DYNAMIC_VP_STATE_CREATE_INFO*)pFreeMe->pCreateInfo;
356 if (pVPCI->pViewports) {
357 void** ppToFree = (void**)&pVPCI->pViewports;
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700358#if ALLOC_DEBUG
Tobin Ehlisfb1ef942015-02-20 09:30:06 -0700359 printf("Free3 #%lu pViewports addr(%p)\n", ++g_free_count, (void*)*ppToFree);
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700360#endif
Tobin Ehlisefa84162015-02-17 09:54:13 -0700361 free(*ppToFree);
362 }
363 if (pVPCI->pScissors) {
364 void** ppToFree = (void**)&pVPCI->pScissors;
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700365#if ALLOC_DEBUG
Tobin Ehlisfb1ef942015-02-20 09:30:06 -0700366 printf("Free4 #%lu pScissors addr(%p)\n", ++g_free_count, (void*)*ppToFree);
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700367#endif
Tobin Ehlisefa84162015-02-17 09:54:13 -0700368 free(*ppToFree);
369 }
370 }
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700371#if ALLOC_DEBUG
Tobin Ehlisfb1ef942015-02-20 09:30:06 -0700372 printf("Free2 #%lu pStateNode->CreateInfo addr(%p)\n", ++g_free_count, (void*)pFreeMe->pCreateInfo);
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700373#endif
Tobin Ehlisefa84162015-02-17 09:54:13 -0700374 free(pFreeMe->pCreateInfo);
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700375#if ALLOC_DEBUG
Tobin Ehlisfb1ef942015-02-20 09:30:06 -0700376 printf("Free1 #%lu pStateNode addr(%p)\n", ++g_free_count, (void*)pFreeMe);
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700377#endif
Tobin Ehlisefa84162015-02-17 09:54:13 -0700378 free(pFreeMe);
379 }
Tobin Ehlisfb1ef942015-02-20 09:30:06 -0700380 g_pDynamicStateHead[i] = NULL;
Tobin Ehlisefa84162015-02-17 09:54:13 -0700381 }
382}
383// Free all sampler nodes
384static void freeSamplers()
385{
386 SAMPLER_NODE* pSampler = g_pSamplerHead;
387 SAMPLER_NODE* pFreeMe = pSampler;
388 while (pSampler) {
389 pFreeMe = pSampler;
390 pSampler = pSampler->pNext;
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700391#if ALLOC_DEBUG
Tobin Ehlisfb1ef942015-02-20 09:30:06 -0700392 printf("Free25 #%lu pSampler addr(%p)\n", ++g_free_count, (void*)pFreeMe);
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700393#endif
Tobin Ehlisefa84162015-02-17 09:54:13 -0700394 free(pFreeMe);
395 }
Tobin Ehlisfb1ef942015-02-20 09:30:06 -0700396 g_pSamplerHead = NULL;
Tobin Ehlisefa84162015-02-17 09:54:13 -0700397}
398// Free all image nodes
399static void freeImages()
400{
401 IMAGE_NODE* pImage = g_pImageHead;
402 IMAGE_NODE* pFreeMe = pImage;
403 while (pImage) {
404 pFreeMe = pImage;
405 pImage = pImage->pNext;
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700406#if ALLOC_DEBUG
Tobin Ehlisfb1ef942015-02-20 09:30:06 -0700407 printf("Free22 #%lu pImage addr(%p)\n", ++g_free_count, (void*)pFreeMe);
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700408#endif
Tobin Ehlisefa84162015-02-17 09:54:13 -0700409 free(pFreeMe);
410 }
Tobin Ehlisfb1ef942015-02-20 09:30:06 -0700411 g_pImageHead = NULL;
Tobin Ehlisefa84162015-02-17 09:54:13 -0700412}
413// Free all buffer nodes
414static void freeBuffers()
415{
416 BUFFER_NODE* pBuffer = g_pBufferHead;
417 BUFFER_NODE* pFreeMe = pBuffer;
418 while (pBuffer) {
419 pFreeMe = pBuffer;
420 pBuffer = pBuffer->pNext;
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700421#if ALLOC_DEBUG
422 printf("Free21 #%lu pBuffer addr(%p)\n", ++g_free_count, (void*)pFreeMe);
423#endif
Tobin Ehlisefa84162015-02-17 09:54:13 -0700424 free(pFreeMe);
425 }
Tobin Ehlisfb1ef942015-02-20 09:30:06 -0700426 g_pBufferHead = NULL;
Tobin Ehlisefa84162015-02-17 09:54:13 -0700427}
Tobin Ehlisd092d232015-02-13 13:30:07 -0700428static GLOBAL_CB_NODE* getCBNode(XGL_CMD_BUFFER cb);
Tobin Ehlis56a61072014-11-21 08:58:46 -0700429// Print the last bound dynamic state
Tobin Ehlis8cced212015-02-13 10:26:14 -0700430static void printDynamicState(const XGL_CMD_BUFFER cb)
Tobin Ehlis56a61072014-11-21 08:58:46 -0700431{
Tobin Ehlis8cced212015-02-13 10:26:14 -0700432 GLOBAL_CB_NODE* pCB = getCBNode(cb);
433 if (pCB) {
434 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700435 char str[4*1024];
Tobin Ehlis8cced212015-02-13 10:26:14 -0700436 for (uint32_t i = 0; i < XGL_NUM_STATE_BIND_POINT; i++) {
437 if (pCB->lastBoundDynamicState[i]) {
438 sprintf(str, "Reporting CreateInfo for currently bound %s object %p", string_XGL_STATE_BIND_POINT(i), pCB->lastBoundDynamicState[i]->stateObj);
439 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, pCB->lastBoundDynamicState[i]->stateObj, 0, DRAWSTATE_NONE, "DS", str);
440 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, pCB->lastBoundDynamicState[i]->stateObj, 0, DRAWSTATE_NONE, "DS", dynamic_display(pCB->lastBoundDynamicState[i]->pCreateInfo, " "));
441 break;
442 }
443 else {
444 sprintf(str, "No dynamic state of type %s bound", string_XGL_STATE_BIND_POINT(i));
445 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", str);
446 }
Tobin Ehlis56a61072014-11-21 08:58:46 -0700447 }
Tobin Ehlis8cced212015-02-13 10:26:14 -0700448 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis56a61072014-11-21 08:58:46 -0700449 }
Tobin Ehlis8cced212015-02-13 10:26:14 -0700450 else {
451 char str[1024];
452 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cb);
453 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cb, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
454 }
Tobin Ehlis56a61072014-11-21 08:58:46 -0700455}
456// Retrieve pipeline node ptr for given pipeline object
Tobin Ehlis8726b9f2014-10-24 12:01:45 -0600457static PIPELINE_NODE *getPipeline(XGL_PIPELINE pipeline)
458{
Ian Elliott81ac44c2015-01-13 17:52:38 -0700459 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700460 PIPELINE_NODE *pTrav = g_pPipelineHead;
Tobin Ehlis8726b9f2014-10-24 12:01:45 -0600461 while (pTrav) {
Tobin Ehlis9e142a32014-11-21 12:04:39 -0700462 if (pTrav->pipeline == pipeline) {
Ian Elliott81ac44c2015-01-13 17:52:38 -0700463 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8726b9f2014-10-24 12:01:45 -0600464 return pTrav;
Tobin Ehlis9e142a32014-11-21 12:04:39 -0700465 }
Tobin Ehlis8726b9f2014-10-24 12:01:45 -0600466 pTrav = pTrav->pNext;
467 }
Ian Elliott81ac44c2015-01-13 17:52:38 -0700468 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8726b9f2014-10-24 12:01:45 -0600469 return NULL;
470}
471
Tobin Ehlis5a1d9f32014-11-20 10:48:56 -0700472// For given sampler, return a ptr to its Create Info struct, or NULL if sampler not found
Tobin Ehlis04f80bb2015-02-11 13:13:18 -0700473// TODO : Use this function to display sampler info
474// commenting out for now to avoid warning about not being used
475/*
Tobin Ehlis5a1d9f32014-11-20 10:48:56 -0700476static XGL_SAMPLER_CREATE_INFO* getSamplerCreateInfo(const XGL_SAMPLER sampler)
477{
Ian Elliott81ac44c2015-01-13 17:52:38 -0700478 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700479 SAMPLER_NODE *pTrav = g_pSamplerHead;
Tobin Ehlis5a1d9f32014-11-20 10:48:56 -0700480 while (pTrav) {
Tobin Ehlis9e142a32014-11-21 12:04:39 -0700481 if (sampler == pTrav->sampler) {
Ian Elliott81ac44c2015-01-13 17:52:38 -0700482 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis5a1d9f32014-11-20 10:48:56 -0700483 return &pTrav->createInfo;
Tobin Ehlis9e142a32014-11-21 12:04:39 -0700484 }
Tobin Ehlis5a1d9f32014-11-20 10:48:56 -0700485 pTrav = pTrav->pNext;
486 }
Ian Elliott81ac44c2015-01-13 17:52:38 -0700487 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis5a1d9f32014-11-20 10:48:56 -0700488 return NULL;
489}
Tobin Ehlis04f80bb2015-02-11 13:13:18 -0700490*/
Tobin Ehlis5a1d9f32014-11-20 10:48:56 -0700491
Tobin Ehlis8726b9f2014-10-24 12:01:45 -0600492// Init the pipeline mapping info based on pipeline create info LL tree
Tobin Ehlis9e142a32014-11-21 12:04:39 -0700493// Threading note : Calls to this function should wrapped in mutex
Tobin Ehlis8726b9f2014-10-24 12:01:45 -0600494static void initPipeline(PIPELINE_NODE *pPipeline, const XGL_GRAPHICS_PIPELINE_CREATE_INFO* pCreateInfo)
495{
Tobin Ehlis26092022014-11-20 09:49:17 -0700496 // First init create info, we'll shadow the structs as we go down the tree
Tobin Ehlis56a61072014-11-21 08:58:46 -0700497 pPipeline->pCreateTree = (XGL_GRAPHICS_PIPELINE_CREATE_INFO*)malloc(sizeof(XGL_GRAPHICS_PIPELINE_CREATE_INFO));
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700498#if ALLOC_DEBUG
499 printf("Alloc5 #%lu pPipeline->pCreateTree addr(%p)\n", ++g_alloc_count, (void*)pPipeline->pCreateTree);
500#endif
Tobin Ehlis26092022014-11-20 09:49:17 -0700501 memcpy(pPipeline->pCreateTree, pCreateInfo, sizeof(XGL_GRAPHICS_PIPELINE_CREATE_INFO));
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700502 GENERIC_HEADER *pShadowTrav = (GENERIC_HEADER*)pPipeline->pCreateTree;
503 GENERIC_HEADER *pTrav = (GENERIC_HEADER*)pCreateInfo->pNext;
Tobin Ehlis8726b9f2014-10-24 12:01:45 -0600504 while (pTrav) {
Tobin Ehlis26092022014-11-20 09:49:17 -0700505 // Shadow the struct
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700506 pShadowTrav->pNext = (GENERIC_HEADER*)malloc(sTypeStructSize(pTrav->sType));
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700507#if ALLOC_DEBUG
508 printf("Alloc6 #%lu pShadowTrav->pNext addr(%p)\n", ++g_alloc_count, (void*)pShadowTrav->pNext);
509#endif
Tobin Ehlis26092022014-11-20 09:49:17 -0700510 // Typically pNext is const so have to cast to avoid warning when we modify it here
511 memcpy((void*)pShadowTrav->pNext, pTrav, sTypeStructSize(pTrav->sType));
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700512 pShadowTrav = (GENERIC_HEADER*)pShadowTrav->pNext;
513 // Special copy of Vtx info as it has embedded array
514 if (XGL_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_CREATE_INFO == pTrav->sType) {
Tobin Ehlis83ebbef2015-02-10 15:35:23 -0700515 XGL_PIPELINE_VERTEX_INPUT_CREATE_INFO *pVICI = (XGL_PIPELINE_VERTEX_INPUT_CREATE_INFO*)pShadowTrav;
Tobin Ehlis1affd3c2014-11-25 10:24:15 -0700516 pPipeline->vtxBindingCount = pVICI->bindingCount;
517 uint32_t allocSize = pPipeline->vtxBindingCount * sizeof(XGL_VERTEX_INPUT_BINDING_DESCRIPTION);
Tobin Ehlis83ebbef2015-02-10 15:35:23 -0700518 if (allocSize) {
519 pPipeline->pVertexBindingDescriptions = (XGL_VERTEX_INPUT_BINDING_DESCRIPTION*)malloc(allocSize);
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700520#if ALLOC_DEBUG
521 printf("Alloc7 #%lu pPipeline->pVertexBindingDescriptions addr(%p)\n", ++g_alloc_count, (void*)pPipeline->pVertexBindingDescriptions);
522#endif
Tobin Ehlis83ebbef2015-02-10 15:35:23 -0700523 memcpy(pPipeline->pVertexBindingDescriptions, ((XGL_PIPELINE_VERTEX_INPUT_CREATE_INFO*)pTrav)->pVertexAttributeDescriptions, allocSize);
524 }
Tobin Ehlis1affd3c2014-11-25 10:24:15 -0700525 pPipeline->vtxAttributeCount = pVICI->attributeCount;
526 allocSize = pPipeline->vtxAttributeCount * sizeof(XGL_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION);
Tobin Ehlis83ebbef2015-02-10 15:35:23 -0700527 if (allocSize) {
528 pPipeline->pVertexAttributeDescriptions = (XGL_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION*)malloc(allocSize);
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700529#if ALLOC_DEBUG
530 printf("Alloc8 #%lu pPipeline->pVertexAttributeDescriptions addr(%p)\n", ++g_alloc_count, (void*)pPipeline->pVertexAttributeDescriptions);
531#endif
Tobin Ehlis83ebbef2015-02-10 15:35:23 -0700532 memcpy(pPipeline->pVertexAttributeDescriptions, ((XGL_PIPELINE_VERTEX_INPUT_CREATE_INFO*)pTrav)->pVertexAttributeDescriptions, allocSize);
533 }
534 }
535 else if (XGL_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO == pTrav->sType) {
536 // Special copy of CB state as it has embedded array
537 XGL_PIPELINE_CB_STATE_CREATE_INFO *pCBCI = (XGL_PIPELINE_CB_STATE_CREATE_INFO*)pShadowTrav;
538 pPipeline->attachmentCount = pCBCI->attachmentCount;
539 uint32_t allocSize = pPipeline->attachmentCount * sizeof(XGL_PIPELINE_CB_ATTACHMENT_STATE);
540 if (allocSize) {
541 pPipeline->pAttachments = (XGL_PIPELINE_CB_ATTACHMENT_STATE*)malloc(allocSize);
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700542#if ALLOC_DEBUG
543 printf("Alloc9 #%lu pPipeline->pAttachments addr(%p)\n", ++g_alloc_count, (void*)pPipeline->pAttachments);
544#endif
Tobin Ehlis83ebbef2015-02-10 15:35:23 -0700545 XGL_PIPELINE_CB_ATTACHMENT_STATE** ppAttachments = (XGL_PIPELINE_CB_ATTACHMENT_STATE**)&pCBCI->pAttachments;
546 *ppAttachments = pPipeline->pAttachments;
547 memcpy(pPipeline->pAttachments, ((XGL_PIPELINE_CB_STATE_CREATE_INFO*)pTrav)->pAttachments, allocSize);
548 }
Tobin Ehlis1affd3c2014-11-25 10:24:15 -0700549 }
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700550 pTrav = (GENERIC_HEADER*)pTrav->pNext;
Tobin Ehlis8726b9f2014-10-24 12:01:45 -0600551 }
552}
Tobin Ehlisefa84162015-02-17 09:54:13 -0700553// Free the Pipeline nodes
554static void freePipelines()
555{
556 PIPELINE_NODE* pPipeline = g_pPipelineHead;
557 PIPELINE_NODE* pFreeMe = pPipeline;
558 while (pPipeline) {
559 pFreeMe = pPipeline;
560 GENERIC_HEADER* pShadowTrav = (GENERIC_HEADER*)pPipeline->pCreateTree;
561 GENERIC_HEADER* pShadowFree = pShadowTrav;
562 while (pShadowTrav) {
563 pShadowFree = pShadowTrav;
564 pShadowTrav = (GENERIC_HEADER*)pShadowTrav->pNext;
565 if (XGL_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_CREATE_INFO == pShadowFree->sType) {
566 // Free the vtx data shadowed directly into pPipeline node
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700567 if (pFreeMe->pVertexBindingDescriptions) {
568#if ALLOC_DEBUG
Tobin Ehlisfb1ef942015-02-20 09:30:06 -0700569 printf("Free7 #%lu pVertexBindingDescriptions addr(%p)\n", ++g_free_count, (void*)pFreeMe->pVertexBindingDescriptions);
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700570#endif
Tobin Ehlisefa84162015-02-17 09:54:13 -0700571 free(pFreeMe->pVertexBindingDescriptions);
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700572 }
573 if (pFreeMe->pVertexAttributeDescriptions) {
574#if ALLOC_DEBUG
Tobin Ehlisfb1ef942015-02-20 09:30:06 -0700575 printf("Free8 #%lu pVertexAttributeDescriptions addr(%p)\n", ++g_free_count, (void*)pFreeMe->pVertexAttributeDescriptions);
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700576#endif
Tobin Ehlisefa84162015-02-17 09:54:13 -0700577 free(pFreeMe->pVertexAttributeDescriptions);
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700578 }
Tobin Ehlisefa84162015-02-17 09:54:13 -0700579 }
580 else if (XGL_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO == pShadowFree->sType) {
581 // Free attachment data shadowed into pPipeline node
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700582 if (pFreeMe->pAttachments) {
583#if ALLOC_DEBUG
Tobin Ehlisfb1ef942015-02-20 09:30:06 -0700584 printf("Free9 #%lu pAttachments addr(%p)\n", ++g_free_count, (void*)pFreeMe->pAttachments);
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700585#endif
Tobin Ehlisefa84162015-02-17 09:54:13 -0700586 free(pFreeMe->pAttachments);
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700587 }
Tobin Ehlisefa84162015-02-17 09:54:13 -0700588 }
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700589#if ALLOC_DEBUG
Tobin Ehlisfb1ef942015-02-20 09:30:06 -0700590 printf("Free5 & Free6 #%lu pShadowNode addr(%p)\n", ++g_free_count, (void*)pShadowFree);
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700591#endif
Tobin Ehlisefa84162015-02-17 09:54:13 -0700592 free(pShadowFree);
593 }
594 pPipeline = pPipeline->pNext;
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700595#if ALLOC_DEBUG
Tobin Ehlisfb1ef942015-02-20 09:30:06 -0700596 printf("Free23 & Free24 #%lu pPipeline addr(%p)\n", ++g_free_count, (void*)pFreeMe);
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700597#endif
Tobin Ehlisefa84162015-02-17 09:54:13 -0700598 free(pFreeMe);
599 }
Tobin Ehlisfb1ef942015-02-20 09:30:06 -0700600 g_pPipelineHead = NULL;
Tobin Ehlisefa84162015-02-17 09:54:13 -0700601}
Tobin Ehlis8726b9f2014-10-24 12:01:45 -0600602// Block of code at start here specifically for managing/tracking DSs
Tobin Ehlis9e3d7532014-10-27 17:12:54 -0600603
Tobin Ehlis84c521c2015-01-19 08:42:29 -0700604// ptr to HEAD of LL of DS Regions
605static REGION_NODE* g_pRegionHead = NULL;
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700606// ptr to HEAD of LL of top-level Layouts
607static LAYOUT_NODE* g_pLayoutHead = NULL;
Tobin Ehlis2f3726c2015-01-15 17:51:52 -0700608
Tobin Ehlis84c521c2015-01-19 08:42:29 -0700609// Return Region node ptr for specified region or else NULL
610static REGION_NODE* getRegionNode(XGL_DESCRIPTOR_REGION region)
611{
Tobin Ehlisbf0146e2015-02-11 14:24:02 -0700612 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis84c521c2015-01-19 08:42:29 -0700613 REGION_NODE* pTrav = g_pRegionHead;
614 while (pTrav) {
615 if (pTrav->region == region) {
Tobin Ehlisbf0146e2015-02-11 14:24:02 -0700616 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis84c521c2015-01-19 08:42:29 -0700617 return pTrav;
618 }
619 pTrav = pTrav->pNext;
620 }
Tobin Ehlisbf0146e2015-02-11 14:24:02 -0700621 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis84c521c2015-01-19 08:42:29 -0700622 return NULL;
623}
Tobin Ehlis84c521c2015-01-19 08:42:29 -0700624// Return Set node ptr for specified set or else NULL
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700625static SET_NODE* getSetNode(XGL_DESCRIPTOR_SET set)
Tobin Ehlis84c521c2015-01-19 08:42:29 -0700626{
Tobin Ehlisbf0146e2015-02-11 14:24:02 -0700627 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis84c521c2015-01-19 08:42:29 -0700628 REGION_NODE* pTrav = g_pRegionHead;
629 while (pTrav) {
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700630 SET_NODE* pSet = pTrav->pSets;
631 while (pSet) {
632 if (pSet->set == set) {
Tobin Ehlisbf0146e2015-02-11 14:24:02 -0700633 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700634 return pSet;
635 }
636 pSet = pSet->pNext;
637 }
638 pTrav = pTrav->pNext;
639 }
Tobin Ehlisbf0146e2015-02-11 14:24:02 -0700640 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700641 return NULL;
642}
643
Tobin Ehlis83ebbef2015-02-10 15:35:23 -0700644// Return XGL_TRUE if DS Exists and is within an xglBeginDescriptorRegionUpdate() call sequence, otherwise XGL_FALSE
645static bool32_t dsUpdateActive(XGL_DESCRIPTOR_SET ds)
646{
Tobin Ehlisfb1ef942015-02-20 09:30:06 -0700647 // Note, both "get" functions use global mutex so this guy does not
Tobin Ehlis83ebbef2015-02-10 15:35:23 -0700648 SET_NODE* pTrav = getSetNode(ds);
649 if (pTrav) {
650 REGION_NODE* pRegion = NULL;
651 pRegion = getRegionNode(pTrav->region);
652 if (pRegion) {
653 return pRegion->updateActive;
654 }
655 }
656 return XGL_FALSE;
657}
658
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700659static LAYOUT_NODE* getLayoutNode(XGL_DESCRIPTOR_SET_LAYOUT layout) {
Tobin Ehlisbf0146e2015-02-11 14:24:02 -0700660 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700661 LAYOUT_NODE* pTrav = g_pLayoutHead;
662 while (pTrav) {
663 if (pTrav->layout == layout) {
Tobin Ehlisbf0146e2015-02-11 14:24:02 -0700664 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis84c521c2015-01-19 08:42:29 -0700665 return pTrav;
666 }
667 pTrav = pTrav->pNext;
668 }
Tobin Ehlisbf0146e2015-02-11 14:24:02 -0700669 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis84c521c2015-01-19 08:42:29 -0700670 return NULL;
671}
Tobin Ehlis8726b9f2014-10-24 12:01:45 -0600672
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700673static uint32_t getUpdateIndex(GENERIC_HEADER* pUpdateStruct)
674{
675 switch (pUpdateStruct->sType)
676 {
677 case XGL_STRUCTURE_TYPE_UPDATE_SAMPLERS:
678 return ((XGL_UPDATE_SAMPLERS*)pUpdateStruct)->index;
679 case XGL_STRUCTURE_TYPE_UPDATE_SAMPLER_TEXTURES:
680 return ((XGL_UPDATE_SAMPLER_TEXTURES*)pUpdateStruct)->index;
681 case XGL_STRUCTURE_TYPE_UPDATE_IMAGES:
682 return ((XGL_UPDATE_IMAGES*)pUpdateStruct)->index;
683 case XGL_STRUCTURE_TYPE_UPDATE_BUFFERS:
684 return ((XGL_UPDATE_BUFFERS*)pUpdateStruct)->index;
685 case XGL_STRUCTURE_TYPE_UPDATE_AS_COPY:
686 return ((XGL_UPDATE_AS_COPY*)pUpdateStruct)->descriptorIndex;
687 default:
688 // TODO : Flag specific error for this case
689 return 0;
690 }
691}
692
693static uint32_t getUpdateUpperBound(GENERIC_HEADER* pUpdateStruct)
694{
695 switch (pUpdateStruct->sType)
696 {
697 case XGL_STRUCTURE_TYPE_UPDATE_SAMPLERS:
Tobin Ehlis82871a82015-02-19 09:55:18 -0700698 return (((XGL_UPDATE_SAMPLERS*)pUpdateStruct)->count + ((XGL_UPDATE_SAMPLERS*)pUpdateStruct)->index);
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700699 case XGL_STRUCTURE_TYPE_UPDATE_SAMPLER_TEXTURES:
Tobin Ehlis82871a82015-02-19 09:55:18 -0700700 return (((XGL_UPDATE_SAMPLER_TEXTURES*)pUpdateStruct)->count + ((XGL_UPDATE_SAMPLER_TEXTURES*)pUpdateStruct)->index);
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700701 case XGL_STRUCTURE_TYPE_UPDATE_IMAGES:
Tobin Ehlis82871a82015-02-19 09:55:18 -0700702 return (((XGL_UPDATE_IMAGES*)pUpdateStruct)->count + ((XGL_UPDATE_IMAGES*)pUpdateStruct)->index);
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700703 case XGL_STRUCTURE_TYPE_UPDATE_BUFFERS:
Tobin Ehlis82871a82015-02-19 09:55:18 -0700704 return (((XGL_UPDATE_BUFFERS*)pUpdateStruct)->count + ((XGL_UPDATE_BUFFERS*)pUpdateStruct)->index);
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700705 case XGL_STRUCTURE_TYPE_UPDATE_AS_COPY:
706 // TODO : Need to understand this case better and make sure code is correct
Tobin Ehlis82871a82015-02-19 09:55:18 -0700707 return (((XGL_UPDATE_AS_COPY*)pUpdateStruct)->count + ((XGL_UPDATE_AS_COPY*)pUpdateStruct)->descriptorIndex);
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700708 default:
709 // TODO : Flag specific error for this case
710 return 0;
711 }
712}
713
714// Verify that the descriptor type in the update struct matches what's expected by the layout
Tobin Ehlisefa84162015-02-17 09:54:13 -0700715static bool32_t validateUpdateType(GENERIC_HEADER* pUpdateStruct, const LAYOUT_NODE* pLayout)//XGL_DESCRIPTOR_TYPE type)
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700716{
717 // First get actual type of update
718 XGL_DESCRIPTOR_TYPE actualType;
Tobin Ehlisefa84162015-02-17 09:54:13 -0700719 uint32_t i = 0;
720 uint32_t bound = getUpdateUpperBound(pUpdateStruct);
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700721 switch (pUpdateStruct->sType)
722 {
723 case XGL_STRUCTURE_TYPE_UPDATE_SAMPLERS:
724 actualType = XGL_DESCRIPTOR_TYPE_SAMPLER;
725 break;
726 case XGL_STRUCTURE_TYPE_UPDATE_SAMPLER_TEXTURES:
727 actualType = XGL_DESCRIPTOR_TYPE_SAMPLER_TEXTURE;
728 break;
729 case XGL_STRUCTURE_TYPE_UPDATE_IMAGES:
730 actualType = ((XGL_UPDATE_IMAGES*)pUpdateStruct)->descriptorType;
731 break;
732 case XGL_STRUCTURE_TYPE_UPDATE_BUFFERS:
733 actualType = ((XGL_UPDATE_BUFFERS*)pUpdateStruct)->descriptorType;
734 break;
735 case XGL_STRUCTURE_TYPE_UPDATE_AS_COPY:
736 actualType = ((XGL_UPDATE_AS_COPY*)pUpdateStruct)->descriptorType;
737 break;
738 default:
739 // TODO : Flag specific error for this case
740 return 0;
741 }
Tobin Ehlis82871a82015-02-19 09:55:18 -0700742 for (i = getUpdateIndex(pUpdateStruct); i < bound; i++) {
Tobin Ehlisefa84162015-02-17 09:54:13 -0700743 if (pLayout->pTypes[i] != actualType)
744 return 0;
745 }
746 return 1;
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700747}
748
749// Verify that update region for this update does not exceed max layout index for this type
750static bool32_t validateUpdateSize(GENERIC_HEADER* pUpdateStruct, uint32_t layoutIdx)
751{
Tobin Ehlis82871a82015-02-19 09:55:18 -0700752 if ((getUpdateUpperBound(pUpdateStruct)-1) > layoutIdx)
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700753 return 0;
754 return 1;
755}
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700756// Determine the update type, allocate a new struct of that type, shadow the given pUpdate
757// struct into the new struct and return ptr to shadow struct cast as GENERIC_HEADER
Tobin Ehlisfb1ef942015-02-20 09:30:06 -0700758// NOTE : Calls to this function should be wrapped in mutex
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700759static GENERIC_HEADER* shadowUpdateNode(GENERIC_HEADER* pUpdate)
760{
761 GENERIC_HEADER* pNewNode = NULL;
Tobin Ehlis83ebbef2015-02-10 15:35:23 -0700762 size_t array_size = 0;
Tobin Ehlis04f80bb2015-02-11 13:13:18 -0700763 size_t base_array_size = 0;
764 size_t total_array_size = 0;
Tobin Ehlis1836fcc2015-02-18 14:38:11 -0700765 size_t baseBuffAddr = 0;
Tobin Ehlis04f80bb2015-02-11 13:13:18 -0700766 XGL_UPDATE_BUFFERS* pUBCI;
Tobin Ehlis1836fcc2015-02-18 14:38:11 -0700767 XGL_UPDATE_IMAGES* pUICI;
Tobin Ehlis8733adc2015-02-23 16:09:58 -0700768 char str[1024];
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700769 switch (pUpdate->sType)
770 {
771 case XGL_STRUCTURE_TYPE_UPDATE_SAMPLERS:
772 pNewNode = (GENERIC_HEADER*)malloc(sizeof(XGL_UPDATE_SAMPLERS));
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700773#if ALLOC_DEBUG
Tobin Ehlisfb1ef942015-02-20 09:30:06 -0700774 printf("Alloc10 #%lu pNewNode addr(%p)\n", ++g_alloc_count, (void*)pNewNode);
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700775#endif
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700776 memcpy(pNewNode, pUpdate, sizeof(XGL_UPDATE_SAMPLERS));
777 array_size = sizeof(XGL_SAMPLER) * ((XGL_UPDATE_SAMPLERS*)pNewNode)->count;
778 ((XGL_UPDATE_SAMPLERS*)pNewNode)->pSamplers = (XGL_SAMPLER*)malloc(array_size);
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700779#if ALLOC_DEBUG
Tobin Ehlisfb1ef942015-02-20 09:30:06 -0700780 printf("Alloc11 #%lu pNewNode->pSamplers addr(%p)\n", ++g_alloc_count, (void*)((XGL_UPDATE_SAMPLERS*)pNewNode)->pSamplers);
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700781#endif
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700782 memcpy((XGL_SAMPLER*)((XGL_UPDATE_SAMPLERS*)pNewNode)->pSamplers, ((XGL_UPDATE_SAMPLERS*)pUpdate)->pSamplers, array_size);
Tobin Ehlis83ebbef2015-02-10 15:35:23 -0700783 break;
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700784 case XGL_STRUCTURE_TYPE_UPDATE_SAMPLER_TEXTURES:
785 pNewNode = (GENERIC_HEADER*)malloc(sizeof(XGL_UPDATE_SAMPLER_TEXTURES));
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700786#if ALLOC_DEBUG
Tobin Ehlisfb1ef942015-02-20 09:30:06 -0700787 printf("Alloc12 #%lu pNewNode addr(%p)\n", ++g_alloc_count, (void*)pNewNode);
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700788#endif
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700789 memcpy(pNewNode, pUpdate, sizeof(XGL_UPDATE_SAMPLER_TEXTURES));
790 array_size = sizeof(XGL_SAMPLER_IMAGE_VIEW_INFO) * ((XGL_UPDATE_SAMPLER_TEXTURES*)pNewNode)->count;
791 ((XGL_UPDATE_SAMPLER_TEXTURES*)pNewNode)->pSamplerImageViews = (XGL_SAMPLER_IMAGE_VIEW_INFO*)malloc(array_size);
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700792#if ALLOC_DEBUG
Tobin Ehlisfb1ef942015-02-20 09:30:06 -0700793 printf("Alloc13 #%lu pNewNode->pSamplerImageViews addr(%p)\n", ++g_alloc_count, (void*)((XGL_UPDATE_SAMPLER_TEXTURES*)pNewNode)->pSamplerImageViews);
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700794#endif
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700795 for (uint32_t i = 0; i < ((XGL_UPDATE_SAMPLER_TEXTURES*)pNewNode)->count; i++) {
796 memcpy((XGL_SAMPLER_IMAGE_VIEW_INFO*)&((XGL_UPDATE_SAMPLER_TEXTURES*)pNewNode)->pSamplerImageViews[i], &((XGL_UPDATE_SAMPLER_TEXTURES*)pUpdate)->pSamplerImageViews[i], sizeof(XGL_SAMPLER_IMAGE_VIEW_INFO));
797 ((XGL_SAMPLER_IMAGE_VIEW_INFO*)((XGL_UPDATE_SAMPLER_TEXTURES*)pNewNode)->pSamplerImageViews)[i].pImageView = malloc(sizeof(XGL_IMAGE_VIEW_ATTACH_INFO));
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700798#if ALLOC_DEBUG
Tobin Ehlisfb1ef942015-02-20 09:30:06 -0700799 printf("Alloc14 #%lu pSamplerImageViews)[%u].pImageView addr(%p)\n", ++g_alloc_count, i, (void*)((XGL_SAMPLER_IMAGE_VIEW_INFO*)((XGL_UPDATE_SAMPLER_TEXTURES*)pNewNode)->pSamplerImageViews)[i].pImageView);
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700800#endif
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700801 memcpy((XGL_IMAGE_VIEW_ATTACH_INFO*)((XGL_UPDATE_SAMPLER_TEXTURES*)pNewNode)->pSamplerImageViews[i].pImageView, ((XGL_UPDATE_SAMPLER_TEXTURES*)pUpdate)->pSamplerImageViews[i].pImageView, sizeof(XGL_IMAGE_VIEW_ATTACH_INFO));
802 }
Tobin Ehlis83ebbef2015-02-10 15:35:23 -0700803 break;
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700804 case XGL_STRUCTURE_TYPE_UPDATE_IMAGES:
Tobin Ehlis1836fcc2015-02-18 14:38:11 -0700805 pUICI = (XGL_UPDATE_IMAGES*)pUpdate;
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700806 pNewNode = (GENERIC_HEADER*)malloc(sizeof(XGL_UPDATE_IMAGES));
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700807#if ALLOC_DEBUG
808 printf("Alloc15 #%lu pNewNode addr(%p)\n", ++g_alloc_count, (void*)pNewNode);
809#endif
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700810 memcpy(pNewNode, pUpdate, sizeof(XGL_UPDATE_IMAGES));
Tobin Ehlis04f80bb2015-02-11 13:13:18 -0700811 base_array_size = sizeof(XGL_IMAGE_VIEW_ATTACH_INFO*) * ((XGL_UPDATE_IMAGES*)pNewNode)->count;
812 total_array_size = (sizeof(XGL_IMAGE_VIEW_ATTACH_INFO) * ((XGL_UPDATE_IMAGES*)pNewNode)->count) + base_array_size;
Tobin Ehlis83ebbef2015-02-10 15:35:23 -0700813 XGL_IMAGE_VIEW_ATTACH_INFO*** pppLocalImageViews = (XGL_IMAGE_VIEW_ATTACH_INFO***)&((XGL_UPDATE_IMAGES*)pNewNode)->pImageViews;
814 *pppLocalImageViews = (XGL_IMAGE_VIEW_ATTACH_INFO**)malloc(total_array_size);
Tobin Ehlis1836fcc2015-02-18 14:38:11 -0700815#if ALLOC_DEBUG
816 printf("Alloc16 #%lu *pppLocalImageViews addr(%p)\n", ++g_alloc_count, (void*)*pppLocalImageViews);
817#endif
818 baseBuffAddr = (size_t)(*pppLocalImageViews) + base_array_size;
819 for (uint32_t i = 0; i < pUICI->count; i++) {
Tobin Ehlisfdbc68c2015-02-19 13:14:59 -0700820 (*pppLocalImageViews)[i] = (XGL_IMAGE_VIEW_ATTACH_INFO*)(baseBuffAddr + (i * sizeof(XGL_IMAGE_VIEW_ATTACH_INFO)));
821 memcpy((*pppLocalImageViews)[i], pUICI->pImageViews[i], sizeof(XGL_IMAGE_VIEW_ATTACH_INFO));
Tobin Ehlis83ebbef2015-02-10 15:35:23 -0700822 }
823 break;
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700824 case XGL_STRUCTURE_TYPE_UPDATE_BUFFERS:
Tobin Ehlis04f80bb2015-02-11 13:13:18 -0700825 pUBCI = (XGL_UPDATE_BUFFERS*)pUpdate;
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700826 pNewNode = (GENERIC_HEADER*)malloc(sizeof(XGL_UPDATE_BUFFERS));
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700827#if ALLOC_DEBUG
828 printf("Alloc17 #%lu pNewNode addr(%p)\n", ++g_alloc_count, (void*)pNewNode);
829#endif
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700830 memcpy(pNewNode, pUpdate, sizeof(XGL_UPDATE_BUFFERS));
Tobin Ehlis04f80bb2015-02-11 13:13:18 -0700831 base_array_size = sizeof(XGL_BUFFER_VIEW_ATTACH_INFO*) * pUBCI->count;
832 total_array_size = (sizeof(XGL_BUFFER_VIEW_ATTACH_INFO) * pUBCI->count) + base_array_size;
833 XGL_BUFFER_VIEW_ATTACH_INFO*** pppLocalBufferViews = (XGL_BUFFER_VIEW_ATTACH_INFO***)&((XGL_UPDATE_BUFFERS*)pNewNode)->pBufferViews;
834 *pppLocalBufferViews = (XGL_BUFFER_VIEW_ATTACH_INFO**)malloc(total_array_size);
Tobin Ehlis1836fcc2015-02-18 14:38:11 -0700835#if ALLOC_DEBUG
836 printf("Alloc18 #%lu *pppLocalBufferViews addr(%p)\n", ++g_alloc_count, (void*)*pppLocalBufferViews);
837#endif
838 baseBuffAddr = (size_t)(*pppLocalBufferViews) + base_array_size;
Tobin Ehlis04f80bb2015-02-11 13:13:18 -0700839 for (uint32_t i = 0; i < pUBCI->count; i++) {
840 // Set ptr and then copy data into that ptr
Tobin Ehlisfdbc68c2015-02-19 13:14:59 -0700841 (*pppLocalBufferViews)[i] = (XGL_BUFFER_VIEW_ATTACH_INFO*)(baseBuffAddr + (i * sizeof(XGL_BUFFER_VIEW_ATTACH_INFO)));
842 memcpy((*pppLocalBufferViews)[i], pUBCI->pBufferViews[i], sizeof(XGL_BUFFER_VIEW_ATTACH_INFO));
Tobin Ehlis04f80bb2015-02-11 13:13:18 -0700843 }
Tobin Ehlis83ebbef2015-02-10 15:35:23 -0700844 break;
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700845 case XGL_STRUCTURE_TYPE_UPDATE_AS_COPY:
846 pNewNode = (GENERIC_HEADER*)malloc(sizeof(XGL_UPDATE_AS_COPY));
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700847#if ALLOC_DEBUG
848 printf("Alloc19 #%lu pNewNode addr(%p)\n", ++g_alloc_count, (void*)pNewNode);
849#endif
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700850 memcpy(pNewNode, pUpdate, sizeof(XGL_UPDATE_AS_COPY));
Tobin Ehlis83ebbef2015-02-10 15:35:23 -0700851 break;
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700852 default:
Tobin Ehlis8733adc2015-02-23 16:09:58 -0700853 sprintf(str, "Unexpected UPDATE struct of type %s (value %u) in xglUpdateDescriptors() struct tree", string_XGL_STRUCTURE_TYPE(pUpdate->sType), pUpdate->sType);
854 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_INVALID_UPDATE_STRUCT, "DS", str);
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700855 return NULL;
856 }
Tobin Ehlis83ebbef2015-02-10 15:35:23 -0700857 // Make sure that pNext for the end of shadow copy is NULL
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700858 pNewNode->pNext = NULL;
859 return pNewNode;
860}
Tobin Ehlis8733adc2015-02-23 16:09:58 -0700861// For given ds, update its mapping based on pUpdateChain linked-list
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700862static void dsUpdate(XGL_DESCRIPTOR_SET ds, GENERIC_HEADER* pUpdateChain)
863{
864 SET_NODE* pSet = getSetNode(ds);
Tobin Ehlisfb1ef942015-02-20 09:30:06 -0700865 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis83ebbef2015-02-10 15:35:23 -0700866 LAYOUT_NODE* pLayout = NULL;
867 XGL_DESCRIPTOR_SET_LAYOUT_CREATE_INFO* pLayoutCI;
868 // TODO : If pCIList is NULL, flag error
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700869 GENERIC_HEADER* pUpdates = pUpdateChain;
870 // Perform all updates
871 while (pUpdates) {
Tobin Ehlis83ebbef2015-02-10 15:35:23 -0700872 pLayout = pSet->pLayouts;
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700873 // For each update first find the layout section that it overlaps
Tobin Ehlis83ebbef2015-02-10 15:35:23 -0700874 while (pLayout && (pLayout->startIndex > getUpdateIndex(pUpdates))) {
875 pLayout = pLayout->pPriorSetLayout;
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700876 }
Tobin Ehlis83ebbef2015-02-10 15:35:23 -0700877 if (!pLayout) {
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700878 char str[1024];
Tobin Ehlis83ebbef2015-02-10 15:35:23 -0700879 sprintf(str, "Descriptor Set %p does not have index to match update index %u for update type %s!", ds, getUpdateIndex(pUpdates), string_XGL_STRUCTURE_TYPE(pUpdates->sType));
880 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, ds, 0, DRAWSTATE_INVALID_UPDATE_INDEX, "DS", str);
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700881 }
Tobin Ehlis83ebbef2015-02-10 15:35:23 -0700882 else {
Tobin Ehlisefa84162015-02-17 09:54:13 -0700883 // Next verify that update is correct size
884 if (!validateUpdateSize(pUpdates, pLayout->endIndex)) {
885 char str[48*1024]; // TODO : Keep count of layout CI structs and size this string dynamically based on that count
886 char* pDSstr = xgl_print_xgl_descriptor_set_layout_create_info(pLayoutCI, "{DS} ");
887 pLayoutCI = (XGL_DESCRIPTOR_SET_LAYOUT_CREATE_INFO*)pLayout->pCreateInfoList;
888 sprintf(str, "Descriptor update type of %s is out of bounds for matching layout w/ CI:\n%s!", string_XGL_STRUCTURE_TYPE(pUpdates->sType), pDSstr);
889 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, ds, 0, DRAWSTATE_DESCRIPTOR_UPDATE_OUT_OF_BOUNDS, "DS", str);
890 free(pDSstr);
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700891 }
Tobin Ehlis83ebbef2015-02-10 15:35:23 -0700892 else { // TODO : should we skip update on a type mismatch or force it?
Tobin Ehlisefa84162015-02-17 09:54:13 -0700893 // We have the right layout section, now verify that update is of the right type
894 if (!validateUpdateType(pUpdates, pLayout)) {
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700895 char str[1024];
Tobin Ehlisefa84162015-02-17 09:54:13 -0700896 sprintf(str, "Descriptor update type of %s does not match overlapping layout type!", string_XGL_STRUCTURE_TYPE(pUpdates->sType));
897 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, ds, 0, DRAWSTATE_DESCRIPTOR_TYPE_MISMATCH, "DS", str);
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700898 }
899 else {
Tobin Ehlis82871a82015-02-19 09:55:18 -0700900 // Save the update info
Tobin Ehlis83ebbef2015-02-10 15:35:23 -0700901 // TODO : Info message that update successful
Tobin Ehlis83ebbef2015-02-10 15:35:23 -0700902 // Create new update struct for this set's shadow copy
903 GENERIC_HEADER* pNewNode = shadowUpdateNode(pUpdates);
904 if (NULL == pNewNode) {
905 char str[1024];
906 sprintf(str, "Out of memory while attempting to allocate UPDATE struct in xglUpdateDescriptors()");
907 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, ds, 0, DRAWSTATE_OUT_OF_MEMORY, "DS", str);
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700908 }
909 else {
Tobin Ehlis82871a82015-02-19 09:55:18 -0700910 // Insert shadow node into LL of updates for this set
911 pNewNode->pNext = pSet->pUpdateStructs;
912 pSet->pUpdateStructs = pNewNode;
913 // Now update appropriate descriptor(s) to point to new Update node
914 for (uint32_t i = getUpdateIndex(pUpdates); i < getUpdateUpperBound(pUpdates); i++) {
915 pSet->ppDescriptors[i] = pNewNode;
Tobin Ehlis83ebbef2015-02-10 15:35:23 -0700916 }
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700917 }
918 }
919 }
920 }
921 pUpdates = (GENERIC_HEADER*)pUpdates->pNext;
922 }
Tobin Ehlisfb1ef942015-02-20 09:30:06 -0700923 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700924}
Tobin Ehlis8733adc2015-02-23 16:09:58 -0700925// Free the shadowed update node for this Set
Tobin Ehlisfb1ef942015-02-20 09:30:06 -0700926// NOTE : Calls to this function should be wrapped in mutex
Tobin Ehlis8733adc2015-02-23 16:09:58 -0700927static void freeShadowUpdateTree(SET_NODE* pSet)
Tobin Ehlis41415bb2015-01-22 10:45:21 -0700928{
Tobin Ehlis8733adc2015-02-23 16:09:58 -0700929 GENERIC_HEADER* pShadowUpdate = pSet->pUpdateStructs;
930 pSet->pUpdateStructs = NULL;
Tobin Ehlisefa84162015-02-17 09:54:13 -0700931 GENERIC_HEADER* pFreeUpdate = pShadowUpdate;
932 while(pShadowUpdate) {
933 pFreeUpdate = pShadowUpdate;
934 pShadowUpdate = (GENERIC_HEADER*)pShadowUpdate->pNext;
935 uint32_t index = 0;
936 XGL_UPDATE_SAMPLERS* pUS = NULL;
937 XGL_UPDATE_SAMPLER_TEXTURES* pUST = NULL;
938 XGL_UPDATE_IMAGES* pUI = NULL;
939 XGL_UPDATE_BUFFERS* pUB = NULL;
940 void** ppToFree = NULL;
941 switch (pFreeUpdate->sType)
942 {
943 case XGL_STRUCTURE_TYPE_UPDATE_SAMPLERS:
944 pUS = (XGL_UPDATE_SAMPLERS*)pFreeUpdate;
945 if (pUS->pSamplers) {
946 ppToFree = (void**)&pUS->pSamplers;
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700947#if ALLOC_DEBUG
Tobin Ehlisfb1ef942015-02-20 09:30:06 -0700948 printf("Free11 #%lu pSamplers addr(%p)\n", ++g_free_count, (void*)*ppToFree);
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700949#endif
Tobin Ehlisefa84162015-02-17 09:54:13 -0700950 free(*ppToFree);
951 }
952 break;
953 case XGL_STRUCTURE_TYPE_UPDATE_SAMPLER_TEXTURES:
954 pUST = (XGL_UPDATE_SAMPLER_TEXTURES*)pFreeUpdate;
955 for (index = 0; index < pUST->count; index++) {
956 if (pUST->pSamplerImageViews[index].pImageView) {
957 ppToFree = (void**)&pUST->pSamplerImageViews[index].pImageView;
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700958#if ALLOC_DEBUG
Tobin Ehlisfb1ef942015-02-20 09:30:06 -0700959 printf("Free14 #%lu pImageView addr(%p)\n", ++g_free_count, (void*)*ppToFree);
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700960#endif
Tobin Ehlisefa84162015-02-17 09:54:13 -0700961 free(*ppToFree);
962 }
963 }
964 ppToFree = (void**)&pUST->pSamplerImageViews;
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700965#if ALLOC_DEBUG
Tobin Ehlisfb1ef942015-02-20 09:30:06 -0700966 printf("Free13 #%lu pSamplerImageViews addr(%p)\n", ++g_free_count, (void*)*ppToFree);
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700967#endif
Tobin Ehlisefa84162015-02-17 09:54:13 -0700968 free(*ppToFree);
969 break;
970 case XGL_STRUCTURE_TYPE_UPDATE_IMAGES:
971 pUI = (XGL_UPDATE_IMAGES*)pFreeUpdate;
972 if (pUI->pImageViews) {
973 ppToFree = (void**)&pUI->pImageViews;
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700974#if ALLOC_DEBUG
Tobin Ehlisfb1ef942015-02-20 09:30:06 -0700975 printf("Free16 #%lu pImageViews addr(%p)\n", ++g_free_count, (void*)*ppToFree);
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700976#endif
Tobin Ehlisefa84162015-02-17 09:54:13 -0700977 free(*ppToFree);
978 }
979 break;
980 case XGL_STRUCTURE_TYPE_UPDATE_BUFFERS:
981 pUB = (XGL_UPDATE_BUFFERS*)pFreeUpdate;
982 if (pUB->pBufferViews) {
983 ppToFree = (void**)&pUB->pBufferViews;
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700984#if ALLOC_DEBUG
Tobin Ehlisfb1ef942015-02-20 09:30:06 -0700985 printf("Free18 #%lu pBufferViews addr(%p)\n", ++g_free_count, (void*)*ppToFree);
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700986#endif
Tobin Ehlisefa84162015-02-17 09:54:13 -0700987 free(*ppToFree);
988 }
989 break;
990 case XGL_STRUCTURE_TYPE_UPDATE_AS_COPY:
991 break;
992 default:
993 assert(0);
994 break;
995 }
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700996#if ALLOC_DEBUG
Tobin Ehlisfb1ef942015-02-20 09:30:06 -0700997 printf("Free10, Free12, Free15, Free17, Free19 #%lu pUpdateNode addr(%p)\n", ++g_free_count, (void*)pFreeUpdate);
Tobin Ehlis8614b8d2015-02-17 16:27:03 -0700998#endif
Tobin Ehlisefa84162015-02-17 09:54:13 -0700999 free(pFreeUpdate);
1000 }
1001}
1002// Free all DS Regions including their Sets & related sub-structs
Tobin Ehlisfb1ef942015-02-20 09:30:06 -07001003// NOTE : Calls to this function should be wrapped in mutex
Tobin Ehlisefa84162015-02-17 09:54:13 -07001004static void freeRegions()
1005{
1006 REGION_NODE* pRegion = g_pRegionHead;
1007 REGION_NODE* pFreeMe = pRegion;
1008 while (pRegion) {
1009 pFreeMe = pRegion;
1010 SET_NODE* pSet = pRegion->pSets;
1011 SET_NODE* pFreeSet = pSet;
1012 while (pSet) {
1013 pFreeSet = pSet;
1014 pSet = pSet->pNext;
1015 // Freeing layouts handled in freeLayouts() function
1016 // Free Update shadow struct tree
Tobin Ehlis8733adc2015-02-23 16:09:58 -07001017 freeShadowUpdateTree(pFreeSet);
Tobin Ehlis82871a82015-02-19 09:55:18 -07001018 if (pFreeSet->ppDescriptors) {
Tobin Ehlis8614b8d2015-02-17 16:27:03 -07001019#if ALLOC_DEBUG
Tobin Ehlis82871a82015-02-19 09:55:18 -07001020 printf("Free35 #%lu pSet->ppDescriptors addr(%p)\n", ++g_free_count, (void*)pFreeSet->ppDescriptors);
1021#endif
1022 free(pFreeSet->ppDescriptors);
1023 }
1024#if ALLOC_DEBUG
1025 printf("Free32 #%lu pSet addr(%p)\n", ++g_free_count, (void*)pFreeSet);
Tobin Ehlis8614b8d2015-02-17 16:27:03 -07001026#endif
Tobin Ehlisefa84162015-02-17 09:54:13 -07001027 free(pFreeSet);
1028 }
1029 pRegion = pRegion->pNext;
1030 if (pFreeMe->createInfo.pTypeCount) {
1031 void** ppToFree = (void**)&pFreeMe->createInfo.pTypeCount;
Tobin Ehlis8614b8d2015-02-17 16:27:03 -07001032#if ALLOC_DEBUG
1033 printf("Free31 #%lu pTypeCount addr(%p)\n", ++g_free_count, (void*)*ppToFree);
1034#endif
Tobin Ehlisefa84162015-02-17 09:54:13 -07001035 free(*ppToFree);
1036 }
Tobin Ehlis8614b8d2015-02-17 16:27:03 -07001037#if ALLOC_DEBUG
1038 printf("Free30 #%lu pRegion addr(%p)\n", ++g_free_count, (void*)pFreeMe);
1039#endif
Tobin Ehlisefa84162015-02-17 09:54:13 -07001040 free(pFreeMe);
1041 }
Tobin Ehlisfb1ef942015-02-20 09:30:06 -07001042 g_pRegionHead = NULL;
Tobin Ehlisefa84162015-02-17 09:54:13 -07001043}
1044// WARN : Once freeLayouts() called, any layout ptrs in Region/Set data structure will be invalid
Tobin Ehlisfb1ef942015-02-20 09:30:06 -07001045// NOTE : Calls to this function should be wrapped in mutex
Tobin Ehlisefa84162015-02-17 09:54:13 -07001046static void freeLayouts()
1047{
1048 LAYOUT_NODE* pLayout = g_pLayoutHead;
1049 LAYOUT_NODE* pFreeLayout = pLayout;
1050 while (pLayout) {
1051 pFreeLayout = pLayout;
1052 GENERIC_HEADER* pTrav = (GENERIC_HEADER*)pLayout->pCreateInfoList;
1053 while (pTrav) {
1054 void* pToFree = (void*)pTrav;
1055 pTrav = (GENERIC_HEADER*)pTrav->pNext;
Tobin Ehlis8614b8d2015-02-17 16:27:03 -07001056#if ALLOC_DEBUG
1057 printf("Free27 & Free28 #%lu pLayoutCITree addr(%p)\n", ++g_free_count, (void*)pToFree);
1058#endif
Tobin Ehlisefa84162015-02-17 09:54:13 -07001059 free(pToFree);
1060 }
Tobin Ehlis8614b8d2015-02-17 16:27:03 -07001061 if (pLayout->pTypes) {
1062#if ALLOC_DEBUG
1063 printf("Free29 #%lu pLayout->pTypes addr(%p)\n", ++g_free_count, (void*)pLayout->pTypes);
1064#endif
1065 free(pLayout->pTypes);
1066 }
Tobin Ehlisefa84162015-02-17 09:54:13 -07001067 pLayout = pLayout->pNext;
Tobin Ehlis8614b8d2015-02-17 16:27:03 -07001068#if ALLOC_DEBUG
1069 printf("Free26 #%lu pLayout addr(%p)\n", ++g_free_count, (void*)pFreeLayout);
1070#endif
Tobin Ehlisefa84162015-02-17 09:54:13 -07001071 free(pFreeLayout);
Tobin Ehlis41415bb2015-01-22 10:45:21 -07001072 }
Tobin Ehlisfb1ef942015-02-20 09:30:06 -07001073 g_pLayoutHead = NULL;
Tobin Ehlis41415bb2015-01-22 10:45:21 -07001074}
Tobin Ehlis83ebbef2015-02-10 15:35:23 -07001075// Currently clearing a set is removing all previous updates to that set
Tobin Ehlis41415bb2015-01-22 10:45:21 -07001076// TODO : Validate if this is correct clearing behavior
1077static void clearDescriptorSet(XGL_DESCRIPTOR_SET set)
1078{
1079 SET_NODE* pSet = getSetNode(set);
1080 if (!pSet) {
1081 // TODO : Return error
1082 }
1083 else {
Tobin Ehlisfb1ef942015-02-20 09:30:06 -07001084 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis8733adc2015-02-23 16:09:58 -07001085 freeShadowUpdateTree(pSet);
Tobin Ehlisfb1ef942015-02-20 09:30:06 -07001086 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis41415bb2015-01-22 10:45:21 -07001087 }
1088}
1089
1090static void clearDescriptorRegion(XGL_DESCRIPTOR_REGION region)
1091{
1092 REGION_NODE* pRegion = getRegionNode(region);
1093 if (!pRegion) {
1094 char str[1024];
1095 sprintf(str, "Unable to find region node for region %p specified in xglClearDescriptorRegion() call", (void*)region);
1096 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, region, 0, DRAWSTATE_INVALID_REGION, "DS", str);
1097 }
1098 else
1099 {
1100 // For every set off of this region, clear it
1101 SET_NODE* pSet = pRegion->pSets;
1102 while (pSet) {
1103 clearDescriptorSet(pSet->set);
1104 }
1105 }
1106}
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001107
Tobin Ehlis8cced212015-02-13 10:26:14 -07001108// Code here to manage the Cmd buffer LL
1109static GLOBAL_CB_NODE* getCBNode(XGL_CMD_BUFFER cb)
Tobin Ehlis56a61072014-11-21 08:58:46 -07001110{
Tobin Ehlis8cced212015-02-13 10:26:14 -07001111 loader_platform_thread_lock_mutex(&globalLock);
1112 GLOBAL_CB_NODE* pCB = g_pCmdBufferHead;
1113 while (pCB) {
1114 if (cb == pCB->cmdBuffer) {
1115 loader_platform_thread_unlock_mutex(&globalLock);
1116 return pCB;
1117 }
1118 pCB = pCB->pNextGlobalCBNode;
Tobin Ehlis56a61072014-11-21 08:58:46 -07001119 }
Tobin Ehlis8cced212015-02-13 10:26:14 -07001120 loader_platform_thread_unlock_mutex(&globalLock);
1121 return NULL;
1122}
Tobin Ehlisefa84162015-02-17 09:54:13 -07001123// Free all CB Nodes
Tobin Ehlisfb1ef942015-02-20 09:30:06 -07001124// NOTE : Calls to this function should be wrapped in mutex
Tobin Ehlisefa84162015-02-17 09:54:13 -07001125static void freeCmdBuffers()
1126{
1127 GLOBAL_CB_NODE* pCB = g_pCmdBufferHead;
1128 GLOBAL_CB_NODE* pFreeMe = pCB;
1129 while (pCB) {
1130 pFreeMe = pCB;
1131 CMD_NODE* pCmd = pCB->pCmds;
1132 CMD_NODE* pFreeCmd = pCmd;
1133 while (pCmd) {
1134 pFreeCmd = pCmd;
1135 pCmd = pCmd->pNext;
Tobin Ehlis8614b8d2015-02-17 16:27:03 -07001136#if ALLOC_DEBUG
1137 printf("Free20 #%lu pCmd addr(%p)\n", ++g_free_count, (void*)pFreeCmd);
1138#endif
Tobin Ehlisefa84162015-02-17 09:54:13 -07001139 free(pFreeCmd);
1140 }
1141 pCB = pCB->pNextGlobalCBNode;
Tobin Ehlis8614b8d2015-02-17 16:27:03 -07001142#if ALLOC_DEBUG
1143 printf("Free33 #%lu pCB addr(%p)\n", ++g_free_count, (void*)pFreeMe);
1144#endif
Tobin Ehlisefa84162015-02-17 09:54:13 -07001145 free(pFreeMe);
1146 }
Tobin Ehlisfb1ef942015-02-20 09:30:06 -07001147 g_pCmdBufferHead = NULL;
Tobin Ehlisefa84162015-02-17 09:54:13 -07001148}
Tobin Ehlisd092d232015-02-13 13:30:07 -07001149static void addCmd(GLOBAL_CB_NODE* pCB, const CMD_TYPE cmd)
1150{
1151 CMD_NODE* pCmd = (CMD_NODE*)malloc(sizeof(CMD_NODE));
Tobin Ehlis8614b8d2015-02-17 16:27:03 -07001152#if ALLOC_DEBUG
1153 printf("Alloc20 #%lu pCmd addr(%p)\n", ++g_alloc_count, (void*)pCmd);
1154#endif
Tobin Ehlisd092d232015-02-13 13:30:07 -07001155 if (pCmd) {
1156 // init cmd node and append to end of cmd LL
1157 memset(pCmd, 0, sizeof(CMD_NODE));
1158 pCB->numCmds++;
1159 pCmd->cmdNumber = pCB->numCmds;
1160 pCmd->type = cmd;
1161 if (!pCB->pCmds) {
1162 pCB->pCmds = pCmd;
1163 }
1164 else {
1165 assert(pCB->lastCmd);
1166 pCB->lastCmd->pNext = pCmd;
1167 }
1168 pCB->lastCmd = pCmd;
1169 }
1170 else {
1171 char str[1024];
1172 sprintf(str, "Out of memory while attempting to allocate new CMD_NODE for cmdBuffer %p", (void*)pCB->cmdBuffer);
1173 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, pCB->cmdBuffer, 0, DRAWSTATE_OUT_OF_MEMORY, "DS", str);
1174 }
1175}
1176static void resetCB(const XGL_CMD_BUFFER cb)
1177{
1178 GLOBAL_CB_NODE* pCB = getCBNode(cb);
1179 if (pCB) {
1180 CMD_NODE* pCur = pCB->pCmds;
1181 CMD_NODE* pFreeMe = pCur;
1182 while (pCur) {
1183 pFreeMe = pCur;
1184 pCur = pCur->pNext;
Tobin Ehlis8614b8d2015-02-17 16:27:03 -07001185#if ALLOC_DEBUG
Tobin Ehlisfb1ef942015-02-20 09:30:06 -07001186 printf("Free20 #%lu pCmd addr(%p)\n", ++g_free_count, (void*)pFreeMe);
Tobin Ehlis8614b8d2015-02-17 16:27:03 -07001187#endif
Tobin Ehlisd092d232015-02-13 13:30:07 -07001188 free(pFreeMe);
1189 }
1190 // Reset CB state
1191 GLOBAL_CB_NODE* pSaveNext = pCB->pNextGlobalCBNode;
1192 XGL_FLAGS saveFlags = pCB->flags;
1193 XGL_QUEUE_TYPE saveQT = pCB->queueType;
1194 memset(pCB, 0, sizeof(GLOBAL_CB_NODE));
1195 pCB->cmdBuffer = cb;
1196 pCB->flags = saveFlags;
1197 pCB->queueType = saveQT;
1198 pCB->pNextGlobalCBNode = pSaveNext;
1199 pCB->lastVtxBinding = MAX_BINDING;
1200 }
1201}
1202// Set the last bound dynamic state of given type
1203// TODO : Need to track this per cmdBuffer and correlate cmdBuffer for Draw w/ last bound for that cmdBuffer?
1204static void setLastBoundDynamicState(const XGL_CMD_BUFFER cmdBuffer, const XGL_DYNAMIC_STATE_OBJECT state, const XGL_STATE_BIND_POINT sType)
1205{
1206 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
1207 if (pCB) {
Tobin Ehlisfb1ef942015-02-20 09:30:06 -07001208 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis45662712015-02-23 09:06:28 -07001209 g_lastCmdBuffer[getTIDIndex()] = cmdBuffer;
Tobin Ehlisd092d232015-02-13 13:30:07 -07001210 addCmd(pCB, CMD_BINDDYNAMICSTATEOBJECT);
Tobin Ehlisd092d232015-02-13 13:30:07 -07001211 DYNAMIC_STATE_NODE* pTrav = g_pDynamicStateHead[sType];
1212 while (pTrav && (state != pTrav->stateObj)) {
1213 pTrav = pTrav->pNext;
1214 }
1215 if (!pTrav) {
1216 char str[1024];
1217 sprintf(str, "Unable to find dynamic state object %p, was it ever created?", (void*)state);
1218 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, state, 0, DRAWSTATE_INVALID_DYNAMIC_STATE_OBJECT, "DS", str);
1219 }
1220 pCB->lastBoundDynamicState[sType] = pTrav;
1221 loader_platform_thread_unlock_mutex(&globalLock);
1222 }
1223 else {
1224 char str[1024];
1225 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
1226 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
1227 }
1228}
Tobin Ehlis8cced212015-02-13 10:26:14 -07001229// Print the last bound Gfx Pipeline
1230static void printPipeline(const XGL_CMD_BUFFER cb)
1231{
1232 GLOBAL_CB_NODE* pCB = getCBNode(cb);
1233 if (pCB) {
1234 PIPELINE_NODE *pPipeTrav = getPipeline(pCB->lastBoundPipeline);
1235 if (!pPipeTrav) {
1236 // nothing to print
1237 }
1238 else {
1239 char* pipeStr = xgl_print_xgl_graphics_pipeline_create_info(pPipeTrav->pCreateTree, "{DS}");
1240 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", pipeStr);
Tobin Ehlisefa84162015-02-17 09:54:13 -07001241 free(pipeStr);
Tobin Ehlis8cced212015-02-13 10:26:14 -07001242 }
Tobin Ehlis56a61072014-11-21 08:58:46 -07001243 }
1244}
Tobin Ehlisa701ef02014-11-27 15:43:39 -07001245// Dump subgraph w/ DS info
Tobin Ehlis8cced212015-02-13 10:26:14 -07001246static void dsDumpDot(const XGL_CMD_BUFFER cb, FILE* pOutFile)
Tobin Ehlisa701ef02014-11-27 15:43:39 -07001247{
Tobin Ehlis8cced212015-02-13 10:26:14 -07001248 GLOBAL_CB_NODE* pCB = getCBNode(cb);
1249 if (pCB && pCB->lastBoundDescriptorSet) {
1250 SET_NODE* pSet = getSetNode(pCB->lastBoundDescriptorSet);
1251 REGION_NODE* pRegion = getRegionNode(pSet->region);
Tobin Ehlis8614b8d2015-02-17 16:27:03 -07001252 char tmp_str[4*1024];
Tobin Ehlis04f80bb2015-02-11 13:13:18 -07001253 fprintf(pOutFile, "subgraph cluster_DescriptorRegion\n{\nlabel=\"Descriptor Region\"\n");
1254 sprintf(tmp_str, "Region (%p)", pRegion->region);
Tobin Ehlisefa84162015-02-17 09:54:13 -07001255 char* pGVstr = xgl_gv_print_xgl_descriptor_region_create_info(&pRegion->createInfo, tmp_str);
1256 fprintf(pOutFile, "%s", pGVstr);
1257 free(pGVstr);
Tobin Ehlis8cced212015-02-13 10:26:14 -07001258 fprintf(pOutFile, "subgraph cluster_DescriptorSet\n{\nlabel=\"Descriptor Set (%p)\"\n", pSet->set);
1259 sprintf(tmp_str, "Descriptor Set (%p)", pSet->set);
1260 LAYOUT_NODE* pLayout = pSet->pLayouts;
1261 uint32_t layout_index = 0;
1262 while (pLayout) {
1263 ++layout_index;
1264 sprintf(tmp_str, "LAYOUT%u", layout_index);
Tobin Ehlisefa84162015-02-17 09:54:13 -07001265 pGVstr = xgl_gv_print_xgl_descriptor_set_layout_create_info(pLayout->pCreateInfoList, tmp_str);
1266 fprintf(pOutFile, "%s", pGVstr);
1267 free(pGVstr);
Tobin Ehlis8cced212015-02-13 10:26:14 -07001268 pLayout = pLayout->pNext;
1269 if (pLayout) {
1270 fprintf(pOutFile, "\"%s\" -> \"LAYOUT%u\" [];\n", tmp_str, layout_index+1);
Tobin Ehlisa701ef02014-11-27 15:43:39 -07001271 }
Tobin Ehlisa701ef02014-11-27 15:43:39 -07001272 }
Tobin Ehlis8cced212015-02-13 10:26:14 -07001273 if (pSet->pUpdateStructs) {
Tobin Ehlisefa84162015-02-17 09:54:13 -07001274 pGVstr = dynamic_gv_display(pSet->pUpdateStructs, "Descriptor Updates");
1275 fprintf(pOutFile, "%s", pGVstr);
1276 free(pGVstr);
Tobin Ehlis8cced212015-02-13 10:26:14 -07001277 }
1278 fprintf(pOutFile, "}\n");
Tobin Ehlisa701ef02014-11-27 15:43:39 -07001279 fprintf(pOutFile, "}\n");
Tobin Ehlis04f80bb2015-02-11 13:13:18 -07001280 pRegion = pRegion->pNext;
Tobin Ehlisa701ef02014-11-27 15:43:39 -07001281 }
1282}
Tobin Ehlis04f80bb2015-02-11 13:13:18 -07001283
Tobin Ehlisa701ef02014-11-27 15:43:39 -07001284// Dump a GraphViz dot file showing the pipeline
Tobin Ehlis8cced212015-02-13 10:26:14 -07001285static void dumpDotFile(const XGL_CMD_BUFFER cb, char *outFileName)
Tobin Ehlisa701ef02014-11-27 15:43:39 -07001286{
Tobin Ehlis8cced212015-02-13 10:26:14 -07001287 GLOBAL_CB_NODE* pCB = getCBNode(cb);
1288 if (pCB) {
1289 PIPELINE_NODE *pPipeTrav = getPipeline(pCB->lastBoundPipeline);
1290 if (pPipeTrav) {
1291 FILE* pOutFile;
1292 pOutFile = fopen(outFileName, "w");
1293 fprintf(pOutFile, "digraph g {\ngraph [\nrankdir = \"TB\"\n];\nnode [\nfontsize = \"16\"\nshape = \"plaintext\"\n];\nedge [\n];\n");
1294 fprintf(pOutFile, "subgraph cluster_dynamicState\n{\nlabel=\"Dynamic State\"\n");
Tobin Ehlisefa84162015-02-17 09:54:13 -07001295 char* pGVstr = NULL;
Tobin Ehlis8cced212015-02-13 10:26:14 -07001296 for (uint32_t i = 0; i < XGL_NUM_STATE_BIND_POINT; i++) {
Tobin Ehlis82871a82015-02-19 09:55:18 -07001297 if (pCB->lastBoundDynamicState[i] && pCB->lastBoundDynamicState[i]->pCreateInfo) {
Tobin Ehlisefa84162015-02-17 09:54:13 -07001298 pGVstr = dynamic_gv_display(pCB->lastBoundDynamicState[i]->pCreateInfo, string_XGL_STATE_BIND_POINT(i));
1299 fprintf(pOutFile, "%s", pGVstr);
1300 free(pGVstr);
Tobin Ehlis8cced212015-02-13 10:26:14 -07001301 }
Tobin Ehlisa701ef02014-11-27 15:43:39 -07001302 }
Tobin Ehlis8cced212015-02-13 10:26:14 -07001303 fprintf(pOutFile, "}\n"); // close dynamicState subgraph
1304 fprintf(pOutFile, "subgraph cluster_PipelineStateObject\n{\nlabel=\"Pipeline State Object\"\n");
Tobin Ehlisefa84162015-02-17 09:54:13 -07001305 pGVstr = xgl_gv_print_xgl_graphics_pipeline_create_info(pPipeTrav->pCreateTree, "PSO HEAD");
1306 fprintf(pOutFile, "%s", pGVstr);
1307 free(pGVstr);
Tobin Ehlis8cced212015-02-13 10:26:14 -07001308 fprintf(pOutFile, "}\n");
1309 dsDumpDot(cb, pOutFile);
1310 fprintf(pOutFile, "}\n"); // close main graph "g"
1311 fclose(pOutFile);
Tobin Ehlisa701ef02014-11-27 15:43:39 -07001312 }
Tobin Ehlisa701ef02014-11-27 15:43:39 -07001313 }
1314}
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001315// Synch up currently bound pipeline settings with DS mappings
Tobin Ehlis83ebbef2015-02-10 15:35:23 -07001316// TODO : Update name. We don't really have to "synch" the descriptors anymore and "mapping" is outdated as well.
Tobin Ehlis8cced212015-02-13 10:26:14 -07001317static void synchDSMapping(const XGL_CMD_BUFFER cb)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001318{
Tobin Ehlis8cced212015-02-13 10:26:14 -07001319 GLOBAL_CB_NODE* pCB = getCBNode(cb);
1320 if (pCB && pCB->lastBoundPipeline) {
1321 // First verify that we have a Node for bound pipeline
1322 PIPELINE_NODE *pPipeTrav = getPipeline(pCB->lastBoundPipeline);
1323 char str[1024];
1324 if (!pPipeTrav) {
1325 sprintf(str, "Can't find last bound Pipeline %p!", (void*)pCB->lastBoundPipeline);
1326 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NO_PIPELINE_BOUND, "DS", str);
1327 }
1328 else {
1329 // Verify Vtx binding
1330 if (MAX_BINDING != pCB->lastVtxBinding) {
1331 if (pCB->lastVtxBinding >= pPipeTrav->vtxBindingCount) {
Tobin Ehlis8614b8d2015-02-17 16:27:03 -07001332 if (0 == pPipeTrav->vtxBindingCount) {
1333 sprintf(str, "Vtx Buffer Index %u was bound, but no vtx buffers are attached to PSO.", pCB->lastVtxBinding);
1334 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_VTX_INDEX_OUT_OF_BOUNDS, "DS", str);
1335 }
1336 else {
1337 sprintf(str, "Vtx binding Index of %u exceeds PSO pVertexBindingDescriptions max array index of %u.", pCB->lastVtxBinding, (pPipeTrav->vtxBindingCount - 1));
1338 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_VTX_INDEX_OUT_OF_BOUNDS, "DS", str);
1339 }
Tobin Ehlis8cced212015-02-13 10:26:14 -07001340 }
1341 else {
1342 char *tmpStr = xgl_print_xgl_vertex_input_binding_description(&pPipeTrav->pVertexBindingDescriptions[pCB->lastVtxBinding], "{DS}INFO : ");
1343 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", tmpStr);
1344 free(tmpStr);
1345 }
Tobin Ehlis1affd3c2014-11-25 10:24:15 -07001346 }
1347 }
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001348 }
1349}
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001350// Print details of DS config to stdout
Tobin Ehlis8cced212015-02-13 10:26:14 -07001351static void printDSConfig(const XGL_CMD_BUFFER cb)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001352{
Tobin Ehlise79df942014-11-18 16:38:08 -07001353 char tmp_str[1024];
1354 char ds_config_str[1024*256] = {0}; // TODO : Currently making this buffer HUGE w/o overrun protection. Need to be smarter, start smaller, and grow as needed.
Tobin Ehlis8cced212015-02-13 10:26:14 -07001355 GLOBAL_CB_NODE* pCB = getCBNode(cb);
1356 if (pCB) {
1357 SET_NODE* pSet = getSetNode(pCB->lastBoundDescriptorSet);
1358 REGION_NODE* pRegion = getRegionNode(pSet->region);
Tobin Ehlis83ebbef2015-02-10 15:35:23 -07001359 // Print out region details
1360 sprintf(tmp_str, "Details for region %p.", (void*)pRegion->region);
1361 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", tmp_str);
Tobin Ehlisefa84162015-02-17 09:54:13 -07001362 char* pRegionStr = xgl_print_xgl_descriptor_region_create_info(&pRegion->createInfo, " ");
1363 sprintf(ds_config_str, "%s", pRegionStr);
Tobin Ehlis83ebbef2015-02-10 15:35:23 -07001364 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", ds_config_str);
Tobin Ehlisefa84162015-02-17 09:54:13 -07001365 free(pRegionStr);
Tobin Ehlis8cced212015-02-13 10:26:14 -07001366 // Print out set details
1367 char prefix[10];
1368 uint32_t index = 0;
1369 sprintf(tmp_str, "Details for descriptor set %p.", (void*)pSet->set);
1370 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", tmp_str);
1371 LAYOUT_NODE* pLayout = pSet->pLayouts;
1372 while (pLayout) {
1373 // Print layout details
1374 sprintf(tmp_str, "Layout #%u, (object %p) for DS %p.", index+1, (void*)pLayout->layout, (void*)pSet->set);
Tobin Ehlis83ebbef2015-02-10 15:35:23 -07001375 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", tmp_str);
Tobin Ehlis8cced212015-02-13 10:26:14 -07001376 sprintf(prefix, " [L%u] ", index);
Tobin Ehlisefa84162015-02-17 09:54:13 -07001377 char* pDSLstr = xgl_print_xgl_descriptor_set_layout_create_info(&pLayout->pCreateInfoList[0], prefix);
1378 sprintf(ds_config_str, "%s", pDSLstr);
Tobin Ehlis8cced212015-02-13 10:26:14 -07001379 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", ds_config_str);
Tobin Ehlisefa84162015-02-17 09:54:13 -07001380 free(pDSLstr);
Tobin Ehlis8cced212015-02-13 10:26:14 -07001381 pLayout = pLayout->pPriorSetLayout;
1382 index++;
1383 }
1384 GENERIC_HEADER* pUpdate = pSet->pUpdateStructs;
1385 if (pUpdate) {
Tobin Ehlis83ebbef2015-02-10 15:35:23 -07001386 sprintf(tmp_str, "Update Chain [UC] for descriptor set %p:", (void*)pSet->set);
1387 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", tmp_str);
1388 sprintf(prefix, " [UC] ");
1389 sprintf(ds_config_str, "%s", dynamic_display(pUpdate, prefix));
1390 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", ds_config_str);
1391 // TODO : If there is a "view" associated with this update, print CI for that view
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001392 }
Tobin Ehlis8cced212015-02-13 10:26:14 -07001393 else {
1394 sprintf(tmp_str, "No Update Chain for descriptor set %p (xglUpdateDescriptors has not been called)", (void*)pSet->set);
1395 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", tmp_str);
1396 }
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001397 }
1398}
1399
Tobin Ehlisd092d232015-02-13 13:30:07 -07001400static void printCB(const XGL_CMD_BUFFER cb)
1401{
1402 GLOBAL_CB_NODE* pCB = getCBNode(cb);
1403 if (pCB) {
1404 char str[1024];
1405 CMD_NODE* pCmd = pCB->pCmds;
1406 sprintf(str, "Cmds in CB %p", (void*)cb);
1407 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", str);
1408 while (pCmd) {
1409 sprintf(str, " CMD#%lu: %s", pCmd->cmdNumber, cmdTypeToString(pCmd->type));
1410 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, cb, 0, DRAWSTATE_NONE, "DS", str);
1411 pCmd = pCmd->pNext;
1412 }
1413 }
1414 else {
1415 // Nothing to print
1416 }
1417}
1418
Tobin Ehlis8cced212015-02-13 10:26:14 -07001419static void synchAndDumpDot(const XGL_CMD_BUFFER cb)
Jeremy Hayes668ca052015-01-29 13:03:36 -07001420{
Tobin Ehlis8cced212015-02-13 10:26:14 -07001421 synchDSMapping(cb);
1422 dumpDotFile(cb, "pipeline_dump.dot");
Jeremy Hayes668ca052015-01-29 13:03:36 -07001423}
1424
Tobin Ehlis8cced212015-02-13 10:26:14 -07001425static void synchAndPrintDSConfig(const XGL_CMD_BUFFER cb)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001426{
Tobin Ehlis8cced212015-02-13 10:26:14 -07001427 synchDSMapping(cb);
1428 printDSConfig(cb);
1429 printPipeline(cb);
1430 printDynamicState(cb);
Tobin Ehlis224dd812015-02-19 15:26:49 -07001431 static int autoDumpOnce = 0;
Tobin Ehlisa701ef02014-11-27 15:43:39 -07001432 if (autoDumpOnce) {
1433 autoDumpOnce = 0;
Tobin Ehlis8cced212015-02-13 10:26:14 -07001434 dumpDotFile(cb, "pipeline_dump.dot");
Tobin Ehlis266473d2014-12-16 17:34:50 -07001435 // Convert dot to png if dot available
Ian Elliott81ac44c2015-01-13 17:52:38 -07001436#if defined(_WIN32)
1437// FIXME: NEED WINDOWS EQUIVALENT
1438#else // WIN32
Tobin Ehlis266473d2014-12-16 17:34:50 -07001439 if(access( "/usr/bin/dot", X_OK) != -1) {
1440 system("/usr/bin/dot pipeline_dump.dot -Tpng -o pipeline_dump.png");
1441 }
Ian Elliott81ac44c2015-01-13 17:52:38 -07001442#endif // WIN32
Tobin Ehlisa701ef02014-11-27 15:43:39 -07001443 }
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001444}
1445
Tobin Ehlisbf0146e2015-02-11 14:24:02 -07001446static void initDrawState(void)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001447{
Jon Ashburn2e9b5612014-12-22 13:38:27 -07001448 const char *strOpt;
Tobin Ehlis5b7acaa2015-01-08 14:26:53 -07001449 // initialize DrawState options
Jon Ashburn2e9b5612014-12-22 13:38:27 -07001450 strOpt = getLayerOption("DrawStateReportLevel");
1451 if (strOpt != NULL)
1452 g_reportingLevel = atoi(strOpt);
Tobin Ehlis5b7acaa2015-01-08 14:26:53 -07001453
Jon Ashburn2e9b5612014-12-22 13:38:27 -07001454 strOpt = getLayerOption("DrawStateDebugAction");
1455 if (strOpt != NULL)
Tobin Ehlis5b7acaa2015-01-08 14:26:53 -07001456 g_debugAction = atoi(strOpt);
1457
Jon Ashburn2e9b5612014-12-22 13:38:27 -07001458 if (g_debugAction & XGL_DBG_LAYER_ACTION_LOG_MSG)
1459 {
1460 strOpt = getLayerOption("DrawStateLogFilename");
1461 if (strOpt)
1462 {
1463 g_logFile = fopen(strOpt, "w");
Jon Ashburn2e9b5612014-12-22 13:38:27 -07001464 }
1465 if (g_logFile == NULL)
1466 g_logFile = stdout;
1467 }
Jon Ashburn2e9b5612014-12-22 13:38:27 -07001468 // initialize Layer dispatch table
1469 // TODO handle multiple GPUs
Mark Lobodzinski953a1692015-01-09 15:12:03 -06001470 xglGetProcAddrType fpNextGPA;
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001471 fpNextGPA = pCurObj->pGPA;
1472 assert(fpNextGPA);
1473
Chia-I Wu0f65b1e2015-01-04 23:11:43 +08001474 layer_initialize_dispatch_table(&nextTable, fpNextGPA, (XGL_PHYSICAL_GPU) pCurObj->nextObject);
1475
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001476 xglGetProcAddrType fpGetProcAddr = fpNextGPA((XGL_PHYSICAL_GPU) pCurObj->nextObject, (char *) "xglGetProcAddr");
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001477 nextTable.GetProcAddr = fpGetProcAddr;
Ian Elliott81ac44c2015-01-13 17:52:38 -07001478
1479 if (!globalLockInitialized)
1480 {
1481 // TODO/TBD: Need to delete this mutex sometime. How??? One
1482 // suggestion is to call this during xglCreateInstance(), and then we
1483 // can clean it up during xglDestroyInstance(). However, that requires
1484 // that the layer have per-instance locks. We need to come back and
1485 // address this soon.
1486 loader_platform_thread_create_mutex(&globalLock);
1487 globalLockInitialized = 1;
1488 }
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001489}
1490
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001491XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateInstance(const XGL_APPLICATION_INFO* pAppInfo, const XGL_ALLOC_CALLBACKS* pAllocCb, XGL_INSTANCE* pInstance)
1492{
1493 XGL_RESULT result = nextTable.CreateInstance(pAppInfo, pAllocCb, pInstance);
1494 return result;
1495}
1496
1497XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglDestroyInstance(XGL_INSTANCE instance)
1498{
1499 XGL_RESULT result = nextTable.DestroyInstance(instance);
1500 return result;
1501}
1502
1503XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglEnumerateGpus(XGL_INSTANCE instance, uint32_t maxGpus, uint32_t* pGpuCount, XGL_PHYSICAL_GPU* pGpus)
1504{
1505 XGL_RESULT result = nextTable.EnumerateGpus(instance, maxGpus, pGpuCount, pGpus);
1506 return result;
1507}
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001508
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001509XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglGetGpuInfo(XGL_PHYSICAL_GPU gpu, XGL_PHYSICAL_GPU_INFO_TYPE infoType, size_t* pDataSize, void* pData)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001510{
1511 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001512 pCurObj = gpuw;
Ian Elliott81ac44c2015-01-13 17:52:38 -07001513 loader_platform_thread_once(&g_initOnce, initDrawState);
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001514 XGL_RESULT result = nextTable.GetGpuInfo((XGL_PHYSICAL_GPU)gpuw->nextObject, infoType, pDataSize, pData);
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001515 return result;
1516}
1517
1518XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateDevice(XGL_PHYSICAL_GPU gpu, const XGL_DEVICE_CREATE_INFO* pCreateInfo, XGL_DEVICE* pDevice)
1519{
1520 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001521 pCurObj = gpuw;
Ian Elliott81ac44c2015-01-13 17:52:38 -07001522 loader_platform_thread_once(&g_initOnce, initDrawState);
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001523 XGL_RESULT result = nextTable.CreateDevice((XGL_PHYSICAL_GPU)gpuw->nextObject, pCreateInfo, pDevice);
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001524 return result;
1525}
1526
1527XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglDestroyDevice(XGL_DEVICE device)
1528{
Tobin Ehlisefa84162015-02-17 09:54:13 -07001529 // Free all the memory
1530 loader_platform_thread_lock_mutex(&globalLock);
1531 freePipelines();
1532 freeSamplers();
1533 freeImages();
1534 freeBuffers();
1535 freeCmdBuffers();
1536 freeDynamicState();
1537 freeRegions();
1538 freeLayouts();
1539 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001540 XGL_RESULT result = nextTable.DestroyDevice(device);
1541 return result;
1542}
1543
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001544XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglGetExtensionSupport(XGL_PHYSICAL_GPU gpu, const char* pExtName)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001545{
1546 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001547 pCurObj = gpuw;
Ian Elliott81ac44c2015-01-13 17:52:38 -07001548 loader_platform_thread_once(&g_initOnce, initDrawState);
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001549 XGL_RESULT result = nextTable.GetExtensionSupport((XGL_PHYSICAL_GPU)gpuw->nextObject, pExtName);
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001550 return result;
1551}
1552
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001553XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglEnumerateLayers(XGL_PHYSICAL_GPU gpu, size_t maxLayerCount, size_t maxStringSize, size_t* pOutLayerCount, char* const* pOutLayers, void* pReserved)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001554{
Jon Ashburn451c16f2014-11-25 11:08:42 -07001555 if (gpu != NULL)
1556 {
1557 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
1558 pCurObj = gpuw;
Ian Elliott81ac44c2015-01-13 17:52:38 -07001559 loader_platform_thread_once(&g_initOnce, initDrawState);
Mark Lobodzinski953a1692015-01-09 15:12:03 -06001560 XGL_RESULT result = nextTable.EnumerateLayers((XGL_PHYSICAL_GPU)gpuw->nextObject, maxLayerCount, maxStringSize, pOutLayerCount, pOutLayers, pReserved);
Jon Ashburn451c16f2014-11-25 11:08:42 -07001561 return result;
1562 } else
1563 {
1564 if (pOutLayerCount == NULL || pOutLayers == NULL || pOutLayers[0] == NULL)
1565 return XGL_ERROR_INVALID_POINTER;
1566 // This layer compatible with all GPUs
1567 *pOutLayerCount = 1;
Chia-I Wua837c522014-12-16 10:47:33 +08001568 strncpy((char *) pOutLayers[0], "DrawState", maxStringSize);
Jon Ashburn451c16f2014-11-25 11:08:42 -07001569 return XGL_SUCCESS;
1570 }
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001571}
1572
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001573XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglGetDeviceQueue(XGL_DEVICE device, XGL_QUEUE_TYPE queueType, uint32_t queueIndex, XGL_QUEUE* pQueue)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001574{
1575 XGL_RESULT result = nextTable.GetDeviceQueue(device, queueType, queueIndex, pQueue);
1576 return result;
1577}
1578
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001579XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglQueueSubmit(XGL_QUEUE queue, uint32_t cmdBufferCount, const XGL_CMD_BUFFER* pCmdBuffers, uint32_t memRefCount, const XGL_MEMORY_REF* pMemRefs, XGL_FENCE fence)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001580{
Tobin Ehlisd092d232015-02-13 13:30:07 -07001581 for (uint32_t i=0; i < cmdBufferCount; i++) {
1582 // Validate that cmd buffers have been updated
1583 }
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001584 XGL_RESULT result = nextTable.QueueSubmit(queue, cmdBufferCount, pCmdBuffers, memRefCount, pMemRefs, fence);
1585 return result;
1586}
1587
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001588XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglQueueSetGlobalMemReferences(XGL_QUEUE queue, uint32_t memRefCount, const XGL_MEMORY_REF* pMemRefs)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001589{
1590 XGL_RESULT result = nextTable.QueueSetGlobalMemReferences(queue, memRefCount, pMemRefs);
1591 return result;
1592}
1593
1594XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglQueueWaitIdle(XGL_QUEUE queue)
1595{
1596 XGL_RESULT result = nextTable.QueueWaitIdle(queue);
1597 return result;
1598}
1599
1600XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglDeviceWaitIdle(XGL_DEVICE device)
1601{
1602 XGL_RESULT result = nextTable.DeviceWaitIdle(device);
1603 return result;
1604}
1605
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001606XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglAllocMemory(XGL_DEVICE device, const XGL_MEMORY_ALLOC_INFO* pAllocInfo, XGL_GPU_MEMORY* pMem)
1607{
1608 XGL_RESULT result = nextTable.AllocMemory(device, pAllocInfo, pMem);
1609 return result;
1610}
1611
1612XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglFreeMemory(XGL_GPU_MEMORY mem)
1613{
1614 XGL_RESULT result = nextTable.FreeMemory(mem);
1615 return result;
1616}
1617
1618XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglSetMemoryPriority(XGL_GPU_MEMORY mem, XGL_MEMORY_PRIORITY priority)
1619{
1620 XGL_RESULT result = nextTable.SetMemoryPriority(mem, priority);
1621 return result;
1622}
1623
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001624XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglMapMemory(XGL_GPU_MEMORY mem, XGL_FLAGS flags, void** ppData)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001625{
1626 XGL_RESULT result = nextTable.MapMemory(mem, flags, ppData);
1627 return result;
1628}
1629
1630XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglUnmapMemory(XGL_GPU_MEMORY mem)
1631{
1632 XGL_RESULT result = nextTable.UnmapMemory(mem);
1633 return result;
1634}
1635
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001636XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglPinSystemMemory(XGL_DEVICE device, const void* pSysMem, size_t memSize, XGL_GPU_MEMORY* pMem)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001637{
1638 XGL_RESULT result = nextTable.PinSystemMemory(device, pSysMem, memSize, pMem);
1639 return result;
1640}
1641
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001642XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglGetMultiGpuCompatibility(XGL_PHYSICAL_GPU gpu0, XGL_PHYSICAL_GPU gpu1, XGL_GPU_COMPATIBILITY_INFO* pInfo)
1643{
1644 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu0;
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001645 pCurObj = gpuw;
Ian Elliott81ac44c2015-01-13 17:52:38 -07001646 loader_platform_thread_once(&g_initOnce, initDrawState);
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001647 XGL_RESULT result = nextTable.GetMultiGpuCompatibility((XGL_PHYSICAL_GPU)gpuw->nextObject, gpu1, pInfo);
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001648 return result;
1649}
1650
1651XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglOpenSharedMemory(XGL_DEVICE device, const XGL_MEMORY_OPEN_INFO* pOpenInfo, XGL_GPU_MEMORY* pMem)
1652{
1653 XGL_RESULT result = nextTable.OpenSharedMemory(device, pOpenInfo, pMem);
1654 return result;
1655}
1656
1657XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglOpenSharedQueueSemaphore(XGL_DEVICE device, const XGL_QUEUE_SEMAPHORE_OPEN_INFO* pOpenInfo, XGL_QUEUE_SEMAPHORE* pSemaphore)
1658{
1659 XGL_RESULT result = nextTable.OpenSharedQueueSemaphore(device, pOpenInfo, pSemaphore);
1660 return result;
1661}
1662
1663XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglOpenPeerMemory(XGL_DEVICE device, const XGL_PEER_MEMORY_OPEN_INFO* pOpenInfo, XGL_GPU_MEMORY* pMem)
1664{
1665 XGL_RESULT result = nextTable.OpenPeerMemory(device, pOpenInfo, pMem);
1666 return result;
1667}
1668
1669XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglOpenPeerImage(XGL_DEVICE device, const XGL_PEER_IMAGE_OPEN_INFO* pOpenInfo, XGL_IMAGE* pImage, XGL_GPU_MEMORY* pMem)
1670{
1671 XGL_RESULT result = nextTable.OpenPeerImage(device, pOpenInfo, pImage, pMem);
1672 return result;
1673}
1674
1675XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglDestroyObject(XGL_OBJECT object)
1676{
Tobin Ehlis83ebbef2015-02-10 15:35:23 -07001677 // TODO : When wrapped objects (such as dynamic state) are destroyed, need to clean up memory
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001678 XGL_RESULT result = nextTable.DestroyObject(object);
1679 return result;
1680}
1681
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001682XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglGetObjectInfo(XGL_BASE_OBJECT object, XGL_OBJECT_INFO_TYPE infoType, size_t* pDataSize, void* pData)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001683{
1684 XGL_RESULT result = nextTable.GetObjectInfo(object, infoType, pDataSize, pData);
1685 return result;
1686}
1687
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001688XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglBindObjectMemory(XGL_OBJECT object, uint32_t allocationIdx, XGL_GPU_MEMORY mem, XGL_GPU_SIZE offset)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001689{
Jon Ashburned62b412015-01-15 10:39:19 -07001690 XGL_RESULT result = nextTable.BindObjectMemory(object, allocationIdx, mem, offset);
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001691 return result;
1692}
1693
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001694XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglBindObjectMemoryRange(XGL_OBJECT object, uint32_t allocationIdx, XGL_GPU_SIZE rangeOffset, XGL_GPU_SIZE rangeSize, XGL_GPU_MEMORY mem, XGL_GPU_SIZE memOffset)
1695{
1696 XGL_RESULT result = nextTable.BindObjectMemoryRange(object, allocationIdx, rangeOffset, rangeSize, mem, memOffset);
1697 return result;
1698}
1699
1700XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglBindImageMemoryRange(XGL_IMAGE image, uint32_t allocationIdx, const XGL_IMAGE_MEMORY_BIND_INFO* bindInfo, XGL_GPU_MEMORY mem, XGL_GPU_SIZE memOffset)
1701{
1702 XGL_RESULT result = nextTable.BindImageMemoryRange(image, allocationIdx, bindInfo, mem, memOffset);
1703 return result;
1704}
1705
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001706XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateFence(XGL_DEVICE device, const XGL_FENCE_CREATE_INFO* pCreateInfo, XGL_FENCE* pFence)
1707{
1708 XGL_RESULT result = nextTable.CreateFence(device, pCreateInfo, pFence);
1709 return result;
1710}
1711
1712XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglGetFenceStatus(XGL_FENCE fence)
1713{
1714 XGL_RESULT result = nextTable.GetFenceStatus(fence);
1715 return result;
1716}
1717
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001718XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglWaitForFences(XGL_DEVICE device, uint32_t fenceCount, const XGL_FENCE* pFences, bool32_t waitAll, uint64_t timeout)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001719{
1720 XGL_RESULT result = nextTable.WaitForFences(device, fenceCount, pFences, waitAll, timeout);
1721 return result;
1722}
1723
1724XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateQueueSemaphore(XGL_DEVICE device, const XGL_QUEUE_SEMAPHORE_CREATE_INFO* pCreateInfo, XGL_QUEUE_SEMAPHORE* pSemaphore)
1725{
1726 XGL_RESULT result = nextTable.CreateQueueSemaphore(device, pCreateInfo, pSemaphore);
1727 return result;
1728}
1729
1730XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglSignalQueueSemaphore(XGL_QUEUE queue, XGL_QUEUE_SEMAPHORE semaphore)
1731{
1732 XGL_RESULT result = nextTable.SignalQueueSemaphore(queue, semaphore);
1733 return result;
1734}
1735
1736XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglWaitQueueSemaphore(XGL_QUEUE queue, XGL_QUEUE_SEMAPHORE semaphore)
1737{
1738 XGL_RESULT result = nextTable.WaitQueueSemaphore(queue, semaphore);
1739 return result;
1740}
1741
1742XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateEvent(XGL_DEVICE device, const XGL_EVENT_CREATE_INFO* pCreateInfo, XGL_EVENT* pEvent)
1743{
1744 XGL_RESULT result = nextTable.CreateEvent(device, pCreateInfo, pEvent);
1745 return result;
1746}
1747
1748XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglGetEventStatus(XGL_EVENT event)
1749{
1750 XGL_RESULT result = nextTable.GetEventStatus(event);
1751 return result;
1752}
1753
1754XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglSetEvent(XGL_EVENT event)
1755{
1756 XGL_RESULT result = nextTable.SetEvent(event);
1757 return result;
1758}
1759
1760XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglResetEvent(XGL_EVENT event)
1761{
1762 XGL_RESULT result = nextTable.ResetEvent(event);
1763 return result;
1764}
1765
1766XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateQueryPool(XGL_DEVICE device, const XGL_QUERY_POOL_CREATE_INFO* pCreateInfo, XGL_QUERY_POOL* pQueryPool)
1767{
1768 XGL_RESULT result = nextTable.CreateQueryPool(device, pCreateInfo, pQueryPool);
1769 return result;
1770}
1771
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001772XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglGetQueryPoolResults(XGL_QUERY_POOL queryPool, uint32_t startQuery, uint32_t queryCount, size_t* pDataSize, void* pData)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001773{
1774 XGL_RESULT result = nextTable.GetQueryPoolResults(queryPool, startQuery, queryCount, pDataSize, pData);
1775 return result;
1776}
1777
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001778XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglGetFormatInfo(XGL_DEVICE device, XGL_FORMAT format, XGL_FORMAT_INFO_TYPE infoType, size_t* pDataSize, void* pData)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001779{
1780 XGL_RESULT result = nextTable.GetFormatInfo(device, format, infoType, pDataSize, pData);
1781 return result;
1782}
1783
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001784XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateBuffer(XGL_DEVICE device, const XGL_BUFFER_CREATE_INFO* pCreateInfo, XGL_BUFFER* pBuffer)
1785{
1786 XGL_RESULT result = nextTable.CreateBuffer(device, pCreateInfo, pBuffer);
Tobin Ehlis41415bb2015-01-22 10:45:21 -07001787 if (XGL_SUCCESS == result) {
Tobin Ehlisbf0146e2015-02-11 14:24:02 -07001788 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis41415bb2015-01-22 10:45:21 -07001789 BUFFER_NODE *pNewNode = (BUFFER_NODE*)malloc(sizeof(BUFFER_NODE));
Tobin Ehlis8614b8d2015-02-17 16:27:03 -07001790#if ALLOC_DEBUG
1791 printf("Alloc21 #%lu pNewNode addr(%p)\n", ++g_alloc_count, (void*)pNewNode);
1792#endif
Tobin Ehlis41415bb2015-01-22 10:45:21 -07001793 pNewNode->buffer = *pBuffer;
1794 memcpy(&pNewNode->createInfo, pCreateInfo, sizeof(XGL_BUFFER_CREATE_INFO));
1795 pNewNode->pNext = g_pBufferHead;
1796 g_pBufferHead = pNewNode;
Tobin Ehlisbf0146e2015-02-11 14:24:02 -07001797 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis41415bb2015-01-22 10:45:21 -07001798 }
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001799 return result;
1800}
1801
1802XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateBufferView(XGL_DEVICE device, const XGL_BUFFER_VIEW_CREATE_INFO* pCreateInfo, XGL_BUFFER_VIEW* pView)
1803{
1804 XGL_RESULT result = nextTable.CreateBufferView(device, pCreateInfo, pView);
1805 return result;
1806}
1807
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001808XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateImage(XGL_DEVICE device, const XGL_IMAGE_CREATE_INFO* pCreateInfo, XGL_IMAGE* pImage)
1809{
1810 XGL_RESULT result = nextTable.CreateImage(device, pCreateInfo, pImage);
1811 return result;
1812}
1813
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001814XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglSetFastClearColor(XGL_IMAGE image, const float color[4])
1815{
1816 XGL_RESULT result = nextTable.SetFastClearColor(image, color);
1817 return result;
1818}
1819
1820XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglSetFastClearDepth(XGL_IMAGE image, float depth)
1821{
1822 XGL_RESULT result = nextTable.SetFastClearDepth(image, depth);
1823 return result;
1824}
1825
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001826XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglGetImageSubresourceInfo(XGL_IMAGE image, const XGL_IMAGE_SUBRESOURCE* pSubresource, XGL_SUBRESOURCE_INFO_TYPE infoType, size_t* pDataSize, void* pData)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001827{
1828 XGL_RESULT result = nextTable.GetImageSubresourceInfo(image, pSubresource, infoType, pDataSize, pData);
1829 return result;
1830}
1831
1832XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateImageView(XGL_DEVICE device, const XGL_IMAGE_VIEW_CREATE_INFO* pCreateInfo, XGL_IMAGE_VIEW* pView)
1833{
1834 XGL_RESULT result = nextTable.CreateImageView(device, pCreateInfo, pView);
Tobin Ehlis41415bb2015-01-22 10:45:21 -07001835 if (XGL_SUCCESS == result) {
Tobin Ehlisbf0146e2015-02-11 14:24:02 -07001836 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis41415bb2015-01-22 10:45:21 -07001837 IMAGE_NODE *pNewNode = (IMAGE_NODE*)malloc(sizeof(IMAGE_NODE));
Tobin Ehlis8614b8d2015-02-17 16:27:03 -07001838#if ALLOC_DEBUG
1839 printf("Alloc22 #%lu pNewNode addr(%p)\n", ++g_alloc_count, (void*)pNewNode);
1840#endif
Tobin Ehlis41415bb2015-01-22 10:45:21 -07001841 pNewNode->image = *pView;
1842 memcpy(&pNewNode->createInfo, pCreateInfo, sizeof(XGL_IMAGE_VIEW_CREATE_INFO));
1843 pNewNode->pNext = g_pImageHead;
1844 g_pImageHead = pNewNode;
Tobin Ehlisbf0146e2015-02-11 14:24:02 -07001845 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis41415bb2015-01-22 10:45:21 -07001846 }
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001847 return result;
1848}
1849
1850XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateColorAttachmentView(XGL_DEVICE device, const XGL_COLOR_ATTACHMENT_VIEW_CREATE_INFO* pCreateInfo, XGL_COLOR_ATTACHMENT_VIEW* pView)
1851{
1852 XGL_RESULT result = nextTable.CreateColorAttachmentView(device, pCreateInfo, pView);
1853 return result;
1854}
1855
1856XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateDepthStencilView(XGL_DEVICE device, const XGL_DEPTH_STENCIL_VIEW_CREATE_INFO* pCreateInfo, XGL_DEPTH_STENCIL_VIEW* pView)
1857{
1858 XGL_RESULT result = nextTable.CreateDepthStencilView(device, pCreateInfo, pView);
1859 return result;
1860}
1861
1862XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateShader(XGL_DEVICE device, const XGL_SHADER_CREATE_INFO* pCreateInfo, XGL_SHADER* pShader)
1863{
1864 XGL_RESULT result = nextTable.CreateShader(device, pCreateInfo, pShader);
1865 return result;
1866}
1867
1868XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateGraphicsPipeline(XGL_DEVICE device, const XGL_GRAPHICS_PIPELINE_CREATE_INFO* pCreateInfo, XGL_PIPELINE* pPipeline)
1869{
1870 XGL_RESULT result = nextTable.CreateGraphicsPipeline(device, pCreateInfo, pPipeline);
1871 // Create LL HEAD for this Pipeline
Tobin Ehlise79df942014-11-18 16:38:08 -07001872 char str[1024];
1873 sprintf(str, "Created Gfx Pipeline %p", (void*)*pPipeline);
1874 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, pPipeline, 0, DRAWSTATE_NONE, "DS", str);
Ian Elliott81ac44c2015-01-13 17:52:38 -07001875 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis41415bb2015-01-22 10:45:21 -07001876 PIPELINE_NODE *pTrav = g_pPipelineHead;
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001877 if (pTrav) {
1878 while (pTrav->pNext)
1879 pTrav = pTrav->pNext;
1880 pTrav->pNext = (PIPELINE_NODE*)malloc(sizeof(PIPELINE_NODE));
Tobin Ehlis8614b8d2015-02-17 16:27:03 -07001881#if ALLOC_DEBUG
1882 printf("Alloc23 #%lu pTrav->pNext addr(%p)\n", ++g_alloc_count, (void*)pTrav->pNext);
1883#endif
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001884 pTrav = pTrav->pNext;
1885 }
1886 else {
1887 pTrav = (PIPELINE_NODE*)malloc(sizeof(PIPELINE_NODE));
Tobin Ehlis8614b8d2015-02-17 16:27:03 -07001888#if ALLOC_DEBUG
1889 printf("Alloc24 #%lu pTrav addr(%p)\n", ++g_alloc_count, (void*)pTrav);
1890#endif
Tobin Ehlis41415bb2015-01-22 10:45:21 -07001891 g_pPipelineHead = pTrav;
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001892 }
1893 memset((void*)pTrav, 0, sizeof(PIPELINE_NODE));
1894 pTrav->pipeline = *pPipeline;
1895 initPipeline(pTrav, pCreateInfo);
Ian Elliott81ac44c2015-01-13 17:52:38 -07001896 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001897 return result;
1898}
1899
1900XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateComputePipeline(XGL_DEVICE device, const XGL_COMPUTE_PIPELINE_CREATE_INFO* pCreateInfo, XGL_PIPELINE* pPipeline)
1901{
1902 XGL_RESULT result = nextTable.CreateComputePipeline(device, pCreateInfo, pPipeline);
1903 return result;
1904}
1905
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001906XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglStorePipeline(XGL_PIPELINE pipeline, size_t* pDataSize, void* pData)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001907{
1908 XGL_RESULT result = nextTable.StorePipeline(pipeline, pDataSize, pData);
1909 return result;
1910}
1911
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001912XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglLoadPipeline(XGL_DEVICE device, size_t dataSize, const void* pData, XGL_PIPELINE* pPipeline)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001913{
1914 XGL_RESULT result = nextTable.LoadPipeline(device, dataSize, pData, pPipeline);
1915 return result;
1916}
1917
1918XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreatePipelineDelta(XGL_DEVICE device, XGL_PIPELINE p1, XGL_PIPELINE p2, XGL_PIPELINE_DELTA* delta)
1919{
1920 XGL_RESULT result = nextTable.CreatePipelineDelta(device, p1, p2, delta);
1921 return result;
1922}
1923
1924XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateSampler(XGL_DEVICE device, const XGL_SAMPLER_CREATE_INFO* pCreateInfo, XGL_SAMPLER* pSampler)
1925{
1926 XGL_RESULT result = nextTable.CreateSampler(device, pCreateInfo, pSampler);
Tobin Ehlis41415bb2015-01-22 10:45:21 -07001927 if (XGL_SUCCESS == result) {
Ian Elliott81ac44c2015-01-13 17:52:38 -07001928 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis41415bb2015-01-22 10:45:21 -07001929 SAMPLER_NODE *pNewNode = (SAMPLER_NODE*)malloc(sizeof(SAMPLER_NODE));
Tobin Ehlis8614b8d2015-02-17 16:27:03 -07001930#if ALLOC_DEBUG
Tobin Ehlisfb1ef942015-02-20 09:30:06 -07001931 printf("Alloc25 #%lu pNewNode addr(%p)\n", ++g_alloc_count, (void*)pNewNode);
Tobin Ehlis8614b8d2015-02-17 16:27:03 -07001932#endif
Tobin Ehlis41415bb2015-01-22 10:45:21 -07001933 pNewNode->sampler = *pSampler;
1934 memcpy(&pNewNode->createInfo, pCreateInfo, sizeof(XGL_SAMPLER_CREATE_INFO));
1935 pNewNode->pNext = g_pSamplerHead;
1936 g_pSamplerHead = pNewNode;
Ian Elliott81ac44c2015-01-13 17:52:38 -07001937 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis41415bb2015-01-22 10:45:21 -07001938 }
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06001939 return result;
1940}
1941
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001942XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateDescriptorSetLayout(XGL_DEVICE device, XGL_FLAGS stageFlags, const uint32_t* pSetBindPoints, XGL_DESCRIPTOR_SET_LAYOUT priorSetLayout, const XGL_DESCRIPTOR_SET_LAYOUT_CREATE_INFO* pSetLayoutInfoList, XGL_DESCRIPTOR_SET_LAYOUT* pSetLayout)
1943{
1944 XGL_RESULT result = nextTable.CreateDescriptorSetLayout(device, stageFlags, pSetBindPoints, priorSetLayout, pSetLayoutInfoList, pSetLayout);
1945 if (XGL_SUCCESS == result) {
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001946 LAYOUT_NODE* pNewNode = (LAYOUT_NODE*)malloc(sizeof(LAYOUT_NODE));
Tobin Ehlis8614b8d2015-02-17 16:27:03 -07001947#if ALLOC_DEBUG
Tobin Ehlisfb1ef942015-02-20 09:30:06 -07001948 printf("Alloc26 #%lu pNewNode addr(%p)\n", ++g_alloc_count, (void*)pNewNode);
Tobin Ehlis8614b8d2015-02-17 16:27:03 -07001949#endif
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001950 if (NULL == pNewNode) {
1951 char str[1024];
1952 sprintf(str, "Out of memory while attempting to allocate LAYOUT_NODE in xglCreateDescriptorSetLayout()");
1953 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, *pSetLayout, 0, DRAWSTATE_OUT_OF_MEMORY, "DS", str);
1954 }
1955 memset(pNewNode, 0, sizeof(LAYOUT_NODE));
Tobin Ehlis41415bb2015-01-22 10:45:21 -07001956 // TODO : API Currently missing a count here that we should multiply by struct size
1957 pNewNode->pCreateInfoList = (XGL_DESCRIPTOR_SET_LAYOUT_CREATE_INFO*)malloc(sizeof(XGL_DESCRIPTOR_SET_LAYOUT_CREATE_INFO));
Tobin Ehlis8614b8d2015-02-17 16:27:03 -07001958#if ALLOC_DEBUG
Tobin Ehlisfb1ef942015-02-20 09:30:06 -07001959 printf("Alloc27 #%lu pNewNode->pCreateInfoList addr(%p)\n", ++g_alloc_count, (void*)pNewNode->pCreateInfoList);
Tobin Ehlis8614b8d2015-02-17 16:27:03 -07001960#endif
Tobin Ehlis8cced212015-02-13 10:26:14 -07001961 memset((void*)pNewNode->pCreateInfoList, 0, sizeof(XGL_DESCRIPTOR_SET_LAYOUT_CREATE_INFO));
Tobin Ehlisefa84162015-02-17 09:54:13 -07001962 void* pCITrav = NULL;
1963 uint32_t totalCount = 0;
1964 if (pSetLayoutInfoList) {
Tobin Ehlis8cced212015-02-13 10:26:14 -07001965 memcpy((void*)pNewNode->pCreateInfoList, pSetLayoutInfoList, sizeof(XGL_DESCRIPTOR_SET_LAYOUT_CREATE_INFO));
Tobin Ehlisefa84162015-02-17 09:54:13 -07001966 pCITrav = (void*)pSetLayoutInfoList->pNext;
1967 totalCount = pSetLayoutInfoList->count;
1968 }
1969 void** ppNext = (void**)&pNewNode->pCreateInfoList->pNext;
1970 while (pCITrav) {
1971 totalCount += ((XGL_DESCRIPTOR_SET_LAYOUT_CREATE_INFO*)pCITrav)->count;
1972 *ppNext = (void*)malloc(sizeof(XGL_DESCRIPTOR_SET_LAYOUT_CREATE_INFO));
Tobin Ehlis8614b8d2015-02-17 16:27:03 -07001973#if ALLOC_DEBUG
Tobin Ehlisfb1ef942015-02-20 09:30:06 -07001974 printf("Alloc28 #%lu *ppNext addr(%p)\n", ++g_alloc_count, (void*)*ppNext);
Tobin Ehlis8614b8d2015-02-17 16:27:03 -07001975#endif
Tobin Ehlisefa84162015-02-17 09:54:13 -07001976 memcpy((void*)*ppNext, pCITrav, sizeof(XGL_DESCRIPTOR_SET_LAYOUT_CREATE_INFO));
1977 pCITrav = (void*)((XGL_DESCRIPTOR_SET_LAYOUT_CREATE_INFO*)pCITrav)->pNext;
Tobin Ehlis82871a82015-02-19 09:55:18 -07001978 ppNext = (void**)&((XGL_DESCRIPTOR_SET_LAYOUT_CREATE_INFO*)*ppNext)->pNext;
Tobin Ehlisefa84162015-02-17 09:54:13 -07001979 }
1980 if (totalCount > 0) {
1981 pNewNode->pTypes = (XGL_DESCRIPTOR_TYPE*)malloc(totalCount*sizeof(XGL_DESCRIPTOR_TYPE));
Tobin Ehlis8614b8d2015-02-17 16:27:03 -07001982#if ALLOC_DEBUG
Tobin Ehlisfb1ef942015-02-20 09:30:06 -07001983 printf("Alloc29 #%lu pNewNode->pTypes addr(%p)\n", ++g_alloc_count, (void*)pNewNode->pTypes);
Tobin Ehlis8614b8d2015-02-17 16:27:03 -07001984#endif
Tobin Ehlisefa84162015-02-17 09:54:13 -07001985 XGL_DESCRIPTOR_SET_LAYOUT_CREATE_INFO* pLCI = (XGL_DESCRIPTOR_SET_LAYOUT_CREATE_INFO*)pSetLayoutInfoList;
Tobin Ehlis82871a82015-02-19 09:55:18 -07001986 uint32_t offset = 0;
1987 uint32_t i = 0;
Tobin Ehlisefa84162015-02-17 09:54:13 -07001988 while (pLCI) {
Tobin Ehlis82871a82015-02-19 09:55:18 -07001989 for (i = 0; i < pLCI->count; i++) {
1990 pNewNode->pTypes[offset + i] = pLCI->descriptorType;
Tobin Ehlisefa84162015-02-17 09:54:13 -07001991 }
Tobin Ehlis82871a82015-02-19 09:55:18 -07001992 offset += i;
Tobin Ehlisefa84162015-02-17 09:54:13 -07001993 pLCI = (XGL_DESCRIPTOR_SET_LAYOUT_CREATE_INFO*)pLCI->pNext;
1994 }
1995 }
Tobin Ehlis41415bb2015-01-22 10:45:21 -07001996 pNewNode->layout = *pSetLayout;
Tobin Ehlis83ebbef2015-02-10 15:35:23 -07001997 pNewNode->stageFlags = stageFlags;
Tobin Ehlisefa84162015-02-17 09:54:13 -07001998 uint32_t i = (XGL_SHADER_STAGE_FLAGS_ALL == stageFlags) ? 0 : XGL_SHADER_STAGE_COMPUTE;
Tobin Ehlisd215d4b2015-02-16 14:29:30 -07001999 for (uint32_t stage = XGL_SHADER_STAGE_FLAGS_COMPUTE_BIT; stage > 0; stage >>= 1) {
2000 assert(i < XGL_NUM_SHADER_STAGE);
2001 if (stage & stageFlags)
2002 pNewNode->shaderStageBindPoints[i] = pSetBindPoints[i];
Tobin Ehlisefa84162015-02-17 09:54:13 -07002003 i = (i == 0) ? 0 : (i-1);
Tobin Ehlisd215d4b2015-02-16 14:29:30 -07002004 }
Tobin Ehlis83ebbef2015-02-10 15:35:23 -07002005 pNewNode->startIndex = 0;
Tobin Ehlis41415bb2015-01-22 10:45:21 -07002006 LAYOUT_NODE* pPriorNode = getLayoutNode(priorSetLayout);
2007 // Point to prior node or NULL if no prior node
Tobin Ehlis83ebbef2015-02-10 15:35:23 -07002008 if (NULL != priorSetLayout && pPriorNode == NULL) {
2009 char str[1024];
2010 sprintf(str, "Invalid priorSetLayout of %p passed to xglCreateDescriptorSetLayout()", (void*)priorSetLayout);
2011 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, priorSetLayout, 0, DRAWSTATE_INVALID_LAYOUT, "DS", str);
2012 }
2013 else if (pPriorNode != NULL) { // We have a node for a valid prior layout
2014 // Get count for prior layout
2015 pNewNode->startIndex = pPriorNode->endIndex + 1;
2016 }
Tobin Ehlisefa84162015-02-17 09:54:13 -07002017 pNewNode->endIndex = pNewNode->startIndex + totalCount - 1;
Tobin Ehlis83ebbef2015-02-10 15:35:23 -07002018 assert(pNewNode->endIndex >= pNewNode->startIndex);
Tobin Ehlis41415bb2015-01-22 10:45:21 -07002019 pNewNode->pPriorSetLayout = pPriorNode;
2020 // Put new node at Head of global Layer list
Tobin Ehlisfb1ef942015-02-20 09:30:06 -07002021 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis83ebbef2015-02-10 15:35:23 -07002022 pNewNode->pNext = g_pLayoutHead;
Tobin Ehlis41415bb2015-01-22 10:45:21 -07002023 g_pLayoutHead = pNewNode;
Tobin Ehlisfb1ef942015-02-20 09:30:06 -07002024 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002025 }
2026 return result;
2027}
2028
2029XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglBeginDescriptorRegionUpdate(XGL_DEVICE device, XGL_DESCRIPTOR_UPDATE_MODE updateMode)
2030{
2031 XGL_RESULT result = nextTable.BeginDescriptorRegionUpdate(device, updateMode);
2032 if (XGL_SUCCESS == result) {
Tobin Ehlisfb1ef942015-02-20 09:30:06 -07002033 loader_platform_thread_lock_mutex(&globalLock);
2034 REGION_NODE* pRegionNode = g_pRegionHead;
2035 if (!pRegionNode) {
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002036 char str[1024];
Tobin Ehlisfb1ef942015-02-20 09:30:06 -07002037 sprintf(str, "Unable to find region node for global region head %p", (void*)g_pRegionHead);
2038 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, g_pRegionHead, 0, DRAWSTATE_INTERNAL_ERROR, "DS", str);
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002039 }
2040 else {
Tobin Ehlisfb1ef942015-02-20 09:30:06 -07002041 pRegionNode->updateActive = 1;
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002042 }
Tobin Ehlisfb1ef942015-02-20 09:30:06 -07002043 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002044 }
2045 return result;
2046}
2047
2048XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglEndDescriptorRegionUpdate(XGL_DEVICE device, XGL_CMD_BUFFER cmd)
2049{
2050 XGL_RESULT result = nextTable.EndDescriptorRegionUpdate(device, cmd);
2051 if (XGL_SUCCESS == result) {
Tobin Ehlisfb1ef942015-02-20 09:30:06 -07002052 loader_platform_thread_lock_mutex(&globalLock);
2053 REGION_NODE* pRegionNode = g_pRegionHead;
2054 if (!pRegionNode) {
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002055 char str[1024];
Tobin Ehlisfb1ef942015-02-20 09:30:06 -07002056 sprintf(str, "Unable to find region node for global region head %p", (void*)g_pRegionHead);
2057 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, g_pRegionHead, 0, DRAWSTATE_INTERNAL_ERROR, "DS", str);
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002058 }
2059 else {
Tobin Ehlisfb1ef942015-02-20 09:30:06 -07002060 if (!pRegionNode->updateActive) {
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002061 char str[1024];
Tobin Ehlisfb1ef942015-02-20 09:30:06 -07002062 sprintf(str, "You must call xglBeginDescriptorRegionUpdate() before this call to xglEndDescriptorRegionUpdate()!");
2063 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, g_pRegionHead, 0, DRAWSTATE_DS_END_WITHOUT_BEGIN, "DS", str);
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002064 }
2065 else {
Tobin Ehlisfb1ef942015-02-20 09:30:06 -07002066 pRegionNode->updateActive = 0;
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002067 }
2068 }
Tobin Ehlisfb1ef942015-02-20 09:30:06 -07002069 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002070 }
2071 return result;
2072}
2073
2074XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateDescriptorRegion(XGL_DEVICE device, XGL_DESCRIPTOR_REGION_USAGE regionUsage, uint32_t maxSets, const XGL_DESCRIPTOR_REGION_CREATE_INFO* pCreateInfo, XGL_DESCRIPTOR_REGION* pDescriptorRegion)
2075{
2076 XGL_RESULT result = nextTable.CreateDescriptorRegion(device, regionUsage, maxSets, pCreateInfo, pDescriptorRegion);
2077 if (XGL_SUCCESS == result) {
2078 // Insert this region into Global Region LL at head
2079 char str[1024];
2080 sprintf(str, "Created Descriptor Region %p", (void*)*pDescriptorRegion);
2081 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, pDescriptorRegion, 0, DRAWSTATE_NONE, "DS", str);
Tobin Ehlisbf0146e2015-02-11 14:24:02 -07002082 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis83ebbef2015-02-10 15:35:23 -07002083 REGION_NODE* pNewNode = (REGION_NODE*)malloc(sizeof(REGION_NODE));
Tobin Ehlis8614b8d2015-02-17 16:27:03 -07002084#if ALLOC_DEBUG
Tobin Ehlisfb1ef942015-02-20 09:30:06 -07002085 printf("Alloc30 #%lu pNewNode addr(%p)\n", ++g_alloc_count, (void*)pNewNode);
Tobin Ehlis8614b8d2015-02-17 16:27:03 -07002086#endif
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002087 if (NULL == pNewNode) {
2088 char str[1024];
Tobin Ehlis83ebbef2015-02-10 15:35:23 -07002089 sprintf(str, "Out of memory while attempting to allocate REGION_NODE in xglCreateDescriptorRegion()");
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002090 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, *pDescriptorRegion, 0, DRAWSTATE_OUT_OF_MEMORY, "DS", str);
2091 }
2092 else {
2093 memset(pNewNode, 0, sizeof(REGION_NODE));
2094 pNewNode->pNext = g_pRegionHead;
2095 g_pRegionHead = pNewNode;
Tobin Ehlis83ebbef2015-02-10 15:35:23 -07002096 XGL_DESCRIPTOR_REGION_CREATE_INFO* pCI = (XGL_DESCRIPTOR_REGION_CREATE_INFO*)&pNewNode->createInfo;
2097 memcpy((void*)pCI, pCreateInfo, sizeof(XGL_DESCRIPTOR_REGION_CREATE_INFO));
2098 size_t typeCountSize = pNewNode->createInfo.count * sizeof(XGL_DESCRIPTOR_TYPE_COUNT);
Tobin Ehlisefa84162015-02-17 09:54:13 -07002099 if (typeCountSize) {
2100 XGL_DESCRIPTOR_TYPE_COUNT** ppTypeCount = (XGL_DESCRIPTOR_TYPE_COUNT**)&pNewNode->createInfo.pTypeCount;
2101 *ppTypeCount = (XGL_DESCRIPTOR_TYPE_COUNT*)malloc(typeCountSize);
Tobin Ehlis8614b8d2015-02-17 16:27:03 -07002102#if ALLOC_DEBUG
Tobin Ehlisfb1ef942015-02-20 09:30:06 -07002103 printf("Alloc31 #%lu *ppTypeCount addr(%p)\n", ++g_alloc_count, (void*)*ppTypeCount);
Tobin Ehlis8614b8d2015-02-17 16:27:03 -07002104#endif
Tobin Ehlisefa84162015-02-17 09:54:13 -07002105 memcpy((void*)*ppTypeCount, pCreateInfo->pTypeCount, typeCountSize);
2106 }
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002107 pNewNode->regionUsage = regionUsage;
2108 pNewNode->updateActive = 0;
2109 pNewNode->maxSets = maxSets;
2110 pNewNode->region = *pDescriptorRegion;
2111 }
Tobin Ehlisbf0146e2015-02-11 14:24:02 -07002112 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002113 }
2114 else {
2115 // Need to do anything if region create fails?
2116 }
2117 return result;
2118}
2119
2120XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglClearDescriptorRegion(XGL_DESCRIPTOR_REGION descriptorRegion)
2121{
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002122 XGL_RESULT result = nextTable.ClearDescriptorRegion(descriptorRegion);
Tobin Ehlis41415bb2015-01-22 10:45:21 -07002123 if (XGL_SUCCESS == result) {
2124 clearDescriptorRegion(descriptorRegion);
2125 }
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002126 return result;
2127}
2128
2129XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglAllocDescriptorSets(XGL_DESCRIPTOR_REGION descriptorRegion, XGL_DESCRIPTOR_SET_USAGE setUsage, uint32_t count, const XGL_DESCRIPTOR_SET_LAYOUT* pSetLayouts, XGL_DESCRIPTOR_SET* pDescriptorSets, uint32_t* pCount)
2130{
2131 XGL_RESULT result = nextTable.AllocDescriptorSets(descriptorRegion, setUsage, count, pSetLayouts, pDescriptorSets, pCount);
Tobin Ehlis41415bb2015-01-22 10:45:21 -07002132 if ((XGL_SUCCESS == result) || (*pCount > 0)) {
2133 REGION_NODE *pRegionNode = getRegionNode(descriptorRegion);
2134 if (!pRegionNode) {
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002135 char str[1024];
Tobin Ehlis41415bb2015-01-22 10:45:21 -07002136 sprintf(str, "Unable to find region node for region %p specified in xglAllocDescriptorSets() call", (void*)descriptorRegion);
Tobin Ehlis83ebbef2015-02-10 15:35:23 -07002137 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, descriptorRegion, 0, DRAWSTATE_INVALID_REGION, "DS", str);
Tobin Ehlis41415bb2015-01-22 10:45:21 -07002138 }
2139 else {
Tobin Ehlis83ebbef2015-02-10 15:35:23 -07002140 for (uint32_t i = 0; i < *pCount; i++) {
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002141 char str[1024];
Tobin Ehlis41415bb2015-01-22 10:45:21 -07002142 sprintf(str, "Created Descriptor Set %p", (void*)pDescriptorSets[i]);
Tobin Ehlis83ebbef2015-02-10 15:35:23 -07002143 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, pDescriptorSets[i], 0, DRAWSTATE_NONE, "DS", str);
Tobin Ehlis41415bb2015-01-22 10:45:21 -07002144 // Create new set node and add to head of region nodes
Tobin Ehlis83ebbef2015-02-10 15:35:23 -07002145 SET_NODE* pNewNode = (SET_NODE*)malloc(sizeof(SET_NODE));
Tobin Ehlis8614b8d2015-02-17 16:27:03 -07002146#if ALLOC_DEBUG
Tobin Ehlis82871a82015-02-19 09:55:18 -07002147 printf("Alloc32 #%lu pNewNode addr(%p)\n", ++g_alloc_count, (void*)pNewNode);
Tobin Ehlis8614b8d2015-02-17 16:27:03 -07002148#endif
Tobin Ehlis41415bb2015-01-22 10:45:21 -07002149 if (NULL == pNewNode) {
2150 char str[1024];
2151 sprintf(str, "Out of memory while attempting to allocate SET_NODE in xglAllocDescriptorSets()");
Tobin Ehlis83ebbef2015-02-10 15:35:23 -07002152 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, pDescriptorSets[i], 0, DRAWSTATE_OUT_OF_MEMORY, "DS", str);
Tobin Ehlis41415bb2015-01-22 10:45:21 -07002153 }
2154 else {
2155 memset(pNewNode, 0, sizeof(SET_NODE));
2156 // Insert set at head of Set LL for this region
2157 pNewNode->pNext = pRegionNode->pSets;
2158 pRegionNode->pSets = pNewNode;
2159 LAYOUT_NODE* pLayout = getLayoutNode(pSetLayouts[i]);
2160 if (NULL == pLayout) {
2161 char str[1024];
2162 sprintf(str, "Unable to find set layout node for layout %p specified in xglAllocDescriptorSets() call", (void*)pSetLayouts[i]);
2163 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, pSetLayouts[i], 0, DRAWSTATE_INVALID_LAYOUT, "DS", str);
2164 }
2165 pNewNode->pLayouts = pLayout;
2166 pNewNode->region = descriptorRegion;
2167 pNewNode->set = pDescriptorSets[i];
2168 pNewNode->setUsage = setUsage;
Tobin Ehlis04f80bb2015-02-11 13:13:18 -07002169 pNewNode->descriptorCount = pLayout->endIndex + 1;
Tobin Ehlis82871a82015-02-19 09:55:18 -07002170 size_t descriptorArraySize = sizeof(GENERIC_HEADER*)*pNewNode->descriptorCount;
2171 pNewNode->ppDescriptors = (GENERIC_HEADER**)malloc(descriptorArraySize);
2172#if ALLOC_DEBUG
2173 printf("Alloc35 #%lu pSet->ppDescriptors addr(%p)\n", ++g_alloc_count, (void*)pNewNode->ppDescriptors);
2174#endif
2175 memset(pNewNode->ppDescriptors, 0, descriptorArraySize);
Tobin Ehlis41415bb2015-01-22 10:45:21 -07002176 }
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002177 }
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002178 }
2179 }
2180 return result;
2181}
2182
2183XGL_LAYER_EXPORT void XGLAPI xglClearDescriptorSets(XGL_DESCRIPTOR_REGION descriptorRegion, uint32_t count, const XGL_DESCRIPTOR_SET* pDescriptorSets)
2184{
Tobin Ehlis41415bb2015-01-22 10:45:21 -07002185 for (uint32_t i = 0; i < count; i++) {
Tobin Ehlis83ebbef2015-02-10 15:35:23 -07002186 clearDescriptorSet(pDescriptorSets[i]);
Tobin Ehlis41415bb2015-01-22 10:45:21 -07002187 }
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002188 nextTable.ClearDescriptorSets(descriptorRegion, count, pDescriptorSets);
2189}
2190
2191XGL_LAYER_EXPORT void XGLAPI xglUpdateDescriptors(XGL_DESCRIPTOR_SET descriptorSet, const void* pUpdateChain)
2192{
Tobin Ehlis83ebbef2015-02-10 15:35:23 -07002193 if (!dsUpdateActive(descriptorSet)) {
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002194 char str[1024];
2195 sprintf(str, "You must call xglBeginDescriptorRegionUpdate() before this call to xglUpdateDescriptors()!");
Tobin Ehlisfb1ef942015-02-20 09:30:06 -07002196 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, g_pRegionHead->region, 0, DRAWSTATE_UPDATE_WITHOUT_BEGIN, "DS", str);
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002197 }
Tobin Ehlis41415bb2015-01-22 10:45:21 -07002198 else {
2199 // pUpdateChain is a Linked-list of XGL_UPDATE_* structures defining the mappings for the descriptors
2200 dsUpdate(descriptorSet, (GENERIC_HEADER*)pUpdateChain);
2201 }
2202
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002203 nextTable.UpdateDescriptors(descriptorSet, pUpdateChain);
2204}
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002205
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002206XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateDynamicViewportState(XGL_DEVICE device, const XGL_DYNAMIC_VP_STATE_CREATE_INFO* pCreateInfo, XGL_DYNAMIC_VP_STATE_OBJECT* pState)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002207{
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002208 XGL_RESULT result = nextTable.CreateDynamicViewportState(device, pCreateInfo, pState);
Tobin Ehlis41415bb2015-01-22 10:45:21 -07002209 insertDynamicState(*pState, (GENERIC_HEADER*)pCreateInfo, XGL_STATE_BIND_VIEWPORT);
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002210 return result;
2211}
2212
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002213XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateDynamicRasterState(XGL_DEVICE device, const XGL_DYNAMIC_RS_STATE_CREATE_INFO* pCreateInfo, XGL_DYNAMIC_RS_STATE_OBJECT* pState)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002214{
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002215 XGL_RESULT result = nextTable.CreateDynamicRasterState(device, pCreateInfo, pState);
Tobin Ehlis41415bb2015-01-22 10:45:21 -07002216 insertDynamicState(*pState, (GENERIC_HEADER*)pCreateInfo, XGL_STATE_BIND_RASTER);
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002217 return result;
2218}
2219
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002220XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateDynamicColorBlendState(XGL_DEVICE device, const XGL_DYNAMIC_CB_STATE_CREATE_INFO* pCreateInfo, XGL_DYNAMIC_CB_STATE_OBJECT* pState)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002221{
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002222 XGL_RESULT result = nextTable.CreateDynamicColorBlendState(device, pCreateInfo, pState);
Tobin Ehlis41415bb2015-01-22 10:45:21 -07002223 insertDynamicState(*pState, (GENERIC_HEADER*)pCreateInfo, XGL_STATE_BIND_COLOR_BLEND);
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002224 return result;
2225}
2226
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002227XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateDynamicDepthStencilState(XGL_DEVICE device, const XGL_DYNAMIC_DS_STATE_CREATE_INFO* pCreateInfo, XGL_DYNAMIC_DS_STATE_OBJECT* pState)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002228{
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002229 XGL_RESULT result = nextTable.CreateDynamicDepthStencilState(device, pCreateInfo, pState);
Tobin Ehlis41415bb2015-01-22 10:45:21 -07002230 insertDynamicState(*pState, (GENERIC_HEADER*)pCreateInfo, XGL_STATE_BIND_DEPTH_STENCIL);
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002231 return result;
2232}
2233
2234XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateCommandBuffer(XGL_DEVICE device, const XGL_CMD_BUFFER_CREATE_INFO* pCreateInfo, XGL_CMD_BUFFER* pCmdBuffer)
2235{
2236 XGL_RESULT result = nextTable.CreateCommandBuffer(device, pCreateInfo, pCmdBuffer);
Tobin Ehlis8cced212015-02-13 10:26:14 -07002237 if (XGL_SUCCESS == result) {
Tobin Ehlisfb1ef942015-02-20 09:30:06 -07002238 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis8cced212015-02-13 10:26:14 -07002239 GLOBAL_CB_NODE* pCB = (GLOBAL_CB_NODE*)malloc(sizeof(GLOBAL_CB_NODE));
Tobin Ehlis8614b8d2015-02-17 16:27:03 -07002240#if ALLOC_DEBUG
Tobin Ehlisfb1ef942015-02-20 09:30:06 -07002241 printf("Alloc33 #%lu pCB addr(%p)\n", ++g_alloc_count, (void*)pCB);
Tobin Ehlis8614b8d2015-02-17 16:27:03 -07002242#endif
Tobin Ehlis8cced212015-02-13 10:26:14 -07002243 memset(pCB, 0, sizeof(GLOBAL_CB_NODE));
2244 pCB->pNextGlobalCBNode = g_pCmdBufferHead;
2245 g_pCmdBufferHead = pCB;
2246 pCB->cmdBuffer = *pCmdBuffer;
2247 pCB->flags = pCreateInfo->flags;
2248 pCB->queueType = pCreateInfo->queueType;
2249 pCB->lastVtxBinding = MAX_BINDING;
Tobin Ehlis45662712015-02-23 09:06:28 -07002250 g_lastCmdBuffer[getTIDIndex()] = *pCmdBuffer;
Tobin Ehlisfb1ef942015-02-20 09:30:06 -07002251 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8cced212015-02-13 10:26:14 -07002252 }
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002253 return result;
2254}
2255
Jon Ashburn57ba18d2014-12-31 17:11:49 -07002256XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglBeginCommandBuffer(XGL_CMD_BUFFER cmdBuffer, const XGL_CMD_BUFFER_BEGIN_INFO* pBeginInfo)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002257{
Jon Ashburn57ba18d2014-12-31 17:11:49 -07002258 XGL_RESULT result = nextTable.BeginCommandBuffer(cmdBuffer, pBeginInfo);
Tobin Ehlis8cced212015-02-13 10:26:14 -07002259 if (XGL_SUCCESS == result) {
2260 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
Tobin Ehlis82871a82015-02-19 09:55:18 -07002261 if (pCB) {
2262 if (CB_NEW != pCB->state)
2263 resetCB(cmdBuffer);
2264 pCB->state = CB_UPDATE_ACTIVE;
2265 }
2266 else {
2267 char str[1024];
2268 sprintf(str, "In xglBeginCommandBuffer() and unable to find CmdBuffer Node for CB %p!", (void*)cmdBuffer);
2269 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2270 }
Tobin Ehlisfb1ef942015-02-20 09:30:06 -07002271 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis45662712015-02-23 09:06:28 -07002272 g_lastCmdBuffer[getTIDIndex()] = cmdBuffer;
Tobin Ehlisfb1ef942015-02-20 09:30:06 -07002273 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8cced212015-02-13 10:26:14 -07002274 }
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002275 return result;
2276}
2277
2278XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglEndCommandBuffer(XGL_CMD_BUFFER cmdBuffer)
2279{
2280 XGL_RESULT result = nextTable.EndCommandBuffer(cmdBuffer);
Tobin Ehlis8cced212015-02-13 10:26:14 -07002281 if (XGL_SUCCESS == result) {
2282 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
Tobin Ehlis82871a82015-02-19 09:55:18 -07002283 if (pCB) {
2284 pCB->state = CB_UPDATE_COMPLETE;
2285 printCB(cmdBuffer);
2286 }
2287 else {
2288 char str[1024];
2289 sprintf(str, "In xglEndCommandBuffer() and unable to find CmdBuffer Node for CB %p!", (void*)cmdBuffer);
2290 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2291 }
Tobin Ehlisfb1ef942015-02-20 09:30:06 -07002292 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis45662712015-02-23 09:06:28 -07002293 g_lastCmdBuffer[getTIDIndex()] = cmdBuffer;
Tobin Ehlisfb1ef942015-02-20 09:30:06 -07002294 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8cced212015-02-13 10:26:14 -07002295 }
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002296 return result;
2297}
2298
2299XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglResetCommandBuffer(XGL_CMD_BUFFER cmdBuffer)
2300{
2301 XGL_RESULT result = nextTable.ResetCommandBuffer(cmdBuffer);
Tobin Ehlis8cced212015-02-13 10:26:14 -07002302 if (XGL_SUCCESS == result) {
Tobin Ehlisd092d232015-02-13 13:30:07 -07002303 resetCB(cmdBuffer);
Tobin Ehlisfb1ef942015-02-20 09:30:06 -07002304 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis45662712015-02-23 09:06:28 -07002305 g_lastCmdBuffer[getTIDIndex()] = cmdBuffer;
Tobin Ehlisfb1ef942015-02-20 09:30:06 -07002306 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8cced212015-02-13 10:26:14 -07002307 }
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002308 return result;
2309}
2310
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06002311XGL_LAYER_EXPORT void XGLAPI xglCmdBindPipeline(XGL_CMD_BUFFER cmdBuffer, XGL_PIPELINE_BIND_POINT pipelineBindPoint, XGL_PIPELINE pipeline)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002312{
Tobin Ehlis8cced212015-02-13 10:26:14 -07002313 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2314 if (pCB) {
Tobin Ehlis45662712015-02-23 09:06:28 -07002315 g_lastCmdBuffer[getTIDIndex()] = cmdBuffer;
Tobin Ehlisd092d232015-02-13 13:30:07 -07002316 addCmd(pCB, CMD_BINDPIPELINE);
Tobin Ehlis8cced212015-02-13 10:26:14 -07002317 if (getPipeline(pipeline)) {
2318 pCB->lastBoundPipeline = pipeline;
2319 }
2320 else {
2321 char str[1024];
2322 sprintf(str, "Attempt to bind Pipeline %p that doesn't exist!", (void*)pipeline);
2323 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, pipeline, 0, DRAWSTATE_INVALID_PIPELINE, "DS", str);
2324 }
2325 synchAndDumpDot(cmdBuffer);
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002326 }
2327 else {
Tobin Ehlise79df942014-11-18 16:38:08 -07002328 char str[1024];
Tobin Ehlis8cced212015-02-13 10:26:14 -07002329 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2330 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002331 }
2332 nextTable.CmdBindPipeline(cmdBuffer, pipelineBindPoint, pipeline);
2333}
2334
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06002335XGL_LAYER_EXPORT void XGLAPI xglCmdBindPipelineDelta(XGL_CMD_BUFFER cmdBuffer, XGL_PIPELINE_BIND_POINT pipelineBindPoint, XGL_PIPELINE_DELTA delta)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002336{
Tobin Ehlisd092d232015-02-13 13:30:07 -07002337 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2338 if (pCB) {
2339 // TODO : Handle storing Pipeline Deltas to cmd buffer here
Tobin Ehlis45662712015-02-23 09:06:28 -07002340 g_lastCmdBuffer[getTIDIndex()] = cmdBuffer;
Tobin Ehlisd092d232015-02-13 13:30:07 -07002341 synchAndDumpDot(cmdBuffer);
2342 addCmd(pCB, CMD_BINDPIPELINEDELTA);
2343 }
2344 else {
2345 char str[1024];
2346 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2347 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2348 }
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002349 nextTable.CmdBindPipelineDelta(cmdBuffer, pipelineBindPoint, delta);
2350}
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002351
2352XGL_LAYER_EXPORT void XGLAPI xglCmdBindDynamicStateObject(XGL_CMD_BUFFER cmdBuffer, XGL_STATE_BIND_POINT stateBindPoint, XGL_DYNAMIC_STATE_OBJECT state)
2353{
Tobin Ehlis8cced212015-02-13 10:26:14 -07002354 setLastBoundDynamicState(cmdBuffer, state, stateBindPoint);
2355 synchAndDumpDot(cmdBuffer);
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002356 nextTable.CmdBindDynamicStateObject(cmdBuffer, stateBindPoint, state);
2357}
2358
2359XGL_LAYER_EXPORT void XGLAPI xglCmdBindDescriptorSet(XGL_CMD_BUFFER cmdBuffer, XGL_PIPELINE_BIND_POINT pipelineBindPoint, XGL_DESCRIPTOR_SET descriptorSet, const uint32_t* pUserData)
2360{
Tobin Ehlis8cced212015-02-13 10:26:14 -07002361 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2362 if (pCB) {
Tobin Ehlis45662712015-02-23 09:06:28 -07002363 g_lastCmdBuffer[getTIDIndex()] = cmdBuffer;
Tobin Ehlisd092d232015-02-13 13:30:07 -07002364 addCmd(pCB, CMD_BINDDESCRIPTORSET);
Tobin Ehlis8cced212015-02-13 10:26:14 -07002365 if (getSetNode(descriptorSet)) {
2366 if (dsUpdateActive(descriptorSet)) {
Tobin Ehlis224dd812015-02-19 15:26:49 -07002367 // TODO : This check here needs to be made at QueueSubmit time
2368/*
Tobin Ehlis8cced212015-02-13 10:26:14 -07002369 char str[1024];
2370 sprintf(str, "You must call xglEndDescriptorRegionUpdate(%p) before this call to xglCmdBindDescriptorSet()!", (void*)descriptorSet);
2371 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, descriptorSet, 0, DRAWSTATE_BINDING_DS_NO_END_UPDATE, "DS", str);
Tobin Ehlis224dd812015-02-19 15:26:49 -07002372*/
Tobin Ehlis8cced212015-02-13 10:26:14 -07002373 }
2374 loader_platform_thread_lock_mutex(&globalLock);
2375 pCB->lastBoundDescriptorSet = descriptorSet;
2376 loader_platform_thread_unlock_mutex(&globalLock);
2377 synchAndDumpDot(cmdBuffer);
Tobin Ehlis83ebbef2015-02-10 15:35:23 -07002378 char str[1024];
Tobin Ehlis8cced212015-02-13 10:26:14 -07002379 sprintf(str, "DS %p bound on pipeline %s", (void*)descriptorSet, string_XGL_PIPELINE_BIND_POINT(pipelineBindPoint));
2380 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, descriptorSet, 0, DRAWSTATE_NONE, "DS", str);
Tobin Ehlis83ebbef2015-02-10 15:35:23 -07002381 }
Tobin Ehlis8cced212015-02-13 10:26:14 -07002382 else {
2383 char str[1024];
2384 sprintf(str, "Attempt to bind DS %p that doesn't exist!", (void*)descriptorSet);
2385 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, descriptorSet, 0, DRAWSTATE_INVALID_SET, "DS", str);
2386 }
Tobin Ehlis83ebbef2015-02-10 15:35:23 -07002387 }
2388 else {
2389 char str[1024];
Tobin Ehlis8cced212015-02-13 10:26:14 -07002390 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2391 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis83ebbef2015-02-10 15:35:23 -07002392 }
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002393 nextTable.CmdBindDescriptorSet(cmdBuffer, pipelineBindPoint, descriptorSet, pUserData);
2394}
2395
2396XGL_LAYER_EXPORT void XGLAPI xglCmdBindIndexBuffer(XGL_CMD_BUFFER cmdBuffer, XGL_BUFFER buffer, XGL_GPU_SIZE offset, XGL_INDEX_TYPE indexType)
2397{
Tobin Ehlis8cced212015-02-13 10:26:14 -07002398 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2399 if (pCB) {
Tobin Ehlis45662712015-02-23 09:06:28 -07002400 g_lastCmdBuffer[getTIDIndex()] = cmdBuffer;
Tobin Ehlisd092d232015-02-13 13:30:07 -07002401 addCmd(pCB, CMD_BINDINDEXBUFFER);
Tobin Ehlis8cced212015-02-13 10:26:14 -07002402 // TODO : Track idxBuffer binding
2403 }
2404 else {
2405 char str[1024];
2406 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2407 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2408 }
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002409 nextTable.CmdBindIndexBuffer(cmdBuffer, buffer, offset, indexType);
2410}
2411
2412XGL_LAYER_EXPORT void XGLAPI xglCmdBindVertexBuffer(XGL_CMD_BUFFER cmdBuffer, XGL_BUFFER buffer, XGL_GPU_SIZE offset, uint32_t binding)
Chia-I Wu3b04af52014-11-08 10:48:20 +08002413{
Tobin Ehlis8cced212015-02-13 10:26:14 -07002414 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2415 if (pCB) {
Tobin Ehlis45662712015-02-23 09:06:28 -07002416 g_lastCmdBuffer[getTIDIndex()] = cmdBuffer;
Tobin Ehlisd092d232015-02-13 13:30:07 -07002417 addCmd(pCB, CMD_BINDVERTEXBUFFER);
Tobin Ehlis8cced212015-02-13 10:26:14 -07002418 pCB->lastVtxBinding = binding;
Tobin Ehlis8cced212015-02-13 10:26:14 -07002419 }
2420 else {
2421 char str[1024];
2422 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2423 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2424 }
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002425 nextTable.CmdBindVertexBuffer(cmdBuffer, buffer, offset, binding);
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002426}
2427
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06002428XGL_LAYER_EXPORT void XGLAPI xglCmdDraw(XGL_CMD_BUFFER cmdBuffer, uint32_t firstVertex, uint32_t vertexCount, uint32_t firstInstance, uint32_t instanceCount)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002429{
Tobin Ehlis8cced212015-02-13 10:26:14 -07002430 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2431 if (pCB) {
Tobin Ehlis45662712015-02-23 09:06:28 -07002432 g_lastCmdBuffer[getTIDIndex()] = cmdBuffer;
Tobin Ehlisd092d232015-02-13 13:30:07 -07002433 addCmd(pCB, CMD_DRAW);
Tobin Ehlis8cced212015-02-13 10:26:14 -07002434 pCB->drawCount[DRAW]++;
Tobin Ehlis8cced212015-02-13 10:26:14 -07002435 char str[1024];
2436 sprintf(str, "xglCmdDraw() call #%lu, reporting DS state:", g_drawCount[DRAW]++);
2437 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_NONE, "DS", str);
2438 synchAndPrintDSConfig(cmdBuffer);
2439 }
2440 else {
2441 char str[1024];
2442 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2443 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2444 }
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002445 nextTable.CmdDraw(cmdBuffer, firstVertex, vertexCount, firstInstance, instanceCount);
2446}
2447
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06002448XGL_LAYER_EXPORT void XGLAPI xglCmdDrawIndexed(XGL_CMD_BUFFER cmdBuffer, uint32_t firstIndex, uint32_t indexCount, int32_t vertexOffset, uint32_t firstInstance, uint32_t instanceCount)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002449{
Tobin Ehlis8cced212015-02-13 10:26:14 -07002450 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2451 if (pCB) {
Tobin Ehlis45662712015-02-23 09:06:28 -07002452 g_lastCmdBuffer[getTIDIndex()] = cmdBuffer;
Tobin Ehlisd092d232015-02-13 13:30:07 -07002453 addCmd(pCB, CMD_DRAWINDEXED);
Tobin Ehlis8cced212015-02-13 10:26:14 -07002454 pCB->drawCount[DRAW_INDEXED]++;
Tobin Ehlis8cced212015-02-13 10:26:14 -07002455 char str[1024];
2456 sprintf(str, "xglCmdDrawIndexed() call #%lu, reporting DS state:", g_drawCount[DRAW_INDEXED]++);
2457 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_NONE, "DS", str);
2458 synchAndPrintDSConfig(cmdBuffer);
2459 }
2460 else {
2461 char str[1024];
2462 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2463 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2464 }
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002465 nextTable.CmdDrawIndexed(cmdBuffer, firstIndex, indexCount, vertexOffset, firstInstance, instanceCount);
2466}
2467
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002468XGL_LAYER_EXPORT void XGLAPI xglCmdDrawIndirect(XGL_CMD_BUFFER cmdBuffer, XGL_BUFFER buffer, XGL_GPU_SIZE offset, uint32_t count, uint32_t stride)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002469{
Tobin Ehlis8cced212015-02-13 10:26:14 -07002470 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2471 if (pCB) {
Tobin Ehlis45662712015-02-23 09:06:28 -07002472 g_lastCmdBuffer[getTIDIndex()] = cmdBuffer;
Tobin Ehlisd092d232015-02-13 13:30:07 -07002473 addCmd(pCB, CMD_DRAWINDIRECT);
Tobin Ehlis8cced212015-02-13 10:26:14 -07002474 pCB->drawCount[DRAW_INDIRECT]++;
Tobin Ehlis8cced212015-02-13 10:26:14 -07002475 char str[1024];
2476 sprintf(str, "xglCmdDrawIndirect() call #%lu, reporting DS state:", g_drawCount[DRAW_INDIRECT]++);
2477 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_NONE, "DS", str);
2478 synchAndPrintDSConfig(cmdBuffer);
2479 }
2480 else {
2481 char str[1024];
2482 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2483 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2484 }
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002485 nextTable.CmdDrawIndirect(cmdBuffer, buffer, offset, count, stride);
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002486}
2487
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002488XGL_LAYER_EXPORT void XGLAPI xglCmdDrawIndexedIndirect(XGL_CMD_BUFFER cmdBuffer, XGL_BUFFER buffer, XGL_GPU_SIZE offset, uint32_t count, uint32_t stride)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002489{
Tobin Ehlis8cced212015-02-13 10:26:14 -07002490 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2491 if (pCB) {
Tobin Ehlis45662712015-02-23 09:06:28 -07002492 g_lastCmdBuffer[getTIDIndex()] = cmdBuffer;
Tobin Ehlisd092d232015-02-13 13:30:07 -07002493 addCmd(pCB, CMD_DRAWINDEXEDINDIRECT);
Tobin Ehlis8cced212015-02-13 10:26:14 -07002494 pCB->drawCount[DRAW_INDEXED_INDIRECT]++;
Tobin Ehlis8cced212015-02-13 10:26:14 -07002495 char str[1024];
2496 sprintf(str, "xglCmdDrawIndexedIndirect() call #%lu, reporting DS state:", g_drawCount[DRAW_INDEXED_INDIRECT]++);
2497 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_NONE, "DS", str);
2498 synchAndPrintDSConfig(cmdBuffer);
2499 }
2500 else {
2501 char str[1024];
2502 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2503 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2504 }
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002505 nextTable.CmdDrawIndexedIndirect(cmdBuffer, buffer, offset, count, stride);
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002506}
2507
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06002508XGL_LAYER_EXPORT void XGLAPI xglCmdDispatch(XGL_CMD_BUFFER cmdBuffer, uint32_t x, uint32_t y, uint32_t z)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002509{
Tobin Ehlis8cced212015-02-13 10:26:14 -07002510 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2511 if (pCB) {
Tobin Ehlis45662712015-02-23 09:06:28 -07002512 g_lastCmdBuffer[getTIDIndex()] = cmdBuffer;
Tobin Ehlisd092d232015-02-13 13:30:07 -07002513 addCmd(pCB, CMD_DISPATCH);
Tobin Ehlis8cced212015-02-13 10:26:14 -07002514 }
2515 else {
2516 char str[1024];
2517 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2518 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2519 }
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002520 nextTable.CmdDispatch(cmdBuffer, x, y, z);
2521}
2522
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002523XGL_LAYER_EXPORT void XGLAPI xglCmdDispatchIndirect(XGL_CMD_BUFFER cmdBuffer, XGL_BUFFER buffer, XGL_GPU_SIZE offset)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002524{
Tobin Ehlis8cced212015-02-13 10:26:14 -07002525 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2526 if (pCB) {
Tobin Ehlis45662712015-02-23 09:06:28 -07002527 g_lastCmdBuffer[getTIDIndex()] = cmdBuffer;
Tobin Ehlisd092d232015-02-13 13:30:07 -07002528 addCmd(pCB, CMD_DISPATCHINDIRECT);
Tobin Ehlis8cced212015-02-13 10:26:14 -07002529 }
2530 else {
2531 char str[1024];
2532 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2533 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2534 }
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002535 nextTable.CmdDispatchIndirect(cmdBuffer, buffer, offset);
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002536}
2537
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002538XGL_LAYER_EXPORT void XGLAPI xglCmdCopyBuffer(XGL_CMD_BUFFER cmdBuffer, XGL_BUFFER srcBuffer, XGL_BUFFER destBuffer, uint32_t regionCount, const XGL_BUFFER_COPY* pRegions)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002539{
Tobin Ehlis8cced212015-02-13 10:26:14 -07002540 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2541 if (pCB) {
Tobin Ehlis45662712015-02-23 09:06:28 -07002542 g_lastCmdBuffer[getTIDIndex()] = cmdBuffer;
Tobin Ehlisd092d232015-02-13 13:30:07 -07002543 addCmd(pCB, CMD_COPYBUFFER);
Tobin Ehlis8cced212015-02-13 10:26:14 -07002544 }
2545 else {
2546 char str[1024];
2547 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2548 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2549 }
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002550 nextTable.CmdCopyBuffer(cmdBuffer, srcBuffer, destBuffer, regionCount, pRegions);
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002551}
2552
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06002553XGL_LAYER_EXPORT void XGLAPI xglCmdCopyImage(XGL_CMD_BUFFER cmdBuffer, XGL_IMAGE srcImage, XGL_IMAGE destImage, uint32_t regionCount, const XGL_IMAGE_COPY* pRegions)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002554{
Tobin Ehlis8cced212015-02-13 10:26:14 -07002555 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2556 if (pCB) {
Tobin Ehlis45662712015-02-23 09:06:28 -07002557 g_lastCmdBuffer[getTIDIndex()] = cmdBuffer;
Tobin Ehlisd092d232015-02-13 13:30:07 -07002558 addCmd(pCB, CMD_COPYIMAGE);
Tobin Ehlis8cced212015-02-13 10:26:14 -07002559 }
2560 else {
2561 char str[1024];
2562 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2563 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2564 }
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002565 nextTable.CmdCopyImage(cmdBuffer, srcImage, destImage, regionCount, pRegions);
2566}
2567
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002568XGL_LAYER_EXPORT void XGLAPI xglCmdCopyBufferToImage(XGL_CMD_BUFFER cmdBuffer, XGL_BUFFER srcBuffer, XGL_IMAGE destImage, uint32_t regionCount, const XGL_BUFFER_IMAGE_COPY* pRegions)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002569{
Tobin Ehlis8cced212015-02-13 10:26:14 -07002570 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2571 if (pCB) {
Tobin Ehlis45662712015-02-23 09:06:28 -07002572 g_lastCmdBuffer[getTIDIndex()] = cmdBuffer;
Tobin Ehlisd092d232015-02-13 13:30:07 -07002573 addCmd(pCB, CMD_COPYBUFFERTOIMAGE);
Tobin Ehlis8cced212015-02-13 10:26:14 -07002574 }
2575 else {
2576 char str[1024];
2577 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2578 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2579 }
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002580 nextTable.CmdCopyBufferToImage(cmdBuffer, srcBuffer, destImage, regionCount, pRegions);
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002581}
2582
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002583XGL_LAYER_EXPORT void XGLAPI xglCmdCopyImageToBuffer(XGL_CMD_BUFFER cmdBuffer, XGL_IMAGE srcImage, XGL_BUFFER destBuffer, uint32_t regionCount, const XGL_BUFFER_IMAGE_COPY* pRegions)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002584{
Tobin Ehlis8cced212015-02-13 10:26:14 -07002585 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2586 if (pCB) {
Tobin Ehlis45662712015-02-23 09:06:28 -07002587 g_lastCmdBuffer[getTIDIndex()] = cmdBuffer;
Tobin Ehlisd092d232015-02-13 13:30:07 -07002588 addCmd(pCB, CMD_COPYIMAGETOBUFFER);
Tobin Ehlis8cced212015-02-13 10:26:14 -07002589 }
2590 else {
2591 char str[1024];
2592 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2593 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2594 }
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002595 nextTable.CmdCopyImageToBuffer(cmdBuffer, srcImage, destBuffer, regionCount, pRegions);
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002596}
2597
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06002598XGL_LAYER_EXPORT void XGLAPI xglCmdCloneImageData(XGL_CMD_BUFFER cmdBuffer, XGL_IMAGE srcImage, XGL_IMAGE_LAYOUT srcImageLayout, XGL_IMAGE destImage, XGL_IMAGE_LAYOUT destImageLayout)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002599{
Tobin Ehlis8cced212015-02-13 10:26:14 -07002600 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2601 if (pCB) {
Tobin Ehlis45662712015-02-23 09:06:28 -07002602 g_lastCmdBuffer[getTIDIndex()] = cmdBuffer;
Tobin Ehlisd092d232015-02-13 13:30:07 -07002603 addCmd(pCB, CMD_CLONEIMAGEDATA);
Tobin Ehlis8cced212015-02-13 10:26:14 -07002604 }
2605 else {
2606 char str[1024];
2607 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2608 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2609 }
Mike Stroyan55658c22014-12-04 11:08:39 +00002610 nextTable.CmdCloneImageData(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout);
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002611}
2612
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002613XGL_LAYER_EXPORT void XGLAPI xglCmdUpdateBuffer(XGL_CMD_BUFFER cmdBuffer, XGL_BUFFER destBuffer, XGL_GPU_SIZE destOffset, XGL_GPU_SIZE dataSize, const uint32_t* pData)
2614{
Tobin Ehlis8cced212015-02-13 10:26:14 -07002615 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2616 if (pCB) {
Tobin Ehlis45662712015-02-23 09:06:28 -07002617 g_lastCmdBuffer[getTIDIndex()] = cmdBuffer;
Tobin Ehlisd092d232015-02-13 13:30:07 -07002618 addCmd(pCB, CMD_UPDATEBUFFER);
Tobin Ehlis8cced212015-02-13 10:26:14 -07002619 }
2620 else {
2621 char str[1024];
2622 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2623 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2624 }
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002625 nextTable.CmdUpdateBuffer(cmdBuffer, destBuffer, destOffset, dataSize, pData);
2626}
2627
2628XGL_LAYER_EXPORT void XGLAPI xglCmdFillBuffer(XGL_CMD_BUFFER cmdBuffer, XGL_BUFFER destBuffer, XGL_GPU_SIZE destOffset, XGL_GPU_SIZE fillSize, uint32_t data)
2629{
Tobin Ehlis8cced212015-02-13 10:26:14 -07002630 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2631 if (pCB) {
Tobin Ehlis45662712015-02-23 09:06:28 -07002632 g_lastCmdBuffer[getTIDIndex()] = cmdBuffer;
Tobin Ehlisd092d232015-02-13 13:30:07 -07002633 addCmd(pCB, CMD_FILLBUFFER);
Tobin Ehlis8cced212015-02-13 10:26:14 -07002634 }
2635 else {
2636 char str[1024];
2637 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2638 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2639 }
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002640 nextTable.CmdFillBuffer(cmdBuffer, destBuffer, destOffset, fillSize, data);
2641}
2642
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06002643XGL_LAYER_EXPORT void XGLAPI xglCmdClearColorImage(XGL_CMD_BUFFER cmdBuffer, XGL_IMAGE image, const float color[4], uint32_t rangeCount, const XGL_IMAGE_SUBRESOURCE_RANGE* pRanges)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002644{
Tobin Ehlis8cced212015-02-13 10:26:14 -07002645 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2646 if (pCB) {
Tobin Ehlis45662712015-02-23 09:06:28 -07002647 g_lastCmdBuffer[getTIDIndex()] = cmdBuffer;
Tobin Ehlisd092d232015-02-13 13:30:07 -07002648 addCmd(pCB, CMD_CLEARCOLORIMAGE);
Tobin Ehlis8cced212015-02-13 10:26:14 -07002649 }
2650 else {
2651 char str[1024];
2652 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2653 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2654 }
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002655 nextTable.CmdClearColorImage(cmdBuffer, image, color, rangeCount, pRanges);
2656}
2657
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06002658XGL_LAYER_EXPORT void XGLAPI xglCmdClearColorImageRaw(XGL_CMD_BUFFER cmdBuffer, XGL_IMAGE image, const uint32_t color[4], uint32_t rangeCount, const XGL_IMAGE_SUBRESOURCE_RANGE* pRanges)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002659{
Tobin Ehlis8cced212015-02-13 10:26:14 -07002660 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2661 if (pCB) {
Tobin Ehlis45662712015-02-23 09:06:28 -07002662 g_lastCmdBuffer[getTIDIndex()] = cmdBuffer;
Tobin Ehlisd092d232015-02-13 13:30:07 -07002663 addCmd(pCB, CMD_CLEARCOLORIMAGERAW);
Tobin Ehlis8cced212015-02-13 10:26:14 -07002664 }
2665 else {
2666 char str[1024];
2667 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2668 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2669 }
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002670 nextTable.CmdClearColorImageRaw(cmdBuffer, image, color, rangeCount, pRanges);
2671}
2672
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06002673XGL_LAYER_EXPORT void XGLAPI xglCmdClearDepthStencil(XGL_CMD_BUFFER cmdBuffer, XGL_IMAGE image, float depth, uint32_t stencil, uint32_t rangeCount, const XGL_IMAGE_SUBRESOURCE_RANGE* pRanges)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002674{
Tobin Ehlis8cced212015-02-13 10:26:14 -07002675 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2676 if (pCB) {
Tobin Ehlis45662712015-02-23 09:06:28 -07002677 g_lastCmdBuffer[getTIDIndex()] = cmdBuffer;
Tobin Ehlisd092d232015-02-13 13:30:07 -07002678 addCmd(pCB, CMD_CLEARDEPTHSTENCIL);
Tobin Ehlis8cced212015-02-13 10:26:14 -07002679 }
2680 else {
2681 char str[1024];
2682 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2683 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2684 }
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002685 nextTable.CmdClearDepthStencil(cmdBuffer, image, depth, stencil, rangeCount, pRanges);
2686}
2687
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06002688XGL_LAYER_EXPORT void XGLAPI xglCmdResolveImage(XGL_CMD_BUFFER cmdBuffer, XGL_IMAGE srcImage, XGL_IMAGE destImage, uint32_t rectCount, const XGL_IMAGE_RESOLVE* pRects)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002689{
Tobin Ehlis8cced212015-02-13 10:26:14 -07002690 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2691 if (pCB) {
Tobin Ehlis45662712015-02-23 09:06:28 -07002692 g_lastCmdBuffer[getTIDIndex()] = cmdBuffer;
Tobin Ehlisd092d232015-02-13 13:30:07 -07002693 addCmd(pCB, CMD_RESOLVEIMAGE);
Tobin Ehlis8cced212015-02-13 10:26:14 -07002694 }
2695 else {
2696 char str[1024];
2697 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2698 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2699 }
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002700 nextTable.CmdResolveImage(cmdBuffer, srcImage, destImage, rectCount, pRects);
2701}
2702
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06002703XGL_LAYER_EXPORT void XGLAPI xglCmdSetEvent(XGL_CMD_BUFFER cmdBuffer, XGL_EVENT event, XGL_SET_EVENT pipeEvent)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002704{
Tobin Ehlis8cced212015-02-13 10:26:14 -07002705 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2706 if (pCB) {
Tobin Ehlis45662712015-02-23 09:06:28 -07002707 g_lastCmdBuffer[getTIDIndex()] = cmdBuffer;
Tobin Ehlisd092d232015-02-13 13:30:07 -07002708 addCmd(pCB, CMD_SETEVENT);
Tobin Ehlis8cced212015-02-13 10:26:14 -07002709 }
2710 else {
2711 char str[1024];
2712 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2713 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2714 }
Mike Stroyan55658c22014-12-04 11:08:39 +00002715 nextTable.CmdSetEvent(cmdBuffer, event, pipeEvent);
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002716}
2717
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06002718XGL_LAYER_EXPORT void XGLAPI xglCmdResetEvent(XGL_CMD_BUFFER cmdBuffer, XGL_EVENT event)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002719{
Tobin Ehlis8cced212015-02-13 10:26:14 -07002720 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2721 if (pCB) {
Tobin Ehlis45662712015-02-23 09:06:28 -07002722 g_lastCmdBuffer[getTIDIndex()] = cmdBuffer;
Tobin Ehlisd092d232015-02-13 13:30:07 -07002723 addCmd(pCB, CMD_RESETEVENT);
Tobin Ehlis8cced212015-02-13 10:26:14 -07002724 }
2725 else {
2726 char str[1024];
2727 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2728 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2729 }
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002730 nextTable.CmdResetEvent(cmdBuffer, event);
2731}
2732
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06002733XGL_LAYER_EXPORT void XGLAPI xglCmdWaitEvents(XGL_CMD_BUFFER cmdBuffer, const XGL_EVENT_WAIT_INFO* pWaitInfo)
Mike Stroyan55658c22014-12-04 11:08:39 +00002734{
Tobin Ehlis8cced212015-02-13 10:26:14 -07002735 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2736 if (pCB) {
Tobin Ehlis45662712015-02-23 09:06:28 -07002737 g_lastCmdBuffer[getTIDIndex()] = cmdBuffer;
Tobin Ehlisd092d232015-02-13 13:30:07 -07002738 addCmd(pCB, CMD_WAITEVENTS);
Tobin Ehlis8cced212015-02-13 10:26:14 -07002739 }
2740 else {
2741 char str[1024];
2742 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2743 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2744 }
Mike Stroyan55658c22014-12-04 11:08:39 +00002745 nextTable.CmdWaitEvents(cmdBuffer, pWaitInfo);
2746}
2747
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002748XGL_LAYER_EXPORT void XGLAPI xglCmdPipelineBarrier(XGL_CMD_BUFFER cmdBuffer, const XGL_PIPELINE_BARRIER* pBarrier)
Mike Stroyan55658c22014-12-04 11:08:39 +00002749{
Tobin Ehlis8cced212015-02-13 10:26:14 -07002750 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2751 if (pCB) {
Tobin Ehlis45662712015-02-23 09:06:28 -07002752 g_lastCmdBuffer[getTIDIndex()] = cmdBuffer;
Tobin Ehlisd092d232015-02-13 13:30:07 -07002753 addCmd(pCB, CMD_PIPELINEBARRIER);
Tobin Ehlis8cced212015-02-13 10:26:14 -07002754 }
2755 else {
2756 char str[1024];
2757 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2758 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2759 }
Mike Stroyan55658c22014-12-04 11:08:39 +00002760 nextTable.CmdPipelineBarrier(cmdBuffer, pBarrier);
2761}
2762
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06002763XGL_LAYER_EXPORT void XGLAPI xglCmdBeginQuery(XGL_CMD_BUFFER cmdBuffer, XGL_QUERY_POOL queryPool, uint32_t slot, XGL_FLAGS flags)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002764{
Tobin Ehlis8cced212015-02-13 10:26:14 -07002765 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2766 if (pCB) {
Tobin Ehlis45662712015-02-23 09:06:28 -07002767 g_lastCmdBuffer[getTIDIndex()] = cmdBuffer;
Tobin Ehlisd092d232015-02-13 13:30:07 -07002768 addCmd(pCB, CMD_BEGINQUERY);
Tobin Ehlis8cced212015-02-13 10:26:14 -07002769 }
2770 else {
2771 char str[1024];
2772 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2773 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2774 }
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002775 nextTable.CmdBeginQuery(cmdBuffer, queryPool, slot, flags);
2776}
2777
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06002778XGL_LAYER_EXPORT void XGLAPI xglCmdEndQuery(XGL_CMD_BUFFER cmdBuffer, XGL_QUERY_POOL queryPool, uint32_t slot)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002779{
Tobin Ehlis8cced212015-02-13 10:26:14 -07002780 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2781 if (pCB) {
Tobin Ehlis45662712015-02-23 09:06:28 -07002782 g_lastCmdBuffer[getTIDIndex()] = cmdBuffer;
Tobin Ehlisd092d232015-02-13 13:30:07 -07002783 addCmd(pCB, CMD_ENDQUERY);
Tobin Ehlis8cced212015-02-13 10:26:14 -07002784 }
2785 else {
2786 char str[1024];
2787 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2788 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2789 }
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002790 nextTable.CmdEndQuery(cmdBuffer, queryPool, slot);
2791}
2792
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06002793XGL_LAYER_EXPORT void XGLAPI xglCmdResetQueryPool(XGL_CMD_BUFFER cmdBuffer, XGL_QUERY_POOL queryPool, uint32_t startQuery, uint32_t queryCount)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002794{
Tobin Ehlis8cced212015-02-13 10:26:14 -07002795 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2796 if (pCB) {
Tobin Ehlis45662712015-02-23 09:06:28 -07002797 g_lastCmdBuffer[getTIDIndex()] = cmdBuffer;
Tobin Ehlisd092d232015-02-13 13:30:07 -07002798 addCmd(pCB, CMD_RESETQUERYPOOL);
Tobin Ehlis8cced212015-02-13 10:26:14 -07002799 }
2800 else {
2801 char str[1024];
2802 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2803 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2804 }
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002805 nextTable.CmdResetQueryPool(cmdBuffer, queryPool, startQuery, queryCount);
2806}
2807
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002808XGL_LAYER_EXPORT void XGLAPI xglCmdWriteTimestamp(XGL_CMD_BUFFER cmdBuffer, XGL_TIMESTAMP_TYPE timestampType, XGL_BUFFER destBuffer, XGL_GPU_SIZE destOffset)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002809{
Tobin Ehlis8cced212015-02-13 10:26:14 -07002810 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2811 if (pCB) {
Tobin Ehlis45662712015-02-23 09:06:28 -07002812 g_lastCmdBuffer[getTIDIndex()] = cmdBuffer;
Tobin Ehlisd092d232015-02-13 13:30:07 -07002813 addCmd(pCB, CMD_WRITETIMESTAMP);
Tobin Ehlis8cced212015-02-13 10:26:14 -07002814 }
2815 else {
2816 char str[1024];
2817 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2818 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2819 }
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002820 nextTable.CmdWriteTimestamp(cmdBuffer, timestampType, destBuffer, destOffset);
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002821}
2822
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06002823XGL_LAYER_EXPORT void XGLAPI xglCmdInitAtomicCounters(XGL_CMD_BUFFER cmdBuffer, XGL_PIPELINE_BIND_POINT pipelineBindPoint, uint32_t startCounter, uint32_t counterCount, const uint32_t* pData)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002824{
Tobin Ehlis8cced212015-02-13 10:26:14 -07002825 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2826 if (pCB) {
Tobin Ehlis45662712015-02-23 09:06:28 -07002827 g_lastCmdBuffer[getTIDIndex()] = cmdBuffer;
Tobin Ehlisd092d232015-02-13 13:30:07 -07002828 addCmd(pCB, CMD_INITATOMICCOUNTERS);
Tobin Ehlis8cced212015-02-13 10:26:14 -07002829 }
2830 else {
2831 char str[1024];
2832 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2833 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2834 }
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002835 nextTable.CmdInitAtomicCounters(cmdBuffer, pipelineBindPoint, startCounter, counterCount, pData);
2836}
2837
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002838XGL_LAYER_EXPORT void XGLAPI xglCmdLoadAtomicCounters(XGL_CMD_BUFFER cmdBuffer, XGL_PIPELINE_BIND_POINT pipelineBindPoint, uint32_t startCounter, uint32_t counterCount, XGL_BUFFER srcBuffer, XGL_GPU_SIZE srcOffset)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002839{
Tobin Ehlis8cced212015-02-13 10:26:14 -07002840 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2841 if (pCB) {
Tobin Ehlis45662712015-02-23 09:06:28 -07002842 g_lastCmdBuffer[getTIDIndex()] = cmdBuffer;
Tobin Ehlisd092d232015-02-13 13:30:07 -07002843 addCmd(pCB, CMD_LOADATOMICCOUNTERS);
Tobin Ehlis8cced212015-02-13 10:26:14 -07002844 }
2845 else {
2846 char str[1024];
2847 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2848 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2849 }
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002850 nextTable.CmdLoadAtomicCounters(cmdBuffer, pipelineBindPoint, startCounter, counterCount, srcBuffer, srcOffset);
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002851}
2852
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002853XGL_LAYER_EXPORT void XGLAPI xglCmdSaveAtomicCounters(XGL_CMD_BUFFER cmdBuffer, XGL_PIPELINE_BIND_POINT pipelineBindPoint, uint32_t startCounter, uint32_t counterCount, XGL_BUFFER destBuffer, XGL_GPU_SIZE destOffset)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002854{
Tobin Ehlis8cced212015-02-13 10:26:14 -07002855 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2856 if (pCB) {
Tobin Ehlis45662712015-02-23 09:06:28 -07002857 g_lastCmdBuffer[getTIDIndex()] = cmdBuffer;
Tobin Ehlisd092d232015-02-13 13:30:07 -07002858 addCmd(pCB, CMD_SAVEATOMICCOUNTERS);
Tobin Ehlis8cced212015-02-13 10:26:14 -07002859 }
2860 else {
2861 char str[1024];
2862 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2863 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2864 }
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002865 nextTable.CmdSaveAtomicCounters(cmdBuffer, pipelineBindPoint, startCounter, counterCount, destBuffer, destOffset);
2866}
2867
2868XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateFramebuffer(XGL_DEVICE device, const XGL_FRAMEBUFFER_CREATE_INFO* pCreateInfo, XGL_FRAMEBUFFER* pFramebuffer)
2869{
2870 XGL_RESULT result = nextTable.CreateFramebuffer(device, pCreateInfo, pFramebuffer);
2871 return result;
2872}
2873
2874XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateRenderPass(XGL_DEVICE device, const XGL_RENDER_PASS_CREATE_INFO* pCreateInfo, XGL_RENDER_PASS* pRenderPass)
2875{
2876 XGL_RESULT result = nextTable.CreateRenderPass(device, pCreateInfo, pRenderPass);
2877 return result;
2878}
2879
2880XGL_LAYER_EXPORT void XGLAPI xglCmdBeginRenderPass(XGL_CMD_BUFFER cmdBuffer, XGL_RENDER_PASS renderPass)
2881{
Tobin Ehlis8cced212015-02-13 10:26:14 -07002882 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2883 if (pCB) {
Tobin Ehlis45662712015-02-23 09:06:28 -07002884 g_lastCmdBuffer[getTIDIndex()] = cmdBuffer;
Tobin Ehlisd092d232015-02-13 13:30:07 -07002885 addCmd(pCB, CMD_BEGINRENDERPASS);
Tobin Ehlis8cced212015-02-13 10:26:14 -07002886 }
2887 else {
2888 char str[1024];
2889 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2890 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2891 }
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002892 nextTable.CmdBeginRenderPass(cmdBuffer, renderPass);
2893}
2894
2895XGL_LAYER_EXPORT void XGLAPI xglCmdEndRenderPass(XGL_CMD_BUFFER cmdBuffer, XGL_RENDER_PASS renderPass)
2896{
Tobin Ehlis8cced212015-02-13 10:26:14 -07002897 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2898 if (pCB) {
Tobin Ehlis45662712015-02-23 09:06:28 -07002899 g_lastCmdBuffer[getTIDIndex()] = cmdBuffer;
Tobin Ehlisd092d232015-02-13 13:30:07 -07002900 addCmd(pCB, CMD_ENDRENDERPASS);
Tobin Ehlis8cced212015-02-13 10:26:14 -07002901 }
2902 else {
2903 char str[1024];
2904 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2905 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2906 }
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002907 nextTable.CmdEndRenderPass(cmdBuffer, renderPass);
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002908}
2909
2910XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglDbgSetValidationLevel(XGL_DEVICE device, XGL_VALIDATION_LEVEL validationLevel)
2911{
2912 XGL_RESULT result = nextTable.DbgSetValidationLevel(device, validationLevel);
2913 return result;
2914}
2915
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06002916XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglDbgRegisterMsgCallback(XGL_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback, void* pUserData)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002917{
Tobin Ehlise79df942014-11-18 16:38:08 -07002918 // This layer intercepts callbacks
Tobin Ehlis8614b8d2015-02-17 16:27:03 -07002919 XGL_LAYER_DBG_FUNCTION_NODE* pNewDbgFuncNode = (XGL_LAYER_DBG_FUNCTION_NODE*)malloc(sizeof(XGL_LAYER_DBG_FUNCTION_NODE));
2920#if ALLOC_DEBUG
2921 printf("Alloc34 #%lu pNewDbgFuncNode addr(%p)\n", ++g_alloc_count, (void*)pNewDbgFuncNode);
2922#endif
Tobin Ehlise79df942014-11-18 16:38:08 -07002923 if (!pNewDbgFuncNode)
2924 return XGL_ERROR_OUT_OF_MEMORY;
2925 pNewDbgFuncNode->pfnMsgCallback = pfnMsgCallback;
2926 pNewDbgFuncNode->pUserData = pUserData;
Jon Ashburn2e9b5612014-12-22 13:38:27 -07002927 pNewDbgFuncNode->pNext = g_pDbgFunctionHead;
2928 g_pDbgFunctionHead = pNewDbgFuncNode;
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002929 XGL_RESULT result = nextTable.DbgRegisterMsgCallback(pfnMsgCallback, pUserData);
2930 return result;
2931}
2932
2933XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglDbgUnregisterMsgCallback(XGL_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback)
2934{
Jon Ashburn2e9b5612014-12-22 13:38:27 -07002935 XGL_LAYER_DBG_FUNCTION_NODE *pTrav = g_pDbgFunctionHead;
Tobin Ehlise79df942014-11-18 16:38:08 -07002936 XGL_LAYER_DBG_FUNCTION_NODE *pPrev = pTrav;
2937 while (pTrav) {
2938 if (pTrav->pfnMsgCallback == pfnMsgCallback) {
2939 pPrev->pNext = pTrav->pNext;
Jon Ashburn2e9b5612014-12-22 13:38:27 -07002940 if (g_pDbgFunctionHead == pTrav)
2941 g_pDbgFunctionHead = pTrav->pNext;
Tobin Ehlis8614b8d2015-02-17 16:27:03 -07002942#if ALLOC_DEBUG
2943 printf("Free34 #%lu pNewDbgFuncNode addr(%p)\n", ++g_alloc_count, (void*)pTrav);
2944#endif
Tobin Ehlise79df942014-11-18 16:38:08 -07002945 free(pTrav);
2946 break;
2947 }
2948 pPrev = pTrav;
2949 pTrav = pTrav->pNext;
2950 }
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002951 XGL_RESULT result = nextTable.DbgUnregisterMsgCallback(pfnMsgCallback);
2952 return result;
2953}
2954
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06002955XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglDbgSetMessageFilter(XGL_DEVICE device, int32_t msgCode, XGL_DBG_MSG_FILTER filter)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002956{
2957 XGL_RESULT result = nextTable.DbgSetMessageFilter(device, msgCode, filter);
2958 return result;
2959}
2960
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06002961XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglDbgSetObjectTag(XGL_BASE_OBJECT object, size_t tagSize, const void* pTag)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002962{
2963 XGL_RESULT result = nextTable.DbgSetObjectTag(object, tagSize, pTag);
2964 return result;
2965}
2966
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06002967XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglDbgSetGlobalOption(XGL_DBG_GLOBAL_OPTION dbgOption, size_t dataSize, const void* pData)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002968{
2969 XGL_RESULT result = nextTable.DbgSetGlobalOption(dbgOption, dataSize, pData);
2970 return result;
2971}
2972
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06002973XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglDbgSetDeviceOption(XGL_DEVICE device, XGL_DBG_DEVICE_OPTION dbgOption, size_t dataSize, const void* pData)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002974{
2975 XGL_RESULT result = nextTable.DbgSetDeviceOption(device, dbgOption, dataSize, pData);
2976 return result;
2977}
2978
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06002979XGL_LAYER_EXPORT void XGLAPI xglCmdDbgMarkerBegin(XGL_CMD_BUFFER cmdBuffer, const char* pMarker)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002980{
2981 nextTable.CmdDbgMarkerBegin(cmdBuffer, pMarker);
2982}
2983
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06002984XGL_LAYER_EXPORT void XGLAPI xglCmdDbgMarkerEnd(XGL_CMD_BUFFER cmdBuffer)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002985{
2986 nextTable.CmdDbgMarkerEnd(cmdBuffer);
2987}
2988
Ian Elliott81ac44c2015-01-13 17:52:38 -07002989#if defined(WIN32)
2990// FIXME: NEED WINDOWS EQUIVALENT
2991#else // WIN32
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002992XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglWsiX11AssociateConnection(XGL_PHYSICAL_GPU gpu, const XGL_WSI_X11_CONNECTION_INFO* pConnectionInfo)
2993{
2994 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002995 pCurObj = gpuw;
Ian Elliott81ac44c2015-01-13 17:52:38 -07002996 loader_platform_thread_once(&g_initOnce, initDrawState);
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002997 XGL_RESULT result = nextTable.WsiX11AssociateConnection((XGL_PHYSICAL_GPU)gpuw->nextObject, pConnectionInfo);
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06002998 return result;
2999}
3000
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06003001XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglWsiX11GetMSC(XGL_DEVICE device, xcb_window_t window, xcb_randr_crtc_t crtc, uint64_t* pMsc)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06003002{
Chia-I Wu6204f342014-11-07 13:33:45 +08003003 XGL_RESULT result = nextTable.WsiX11GetMSC(device, window, crtc, pMsc);
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06003004 return result;
3005}
3006
3007XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglWsiX11CreatePresentableImage(XGL_DEVICE device, const XGL_WSI_X11_PRESENTABLE_IMAGE_CREATE_INFO* pCreateInfo, XGL_IMAGE* pImage, XGL_GPU_MEMORY* pMem)
3008{
3009 XGL_RESULT result = nextTable.WsiX11CreatePresentableImage(device, pCreateInfo, pImage, pMem);
3010 return result;
3011}
3012
3013XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglWsiX11QueuePresent(XGL_QUEUE queue, const XGL_WSI_X11_PRESENT_INFO* pPresentInfo, XGL_FENCE fence)
3014{
3015 XGL_RESULT result = nextTable.WsiX11QueuePresent(queue, pPresentInfo, fence);
3016 return result;
3017}
Ian Elliott81ac44c2015-01-13 17:52:38 -07003018#endif // WIN32
Tobin Ehlis8cced212015-02-13 10:26:14 -07003019// TODO : Want to pass in a cmdBuffer here based on which state to display
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06003020void drawStateDumpDotFile(char* outFileName)
Tobin Ehlisa701ef02014-11-27 15:43:39 -07003021{
Tobin Ehlis8cced212015-02-13 10:26:14 -07003022 // TODO : Currently just setting cmdBuffer based on global var
Tobin Ehlis45662712015-02-23 09:06:28 -07003023 dumpDotFile(g_lastCmdBuffer[getTIDIndex()], outFileName);
Tobin Ehlisa701ef02014-11-27 15:43:39 -07003024}
3025
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06003026void drawStateDumpPngFile(char* outFileName)
Tobin Ehlis266473d2014-12-16 17:34:50 -07003027{
Ian Elliott81ac44c2015-01-13 17:52:38 -07003028#if defined(_WIN32)
3029// FIXME: NEED WINDOWS EQUIVALENT
3030 char str[1024];
3031 sprintf(str, "Cannot execute dot program yet on Windows.");
3032 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_MISSING_DOT_PROGRAM, "DS", str);
3033#else // WIN32
Tobin Ehlis266473d2014-12-16 17:34:50 -07003034 char dotExe[32] = "/usr/bin/dot";
3035 if( access(dotExe, X_OK) != -1) {
Tobin Ehlis45662712015-02-23 09:06:28 -07003036 dumpDotFile(g_lastCmdBuffer[getTIDIndex()], "/tmp/tmp.dot");
Tobin Ehlis266473d2014-12-16 17:34:50 -07003037 char dotCmd[1024];
3038 sprintf(dotCmd, "%s /tmp/tmp.dot -Tpng -o %s", dotExe, outFileName);
3039 system(dotCmd);
3040 remove("/tmp/tmp.dot");
3041 }
3042 else {
3043 char str[1024];
3044 sprintf(str, "Cannot execute dot program at (%s) to dump requested %s file.", dotExe, outFileName);
3045 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_MISSING_DOT_PROGRAM, "DS", str);
3046 }
Ian Elliott81ac44c2015-01-13 17:52:38 -07003047#endif // WIN32
Tobin Ehlis266473d2014-12-16 17:34:50 -07003048}
3049
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06003050XGL_LAYER_EXPORT void* XGLAPI xglGetProcAddr(XGL_PHYSICAL_GPU gpu, const char* funcName)
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06003051{
3052 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
Chia-I Wu706533e2015-01-05 13:18:57 +08003053 void *addr;
3054
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06003055 if (gpu == NULL)
3056 return NULL;
3057 pCurObj = gpuw;
Ian Elliott81ac44c2015-01-13 17:52:38 -07003058 loader_platform_thread_once(&g_initOnce, initDrawState);
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06003059
Chia-I Wu706533e2015-01-05 13:18:57 +08003060 addr = layer_intercept_proc(funcName);
3061 if (addr)
3062 return addr;
Chia-I Wu7461fcf2014-12-27 15:16:07 +08003063 else if (!strncmp("drawStateDumpDotFile", funcName, sizeof("drawStateDumpDotFile")))
Tobin Ehlisa701ef02014-11-27 15:43:39 -07003064 return drawStateDumpDotFile;
Chia-I Wu7461fcf2014-12-27 15:16:07 +08003065 else if (!strncmp("drawStateDumpPngFile", funcName, sizeof("drawStateDumpPngFile")))
Tobin Ehlis266473d2014-12-16 17:34:50 -07003066 return drawStateDumpPngFile;
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06003067 else {
Tobin Ehlis8726b9f2014-10-24 12:01:45 -06003068 if (gpuw->pGPA == NULL)
3069 return NULL;
3070 return gpuw->pGPA(gpuw->nextObject, funcName);
3071 }
3072}