blob: 8084e8fd1d2d4468adb5edd3949a6ba272b7d73f [file] [log] [blame]
Tobin Ehlis6663f492014-11-10 12:29:12 -07001/*
2 * XGL
3 *
4 * Copyright (C) 2014 LunarG, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -050025#include <inttypes.h>
Tobin Ehlis6663f492014-11-10 12:29:12 -070026#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29#include <assert.h>
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070030#include "loader_platform.h"
Chia-I Wuaa4121f2015-01-04 23:11:43 +080031#include "xgl_dispatch_table_helper.h"
Tobin Ehlis6663f492014-11-10 12:29:12 -070032#include "xgl_struct_string_helper.h"
Tobin Ehliscd9223b2014-11-19 16:19:28 -070033#include "mem_tracker.h"
Jon Ashburn7d7b3cf2014-12-22 13:24:15 -070034#include "layers_config.h"
Ian Elliott655cad72015-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 Ashburn2e672892015-02-16 08:46:53 -070038#include "layers_msg.h"
Tobin Ehlis6663f492014-11-10 12:29:12 -070039
40static XGL_LAYER_DISPATCH_TABLE nextTable;
41static XGL_BASE_LAYER_OBJECT *pCurObj;
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070042static LOADER_PLATFORM_THREAD_ONCE_DECLARATION(g_initOnce);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -060043// TODO : This can be much smarter, using separate locks for separate global data
44static int globalLockInitialized = 0;
45static loader_platform_thread_mutex globalLock;
Jon Ashburn7d7b3cf2014-12-22 13:24:15 -070046
Jon Ashburn7d7b3cf2014-12-22 13:24:15 -070047
Tobin Ehlisc145be82015-01-08 15:22:32 -070048#define MAX_BINDING 0xFFFFFFFF
Tobin Ehlisc145be82015-01-08 15:22:32 -070049
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -050050static GLOBAL_CB_NODE* pGlobalCBHead = NULL;
Tobin Ehlis6663f492014-11-10 12:29:12 -070051static GLOBAL_MEM_OBJ_NODE* pGlobalMemObjHead = NULL;
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -050052static GLOBAL_OBJECT_NODE* pGlobalObjectHead = NULL;
53static GLOBAL_FENCE_NODE* pGlobalFenceList = NULL;
54// TODO : Add support for per-queue and per-device fence completion
55static uint64_t g_currentFenceId = 1;
56static uint64_t g_lastRetiredId = 0;
57static XGL_DEVICE globalDevice = NULL;
58static uint64_t numCBNodes = 0;
59static uint64_t numMemObjNodes = 0;
60static uint64_t numObjectNodes = 0;
Mark Lobodzinskic52b7752015-02-18 16:38:17 -060061
Tobin Ehlis6663f492014-11-10 12:29:12 -070062// Check list for data and if it's not included insert new node
63// into HEAD of list pointed to by pHEAD & update pHEAD
Tobin Ehliscd9223b2014-11-19 16:19:28 -070064// Increment 'insert' if new node was inserted
Tobin Ehlis6663f492014-11-10 12:29:12 -070065// return XGL_SUCCESS if no errors occur
Mark Lobodzinski93f494b2015-03-02 20:23:52 -060066static bool32_t insertMiniNode(MINI_NODE** pHEAD, const XGL_BASE_OBJECT data, uint32_t* insert)
Tobin Ehlis6663f492014-11-10 12:29:12 -070067{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -060068 bool32_t result = XGL_TRUE;
Tobin Ehlis6663f492014-11-10 12:29:12 -070069 MINI_NODE* pTrav = *pHEAD;
70 while (pTrav && (pTrav->data != data)) {
71 pTrav = pTrav->pNext;
72 }
73 if (!pTrav) { // Add node to front of LL
74 pTrav = (MINI_NODE*)malloc(sizeof(MINI_NODE));
Mark Lobodzinski93f494b2015-03-02 20:23:52 -060075 if (!pTrav) {
76 char str[1024];
77 sprintf(str, "Malloc failed to alloc memory for Mini Node");
78 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, data, 0, MEMTRACK_OUT_OF_MEMORY_ERROR, "MEM", str);
79 result = XGL_FALSE;
80 } else {
81 memset(pTrav, 0, sizeof(MINI_NODE));
82 if (*pHEAD) {
83 pTrav->pNext = *pHEAD;
84 }
85 *pHEAD = pTrav;
86 *insert += 1;
87 //pMemTrav->refCount++;
88 //sprintf(str, "MEM INFO : Incremented refCount for mem obj %p to %u", (void*)mem, pMemTrav->refCount);
89 if (pTrav->data) { // This is just FYI
90 assert(data == pTrav->data);
91 char str[1024];
92 sprintf(str, "Data %p is already in data LL w/ HEAD at %p", data, *pHEAD);
93 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, data, 0, MEMTRACK_NONE, "MEM", str);
94 }
95 pTrav->data = data;
96 }
97 } else {
98 pTrav->data = data;
Tobin Ehlis6663f492014-11-10 12:29:12 -070099 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600100 return result;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700101}
102
103// Add new CB node for this cb at end of global CB LL
104static void insertGlobalCB(const XGL_CMD_BUFFER cb)
105{
106 GLOBAL_CB_NODE* pTrav = pGlobalCBHead;
107 if (!pTrav) {
108 pTrav = (GLOBAL_CB_NODE*)malloc(sizeof(GLOBAL_CB_NODE));
109 pGlobalCBHead = pTrav;
110 }
111 else {
112 while (NULL != pTrav->pNextGlobalCBNode)
113 pTrav = pTrav->pNextGlobalCBNode;
114 pTrav->pNextGlobalCBNode = (GLOBAL_CB_NODE*)malloc(sizeof(GLOBAL_CB_NODE));
115 pTrav = pTrav->pNextGlobalCBNode;
116 }
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700117 if (!pTrav) {
118 char str[1024];
119 sprintf(str, "Malloc failed to alloc node for Cmd Buffer %p", (void*)cb);
120 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_OUT_OF_MEMORY_ERROR, "MEM", str);
121 }
122 else {
123 numCBNodes++;
124 memset(pTrav, 0, sizeof(GLOBAL_CB_NODE));
125 pTrav->cmdBuffer = cb;
126 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700127}
128
129// Return ptr to node in global LL containing cb, or NULL if not found
130static GLOBAL_CB_NODE* getGlobalCBNode(const XGL_CMD_BUFFER cb)
131{
132 GLOBAL_CB_NODE* pTrav = pGlobalCBHead;
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600133 while (pTrav && (pTrav->cmdBuffer != cb)) {
Tobin Ehlis6663f492014-11-10 12:29:12 -0700134 pTrav = pTrav->pNextGlobalCBNode;
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600135 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700136 return pTrav;
137}
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600138
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -0500139// Add a fence, creating one if necessary to our list of fences/fenceIds
140// Linked list is FIFO: head = oldest, tail = newest
141static uint64_t addFenceNode(XGL_FENCE fence)
142{
143 // Create fence node
144 GLOBAL_FENCE_NODE* pFenceNode = (GLOBAL_FENCE_NODE*)malloc(sizeof(GLOBAL_FENCE_NODE));
145 memset(pFenceNode, 0, sizeof(GLOBAL_FENCE_NODE));
146 pFenceNode->fenceId = g_currentFenceId++;
147 // If no fence, create an internal fence to track the submissions
148 if (fence == NULL) {
149 XGL_FENCE_CREATE_INFO fci;
150 fci.sType = XGL_STRUCTURE_TYPE_FENCE_CREATE_INFO;
151 fci.pNext = NULL;
152 fci.flags = 0;
153 nextTable.CreateFence(globalDevice, &fci, &pFenceNode->fence);
154 pFenceNode->localFence = XGL_TRUE;
155 } else {
156 pFenceNode->localFence = XGL_FALSE;
157 pFenceNode->fence = fence;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700158 }
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -0500159
160 // Add to END of fence list
161 if (pGlobalFenceList == NULL) {
162 pGlobalFenceList = pFenceNode;
163 } else {
164 GLOBAL_FENCE_NODE* pCurFenceNode = pGlobalFenceList;
165 while (pCurFenceNode && pCurFenceNode->pNextGlobalFenceNode != NULL) {
166 pCurFenceNode = pCurFenceNode->pNextGlobalFenceNode;
167 }
168 pCurFenceNode->pNextGlobalFenceNode = pFenceNode;
169 }
170
171 return pFenceNode->fenceId;
172}
173
174// Remove a node from our list of fences/fenceIds
175static void deleteFenceNode(uint64_t fenceId)
176{
177 if (fenceId != 0) {
178 // Search for a node with this fenceId
179 GLOBAL_FENCE_NODE* pCurFenceNode = pGlobalFenceList;
180 GLOBAL_FENCE_NODE* pPrevFenceNode = pCurFenceNode;
181 while ((pCurFenceNode != NULL) && (pCurFenceNode->fenceId != fenceId)) {
182 pPrevFenceNode = pCurFenceNode;
183 pCurFenceNode = pCurFenceNode->pNextGlobalFenceNode;
184 }
185 if (pCurFenceNode != NULL) {
186 // TODO: Wait on this fence?
187 if (pCurFenceNode->localFence == XGL_TRUE) {
188 nextTable.DestroyObject(pCurFenceNode->fence);
189 }
190 // Remove links to this node
191 pPrevFenceNode->pNextGlobalFenceNode = pCurFenceNode->pNextGlobalFenceNode;
192 // Update head pointer if necessary
193 if (pCurFenceNode == pGlobalFenceList) {
194 pGlobalFenceList = pCurFenceNode->pNextGlobalFenceNode;
195 }
196 free(pCurFenceNode);
197 } else {
198 char str[1024];
199 sprintf(str, "FenceId %"PRIx64" node is missing from global fence list", fenceId);
200 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_CB_MISSING_FENCE, "MEM", str);
201 }
202 }
203}
204
205// Search through list for this fence, deleting all nodes before it (with lower IDs) and updating lastRetiredId
206static void updateFenceTracking(XGL_FENCE fence)
207{
208 // Technically, we can delete all nodes until we hit this fence. But for now, make sure they're in the list first.
209 GLOBAL_FENCE_NODE* pCurFenceNode = pGlobalFenceList;
210 while ((pCurFenceNode != NULL) && (pCurFenceNode->fence != fence)) {
211 pCurFenceNode = pCurFenceNode->pNextGlobalFenceNode;
212 }
213 if (pCurFenceNode != NULL) {
214 // Delete all nodes in front of this one and update the global last retired value
215 GLOBAL_FENCE_NODE* pDelNode = NULL;
216 g_lastRetiredId = pCurFenceNode->fenceId;
217 pCurFenceNode = pGlobalFenceList;
218 while ((pCurFenceNode != NULL) && (pCurFenceNode->fence != fence)) {
219 pDelNode = pCurFenceNode;
220 pCurFenceNode = pCurFenceNode->pNextGlobalFenceNode;
221 deleteFenceNode(pDelNode->fenceId);
222 }
223 }
224}
225
226// Utility function that determines if a fenceId has been retired yet
227static bool32_t fenceRetired(uint64_t fenceId)
228{
229 bool32_t result = XGL_FALSE;
230 if (fenceId <= g_lastRetiredId) {
231 result = XGL_TRUE;
232 }
233 return result;
234}
235
236// Return the fence associated with a fenceId
237static XGL_FENCE getFenceFromId(uint64_t fenceId)
238{
239 XGL_FENCE fence = NULL;
240 if (fenceId != 0) {
241 // Search for a node with this fenceId
242 if (fenceId > g_lastRetiredId) {
243 GLOBAL_FENCE_NODE* pCurFenceNode = pGlobalFenceList;
244 while ((pCurFenceNode != NULL) && (pCurFenceNode->fenceId != fenceId)) {
245 pCurFenceNode = pCurFenceNode->pNextGlobalFenceNode;
246 }
247 if (pCurFenceNode != NULL) {
248 fence = pCurFenceNode->fence;
249 } else {
250 char str[1024];
251 sprintf(str, "Dangit, couldn't find fenceId %"PRIx64" in the list", fenceId);
252 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_CB_MISSING_FENCE, "MEM", str);
253 }
254 }
255 }
256 return fence;
257}
258
259// Helper routine that updates the fence list to all-retired, as for Queue/DeviceWaitIdle
260static void retireAllFences(void)
261{
262 // In this case, we go throught the whole list, retiring each node and update the global retired ID until the list is empty
263 GLOBAL_FENCE_NODE* pCurFenceNode = pGlobalFenceList;
264 GLOBAL_FENCE_NODE* pDelNode = NULL;
265
266 while (pCurFenceNode != NULL) {
267 pDelNode = pCurFenceNode;
268 pCurFenceNode = pCurFenceNode->pNextGlobalFenceNode;
269 g_lastRetiredId = pDelNode->fenceId;
270 deleteFenceNode(pDelNode->fenceId);
271 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700272}
273
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600274static bool32_t validateCBMemRef(const XGL_CMD_BUFFER cb, uint32_t memRefCount, const XGL_MEMORY_REF* pMemRefs)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700275{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600276 bool32_t result = XGL_TRUE;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700277 GLOBAL_CB_NODE* pTrav = getGlobalCBNode(cb);
278 if (!pTrav) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700279 char str[1024];
280 sprintf(str, "Unable to find node for CB %p in order to check memory references", (void*)cb);
281 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_INVALID_CB, "MEM", str);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600282 result = XGL_FALSE;
283 } else {
284 // Validate that all actual references are accounted for in pMemRefs
285 MINI_NODE* pMemNode = pTrav->pMemObjList;
286 uint32_t i;
287 uint8_t found = 0;
288 uint64_t foundCount = 0;
289 while (pMemNode && (result == XGL_TRUE)) {
290 // TODO : Improve this algorithm
291 for (i = 0; i < memRefCount; i++) {
292 if (pMemNode->mem == pMemRefs[i].mem) {
293 char str[1024];
294 sprintf(str, "Found Mem Obj %p binding to CB %p", pMemNode->mem, cb);
295 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_NONE, "MEM", str);
296 found = 1;
297 foundCount++;
298 break;
299 }
300 }
301 if (!found) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700302 char str[1024];
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600303 sprintf(str, "Memory reference list for Command Buffer %p is missing ref to mem obj %p", cb, pMemNode->mem);
304 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_CB_MISSING_MEM_REF, "MEM", str);
305 result = XGL_FALSE;
306 }
307 found = 0;
308 pMemNode = pMemNode->pNext;
309 }
310 if (result == XGL_TRUE) {
311 char str[1024];
312 sprintf(str, "Verified all %lu memory dependencies for CB %p are included in pMemRefs list", foundCount, cb);
313 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_NONE, "MEM", str);
314 // TODO : Could report mem refs in pMemRefs that AREN'T in mem LL, that would be primarily informational
315 // Currently just noting that there is a difference
316 if (foundCount != memRefCount) {
317 sprintf(str, "There are %u mem refs included in pMemRefs list, but only %lu appear are required", memRefCount, foundCount);
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700318 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700319 }
320 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700321 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600322 return result;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700323}
Tobin Ehlisc145be82015-01-08 15:22:32 -0700324// Return ptr to node in global LL containing mem, or NULL if not found
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -0700325// Calls to this function should be wrapped in mutex
Tobin Ehlisc145be82015-01-08 15:22:32 -0700326static GLOBAL_MEM_OBJ_NODE* getGlobalMemNode(const XGL_GPU_MEMORY mem)
327{
328 GLOBAL_MEM_OBJ_NODE* pTrav = pGlobalMemObjHead;
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600329 while (pTrav && (pTrav->mem != mem)) {
Tobin Ehlisc145be82015-01-08 15:22:32 -0700330 pTrav = pTrav->pNextGlobalNode;
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600331 }
Tobin Ehlisc145be82015-01-08 15:22:32 -0700332 return pTrav;
333}
334
Mark Lobodzinskic52b7752015-02-18 16:38:17 -0600335static void insertGlobalMemObj(const XGL_GPU_MEMORY mem, const XGL_MEMORY_ALLOC_INFO* pAllocInfo)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700336{
337 GLOBAL_MEM_OBJ_NODE* pTrav = pGlobalMemObjHead;
338 if (!pTrav) {
339 pTrav = (GLOBAL_MEM_OBJ_NODE*)malloc(sizeof(GLOBAL_MEM_OBJ_NODE));
340 pGlobalMemObjHead = pTrav;
341 }
342 else {
343 while (NULL != pTrav->pNextGlobalNode)
344 pTrav = pTrav->pNextGlobalNode;
345 pTrav->pNextGlobalNode = (GLOBAL_MEM_OBJ_NODE*)malloc(sizeof(GLOBAL_MEM_OBJ_NODE));
346 pTrav = pTrav->pNextGlobalNode;
347 }
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700348 if (!pTrav) {
349 char str[1024];
350 sprintf(str, "Malloc failed to alloc node for Mem Object %p", (void*)mem);
351 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_OUT_OF_MEMORY_ERROR, "MEM", str);
352 }
353 else {
354 numMemObjNodes++;
355 memset(pTrav, 0, sizeof(GLOBAL_MEM_OBJ_NODE));
Mark Lobodzinskic52b7752015-02-18 16:38:17 -0600356 if (pAllocInfo) { // MEM alloc created by xglWsiX11CreatePresentableImage() doesn't have alloc info struct
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700357 memcpy(&pTrav->allocInfo, pAllocInfo, sizeof(XGL_MEMORY_ALLOC_INFO));
Mark Lobodzinskic52b7752015-02-18 16:38:17 -0600358 // TODO: Update for real hardware, actually process allocation info structures
359 pTrav->allocInfo.pNext = NULL;
Tobin Ehlisc145be82015-01-08 15:22:32 -0700360 }
Mark Lobodzinskic52b7752015-02-18 16:38:17 -0600361 pTrav->mem = mem;
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700362 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700363}
364
Tobin Ehlis6663f492014-11-10 12:29:12 -0700365// Find Global CB Node and add mem binding to mini LL
366// Find Global Mem Obj Node and add CB binding to mini LL
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600367static bool32_t updateCBBinding(const XGL_CMD_BUFFER cb, const XGL_GPU_MEMORY mem)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700368{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600369 bool32_t result = XGL_FALSE;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700370 // First update CB binding in MemObj mini CB list
371 GLOBAL_MEM_OBJ_NODE* pMemTrav = getGlobalMemNode(mem);
372 if (!pMemTrav) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700373 char str[1024];
374 sprintf(str, "Trying to bind mem obj %p to CB %p but no Node for that mem obj.\n Was it correctly allocated? Did it already get freed?", mem, cb);
375 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600376 result = XGL_FALSE;
377 } else {
378 result = insertMiniNode(&pMemTrav->pCmdBufferBindings, cb, &pMemTrav->refCount);
379 if (XGL_TRUE == result) {
380 // Now update Global CB's Mini Mem binding list
381 GLOBAL_CB_NODE* pCBTrav = getGlobalCBNode(cb);
382 if (!pCBTrav) {
383 char str[1024];
384 sprintf(str, "Trying to bind mem obj %p to CB %p but no Node for that CB. Was it CB incorrectly destroyed?", mem, cb);
385 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
386 result = XGL_FALSE;
387 } else {
388 uint32_t dontCare;
389 result = insertMiniNode(&pCBTrav->pMemObjList, mem, &dontCare);
390 }
391 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700392 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600393 return result;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700394}
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600395
Tobin Ehlis6663f492014-11-10 12:29:12 -0700396// Clear the CB Binding for mem
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -0700397// Calls to this function should be wrapped in mutex
Tobin Ehlis6663f492014-11-10 12:29:12 -0700398static void clearCBBinding(const XGL_CMD_BUFFER cb, const XGL_GPU_MEMORY mem)
399{
400 GLOBAL_MEM_OBJ_NODE* pTrav = getGlobalMemNode(mem);
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -0700401 // TODO : Having this check is not ideal, really if mem node was deleted,
402 // its CB bindings should be cleared and then freeCBBindings wouldn't call
403 // us here with stale mem objs
404 if (pTrav) {
405 MINI_NODE* pMiniCB = pTrav->pCmdBufferBindings;
406 MINI_NODE* pPrev = pMiniCB;
407 while (pMiniCB && (cb != pMiniCB->cmdBuffer)) {
408 pPrev = pMiniCB;
409 pMiniCB = pMiniCB->pNext;
410 }
Mark Lobodzinski3e4710d2015-03-05 10:07:53 -0600411 if (pMiniCB) { // remove node from list & decrement refCount
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -0700412 pPrev->pNext = pMiniCB->pNext;
413 if (pMiniCB == pTrav->pCmdBufferBindings)
414 pTrav->pCmdBufferBindings = NULL;
415 free(pMiniCB);
416 pTrav->refCount--;
417 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700418 }
419}
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600420
Tobin Ehlis6663f492014-11-10 12:29:12 -0700421// Free bindings related to CB
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600422static bool32_t freeCBBindings(const XGL_CMD_BUFFER cb)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700423{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600424 bool32_t result = XGL_TRUE;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700425 GLOBAL_CB_NODE* pCBTrav = getGlobalCBNode(cb);
426 if (!pCBTrav) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700427 char str[1024];
428 sprintf(str, "Unable to find global CB node %p for deletion", cb);
429 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_INVALID_CB, "MEM", str);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600430 result = XGL_FALSE;
431 } else {
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -0500432 if (!fenceRetired(pCBTrav->fenceId)) {
433 deleteFenceNode(pCBTrav->fenceId);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600434 }
435 MINI_NODE* pMemTrav = pCBTrav->pMemObjList;
436 MINI_NODE* pDeleteMe = NULL;
437 // We traverse LL in order and free nodes as they're cleared
438 while (pMemTrav) {
439 pDeleteMe = pMemTrav;
440 if (pMemTrav->mem)
441 clearCBBinding(cb, pMemTrav->mem);
442 pMemTrav = pMemTrav->pNext;
443 free(pDeleteMe);
444 }
445 pCBTrav->pMemObjList = NULL;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700446 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600447 return result;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700448}
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600449
Tobin Ehlis6663f492014-11-10 12:29:12 -0700450// Delete Global CB Node from list along with all of it's mini mem obj node
451// and also clear Global mem references to CB
452// TODO : When should this be called? There's no Destroy of CBs that I see
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600453static bool32_t deleteGlobalCBNode(const XGL_CMD_BUFFER cb)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700454{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600455 bool32_t result = XGL_TRUE;
456 result = freeCBBindings(cb);
457 if (result == XGL_TRUE) {
458 // Delete the Global CB node
459 GLOBAL_CB_NODE* pCBTrav = getGlobalCBNode(cb);
460 pCBTrav = pGlobalCBHead;
461 GLOBAL_CB_NODE* pPrev = pCBTrav;
462 while (pCBTrav && (cb != pCBTrav->cmdBuffer)) {
463 pPrev = pCBTrav;
464 pCBTrav = pCBTrav->pNextGlobalCBNode;
465 }
466 assert(cb); // We found node at start of function so it should still be here
467 pPrev->pNextGlobalCBNode = pCBTrav->pNextGlobalCBNode;
468 if (pCBTrav == pGlobalCBHead) {
469 pGlobalCBHead = pCBTrav->pNextGlobalCBNode;
470 }
471 free(pCBTrav);
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700472 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600473 return result;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700474}
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600475
Tobin Ehlis6663f492014-11-10 12:29:12 -0700476// Delete the entire CB list
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600477static bool32_t deleteGlobalCBList()
Tobin Ehlis6663f492014-11-10 12:29:12 -0700478{
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600479 bool32_t result = XGL_TRUE;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700480 GLOBAL_CB_NODE* pCBTrav = pGlobalCBHead;
481 while (pCBTrav) {
Tobin Ehlisc0418f92014-11-25 14:47:20 -0700482 XGL_CMD_BUFFER cbToDelete = pCBTrav->cmdBuffer;
483 pCBTrav = pCBTrav->pNextGlobalCBNode;
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600484 bool32_t tmpResult = deleteGlobalCBNode(cbToDelete);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700485 // If any result is FALSE, final result should be FALSE
486 if ((XGL_FALSE == tmpResult) || (XGL_FALSE == result))
487 result = XGL_FALSE;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700488 }
489 return result;
490}
491
492// For given MemObj node, report Obj & CB bindings
493static void reportMemReferences(const GLOBAL_MEM_OBJ_NODE* pMemObjTrav)
494{
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600495 uint32_t refCount = 0; // Count found references
Tobin Ehlis6663f492014-11-10 12:29:12 -0700496 MINI_NODE* pObjTrav = pMemObjTrav->pObjBindings;
497 MINI_NODE* pCBTrav = pMemObjTrav->pCmdBufferBindings;
498 while (pCBTrav) {
499 refCount++;
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700500 char str[1024];
501 sprintf(str, "Command Buffer %p has reference to mem obj %p", pCBTrav->cmdBuffer, pMemObjTrav->mem);
502 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, pCBTrav->cmdBuffer, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700503 pCBTrav = pCBTrav->pNext;
504 }
505 while (pObjTrav) {
506 refCount++;
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700507 char str[1024];
508 sprintf(str, "XGL Object %p has reference to mem obj %p", pObjTrav->object, pMemObjTrav->mem);
509 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, pObjTrav->object, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700510 pObjTrav = pObjTrav->pNext;
511 }
512 if (refCount != pMemObjTrav->refCount) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700513 char str[1024];
514 sprintf(str, "Refcount of %u for Mem Obj %p does't match reported refs of %u", pMemObjTrav->refCount, pMemObjTrav->mem, refCount);
Mark Lobodzinskiae5f13b2015-02-26 15:18:57 -0600515 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, pMemObjTrav->mem, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700516 }
517}
518
519static void deleteGlobalMemNode(XGL_GPU_MEMORY mem)
520{
521 GLOBAL_MEM_OBJ_NODE* pTrav = pGlobalMemObjHead;
522 GLOBAL_MEM_OBJ_NODE* pPrev = pTrav;
523 while (pTrav && (pTrav->mem != mem)) {
524 pPrev = pTrav;
525 pTrav = pTrav->pNextGlobalNode;
526 }
527 if (pTrav) {
528 pPrev->pNextGlobalNode = pTrav->pNextGlobalNode;
529 if (pGlobalMemObjHead == pTrav)
530 pGlobalMemObjHead = pTrav->pNextGlobalNode;
531 free(pTrav);
532 }
533 else {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700534 char str[1024];
535 sprintf(str, "Could not find global mem obj node for %p to delete!", mem);
536 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700537 }
538}
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -0500539
Tobin Ehlis6663f492014-11-10 12:29:12 -0700540// Check if fence for given CB is completed
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600541static bool32_t checkCBCompleted(const XGL_CMD_BUFFER cb)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700542{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600543 bool32_t result = XGL_TRUE;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700544 GLOBAL_CB_NODE* pCBTrav = getGlobalCBNode(cb);
545 if (!pCBTrav) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700546 char str[1024];
547 sprintf(str, "Unable to find global CB node %p to check for completion", cb);
548 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_INVALID_CB, "MEM", str);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600549 result = XGL_FALSE;
550 } else {
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -0500551 if (!fenceRetired(pCBTrav->fenceId)) {
552 // Explicitly call the internal xglGetFenceStatus routine
553 if (XGL_SUCCESS != xglGetFenceStatus(getFenceFromId(pCBTrav->fenceId))) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600554 char str[1024];
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -0500555 sprintf(str, "FenceId %"PRIx64", fence %p for CB %p has not completed", pCBTrav->fenceId, getFenceFromId(pCBTrav->fenceId), cb);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600556 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_NONE, "MEM", str);
557 result = XGL_FALSE;
558 }
559 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700560 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600561 return result;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700562}
563
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600564static bool32_t freeMemNode(XGL_GPU_MEMORY mem)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700565{
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600566 bool32_t result = XGL_TRUE;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700567 // Parse global list to find node w/ mem
568 GLOBAL_MEM_OBJ_NODE* pTrav = getGlobalMemNode(mem);
569 if (!pTrav) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700570 char str[1024];
571 sprintf(str, "Couldn't find mem node object for %p\n Was %p never allocated or previously freed?", (void*)mem, (void*)mem);
572 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600573 result = XGL_FALSE;
574 } else {
Mark Lobodzinski2f3b19b2015-02-18 18:06:24 -0600575 if (pTrav->allocInfo.allocationSize == 0) {
576 char str[1024];
577 sprintf(str, "Attempting to free memory associated with a Presentable Image, %p, this should not be explicitly freed\n", (void*)mem);
Mark Lobodzinski78a21972015-03-05 12:39:33 -0600578 layerCbMsg(XGL_DBG_MSG_WARNING, XGL_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700579 result = XGL_FALSE;
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600580 } else {
581 // Clear any CB bindings for completed CBs
582 // TODO : Is there a better place to do this?
583 MINI_NODE* pMiniCB = pTrav->pCmdBufferBindings;
584 while (pMiniCB) {
585 XGL_CMD_BUFFER curCB = pMiniCB->cmdBuffer;
586 pMiniCB = pMiniCB->pNext;
587 if (XGL_TRUE == checkCBCompleted(curCB)) {
588 freeCBBindings(curCB);
589 }
590 }
591 // Now verify that no references to this mem obj remain
592 if (0 != pTrav->refCount) {
593 // If references remain, report the error and can search down CB LL to find references
594 char str[1024];
595 sprintf(str, "Freeing mem obj %p while it still has references", (void*)mem);
596 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_FREED_MEM_REF, "MEM", str);
597 reportMemReferences(pTrav);
598 result = XGL_FALSE;
599 }
600 // Delete global node
601 deleteGlobalMemNode(mem);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700602 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700603 }
604 return result;
605}
606
607// Return object node for 'object' or return NULL if no node exists
608static GLOBAL_OBJECT_NODE* getGlobalObjectNode(const XGL_OBJECT object)
609{
610 GLOBAL_OBJECT_NODE* pTrav = pGlobalObjectHead;
611 while (pTrav && (object != pTrav->object)) {
612 pTrav = pTrav->pNext;
613 }
614 return pTrav;
615}
616
Tobin Ehlis8be20fd2015-01-07 17:49:29 -0700617static GLOBAL_OBJECT_NODE* insertGlobalObjectNode(XGL_OBJECT object, XGL_STRUCTURE_TYPE sType, const void *pCreateInfo, const int struct_size, char *name_prefix)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700618{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600619 GLOBAL_OBJECT_NODE* newNode = NULL;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700620 GLOBAL_OBJECT_NODE* pTrav = pGlobalObjectHead;
621 if (!pTrav) {
622 pTrav = (GLOBAL_OBJECT_NODE*)malloc(sizeof(GLOBAL_OBJECT_NODE));
Tobin Ehlis6663f492014-11-10 12:29:12 -0700623 memset(pTrav, 0, sizeof(GLOBAL_OBJECT_NODE));
624 pGlobalObjectHead = pTrav;
625 }
626 else {
627 GLOBAL_OBJECT_NODE* pPrev = pTrav;
628 while (pTrav) {
629 pPrev = pTrav;
630 pTrav = pTrav->pNext;
631 }
632 pTrav = (GLOBAL_OBJECT_NODE*)malloc(sizeof(GLOBAL_OBJECT_NODE));
Tobin Ehlis6663f492014-11-10 12:29:12 -0700633 memset(pTrav, 0, sizeof(GLOBAL_OBJECT_NODE));
634 pPrev->pNext = pTrav;
635 }
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700636 if (!pTrav) {
637 char str[1024];
638 sprintf(str, "Malloc failed to alloc node for XGL Object %p", (void*)object);
639 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, object, 0, MEMTRACK_OUT_OF_MEMORY_ERROR, "MEM", str);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600640 } else {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700641 numObjectNodes++;
642 pTrav->object = object;
Tobin Ehlis8be20fd2015-01-07 17:49:29 -0700643 pTrav->ref_count = 1;
644 pTrav->sType = sType;
645 memcpy(&pTrav->create_info, pCreateInfo, struct_size);
646 sprintf(pTrav->object_name, "%s_%p", name_prefix, object);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600647 newNode = pTrav;
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700648 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600649 return newNode;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700650}
651
652// Remove object binding performs 3 tasks:
653// 1. Remove object node from Global Mem Obj mini LL of obj bindings & free it
654// 2. Decrement refCount for Global Mem Obj
655// 3. Clear Global Mem Obj ptr from Global Object Node
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600656static bool32_t clearObjectBinding(XGL_OBJECT object)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700657{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600658 bool32_t result = XGL_FALSE;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700659 GLOBAL_OBJECT_NODE* pGlobalObjTrav = getGlobalObjectNode(object);
660 if (!pGlobalObjTrav) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700661 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -0600662 sprintf(str, "Attempting to clear mem binding for object %p: devices, queues, command buffers, shaders and memory objects do not have external memory requirements and it is unneccessary to call bind/unbindObjectMemory on them.", object);
663 layerCbMsg(XGL_DBG_MSG_WARNING, XGL_VALIDATION_LEVEL_0, object, 0, MEMTRACK_INVALID_OBJECT, "MEM", str);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600664 } else {
665 if (!pGlobalObjTrav->pMemNode) {
666 char str[1024];
667 sprintf(str, "Attempting to clear mem binding on obj %p but it has no binding.", (void*)object);
668 layerCbMsg(XGL_DBG_MSG_WARNING, XGL_VALIDATION_LEVEL_0, object, 0, MEMTRACK_MEM_OBJ_CLEAR_EMPTY_BINDINGS, "MEM", str);
669 } else {
670 MINI_NODE* pObjTrav = pGlobalObjTrav->pMemNode->pObjBindings;
671 MINI_NODE* pPrevObj = pObjTrav;
672 while (pObjTrav && (result == XGL_FALSE)) {
673 if (object == pObjTrav->object) {
674 pPrevObj->pNext = pObjTrav->pNext;
675 // check if HEAD needs to be updated
676 if (pGlobalObjTrav->pMemNode->pObjBindings == pObjTrav)
677 pGlobalObjTrav->pMemNode->pObjBindings = pObjTrav->pNext;
678 free(pObjTrav);
679 pGlobalObjTrav->pMemNode->refCount--;
680 pGlobalObjTrav->pMemNode = NULL;
681 result = XGL_TRUE;
682 }
683 pPrevObj = pObjTrav;
684 pObjTrav = pObjTrav->pNext;
685 }
686 if (result == XGL_FALSE) {
687 char str[1024];
688 sprintf(str, "While trying to clear mem binding for object %p, unable to find that object referenced by mem obj %p", object, pGlobalObjTrav->pMemNode->mem);
689 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, object, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
690 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700691 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700692 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600693 return result;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700694}
695
696// For NULL mem case, clear any previous binding Else...
697// Make sure given object is in global object LL
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700698// IF a previous binding existed, clear it
Tobin Ehlis6663f492014-11-10 12:29:12 -0700699// Add link from global object node to global memory node
700// Add mini-object node & reference off of global obj node
701// Return XGL_TRUE if addition is successful, XGL_FALSE otherwise
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600702static bool32_t updateObjectBinding(XGL_OBJECT object, XGL_GPU_MEMORY mem)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700703{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600704 bool32_t result = XGL_FALSE;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700705 // Handle NULL case separately, just clear previous binding & decrement reference
706 if (mem == XGL_NULL_HANDLE) {
707 clearObjectBinding(object);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600708 result = XGL_TRUE;
709 } else {
710 char str[1024];
711 GLOBAL_OBJECT_NODE* pGlobalObjTrav = getGlobalObjectNode(object);
712 if (!pGlobalObjTrav) {
713 sprintf(str, "Attempting to update Binding of Obj(%p) that's not in global list()", (void*)object);
714 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, object, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
715 return XGL_FALSE;
716 }
717 // non-null case so should have real mem obj
718 GLOBAL_MEM_OBJ_NODE* pTrav = getGlobalMemNode(mem);
719 if (!pTrav) {
720 sprintf(str, "While trying to bind mem for obj %p, couldn't find node for mem obj %p", (void*)object, (void*)mem);
721 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
722 } else {
723 result = insertMiniNode(&pTrav->pObjBindings, object, &pTrav->refCount);
724 if (XGL_TRUE == result) {
725 if (pGlobalObjTrav->pMemNode) {
726 clearObjectBinding(object); // Need to clear the previous object binding before setting new binding
727 sprintf(str, "Updating memory binding for object %p from mem obj %p to %p", object, pGlobalObjTrav->pMemNode->mem, mem);
728 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, object, 0, MEMTRACK_NONE, "MEM", str);
729 }
730 // For image objects, make sure default memory state is correctly set
731 // TODO : What's the best/correct way to handle this?
732 if (XGL_STRUCTURE_TYPE_IMAGE_CREATE_INFO == pGlobalObjTrav->sType) {
733 if (pGlobalObjTrav->create_info.image_create_info.usage & (XGL_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | XGL_IMAGE_USAGE_DEPTH_STENCIL_BIT)) {
734 // TODO:: More memory state transition stuff.
735 }
736 }
737 pGlobalObjTrav->pMemNode = pTrav;
738 }
Tobin Ehlis8be20fd2015-01-07 17:49:29 -0700739 }
740 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700741 return XGL_TRUE;
742}
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600743
Tobin Ehlis6663f492014-11-10 12:29:12 -0700744// Print details of global Obj tracking list
745static void printObjList()
746{
747 GLOBAL_OBJECT_NODE* pGlobalObjTrav = pGlobalObjectHead;
748 if (!pGlobalObjTrav) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700749 char str[1024];
750 sprintf(str, "Global Object list is empty :(\n");
751 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700752 }
753 else {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700754 char str[1024];
755 sprintf(str, "Details of Global Object list w/ HEAD at %p", (void*)pGlobalObjTrav);
756 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700757 while (pGlobalObjTrav) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600758 sprintf(str, " GlobObjNode %p has object %p, pNext %p, pMemNode %p",
759 pGlobalObjTrav, pGlobalObjTrav->object, pGlobalObjTrav->pNext, pGlobalObjTrav->pMemNode);
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700760 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, pGlobalObjTrav->object, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700761 pGlobalObjTrav = pGlobalObjTrav->pNext;
762 }
763 }
764}
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600765
Tobin Ehlis6663f492014-11-10 12:29:12 -0700766// For given Object, get 'mem' obj that it's bound to or NULL if no binding
767static XGL_GPU_MEMORY getMemBindingFromObject(const XGL_OBJECT object)
768{
769 XGL_GPU_MEMORY mem = NULL;
770 GLOBAL_OBJECT_NODE* pObjNode = getGlobalObjectNode(object);
771 if (pObjNode) {
772 if (pObjNode->pMemNode) {
773 mem = pObjNode->pMemNode->mem;
774 }
775 else {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700776 char str[1024];
777 sprintf(str, "Trying to get mem binding for object %p but object has no mem binding", (void*)object);
778 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, object, 0, MEMTRACK_MISSING_MEM_BINDINGS, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700779 printObjList();
780 }
781 }
782 else {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700783 char str[1024];
784 sprintf(str, "Trying to get mem binding for object %p but no such object in global list", (void*)object);
785 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, object, 0, MEMTRACK_INVALID_OBJECT, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700786 printObjList();
787 }
788 return mem;
789}
790// Print details of global Mem Obj list
791static void printMemList()
792{
793 GLOBAL_MEM_OBJ_NODE* pTrav = pGlobalMemObjHead;
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700794 // Just printing each msg individually for now, may want to package these into single large print
795 char str[1024];
Tobin Ehlis6663f492014-11-10 12:29:12 -0700796 if (!pTrav) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700797 sprintf(str, "MEM INFO : Global Memory Object list is empty :(\n");
798 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700799 }
800 else {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700801 sprintf(str, "MEM INFO : Details of Global Memory Object list w/ HEAD at %p", (void*)pTrav);
802 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700803 while (pTrav) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700804 sprintf(str, " ===MemObj Node at %p===", (void*)pTrav);
805 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
806 sprintf(str, " Mem object: %p", (void*)pTrav->mem);
807 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
808 sprintf(str, " Ref Count: %u", pTrav->refCount);
809 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
810 sprintf(str, " pNext Mem Obj Node: %p", (void*)pTrav->pNextGlobalNode);
811 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinskic815b002015-02-26 18:33:10 -0600812 if (0 != pTrav->allocInfo.allocationSize) {
813 char* pAllocInfoMsg = xgl_print_xgl_memory_alloc_info(&pTrav->allocInfo, "{MEM}INFO : ");
814 sprintf(str, " Mem Alloc info:\n%s", pAllocInfoMsg);
815 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
816 free(pAllocInfoMsg);
817 } else {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700818 sprintf(str, " Mem Alloc info is NULL (alloc done by xglWsiX11CreatePresentableImage())");
Mark Lobodzinskic815b002015-02-26 18:33:10 -0600819 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
820 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700821 MINI_NODE* pObjTrav = pTrav->pObjBindings;
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700822 if (!pObjTrav) {
823 sprintf(str, " No XGL Object bindings");
824 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
825 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700826 else {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700827 sprintf(str, " XGL OBJECT Binding list w/ HEAD at %p:", pObjTrav);
828 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700829 while (pObjTrav) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700830 sprintf(str, " OBJ_NODE(%p): XGL OBJECT %p, pNext %p", pObjTrav, pObjTrav->object, pObjTrav->pNext);
831 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700832 pObjTrav = pObjTrav->pNext;
833 }
834 }
835 MINI_NODE* pCBTrav = pTrav->pCmdBufferBindings;
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700836 if (!pCBTrav) {
837 sprintf(str, " No Command Buffer bindings");
838 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
839 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700840 else {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700841 sprintf(str, " XGL Command Buffer (CB) binding list w/ HEAD at %p:", pCBTrav);
842 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700843 while (pCBTrav) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700844 sprintf(str, " CB_NODE(%p): XGL CB %p, pNext %p", pCBTrav, pCBTrav->cmdBuffer, pCBTrav->pNext);
845 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700846 pCBTrav = pCBTrav->pNext;
847 }
848 }
849 pTrav = pTrav->pNextGlobalNode;
850 }
851 }
852}
853
854static void printGlobalCB()
855{
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700856 char str[1024] = {0};
Tobin Ehlis6663f492014-11-10 12:29:12 -0700857 GLOBAL_CB_NODE* pTrav = pGlobalCBHead;
858 if (!pTrav) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700859 sprintf(str, "Global Command Buffer (CB) list is empty :(\n");
860 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700861 }
862 else {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700863 sprintf(str, "Details of Global CB list w/ HEAD at %p:", (void*)pTrav);
864 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700865 while (pTrav) {
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -0500866 sprintf(str, " Global CB Node (%p) w/ pNextGlobalCBNode (%p) has CB %p, fenceId %"PRIx64", fence %p, and pMemObjList %p", (void*)pTrav, (void*)pTrav->pNextGlobalCBNode, (void*)pTrav->cmdBuffer, pTrav->fenceId, (void*)getFenceFromId(pTrav->fenceId), (void*)pTrav->pMemObjList);
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700867 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700868 MINI_NODE* pMemObjTrav = pTrav->pMemObjList;
869 while (pMemObjTrav) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700870 sprintf(str, " MEM_NODE(%p): Mem obj %p, pNext %p", (void*)pMemObjTrav, (void*)pMemObjTrav->mem, (void*)pMemObjTrav->pNext);
871 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700872 pMemObjTrav = pMemObjTrav->pNext;
873 }
874 pTrav = pTrav->pNextGlobalCBNode;
875 }
876 }
877}
878
Mark Lobodzinskic52b7752015-02-18 16:38:17 -0600879static void initMemTracker(void)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700880{
Jon Ashburn7d7b3cf2014-12-22 13:24:15 -0700881 const char *strOpt;
882 // initialize MemTracker options
Ian Elliotte7826712015-03-06 13:50:05 -0700883 getLayerOptionEnum("MemTrackerReportLevel", (uint32_t *) &g_reportingLevel);
884 g_actionIsDefault = getLayerOptionEnum("MemTrackerDebugAction", (uint32_t *) &g_debugAction);
Tobin Ehlisee702232015-01-08 14:26:53 -0700885
Jon Ashburn7d7b3cf2014-12-22 13:24:15 -0700886 if (g_debugAction & XGL_DBG_LAYER_ACTION_LOG_MSG)
887 {
888 strOpt = getLayerOption("MemTrackerLogFilename");
889 if (strOpt)
890 {
891 g_logFile = fopen(strOpt, "w");
Jon Ashburn7d7b3cf2014-12-22 13:24:15 -0700892 }
893 if (g_logFile == NULL)
894 g_logFile = stdout;
895 }
896
897 // initialize Layer dispatch table
898 // TODO handle multiple GPUs
Mark Lobodzinski391bb6d2015-01-09 15:12:03 -0600899 xglGetProcAddrType fpNextGPA;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700900 fpNextGPA = pCurObj->pGPA;
901 assert(fpNextGPA);
902
Chia-I Wuaa4121f2015-01-04 23:11:43 +0800903 layer_initialize_dispatch_table(&nextTable, fpNextGPA, (XGL_PHYSICAL_GPU) pCurObj->nextObject);
904
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600905 xglGetProcAddrType fpGetProcAddr = fpNextGPA((XGL_PHYSICAL_GPU) pCurObj->nextObject, (char *) "xglGetProcAddr");
Tobin Ehlis6663f492014-11-10 12:29:12 -0700906 nextTable.GetProcAddr = fpGetProcAddr;
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600907
908 if (!globalLockInitialized)
909 {
910 // TODO/TBD: Need to delete this mutex sometime. How??? One
911 // suggestion is to call this during xglCreateInstance(), and then we
912 // can clean it up during xglDestroyInstance(). However, that requires
913 // that the layer have per-instance locks. We need to come back and
914 // address this soon.
915 loader_platform_thread_create_mutex(&globalLock);
916 globalLockInitialized = 1;
917 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700918}
919
Tobin Ehlis6663f492014-11-10 12:29:12 -0700920XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateDevice(XGL_PHYSICAL_GPU gpu, const XGL_DEVICE_CREATE_INFO* pCreateInfo, XGL_DEVICE* pDevice)
921{
922 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
923 pCurObj = gpuw;
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700924 loader_platform_thread_once(&g_initOnce, initMemTracker);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700925 XGL_RESULT result = nextTable.CreateDevice((XGL_PHYSICAL_GPU)gpuw->nextObject, pCreateInfo, pDevice);
926 // Save off device in case we need it to create Fences
927 globalDevice = *pDevice;
928 return result;
929}
930
931XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglDestroyDevice(XGL_DEVICE device)
932{
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700933 char str[1024];
934 sprintf(str, "Printing List details prior to xglDestroyDevice()");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600935 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700936 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, device, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700937 printMemList();
938 printGlobalCB();
939 printObjList();
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700940 if (XGL_FALSE == deleteGlobalCBList()) {
941 sprintf(str, "Issue deleting global CB list in xglDestroyDevice()");
942 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, device, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
943 }
Tobin Ehlisb54ef782014-11-25 18:01:12 -0700944 // Report any memory leaks
945 GLOBAL_MEM_OBJ_NODE* pTrav = pGlobalMemObjHead;
946 while (pTrav) {
Mark Lobodzinski2f3b19b2015-02-18 18:06:24 -0600947 if (pTrav->allocInfo.allocationSize != 0) {
948 sprintf(str, "Mem Object %p has not been freed. You should clean up this memory by calling xglFreeMemory(%p) prior to xglDestroyDevice().", pTrav->mem, pTrav->mem);
949 layerCbMsg(XGL_DBG_MSG_WARNING, XGL_VALIDATION_LEVEL_0, pTrav->mem, 0, MEMTRACK_MEMORY_LEAK, "MEM", str);
950 }
Tobin Ehlisb54ef782014-11-25 18:01:12 -0700951 pTrav = pTrav->pNextGlobalNode;
952 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600953 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700954 XGL_RESULT result = nextTable.DestroyDevice(device);
955 return result;
956}
957
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600958XGL_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 Ehlis6663f492014-11-10 12:29:12 -0700959{
Jon Ashburnf7a08742014-11-25 11:08:42 -0700960 if (gpu != NULL)
961 {
962 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
963 pCurObj = gpuw;
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700964 loader_platform_thread_once(&g_initOnce, initMemTracker);
Mark Lobodzinski391bb6d2015-01-09 15:12:03 -0600965 XGL_RESULT result = nextTable.EnumerateLayers((XGL_PHYSICAL_GPU)gpuw->nextObject, maxLayerCount, maxStringSize, pOutLayerCount, pOutLayers, pReserved);
Jon Ashburnf7a08742014-11-25 11:08:42 -0700966 return result;
967 } else
968 {
969 if (pOutLayerCount == NULL || pOutLayers == NULL || pOutLayers[0] == NULL)
970 return XGL_ERROR_INVALID_POINTER;
971 // This layer compatible with all GPUs
972 *pOutLayerCount = 1;
Chia-I Wu1da4b9f2014-12-16 10:47:33 +0800973 strncpy((char *) pOutLayers[0], "MemTracker", maxStringSize);
Jon Ashburnf7a08742014-11-25 11:08:42 -0700974 return XGL_SUCCESS;
975 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700976}
977
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600978XGL_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 Ehlis6663f492014-11-10 12:29:12 -0700979{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600980 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700981 // TODO : Need to track fence and clear mem references when fence clears
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -0500982 GLOBAL_CB_NODE* pCBNode = NULL;
983 uint64_t fenceId = addFenceNode(fence);
984 char str[1024];
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700985 sprintf(str, "In xglQueueSubmit(), checking %u cmdBuffers with %u memRefs", cmdBufferCount, memRefCount);
986 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, queue, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700987 printMemList();
988 printGlobalCB();
989 for (uint32_t i = 0; i < cmdBufferCount; i++) {
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -0500990 pCBNode = getGlobalCBNode(pCmdBuffers[i]);
991 pCBNode->fenceId = fenceId;
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700992 sprintf(str, "Verifying mem refs for CB %p", pCmdBuffers[i]);
993 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, pCmdBuffers[i], 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700994 if (XGL_FALSE == validateCBMemRef(pCmdBuffers[i], memRefCount, pMemRefs)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700995 sprintf(str, "Unable to verify memory references for CB %p", (void*)pCmdBuffers[i]);
996 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, pCmdBuffers[i], 0, MEMTRACK_CB_MISSING_MEM_REF, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700997 }
998 }
999 printGlobalCB();
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001000 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -05001001 XGL_RESULT result = nextTable.QueueSubmit(queue, cmdBufferCount, pCmdBuffers, memRefCount, pMemRefs, getFenceFromId(fenceId));
Tobin Ehlis6663f492014-11-10 12:29:12 -07001002 return result;
1003}
1004
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001005XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglQueueSetGlobalMemReferences(XGL_QUEUE queue, uint32_t memRefCount, const XGL_MEMORY_REF* pMemRefs)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001006{
1007 // TODO : Use global mem references as part of list checked on QueueSubmit above
1008 XGL_RESULT result = nextTable.QueueSetGlobalMemReferences(queue, memRefCount, pMemRefs);
1009 return result;
1010}
1011
Tobin Ehlis6663f492014-11-10 12:29:12 -07001012XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglAllocMemory(XGL_DEVICE device, const XGL_MEMORY_ALLOC_INFO* pAllocInfo, XGL_GPU_MEMORY* pMem)
1013{
1014 XGL_RESULT result = nextTable.AllocMemory(device, pAllocInfo, pMem);
1015 // TODO : Track allocations and overall size here
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001016 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001017 insertGlobalMemObj(*pMem, pAllocInfo);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001018 printMemList();
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001019 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001020 return result;
1021}
1022
1023XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglFreeMemory(XGL_GPU_MEMORY mem)
1024{
Tobin Ehlisc0418f92014-11-25 14:47:20 -07001025 /* From spec : A memory object is freed by calling xglFreeMemory() when it is no longer needed. Before
1026 * freeing a memory object, an application must ensure the memory object is unbound from
1027 * all API objects referencing it and that it is not referenced by any queued command buffers
1028 */
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001029 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001030 if (XGL_FALSE == freeMemNode(mem)) {
1031 char str[1024];
1032 sprintf(str, "Issue while freeing mem obj %p", (void*)mem);
1033 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_FREE_MEM_ERROR, "MEM", str);
1034 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001035 printMemList();
1036 printObjList();
1037 printGlobalCB();
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001038 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001039 XGL_RESULT result = nextTable.FreeMemory(mem);
1040 return result;
1041}
1042
1043XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglSetMemoryPriority(XGL_GPU_MEMORY mem, XGL_MEMORY_PRIORITY priority)
1044{
1045 // TODO : Update tracking for this alloc
1046 // Make sure memory is not pinned, which can't have priority set
1047 XGL_RESULT result = nextTable.SetMemoryPriority(mem, priority);
1048 return result;
1049}
1050
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001051XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglMapMemory(XGL_GPU_MEMORY mem, XGL_FLAGS flags, void** ppData)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001052{
1053 // TODO : Track when memory is mapped
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001054 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski95152dc2015-02-25 12:16:04 -06001055 GLOBAL_MEM_OBJ_NODE *pMemObj = getGlobalMemNode(mem);
1056 if ((pMemObj->allocInfo.memProps & XGL_MEMORY_PROPERTY_CPU_VISIBLE_BIT) == 0) {
1057 char str[1024];
1058 sprintf(str, "Mapping Memory (%p) without XGL_MEMORY_PROPERTY_CPU_VISIBLE_BIT set", (void*)mem);
1059 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_STATE, "MEM", str);
1060 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001061 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001062 XGL_RESULT result = nextTable.MapMemory(mem, flags, ppData);
1063 return result;
1064}
1065
1066XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglUnmapMemory(XGL_GPU_MEMORY mem)
1067{
1068 // TODO : Track as memory gets unmapped, do we want to check what changed following map?
1069 // Make sure that memory was ever mapped to begin with
1070 XGL_RESULT result = nextTable.UnmapMemory(mem);
1071 return result;
1072}
1073
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001074XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglPinSystemMemory(XGL_DEVICE device, const void* pSysMem, size_t memSize, XGL_GPU_MEMORY* pMem)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001075{
1076 // TODO : Track this
1077 // Verify that memory is actually pinnable
1078 XGL_RESULT result = nextTable.PinSystemMemory(device, pSysMem, memSize, pMem);
1079 return result;
1080}
1081
Tobin Ehlis6663f492014-11-10 12:29:12 -07001082XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglOpenSharedMemory(XGL_DEVICE device, const XGL_MEMORY_OPEN_INFO* pOpenInfo, XGL_GPU_MEMORY* pMem)
1083{
1084 // TODO : Track this
1085 XGL_RESULT result = nextTable.OpenSharedMemory(device, pOpenInfo, pMem);
1086 return result;
1087}
1088
Tobin Ehlis6663f492014-11-10 12:29:12 -07001089XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglOpenPeerMemory(XGL_DEVICE device, const XGL_PEER_MEMORY_OPEN_INFO* pOpenInfo, XGL_GPU_MEMORY* pMem)
1090{
1091 // TODO : Track this
1092 XGL_RESULT result = nextTable.OpenPeerMemory(device, pOpenInfo, pMem);
1093 return result;
1094}
1095
1096XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglOpenPeerImage(XGL_DEVICE device, const XGL_PEER_IMAGE_OPEN_INFO* pOpenInfo, XGL_IMAGE* pImage, XGL_GPU_MEMORY* pMem)
1097{
1098 // TODO : Track this
1099 XGL_RESULT result = nextTable.OpenPeerImage(device, pOpenInfo, pImage, pMem);
1100 return result;
1101}
1102
1103XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglDestroyObject(XGL_OBJECT object)
1104{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001105 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlisa98df732014-11-27 07:52:04 -07001106 // First check if this is a CmdBuffer
1107 if (NULL != getGlobalCBNode((XGL_CMD_BUFFER)object)) {
1108 deleteGlobalCBNode((XGL_CMD_BUFFER)object);
1109 }
1110 // Now locate node in global list along with prev node
Tobin Ehlisa6c0e3c2014-11-25 12:27:38 -07001111 GLOBAL_OBJECT_NODE* pTrav = pGlobalObjectHead;
1112 GLOBAL_OBJECT_NODE* pPrev = pTrav;
Tobin Ehlisa6c0e3c2014-11-25 12:27:38 -07001113 while (pTrav) {
1114 if (object == pTrav->object)
1115 break;
1116 pPrev = pTrav;
1117 pTrav = pTrav->pNext;
1118 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001119 if (pTrav) {
1120 if (pTrav->pMemNode) {
Tobin Ehlisa98df732014-11-27 07:52:04 -07001121 // Wsi allocated Memory is tied to image object so clear the binding and free that memory automatically
1122 if (0 == pTrav->pMemNode->allocInfo.allocationSize) { // Wsi allocated memory has NULL allocInfo w/ 0 size
1123 XGL_GPU_MEMORY memToFree = pTrav->pMemNode->mem;
1124 clearObjectBinding(object);
1125 freeMemNode(memToFree);
1126 }
1127 else {
1128 char str[1024];
1129 sprintf(str, "Destroying obj %p that is still bound to memory object %p\nYou should first clear binding by calling xglBindObjectMemory(%p, 0, XGL_NULL_HANDLE)", object, (void*)pTrav->pMemNode->mem, object);
1130 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, object, 0, MEMTRACK_DESTROY_OBJECT_ERROR, "MEM", str);
1131 // From the spec : If an object has previous memory binding, it is required to unbind memory from an API object before it is destroyed.
1132 clearObjectBinding(object);
1133 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001134 }
1135 if (pGlobalObjectHead == pTrav) // update HEAD if needed
1136 pGlobalObjectHead = pTrav->pNext;
Tobin Ehlisa6c0e3c2014-11-25 12:27:38 -07001137 // Delete the obj node from global list
1138 pPrev->pNext = pTrav->pNext;
Tobin Ehlis6663f492014-11-10 12:29:12 -07001139 free(pTrav);
1140 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001141 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001142 XGL_RESULT result = nextTable.DestroyObject(object);
1143 return result;
1144}
1145
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001146XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglGetObjectInfo(XGL_BASE_OBJECT object, XGL_OBJECT_INFO_TYPE infoType, size_t* pDataSize, void* pData)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001147{
1148 // TODO : What to track here?
1149 // Could potentially save returned mem requirements and validate values passed into BindObjectMemory for this object
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001150 // From spec : The only objects that are guaranteed to have no external memory requirements are devices, queues, command buffers, shaders and memory objects.
Tobin Ehlis6663f492014-11-10 12:29:12 -07001151 XGL_RESULT result = nextTable.GetObjectInfo(object, infoType, pDataSize, pData);
1152 return result;
1153}
1154
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001155XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglBindObjectMemory(XGL_OBJECT object, uint32_t allocationIdx, XGL_GPU_MEMORY mem, XGL_GPU_SIZE offset)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001156{
Jon Ashburn9b6eae52015-01-15 10:39:19 -07001157 XGL_RESULT result = nextTable.BindObjectMemory(object, allocationIdx, mem, offset);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001158 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001159 // Track objects tied to memory
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001160 if (XGL_FALSE == updateObjectBinding(object, mem)) {
1161 char str[1024];
1162 sprintf(str, "Unable to set object %p binding to mem obj %p", (void*)object, (void*)mem);
1163 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, object, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1164 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001165 printObjList();
1166 printMemList();
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001167 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001168 return result;
1169}
1170
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07001171XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateFence(XGL_DEVICE device, const XGL_FENCE_CREATE_INFO* pCreateInfo, XGL_FENCE* pFence)
1172{
1173 XGL_RESULT result = nextTable.CreateFence(device, pCreateInfo, pFence);
1174 if (XGL_SUCCESS == result) {
1175 loader_platform_thread_lock_mutex(&globalLock);
1176 insertGlobalObjectNode(*pFence, pCreateInfo->sType, pCreateInfo, sizeof(XGL_FENCE_CREATE_INFO), "fence");
1177 loader_platform_thread_unlock_mutex(&globalLock);
1178 }
1179 return result;
1180}
1181
1182XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglGetFenceStatus(XGL_FENCE fence)
1183{
1184 XGL_RESULT result = nextTable.GetFenceStatus(fence);
1185 if (XGL_SUCCESS == result) {
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -05001186 loader_platform_thread_lock_mutex(&globalLock);
1187 updateFenceTracking(fence);
1188 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07001189 }
1190 return result;
1191}
1192
1193XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglWaitForFences(XGL_DEVICE device, uint32_t fenceCount, const XGL_FENCE* pFences, bool32_t waitAll, uint64_t timeout)
1194{
1195 XGL_RESULT result = nextTable.WaitForFences(device, fenceCount, pFences, waitAll, timeout);
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -05001196 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07001197 if (XGL_SUCCESS == result) {
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07001198 if (waitAll) { // Clear all the fences
1199 for(uint32_t i = 0; i < fenceCount; i++) {
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -05001200 updateFenceTracking(pFences[i]);
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07001201 }
1202 }
1203 else { // Clear only completed fences
1204 for(uint32_t i = 0; i < fenceCount; i++) {
1205 if (XGL_SUCCESS == nextTable.GetFenceStatus(pFences[i])) {
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -05001206 updateFenceTracking(pFences[i]);
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07001207 }
1208 }
1209 }
1210 }
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -05001211 loader_platform_thread_unlock_mutex(&globalLock);
1212 return result;
1213}
1214
1215XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglQueueWaitIdle(XGL_QUEUE queue)
1216{
1217 XGL_RESULT result = nextTable.QueueWaitIdle(queue);
1218 if (XGL_SUCCESS == result) {
1219 loader_platform_thread_lock_mutex(&globalLock);
1220 retireAllFences();
1221 loader_platform_thread_unlock_mutex(&globalLock);
1222 }
1223 return result;
1224}
1225
1226XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglDeviceWaitIdle(XGL_DEVICE device)
1227{
1228 XGL_RESULT result = nextTable.DeviceWaitIdle(device);
1229 if (XGL_SUCCESS == result) {
1230 loader_platform_thread_lock_mutex(&globalLock);
1231 retireAllFences();
1232 loader_platform_thread_unlock_mutex(&globalLock);
1233 }
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07001234 return result;
1235}
1236
Tobin Ehlis6663f492014-11-10 12:29:12 -07001237XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateEvent(XGL_DEVICE device, const XGL_EVENT_CREATE_INFO* pCreateInfo, XGL_EVENT* pEvent)
1238{
1239 XGL_RESULT result = nextTable.CreateEvent(device, pCreateInfo, pEvent);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001240 if (XGL_SUCCESS == result) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001241 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001242 insertGlobalObjectNode(*pEvent, pCreateInfo->sType, pCreateInfo, sizeof(XGL_EVENT_CREATE_INFO), "event");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001243 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001244 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001245 return result;
1246}
1247
Tobin Ehlis6663f492014-11-10 12:29:12 -07001248XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateQueryPool(XGL_DEVICE device, const XGL_QUERY_POOL_CREATE_INFO* pCreateInfo, XGL_QUERY_POOL* pQueryPool)
1249{
1250 XGL_RESULT result = nextTable.CreateQueryPool(device, pCreateInfo, pQueryPool);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001251 if (XGL_SUCCESS == result) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001252 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001253 insertGlobalObjectNode(*pQueryPool, pCreateInfo->sType, pCreateInfo, sizeof(XGL_QUERY_POOL_CREATE_INFO), "query_pool");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001254 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001255 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001256 return result;
1257}
1258
Tobin Ehlis7265e832015-01-19 08:42:29 -07001259XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateBuffer(XGL_DEVICE device, const XGL_BUFFER_CREATE_INFO* pCreateInfo, XGL_BUFFER* pBuffer)
1260{
1261 XGL_RESULT result = nextTable.CreateBuffer(device, pCreateInfo, pBuffer);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001262 if (XGL_SUCCESS == result) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001263 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001264 insertGlobalObjectNode(*pBuffer, pCreateInfo->sType, pCreateInfo, sizeof(XGL_BUFFER_CREATE_INFO), "buffer");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001265 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001266 }
Tobin Ehlis7265e832015-01-19 08:42:29 -07001267 return result;
1268}
1269
1270XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateBufferView(XGL_DEVICE device, const XGL_BUFFER_VIEW_CREATE_INFO* pCreateInfo, XGL_BUFFER_VIEW* pView)
1271{
1272 XGL_RESULT result = nextTable.CreateBufferView(device, pCreateInfo, pView);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001273 if (result == XGL_SUCCESS) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001274 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001275 insertGlobalObjectNode(*pView, pCreateInfo->sType, pCreateInfo, sizeof(XGL_BUFFER_VIEW_CREATE_INFO), "buffer_view");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001276 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001277 }
Tobin Ehlis7265e832015-01-19 08:42:29 -07001278 return result;
1279}
1280
Tobin Ehlis6663f492014-11-10 12:29:12 -07001281XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateImage(XGL_DEVICE device, const XGL_IMAGE_CREATE_INFO* pCreateInfo, XGL_IMAGE* pImage)
1282{
1283 XGL_RESULT result = nextTable.CreateImage(device, pCreateInfo, pImage);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001284 if (XGL_SUCCESS == result) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001285 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001286 insertGlobalObjectNode(*pImage, pCreateInfo->sType, pCreateInfo, sizeof(XGL_IMAGE_CREATE_INFO), "image");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001287 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001288 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001289 return result;
1290}
1291
Tobin Ehlis6663f492014-11-10 12:29:12 -07001292XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateImageView(XGL_DEVICE device, const XGL_IMAGE_VIEW_CREATE_INFO* pCreateInfo, XGL_IMAGE_VIEW* pView)
1293{
1294 XGL_RESULT result = nextTable.CreateImageView(device, pCreateInfo, pView);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001295 if (result == XGL_SUCCESS) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001296 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001297 insertGlobalObjectNode(*pView, pCreateInfo->sType, pCreateInfo, sizeof(XGL_IMAGE_VIEW_CREATE_INFO), "image_view");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001298 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001299 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001300 return result;
1301}
1302
1303XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateColorAttachmentView(XGL_DEVICE device, const XGL_COLOR_ATTACHMENT_VIEW_CREATE_INFO* pCreateInfo, XGL_COLOR_ATTACHMENT_VIEW* pView)
1304{
1305 XGL_RESULT result = nextTable.CreateColorAttachmentView(device, pCreateInfo, pView);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001306 if (result == XGL_SUCCESS) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001307 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001308 insertGlobalObjectNode(*pView, pCreateInfo->sType, pCreateInfo, sizeof(XGL_COLOR_ATTACHMENT_VIEW_CREATE_INFO), "color_attachment_view");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001309 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001310 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001311 return result;
1312}
1313
1314XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateDepthStencilView(XGL_DEVICE device, const XGL_DEPTH_STENCIL_VIEW_CREATE_INFO* pCreateInfo, XGL_DEPTH_STENCIL_VIEW* pView)
1315{
1316 XGL_RESULT result = nextTable.CreateDepthStencilView(device, pCreateInfo, pView);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001317 if (result == XGL_SUCCESS) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001318 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001319 insertGlobalObjectNode(*pView, pCreateInfo->sType, pCreateInfo, sizeof(XGL_DEPTH_STENCIL_VIEW_CREATE_INFO), "ds_view");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001320 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001321 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001322 return result;
1323}
1324
1325XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateShader(XGL_DEVICE device, const XGL_SHADER_CREATE_INFO* pCreateInfo, XGL_SHADER* pShader)
1326{
1327 XGL_RESULT result = nextTable.CreateShader(device, pCreateInfo, pShader);
1328 return result;
1329}
1330
1331XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateGraphicsPipeline(XGL_DEVICE device, const XGL_GRAPHICS_PIPELINE_CREATE_INFO* pCreateInfo, XGL_PIPELINE* pPipeline)
1332{
1333 XGL_RESULT result = nextTable.CreateGraphicsPipeline(device, pCreateInfo, pPipeline);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001334 if (result == XGL_SUCCESS) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001335 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001336 insertGlobalObjectNode(*pPipeline, pCreateInfo->sType, pCreateInfo, sizeof(XGL_GRAPHICS_PIPELINE_CREATE_INFO), "graphics_pipeline");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001337 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001338 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001339 return result;
1340}
1341
1342XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateComputePipeline(XGL_DEVICE device, const XGL_COMPUTE_PIPELINE_CREATE_INFO* pCreateInfo, XGL_PIPELINE* pPipeline)
1343{
1344 XGL_RESULT result = nextTable.CreateComputePipeline(device, pCreateInfo, pPipeline);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001345 if (result == XGL_SUCCESS) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001346 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001347 insertGlobalObjectNode(*pPipeline, pCreateInfo->sType, pCreateInfo, sizeof(XGL_COMPUTE_PIPELINE_CREATE_INFO), "compute_pipeline");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001348 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001349 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001350 return result;
1351}
1352
Tobin Ehlis6663f492014-11-10 12:29:12 -07001353XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateSampler(XGL_DEVICE device, const XGL_SAMPLER_CREATE_INFO* pCreateInfo, XGL_SAMPLER* pSampler)
1354{
1355 XGL_RESULT result = nextTable.CreateSampler(device, pCreateInfo, pSampler);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001356 if (result == XGL_SUCCESS) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001357 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001358 insertGlobalObjectNode(*pSampler, pCreateInfo->sType, pCreateInfo, sizeof(XGL_SAMPLER_CREATE_INFO), "sampler");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001359 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001360 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001361 return result;
1362}
1363
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001364XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateDynamicViewportState(XGL_DEVICE device, const XGL_DYNAMIC_VP_STATE_CREATE_INFO* pCreateInfo, XGL_DYNAMIC_VP_STATE_OBJECT* pState)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001365{
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001366 XGL_RESULT result = nextTable.CreateDynamicViewportState(device, pCreateInfo, pState);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001367 if (result == XGL_SUCCESS) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001368 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001369 insertGlobalObjectNode(*pState, pCreateInfo->sType, pCreateInfo, sizeof(XGL_DYNAMIC_VP_STATE_CREATE_INFO), "viewport_state");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001370 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001371 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001372 return result;
1373}
1374
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001375XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateDynamicRasterState(XGL_DEVICE device, const XGL_DYNAMIC_RS_STATE_CREATE_INFO* pCreateInfo, XGL_DYNAMIC_RS_STATE_OBJECT* pState)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001376{
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001377 XGL_RESULT result = nextTable.CreateDynamicRasterState(device, pCreateInfo, pState);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001378 if (result == XGL_SUCCESS) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001379 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001380 insertGlobalObjectNode(*pState, pCreateInfo->sType, pCreateInfo, sizeof(XGL_DYNAMIC_RS_STATE_CREATE_INFO), "raster_state");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001381 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001382 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001383 return result;
1384}
1385
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001386XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateDynamicColorBlendState(XGL_DEVICE device, const XGL_DYNAMIC_CB_STATE_CREATE_INFO* pCreateInfo, XGL_DYNAMIC_CB_STATE_OBJECT* pState)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001387{
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001388 XGL_RESULT result = nextTable.CreateDynamicColorBlendState(device, pCreateInfo, pState);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001389 if (result == XGL_SUCCESS) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001390 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001391 insertGlobalObjectNode(*pState, pCreateInfo->sType, pCreateInfo, sizeof(XGL_DYNAMIC_CB_STATE_CREATE_INFO), "cb_state");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001392 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001393 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001394 return result;
1395}
1396
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001397XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateDynamicDepthStencilState(XGL_DEVICE device, const XGL_DYNAMIC_DS_STATE_CREATE_INFO* pCreateInfo, XGL_DYNAMIC_DS_STATE_OBJECT* pState)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001398{
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001399 XGL_RESULT result = nextTable.CreateDynamicDepthStencilState(device, pCreateInfo, pState);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001400 if (result == XGL_SUCCESS) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001401 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001402 insertGlobalObjectNode(*pState, pCreateInfo->sType, pCreateInfo, sizeof(XGL_DYNAMIC_DS_STATE_CREATE_INFO), "ds_state");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001403 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001404 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001405 return result;
1406}
1407
1408XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateCommandBuffer(XGL_DEVICE device, const XGL_CMD_BUFFER_CREATE_INFO* pCreateInfo, XGL_CMD_BUFFER* pCmdBuffer)
1409{
1410 XGL_RESULT result = nextTable.CreateCommandBuffer(device, pCreateInfo, pCmdBuffer);
1411 // At time of cmd buffer creation, create global cmd buffer node for the returned cmd buffer
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001412 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001413 if (*pCmdBuffer)
1414 insertGlobalCB(*pCmdBuffer);
1415 printGlobalCB();
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001416 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001417 return result;
1418}
1419
Jon Ashburn86522372014-12-31 17:11:49 -07001420XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglBeginCommandBuffer(XGL_CMD_BUFFER cmdBuffer, const XGL_CMD_BUFFER_BEGIN_INFO* pBeginInfo)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001421{
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07001422 // This implicitly resets the Cmd Buffer so make sure any fence is done and then clear memory references
1423 GLOBAL_CB_NODE* pCBTrav = getGlobalCBNode(cmdBuffer);
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -05001424 if (pCBTrav && (!fenceRetired(pCBTrav->fenceId))) {
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07001425 bool32_t cbDone = checkCBCompleted(cmdBuffer);
1426 if (XGL_FALSE == cbDone) {
1427 char str[1024];
1428 sprintf(str, "Calling xglBeginCommandBuffer() on active CB %p before it has completed. You must check CB flag before this call.", cmdBuffer);
1429 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_RESET_CB_WHILE_IN_FLIGHT, "MEM", str);
1430 }
1431 }
Jon Ashburn86522372014-12-31 17:11:49 -07001432 XGL_RESULT result = nextTable.BeginCommandBuffer(cmdBuffer, pBeginInfo);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001433 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis7265e832015-01-19 08:42:29 -07001434 freeCBBindings(cmdBuffer);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001435 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001436 return result;
1437}
1438
1439XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglEndCommandBuffer(XGL_CMD_BUFFER cmdBuffer)
1440{
1441 // TODO : Anything to do here?
1442 XGL_RESULT result = nextTable.EndCommandBuffer(cmdBuffer);
1443 return result;
1444}
1445
1446XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglResetCommandBuffer(XGL_CMD_BUFFER cmdBuffer)
1447{
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07001448 // Verify that CB is complete (not in-flight)
1449 GLOBAL_CB_NODE* pCBTrav = getGlobalCBNode(cmdBuffer);
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -05001450 if (pCBTrav && (!fenceRetired(pCBTrav->fenceId))) {
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07001451 bool32_t cbDone = checkCBCompleted(cmdBuffer);
1452 if (XGL_FALSE == cbDone) {
1453 char str[1024];
1454 sprintf(str, "Resetting CB %p before it has completed. You must check CB flag before calling xglResetCommandBuffer().", cmdBuffer);
1455 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_RESET_CB_WHILE_IN_FLIGHT, "MEM", str);
1456 }
1457 }
1458 // Clear memory references as this point.
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001459 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001460 freeCBBindings(cmdBuffer);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001461 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001462 XGL_RESULT result = nextTable.ResetCommandBuffer(cmdBuffer);
1463 return result;
1464}
1465// TODO : For any xglCmdBind* calls that include an object which has mem bound to it,
1466// need to account for that mem now having binding to given cmdBuffer
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001467XGL_LAYER_EXPORT void XGLAPI xglCmdBindPipeline(XGL_CMD_BUFFER cmdBuffer, XGL_PIPELINE_BIND_POINT pipelineBindPoint, XGL_PIPELINE pipeline)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001468{
Tobin Ehlisc145be82015-01-08 15:22:32 -07001469#if 0
1470 // TODO : If memory bound to pipeline, then need to tie that mem to cmdBuffer
1471 if (getPipeline(pipeline)) {
1472 GLOBAL_CB_NODE *pCBTrav = getGlobalCBNode(cmdBuffer);
1473 if (pCBTrav) {
1474 pCBTrav->pipelines[pipelineBindPoint] = pipeline;
1475 } else {
1476 char str[1024];
1477 sprintf(str, "Attempt to bind Pipeline %p to non-existant command buffer %p!", (void*)pipeline, cmdBuffer);
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001478 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_INVALID_CB, (char *) "DS", (char *) str);
Tobin Ehlisc145be82015-01-08 15:22:32 -07001479 }
1480 }
1481 else {
1482 char str[1024];
1483 sprintf(str, "Attempt to bind Pipeline %p that doesn't exist!", (void*)pipeline);
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001484 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, pipeline, 0, MEMTRACK_INVALID_OBJECT, (char *) "DS", (char *) str);
Tobin Ehlisc145be82015-01-08 15:22:32 -07001485 }
1486#endif
Tobin Ehlis6663f492014-11-10 12:29:12 -07001487 nextTable.CmdBindPipeline(cmdBuffer, pipelineBindPoint, pipeline);
1488}
1489
Tobin Ehlis7265e832015-01-19 08:42:29 -07001490XGL_LAYER_EXPORT void XGLAPI xglCmdBindDynamicStateObject(XGL_CMD_BUFFER cmdBuffer, XGL_STATE_BIND_POINT stateBindPoint, XGL_DYNAMIC_STATE_OBJECT state)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001491{
Tobin Ehlisc145be82015-01-08 15:22:32 -07001492 GLOBAL_OBJECT_NODE *pNode;
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001493 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlisc145be82015-01-08 15:22:32 -07001494 GLOBAL_CB_NODE *pCmdBuf = getGlobalCBNode(cmdBuffer);
1495 if (!pCmdBuf) {
1496 char str[1024];
1497 sprintf(str, "Unable to find command buffer object %p, was it ever created?", (void*)cmdBuffer);
1498 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_INVALID_CB, "DD", str);
1499 }
1500 pNode = getGlobalObjectNode(state);
1501 if (!pNode) {
1502 char str[1024];
1503 sprintf(str, "Unable to find dynamic state object %p, was it ever created?", (void*)state);
1504 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, state, 0, MEMTRACK_INVALID_OBJECT, "DD", str);
1505 }
1506 pCmdBuf->pDynamicState[stateBindPoint] = pNode;
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001507 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001508 nextTable.CmdBindDynamicStateObject(cmdBuffer, stateBindPoint, state);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001509}
1510
Tobin Ehlis7265e832015-01-19 08:42:29 -07001511XGL_LAYER_EXPORT void XGLAPI xglCmdBindDescriptorSet(XGL_CMD_BUFFER cmdBuffer, XGL_PIPELINE_BIND_POINT pipelineBindPoint, XGL_DESCRIPTOR_SET descriptorSet, const uint32_t* pUserData)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001512{
Tobin Ehlisc145be82015-01-08 15:22:32 -07001513 // TODO : Somewhere need to verify that all textures referenced by shaders in DS are in some type of *SHADER_READ* state
Tobin Ehlis7265e832015-01-19 08:42:29 -07001514 nextTable.CmdBindDescriptorSet(cmdBuffer, pipelineBindPoint, descriptorSet, pUserData);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001515}
1516
Tobin Ehlis7265e832015-01-19 08:42:29 -07001517XGL_LAYER_EXPORT void XGLAPI xglCmdBindVertexBuffer(XGL_CMD_BUFFER cmdBuffer, XGL_BUFFER buffer, XGL_GPU_SIZE offset, uint32_t binding)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001518{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001519 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001520 XGL_GPU_MEMORY mem = getMemBindingFromObject(buffer);
1521 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
Chia-I Wu19156822015-01-05 13:42:56 +08001522 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001523 sprintf(str, "In xglCmdBindVertexBuffer() call unable to update binding of buffer %p to cmdBuffer %p", buffer, cmdBuffer);
Chia-I Wu19156822015-01-05 13:42:56 +08001524 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1525 }
Tobin Ehlisc145be82015-01-08 15:22:32 -07001526 // Now update CB's vertex binding list
1527 GLOBAL_CB_NODE* pCBTrav = getGlobalCBNode(cmdBuffer);
1528 if (!pCBTrav) {
1529 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001530 sprintf(str, "Trying to BindVertexuffer obj %p to CB %p but no Node for that CB. Was CB incorrectly destroyed?", buffer, cmdBuffer);
Tobin Ehlisc145be82015-01-08 15:22:32 -07001531 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_INVALID_CB, "MEM", str);
1532 } else {
1533 MEMORY_BINDING *pBindInfo;
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001534 uint32_t dontCare;
Tobin Ehlisc145be82015-01-08 15:22:32 -07001535 pBindInfo = malloc(sizeof(MEMORY_BINDING));
1536 pBindInfo->offset = offset;
1537 pBindInfo->binding = binding;
Tobin Ehlis7265e832015-01-19 08:42:29 -07001538 pBindInfo->buffer = buffer;
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001539 if (XGL_FALSE == insertMiniNode(&pCBTrav->pVertexBufList, pBindInfo, &dontCare)) {
Tobin Ehlisc145be82015-01-08 15:22:32 -07001540 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001541 sprintf(str, "In xglCmdBindVertexBuffer and ran out of memory to track binding. CmdBuffer: %p, buffer %p", cmdBuffer, buffer);
Tobin Ehlisc145be82015-01-08 15:22:32 -07001542 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_OUT_OF_MEMORY_ERROR, "MEM", str);
1543 }
1544 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001545 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis7265e832015-01-19 08:42:29 -07001546 nextTable.CmdBindVertexBuffer(cmdBuffer, buffer, offset, binding);
Chia-I Wu19156822015-01-05 13:42:56 +08001547}
1548
Tobin Ehlis7265e832015-01-19 08:42:29 -07001549XGL_LAYER_EXPORT void XGLAPI xglCmdBindIndexBuffer(XGL_CMD_BUFFER cmdBuffer, XGL_BUFFER buffer, XGL_GPU_SIZE offset, XGL_INDEX_TYPE indexType)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001550{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001551 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis7265e832015-01-19 08:42:29 -07001552 // Track this buffer. What exactly is this call doing?
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001553 XGL_GPU_MEMORY mem = getMemBindingFromObject(buffer);
1554 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001555 char str[1024];
Tobin Ehlis7265e832015-01-19 08:42:29 -07001556 sprintf(str, "In xglCmdBindIndexData() call unable to update binding of buffer %p to cmdBuffer %p", buffer, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001557 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1558 }
Tobin Ehlisc145be82015-01-08 15:22:32 -07001559 // Now update CB's index binding list
1560 GLOBAL_CB_NODE* pCBTrav = getGlobalCBNode(cmdBuffer);
1561 if (!pCBTrav) {
1562 char str[1024];
Tobin Ehlis7265e832015-01-19 08:42:29 -07001563 sprintf(str, "Trying to BindIndexData buffer obj %p to CB %p but no Node for that CB. Was CB incorrectly destroyed?", buffer, cmdBuffer);
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001564 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_INVALID_MEM_OBJ, (char *) "MEM", (char *) str);
Tobin Ehlisc145be82015-01-08 15:22:32 -07001565 } else {
1566 MEMORY_BINDING *pBindInfo;
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001567 uint32_t dontCare;
Tobin Ehlisc145be82015-01-08 15:22:32 -07001568 pBindInfo = malloc(sizeof(MEMORY_BINDING));
1569 pBindInfo->indexType = indexType;
Tobin Ehlis7265e832015-01-19 08:42:29 -07001570 pBindInfo->buffer = buffer;
Tobin Ehlisc145be82015-01-08 15:22:32 -07001571 pBindInfo->offset = offset;
1572 pBindInfo->binding = 0;
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001573 if (XGL_FALSE == insertMiniNode(&pCBTrav->pIndexBufList, pBindInfo, &dontCare)) {
Tobin Ehlisc145be82015-01-08 15:22:32 -07001574 char str[1024];
Tobin Ehlis7265e832015-01-19 08:42:29 -07001575 sprintf(str, "In xglCmdBindIndexData and ran out of memory to track binding. CmdBuffer: %p, buffer %p", cmdBuffer, buffer);
Tobin Ehlisc145be82015-01-08 15:22:32 -07001576 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_OUT_OF_MEMORY_ERROR, "MEM", str);
1577 }
1578 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001579 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis7265e832015-01-19 08:42:29 -07001580 nextTable.CmdBindIndexBuffer(cmdBuffer, buffer, offset, indexType);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001581}
1582
Tobin Ehlis7265e832015-01-19 08:42:29 -07001583XGL_LAYER_EXPORT void XGLAPI xglCmdDrawIndirect(XGL_CMD_BUFFER cmdBuffer, XGL_BUFFER buffer, XGL_GPU_SIZE offset, uint32_t count, uint32_t stride)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001584{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001585 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001586 XGL_GPU_MEMORY mem = getMemBindingFromObject(buffer);
1587 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001588 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001589 sprintf(str, "In xglCmdDrawIndirect() call unable to update binding of buffer %p to cmdBuffer %p", buffer, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001590 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1591 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001592 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis7265e832015-01-19 08:42:29 -07001593 nextTable.CmdDrawIndirect(cmdBuffer, buffer, offset, count, stride);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001594}
1595
Tobin Ehlis7265e832015-01-19 08:42:29 -07001596XGL_LAYER_EXPORT void XGLAPI xglCmdDrawIndexedIndirect(XGL_CMD_BUFFER cmdBuffer, XGL_BUFFER buffer, XGL_GPU_SIZE offset, uint32_t count, uint32_t stride)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001597{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001598 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001599 XGL_GPU_MEMORY mem = getMemBindingFromObject(buffer);
1600 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001601 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001602 sprintf(str, "In xglCmdDrawIndexedIndirect() call unable to update binding of buffer %p to cmdBuffer %p", buffer, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001603 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1604 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001605 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis7265e832015-01-19 08:42:29 -07001606 nextTable.CmdDrawIndexedIndirect(cmdBuffer, buffer, offset, count, stride);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001607}
1608
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001609XGL_LAYER_EXPORT void XGLAPI xglCmdDispatchIndirect(XGL_CMD_BUFFER cmdBuffer, XGL_BUFFER buffer, XGL_GPU_SIZE offset)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001610{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001611 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001612 XGL_GPU_MEMORY mem = getMemBindingFromObject(buffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001613 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1614 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001615 sprintf(str, "In xglCmdDispatchIndirect() call unable to update binding of buffer %p to cmdBuffer %p", buffer, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001616 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1617 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001618 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001619 nextTable.CmdDispatchIndirect(cmdBuffer, buffer, offset);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001620}
1621
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001622XGL_LAYER_EXPORT void XGLAPI xglCmdCopyBuffer(XGL_CMD_BUFFER cmdBuffer, XGL_BUFFER srcBuffer, XGL_BUFFER destBuffer, uint32_t regionCount, const XGL_BUFFER_COPY* pRegions)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001623{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001624 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001625 XGL_GPU_MEMORY mem = getMemBindingFromObject(srcBuffer);
1626 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001627 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001628 sprintf(str, "In xglCmdCopyBuffer() call unable to update binding of srcBuffer %p to cmdBuffer %p", srcBuffer, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001629 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1630 }
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001631 mem = getMemBindingFromObject(destBuffer);
1632 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001633 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001634 sprintf(str, "In xglCmdCopyBuffer() call unable to update binding of destBuffer %p to cmdBuffer %p", destBuffer, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001635 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1636 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001637 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001638 nextTable.CmdCopyBuffer(cmdBuffer, srcBuffer, destBuffer, regionCount, pRegions);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001639}
1640
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001641XGL_LAYER_EXPORT void XGLAPI xglCmdCopyImage(XGL_CMD_BUFFER cmdBuffer, XGL_IMAGE srcImage, XGL_IMAGE destImage, uint32_t regionCount, const XGL_IMAGE_COPY* pRegions)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001642{
1643 // TODO : Each image will have mem mapping so track them
1644 nextTable.CmdCopyImage(cmdBuffer, srcImage, destImage, regionCount, pRegions);
1645}
1646
Tobin Ehlis7265e832015-01-19 08:42:29 -07001647XGL_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 Ehlis6663f492014-11-10 12:29:12 -07001648{
1649 // TODO : Track this
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001650 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001651 XGL_GPU_MEMORY mem = getMemBindingFromObject(destImage);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001652 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1653 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001654 sprintf(str, "In xglCmdCopyMemoryToImage() call unable to update binding of destImage buffer %p to cmdBuffer %p", destImage, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001655 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1656 }
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001657
1658 mem = getMemBindingFromObject(srcBuffer);
1659 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001660 char str[1024];
Tobin Ehlis7265e832015-01-19 08:42:29 -07001661 sprintf(str, "In xglCmdCopyMemoryToImage() call unable to update binding of srcBuffer %p to cmdBuffer %p", srcBuffer, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001662 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1663 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001664 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis7265e832015-01-19 08:42:29 -07001665 nextTable.CmdCopyBufferToImage(cmdBuffer, srcBuffer, destImage, regionCount, pRegions);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001666}
1667
Tobin Ehlis7265e832015-01-19 08:42:29 -07001668XGL_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 Ehlis6663f492014-11-10 12:29:12 -07001669{
1670 // TODO : Track this
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001671 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001672 XGL_GPU_MEMORY mem = getMemBindingFromObject(srcImage);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001673 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1674 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001675 sprintf(str, "In xglCmdCopyImageToMemory() call unable to update binding of srcImage buffer %p to cmdBuffer %p", srcImage, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001676 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1677 }
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001678 mem = getMemBindingFromObject(destBuffer);
1679 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001680 char str[1024];
Tobin Ehlis7265e832015-01-19 08:42:29 -07001681 sprintf(str, "In xglCmdCopyImageToMemory() call unable to update binding of destBuffer %p to cmdBuffer %p", destBuffer, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001682 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1683 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001684 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis7265e832015-01-19 08:42:29 -07001685 nextTable.CmdCopyImageToBuffer(cmdBuffer, srcImage, destBuffer, regionCount, pRegions);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001686}
1687
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001688XGL_LAYER_EXPORT void XGLAPI xglCmdCloneImageData(XGL_CMD_BUFFER cmdBuffer, XGL_IMAGE srcImage, XGL_IMAGE_LAYOUT srcImageLayout, XGL_IMAGE destImage, XGL_IMAGE_LAYOUT destImageLayout)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001689{
1690 // TODO : Each image will have mem mapping so track them
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001691 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001692 XGL_GPU_MEMORY mem = getMemBindingFromObject(srcImage);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001693 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1694 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001695 sprintf(str, "In xglCmdCloneImageData() call unable to update binding of srcImage buffer %p to cmdBuffer %p", srcImage, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001696 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1697 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001698 mem = getMemBindingFromObject(destImage);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001699 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1700 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001701 sprintf(str, "In xglCmdCloneImageData() call unable to update binding of destImage buffer %p to cmdBuffer %p", destImage, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001702 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1703 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001704 loader_platform_thread_unlock_mutex(&globalLock);
Mike Stroyanfb80d5f2014-12-04 11:08:39 +00001705 nextTable.CmdCloneImageData(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001706}
1707
Tobin Ehlis7265e832015-01-19 08:42:29 -07001708XGL_LAYER_EXPORT void XGLAPI xglCmdUpdateBuffer(XGL_CMD_BUFFER cmdBuffer, XGL_BUFFER destBuffer, XGL_GPU_SIZE destOffset, XGL_GPU_SIZE dataSize, const uint32_t* pData)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001709{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001710 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001711 XGL_GPU_MEMORY mem = getMemBindingFromObject(destBuffer);
1712 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001713 char str[1024];
Tobin Ehlis7265e832015-01-19 08:42:29 -07001714 sprintf(str, "In xglCmdUpdateMemory() call unable to update binding of destBuffer %p to cmdBuffer %p", destBuffer, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001715 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1716 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001717 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis7265e832015-01-19 08:42:29 -07001718 nextTable.CmdUpdateBuffer(cmdBuffer, destBuffer, destOffset, dataSize, pData);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001719}
1720
Tobin Ehlis7265e832015-01-19 08:42:29 -07001721XGL_LAYER_EXPORT void XGLAPI xglCmdFillBuffer(XGL_CMD_BUFFER cmdBuffer, XGL_BUFFER destBuffer, XGL_GPU_SIZE destOffset, XGL_GPU_SIZE fillSize, uint32_t data)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001722{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001723 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001724 XGL_GPU_MEMORY mem = getMemBindingFromObject(destBuffer);
1725 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001726 char str[1024];
Tobin Ehlis7265e832015-01-19 08:42:29 -07001727 sprintf(str, "In xglCmdFillMemory() call unable to update binding of destBuffer %p to cmdBuffer %p", destBuffer, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001728 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1729 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001730 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis7265e832015-01-19 08:42:29 -07001731 nextTable.CmdFillBuffer(cmdBuffer, destBuffer, destOffset, fillSize, data);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001732}
1733
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001734XGL_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 Ehlis6663f492014-11-10 12:29:12 -07001735{
Tobin Ehlisc145be82015-01-08 15:22:32 -07001736 // TODO : Verify memory is in XGL_IMAGE_STATE_CLEAR state
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001737 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001738 XGL_GPU_MEMORY mem = getMemBindingFromObject(image);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001739 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1740 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001741 sprintf(str, "In xglCmdClearColorImage() call unable to update binding of image buffer %p to cmdBuffer %p", image, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001742 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1743 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001744 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001745 nextTable.CmdClearColorImage(cmdBuffer, image, color, rangeCount, pRanges);
1746}
1747
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001748XGL_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 Ehlis6663f492014-11-10 12:29:12 -07001749{
Tobin Ehlisc145be82015-01-08 15:22:32 -07001750 // TODO : Verify memory is in XGL_IMAGE_STATE_CLEAR state
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001751 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001752 XGL_GPU_MEMORY mem = getMemBindingFromObject(image);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001753 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1754 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001755 sprintf(str, "In xglCmdClearColorImageRaw() call unable to update binding of image buffer %p to cmdBuffer %p", image, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001756 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1757 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001758 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001759 nextTable.CmdClearColorImageRaw(cmdBuffer, image, color, rangeCount, pRanges);
1760}
1761
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001762XGL_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 Ehlis6663f492014-11-10 12:29:12 -07001763{
Tobin Ehlisc145be82015-01-08 15:22:32 -07001764 // TODO : Verify memory is in XGL_IMAGE_STATE_CLEAR state
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001765 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001766 XGL_GPU_MEMORY mem = getMemBindingFromObject(image);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001767 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1768 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001769 sprintf(str, "In xglCmdClearDepthStencil() call unable to update binding of image buffer %p to cmdBuffer %p", image, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001770 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1771 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001772 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001773 nextTable.CmdClearDepthStencil(cmdBuffer, image, depth, stencil, rangeCount, pRanges);
1774}
1775
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001776XGL_LAYER_EXPORT void XGLAPI xglCmdResolveImage(XGL_CMD_BUFFER cmdBuffer, XGL_IMAGE srcImage, XGL_IMAGE destImage, uint32_t rectCount, const XGL_IMAGE_RESOLVE* pRects)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001777{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001778 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001779 XGL_GPU_MEMORY mem = getMemBindingFromObject(srcImage);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001780 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1781 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001782 sprintf(str, "In xglCmdResolveImage() call unable to update binding of srcImage buffer %p to cmdBuffer %p", srcImage, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001783 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1784 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001785 mem = getMemBindingFromObject(destImage);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001786 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1787 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001788 sprintf(str, "In xglCmdResolveImage() call unable to update binding of destImage buffer %p to cmdBuffer %p", destImage, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001789 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1790 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001791 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001792 nextTable.CmdResolveImage(cmdBuffer, srcImage, destImage, rectCount, pRects);
1793}
1794
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001795XGL_LAYER_EXPORT void XGLAPI xglCmdBeginQuery(XGL_CMD_BUFFER cmdBuffer, XGL_QUERY_POOL queryPool, uint32_t slot, XGL_FLAGS flags)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001796{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001797 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001798 XGL_GPU_MEMORY mem = getMemBindingFromObject(queryPool);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001799 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1800 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001801 sprintf(str, "In xglCmdBeginQuery() call unable to update binding of queryPool buffer %p to cmdBuffer %p", queryPool, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001802 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1803 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001804 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001805 nextTable.CmdBeginQuery(cmdBuffer, queryPool, slot, flags);
1806}
1807
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001808XGL_LAYER_EXPORT void XGLAPI xglCmdEndQuery(XGL_CMD_BUFFER cmdBuffer, XGL_QUERY_POOL queryPool, uint32_t slot)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001809{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001810 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001811 XGL_GPU_MEMORY mem = getMemBindingFromObject(queryPool);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001812 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1813 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001814 sprintf(str, "In xglCmdEndQuery() call unable to update binding of queryPool buffer %p to cmdBuffer %p", queryPool, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001815 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1816 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001817 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001818 nextTable.CmdEndQuery(cmdBuffer, queryPool, slot);
1819}
1820
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001821XGL_LAYER_EXPORT void XGLAPI xglCmdResetQueryPool(XGL_CMD_BUFFER cmdBuffer, XGL_QUERY_POOL queryPool, uint32_t startQuery, uint32_t queryCount)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001822{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001823 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001824 XGL_GPU_MEMORY mem = getMemBindingFromObject(queryPool);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001825 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1826 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001827 sprintf(str, "In xglCmdResetQueryPool() call unable to update binding of queryPool buffer %p to cmdBuffer %p", queryPool, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001828 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1829 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001830 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001831 nextTable.CmdResetQueryPool(cmdBuffer, queryPool, startQuery, queryCount);
1832}
1833
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001834XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglDbgRegisterMsgCallback(XGL_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback, void* pUserData)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001835{
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001836 // This layer intercepts callbacks
1837 XGL_LAYER_DBG_FUNCTION_NODE *pNewDbgFuncNode = (XGL_LAYER_DBG_FUNCTION_NODE*)malloc(sizeof(XGL_LAYER_DBG_FUNCTION_NODE));
1838 if (!pNewDbgFuncNode)
1839 return XGL_ERROR_OUT_OF_MEMORY;
1840 pNewDbgFuncNode->pfnMsgCallback = pfnMsgCallback;
1841 pNewDbgFuncNode->pUserData = pUserData;
Jon Ashburn7d7b3cf2014-12-22 13:24:15 -07001842 pNewDbgFuncNode->pNext = g_pDbgFunctionHead;
1843 g_pDbgFunctionHead = pNewDbgFuncNode;
Jon Ashburna8aa8372015-03-03 15:07:15 -07001844 // force callbacks if DebugAction hasn't been set already other than initial value
Courtney Goeltzenleuchter90d93202015-03-04 15:47:34 -07001845 if (g_actionIsDefault) {
Jon Ashburna8aa8372015-03-03 15:07:15 -07001846 g_debugAction = XGL_DBG_LAYER_ACTION_CALLBACK;
Courtney Goeltzenleuchter90d93202015-03-04 15:47:34 -07001847 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001848 XGL_RESULT result = nextTable.DbgRegisterMsgCallback(pfnMsgCallback, pUserData);
1849 return result;
1850}
1851
1852XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglDbgUnregisterMsgCallback(XGL_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback)
1853{
Jon Ashburn7d7b3cf2014-12-22 13:24:15 -07001854 XGL_LAYER_DBG_FUNCTION_NODE *pTrav = g_pDbgFunctionHead;
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001855 XGL_LAYER_DBG_FUNCTION_NODE *pPrev = pTrav;
1856 while (pTrav) {
1857 if (pTrav->pfnMsgCallback == pfnMsgCallback) {
1858 pPrev->pNext = pTrav->pNext;
Jon Ashburn7d7b3cf2014-12-22 13:24:15 -07001859 if (g_pDbgFunctionHead == pTrav)
1860 g_pDbgFunctionHead = pTrav->pNext;
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001861 free(pTrav);
1862 break;
1863 }
1864 pPrev = pTrav;
1865 pTrav = pTrav->pNext;
1866 }
Jon Ashburna8aa8372015-03-03 15:07:15 -07001867 if (g_pDbgFunctionHead == NULL)
1868 {
1869 if (g_actionIsDefault)
1870 g_debugAction = XGL_DBG_LAYER_ACTION_LOG_MSG;
1871 else
1872 g_debugAction &= ~XGL_DBG_LAYER_ACTION_CALLBACK;
1873 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001874 XGL_RESULT result = nextTable.DbgUnregisterMsgCallback(pfnMsgCallback);
1875 return result;
1876}
1877
Jon Ashburn71c2b152015-03-02 16:51:38 -07001878#if !defined(WIN32)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001879XGL_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)
1880{
1881 XGL_RESULT result = nextTable.WsiX11CreatePresentableImage(device, pCreateInfo, pImage, pMem);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001882 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001883 if (XGL_SUCCESS == result) {
1884 // Add image object, then insert the new Mem Object and then bind it to created image
1885 insertGlobalObjectNode(*pImage, _XGL_STRUCTURE_TYPE_MAX_ENUM, pCreateInfo, sizeof(XGL_WSI_X11_PRESENTABLE_IMAGE_CREATE_INFO), "wsi_x11_image");
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001886 insertGlobalMemObj(*pMem, NULL);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001887 if (XGL_FALSE == updateObjectBinding(*pImage, *pMem)) {
1888 char str[1024];
1889 sprintf(str, "In xglWsiX11CreatePresentableImage(), unable to set image %p binding to mem obj %p", (void*)*pImage, (void*)*pMem);
1890 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, *pImage, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1891 }
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001892 }
1893 printObjList();
1894 printMemList();
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001895 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001896 return result;
1897}
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -05001898
1899XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglWsiX11QueuePresent(XGL_QUEUE queue, const XGL_WSI_X11_PRESENT_INFO* pPresentInfo, XGL_FENCE fence)
1900{
1901 loader_platform_thread_lock_mutex(&globalLock);
1902 addFenceNode(fence);
1903 char str[1024];
1904 sprintf(str, "In xglWsiX11QueuePresent(), checking queue %p for fence %p", queue, fence);
1905 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, queue, 0, MEMTRACK_NONE, "MEM", str);
1906 loader_platform_thread_unlock_mutex(&globalLock);
1907 XGL_RESULT result = nextTable.WsiX11QueuePresent(queue, pPresentInfo, fence);
1908 return result;
1909}
Ian Elliott2d4ab1e2015-01-13 17:52:38 -07001910#endif // WIN32
Tobin Ehlis6663f492014-11-10 12:29:12 -07001911
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001912XGL_LAYER_EXPORT void* XGLAPI xglGetProcAddr(XGL_PHYSICAL_GPU gpu, const char* funcName)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001913{
1914 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
Chia-I Wu4d11dcc2015-01-05 13:18:57 +08001915
Tobin Ehlis6663f492014-11-10 12:29:12 -07001916 if (gpu == NULL)
1917 return NULL;
1918 pCurObj = gpuw;
Ian Elliott2d4ab1e2015-01-13 17:52:38 -07001919 loader_platform_thread_once(&g_initOnce, initMemTracker);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001920
Jon Ashburn71c2b152015-03-02 16:51:38 -07001921 if (!strcmp(funcName, "xglGetProcAddr"))
1922 return (void *) xglGetProcAddr;
1923 if (!strcmp(funcName, "xglCreateDevice"))
1924 return (void*) xglCreateDevice;
1925 if (!strcmp(funcName, "xglDestroyDevice"))
1926 return (void*) xglDestroyDevice;
1927 if (!strcmp(funcName, "xglEnumerateLayers"))
1928 return (void*) xglEnumerateLayers;
1929 if (!strcmp(funcName, "xglQueueSubmit"))
1930 return (void*) xglQueueSubmit;
1931 if (!strcmp(funcName, "xglQueueSetGlobalMemReferences"))
1932 return (void*) xglQueueSetGlobalMemReferences;
1933 if (!strcmp(funcName, "xglAllocMemory"))
1934 return (void*) xglAllocMemory;
1935 if (!strcmp(funcName, "xglFreeMemory"))
1936 return (void*) xglFreeMemory;
1937 if (!strcmp(funcName, "xglSetMemoryPriority"))
1938 return (void*) xglSetMemoryPriority;
1939 if (!strcmp(funcName, "xglMapMemory"))
1940 return (void*) xglMapMemory;
1941 if (!strcmp(funcName, "xglUnmapMemory"))
1942 return (void*) xglUnmapMemory;
1943 if (!strcmp(funcName, "xglPinSystemMemory"))
1944 return (void*) xglPinSystemMemory;
1945 if (!strcmp(funcName, "xglOpenSharedMemory"))
1946 return (void*) xglOpenSharedMemory;
1947 if (!strcmp(funcName, "xglOpenPeerMemory"))
1948 return (void*) xglOpenPeerMemory;
1949 if (!strcmp(funcName, "xglOpenPeerImage"))
1950 return (void*) xglOpenPeerImage;
1951 if (!strcmp(funcName, "xglDestroyObject"))
1952 return (void*) xglDestroyObject;
1953 if (!strcmp(funcName, "xglGetObjectInfo"))
1954 return (void*) xglGetObjectInfo;
1955 if (!strcmp(funcName, "xglBindObjectMemory"))
1956 return (void*) xglBindObjectMemory;
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07001957 if (!strcmp(funcName, "xglCreateFence"))
1958 return (void*) xglCreateFence;
1959 if (!strcmp(funcName, "xglGetFenceStatus"))
1960 return (void*) xglGetFenceStatus;
1961 if (!strcmp(funcName, "xglWaitForFences"))
1962 return (void*) xglWaitForFences;
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -05001963 if (!strcmp(funcName, "xglQueueWaitIdle"))
1964 return (void*) xglQueueWaitIdle;
1965 if (!strcmp(funcName, "xglDeviceWaitIdle"))
1966 return (void*) xglDeviceWaitIdle;
Jon Ashburn71c2b152015-03-02 16:51:38 -07001967 if (!strcmp(funcName, "xglCreateEvent"))
1968 return (void*) xglCreateEvent;
1969 if (!strcmp(funcName, "xglCreateQueryPool"))
1970 return (void*) xglCreateQueryPool;
1971 if (!strcmp(funcName, "xglCreateBuffer"))
1972 return (void*) xglCreateBuffer;
1973 if (!strcmp(funcName, "xglCreateBufferView"))
1974 return (void*) xglCreateBufferView;
1975 if (!strcmp(funcName, "xglCreateImage"))
1976 return (void*) xglCreateImage;
1977 if (!strcmp(funcName, "xglCreateImageView"))
1978 return (void*) xglCreateImageView;
1979 if (!strcmp(funcName, "xglCreateColorAttachmentView"))
1980 return (void*) xglCreateColorAttachmentView;
1981 if (!strcmp(funcName, "xglCreateDepthStencilView"))
1982 return (void*) xglCreateDepthStencilView;
1983 if (!strcmp(funcName, "xglCreateShader"))
1984 return (void*) xglCreateShader;
1985 if (!strcmp(funcName, "xglCreateGraphicsPipeline"))
1986 return (void*) xglCreateGraphicsPipeline;
1987 if (!strcmp(funcName, "xglCreateComputePipeline"))
1988 return (void*) xglCreateComputePipeline;
1989 if (!strcmp(funcName, "xglCreateSampler"))
1990 return (void*) xglCreateSampler;
1991 if (!strcmp(funcName, "xglCreateDynamicViewportState"))
1992 return (void*) xglCreateDynamicViewportState;
1993 if (!strcmp(funcName, "xglCreateDynamicRasterState"))
1994 return (void*) xglCreateDynamicRasterState;
1995 if (!strcmp(funcName, "xglCreateDynamicColorBlendState"))
1996 return (void*) xglCreateDynamicColorBlendState;
1997 if (!strcmp(funcName, "xglCreateDynamicDepthStencilState"))
1998 return (void*) xglCreateDynamicDepthStencilState;
1999 if (!strcmp(funcName, "xglCreateCommandBuffer"))
2000 return (void*) xglCreateCommandBuffer;
2001 if (!strcmp(funcName, "xglBeginCommandBuffer"))
2002 return (void*) xglBeginCommandBuffer;
2003 if (!strcmp(funcName, "xglEndCommandBuffer"))
2004 return (void*) xglEndCommandBuffer;
2005 if (!strcmp(funcName, "xglResetCommandBuffer"))
2006 return (void*) xglResetCommandBuffer;
2007 if (!strcmp(funcName, "xglCmdBindPipeline"))
2008 return (void*) xglCmdBindPipeline;
2009 if (!strcmp(funcName, "xglCmdBindDynamicStateObject"))
2010 return (void*) xglCmdBindDynamicStateObject;
2011 if (!strcmp(funcName, "xglCmdBindDescriptorSet"))
2012 return (void*) xglCmdBindDescriptorSet;
2013 if (!strcmp(funcName, "xglCmdBindVertexBuffer"))
2014 return (void*) xglCmdBindVertexBuffer;
2015 if (!strcmp(funcName, "xglCmdBindIndexBuffer"))
2016 return (void*) xglCmdBindIndexBuffer;
2017 if (!strcmp(funcName, "xglCmdDrawIndirect"))
2018 return (void*) xglCmdDrawIndirect;
2019 if (!strcmp(funcName, "xglCmdDrawIndexedIndirect"))
2020 return (void*) xglCmdDrawIndexedIndirect;
2021 if (!strcmp(funcName, "xglCmdDispatchIndirect"))
2022 return (void*) xglCmdDispatchIndirect;
2023 if (!strcmp(funcName, "xglCmdCopyBuffer"))
2024 return (void*) xglCmdCopyBuffer;
2025 if (!strcmp(funcName, "xglCmdCopyImage"))
2026 return (void*) xglCmdCopyImage;
2027 if (!strcmp(funcName, "xglCmdCopyBufferToImage"))
2028 return (void*) xglCmdCopyBufferToImage;
2029 if (!strcmp(funcName, "xglCmdCopyImageToBuffer"))
2030 return (void*) xglCmdCopyImageToBuffer;
2031 if (!strcmp(funcName, "xglCmdCloneImageData"))
2032 return (void*) xglCmdCloneImageData;
2033 if (!strcmp(funcName, "xglCmdUpdateBuffer"))
2034 return (void*) xglCmdUpdateBuffer;
2035 if (!strcmp(funcName, "xglCmdFillBuffer"))
2036 return (void*) xglCmdFillBuffer;
2037 if (!strcmp(funcName, "xglCmdClearColorImage"))
2038 return (void*) xglCmdClearColorImage;
2039 if (!strcmp(funcName, "xglCmdClearColorImageRaw"))
2040 return (void*) xglCmdClearColorImageRaw;
2041 if (!strcmp(funcName, "xglCmdClearDepthStencil"))
2042 return (void*) xglCmdClearDepthStencil;
2043 if (!strcmp(funcName, "xglCmdResolveImage"))
2044 return (void*) xglCmdResolveImage;
2045 if (!strcmp(funcName, "xglCmdBeginQuery"))
2046 return (void*) xglCmdBeginQuery;
2047 if (!strcmp(funcName, "xglCmdEndQuery"))
2048 return (void*) xglCmdEndQuery;
2049 if (!strcmp(funcName, "xglCmdResetQueryPool"))
2050 return (void*) xglCmdResetQueryPool;
2051 if (!strcmp(funcName, "xglDbgRegisterMsgCallback"))
2052 return (void*) xglDbgRegisterMsgCallback;
2053 if (!strcmp(funcName, "xglDbgUnregisterMsgCallback"))
2054 return (void*) xglDbgUnregisterMsgCallback;
2055#if !defined(WIN32)
2056 if (!strcmp(funcName, "xglWsiX11CreatePresentableImage"))
2057 return (void*) xglWsiX11CreatePresentableImage;
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -05002058 if (!strcmp(funcName, "xglWsiX11QueuePresent"))
2059 return (void*) xglWsiX11QueuePresent;
Jon Ashburn71c2b152015-03-02 16:51:38 -07002060#endif
Tobin Ehlis6663f492014-11-10 12:29:12 -07002061 else {
Tobin Ehlis6663f492014-11-10 12:29:12 -07002062 if (gpuw->pGPA == NULL)
2063 return NULL;
2064 return gpuw->pGPA(gpuw->nextObject, funcName);
2065 }
2066}