blob: 228dc45f270559a6b3de3f8bff83a06ebf3cfe3d [file] [log] [blame]
Tobin Ehlis791a49c2014-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
25#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
28#include <assert.h>
Ian Elliott81ac44c2015-01-13 17:52:38 -070029#include "loader_platform.h"
Chia-I Wu0f65b1e2015-01-04 23:11:43 +080030#include "xgl_dispatch_table_helper.h"
Tobin Ehlis791a49c2014-11-10 12:29:12 -070031#include "xgl_struct_string_helper.h"
Tobin Ehlis62086412014-11-19 16:19:28 -070032#include "mem_tracker.h"
Jon Ashburnf57ea372014-12-22 13:24:15 -070033#include "layers_config.h"
Ian Elliott20f06872015-02-12 17:08:34 -070034// The following is #included again to catch certain OS-specific functions
35// being used:
36#include "loader_platform.h"
Jon Ashburn5a7be202015-02-16 08:46:53 -070037#include "layers_msg.h"
Tobin Ehlis791a49c2014-11-10 12:29:12 -070038
39static XGL_LAYER_DISPATCH_TABLE nextTable;
40static XGL_BASE_LAYER_OBJECT *pCurObj;
Ian Elliott81ac44c2015-01-13 17:52:38 -070041static LOADER_PLATFORM_THREAD_ONCE_DECLARATION(g_initOnce);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -060042// TODO : This can be much smarter, using separate locks for separate global data
43static int globalLockInitialized = 0;
44static loader_platform_thread_mutex globalLock;
Jon Ashburnf57ea372014-12-22 13:24:15 -070045
Jon Ashburnf57ea372014-12-22 13:24:15 -070046
Tobin Ehlis2836a7d2015-01-08 15:22:32 -070047#define MAX_BINDING 0xFFFFFFFF
Tobin Ehlis2836a7d2015-01-08 15:22:32 -070048
Tobin Ehlis791a49c2014-11-10 12:29:12 -070049static GLOBAL_CB_NODE* pGlobalCBHead = NULL;
50static GLOBAL_MEM_OBJ_NODE* pGlobalMemObjHead = NULL;
51static GLOBAL_OBJECT_NODE* pGlobalObjectHead = NULL;
52static XGL_DEVICE globalDevice = NULL;
Tobin Ehlis62086412014-11-19 16:19:28 -070053static uint64_t numCBNodes = 0;
54static uint64_t numMemObjNodes = 0;
55static uint64_t numObjectNodes = 0;
Mark Lobodzinski15427102015-02-18 16:38:17 -060056
Tobin Ehlis791a49c2014-11-10 12:29:12 -070057// Check list for data and if it's not included insert new node
58// into HEAD of list pointed to by pHEAD & update pHEAD
Tobin Ehlis62086412014-11-19 16:19:28 -070059// Increment 'insert' if new node was inserted
Tobin Ehlis791a49c2014-11-10 12:29:12 -070060// return XGL_SUCCESS if no errors occur
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -060061static bool32_t insertMiniNode(MINI_NODE** pHEAD, const XGL_BASE_OBJECT data, uint32_t* insert)
Tobin Ehlis791a49c2014-11-10 12:29:12 -070062{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -060063 bool32_t result = XGL_TRUE;
Tobin Ehlis791a49c2014-11-10 12:29:12 -070064 MINI_NODE* pTrav = *pHEAD;
65 while (pTrav && (pTrav->data != data)) {
66 pTrav = pTrav->pNext;
67 }
68 if (!pTrav) { // Add node to front of LL
69 pTrav = (MINI_NODE*)malloc(sizeof(MINI_NODE));
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -060070 if (!pTrav) {
71 char str[1024];
72 sprintf(str, "Malloc failed to alloc memory for Mini Node");
73 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, data, 0, MEMTRACK_OUT_OF_MEMORY_ERROR, "MEM", str);
74 result = XGL_FALSE;
75 } else {
76 memset(pTrav, 0, sizeof(MINI_NODE));
77 if (*pHEAD) {
78 pTrav->pNext = *pHEAD;
79 }
80 *pHEAD = pTrav;
81 *insert += 1;
82 //pMemTrav->refCount++;
83 //sprintf(str, "MEM INFO : Incremented refCount for mem obj %p to %u", (void*)mem, pMemTrav->refCount);
84 if (pTrav->data) { // This is just FYI
85 assert(data == pTrav->data);
86 char str[1024];
87 sprintf(str, "Data %p is already in data LL w/ HEAD at %p", data, *pHEAD);
88 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, data, 0, MEMTRACK_NONE, "MEM", str);
89 }
90 pTrav->data = data;
91 }
92 } else {
93 pTrav->data = data;
Tobin Ehlis791a49c2014-11-10 12:29:12 -070094 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -060095 return result;
Tobin Ehlis791a49c2014-11-10 12:29:12 -070096}
97
98// Add new CB node for this cb at end of global CB LL
99static void insertGlobalCB(const XGL_CMD_BUFFER cb)
100{
101 GLOBAL_CB_NODE* pTrav = pGlobalCBHead;
102 if (!pTrav) {
103 pTrav = (GLOBAL_CB_NODE*)malloc(sizeof(GLOBAL_CB_NODE));
104 pGlobalCBHead = pTrav;
105 }
106 else {
107 while (NULL != pTrav->pNextGlobalCBNode)
108 pTrav = pTrav->pNextGlobalCBNode;
109 pTrav->pNextGlobalCBNode = (GLOBAL_CB_NODE*)malloc(sizeof(GLOBAL_CB_NODE));
110 pTrav = pTrav->pNextGlobalCBNode;
111 }
Tobin Ehlis62086412014-11-19 16:19:28 -0700112 if (!pTrav) {
113 char str[1024];
114 sprintf(str, "Malloc failed to alloc node for Cmd Buffer %p", (void*)cb);
115 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_OUT_OF_MEMORY_ERROR, "MEM", str);
116 }
117 else {
118 numCBNodes++;
119 memset(pTrav, 0, sizeof(GLOBAL_CB_NODE));
120 pTrav->cmdBuffer = cb;
121 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700122}
123
124// Return ptr to node in global LL containing cb, or NULL if not found
125static GLOBAL_CB_NODE* getGlobalCBNode(const XGL_CMD_BUFFER cb)
126{
127 GLOBAL_CB_NODE* pTrav = pGlobalCBHead;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600128 while (pTrav && (pTrav->cmdBuffer != cb)) {
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700129 pTrav = pTrav->pNextGlobalCBNode;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600130 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700131 return pTrav;
132}
133// Set fence for given cb in global cb node
Mark Lobodzinski821b57f2015-02-25 18:11:05 -0600134static bool32_t setCBFence(const XGL_CMD_BUFFER cb, const XGL_FENCE fence, bool32_t localFlag)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700135{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600136
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700137 GLOBAL_CB_NODE* pTrav = getGlobalCBNode(cb);
138 if (!pTrav) {
Tobin Ehlis62086412014-11-19 16:19:28 -0700139 char str[1024];
140 sprintf(str, "Unable to find node for CB %p in order to set fence to %p", (void*)cb, (void*)fence);
141 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_INVALID_CB, "MEM", str);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700142 return XGL_FALSE;
143 }
144 pTrav->fence = fence;
Mark Lobodzinski821b57f2015-02-25 18:11:05 -0600145 pTrav->localFlag = localFlag;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700146 return XGL_TRUE;
147}
148
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600149static bool32_t validateCBMemRef(const XGL_CMD_BUFFER cb, uint32_t memRefCount, const XGL_MEMORY_REF* pMemRefs)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700150{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600151 bool32_t result = XGL_TRUE;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700152 GLOBAL_CB_NODE* pTrav = getGlobalCBNode(cb);
153 if (!pTrav) {
Tobin Ehlis62086412014-11-19 16:19:28 -0700154 char str[1024];
155 sprintf(str, "Unable to find node for CB %p in order to check memory references", (void*)cb);
156 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_INVALID_CB, "MEM", str);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600157 result = XGL_FALSE;
158 } else {
159 // Validate that all actual references are accounted for in pMemRefs
160 MINI_NODE* pMemNode = pTrav->pMemObjList;
161 uint32_t i;
162 uint8_t found = 0;
163 uint64_t foundCount = 0;
164 while (pMemNode && (result == XGL_TRUE)) {
165 // TODO : Improve this algorithm
166 for (i = 0; i < memRefCount; i++) {
167 if (pMemNode->mem == pMemRefs[i].mem) {
168 char str[1024];
169 sprintf(str, "Found Mem Obj %p binding to CB %p", pMemNode->mem, cb);
170 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_NONE, "MEM", str);
171 found = 1;
172 foundCount++;
173 break;
174 }
175 }
176 if (!found) {
Tobin Ehlis62086412014-11-19 16:19:28 -0700177 char str[1024];
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600178 sprintf(str, "Memory reference list for Command Buffer %p is missing ref to mem obj %p", cb, pMemNode->mem);
179 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_CB_MISSING_MEM_REF, "MEM", str);
180 result = XGL_FALSE;
181 }
182 found = 0;
183 pMemNode = pMemNode->pNext;
184 }
185 if (result == XGL_TRUE) {
186 char str[1024];
187 sprintf(str, "Verified all %lu memory dependencies for CB %p are included in pMemRefs list", foundCount, cb);
188 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_NONE, "MEM", str);
189 // TODO : Could report mem refs in pMemRefs that AREN'T in mem LL, that would be primarily informational
190 // Currently just noting that there is a difference
191 if (foundCount != memRefCount) {
192 sprintf(str, "There are %u mem refs included in pMemRefs list, but only %lu appear are required", memRefCount, foundCount);
Tobin Ehlis62086412014-11-19 16:19:28 -0700193 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700194 }
195 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700196 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600197 return result;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700198}
Tobin Ehlis2836a7d2015-01-08 15:22:32 -0700199// Return ptr to node in global LL containing mem, or NULL if not found
Tobin Ehlis77b3abb2015-03-04 08:38:22 -0700200// Calls to this function should be wrapped in mutex
Tobin Ehlis2836a7d2015-01-08 15:22:32 -0700201static GLOBAL_MEM_OBJ_NODE* getGlobalMemNode(const XGL_GPU_MEMORY mem)
202{
203 GLOBAL_MEM_OBJ_NODE* pTrav = pGlobalMemObjHead;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600204 while (pTrav && (pTrav->mem != mem)) {
Tobin Ehlis2836a7d2015-01-08 15:22:32 -0700205 pTrav = pTrav->pNextGlobalNode;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600206 }
Tobin Ehlis2836a7d2015-01-08 15:22:32 -0700207 return pTrav;
208}
209
Mark Lobodzinski15427102015-02-18 16:38:17 -0600210static void insertGlobalMemObj(const XGL_GPU_MEMORY mem, const XGL_MEMORY_ALLOC_INFO* pAllocInfo)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700211{
212 GLOBAL_MEM_OBJ_NODE* pTrav = pGlobalMemObjHead;
213 if (!pTrav) {
214 pTrav = (GLOBAL_MEM_OBJ_NODE*)malloc(sizeof(GLOBAL_MEM_OBJ_NODE));
215 pGlobalMemObjHead = pTrav;
216 }
217 else {
218 while (NULL != pTrav->pNextGlobalNode)
219 pTrav = pTrav->pNextGlobalNode;
220 pTrav->pNextGlobalNode = (GLOBAL_MEM_OBJ_NODE*)malloc(sizeof(GLOBAL_MEM_OBJ_NODE));
221 pTrav = pTrav->pNextGlobalNode;
222 }
Tobin Ehlis62086412014-11-19 16:19:28 -0700223 if (!pTrav) {
224 char str[1024];
225 sprintf(str, "Malloc failed to alloc node for Mem Object %p", (void*)mem);
226 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_OUT_OF_MEMORY_ERROR, "MEM", str);
227 }
228 else {
229 numMemObjNodes++;
230 memset(pTrav, 0, sizeof(GLOBAL_MEM_OBJ_NODE));
Mark Lobodzinski15427102015-02-18 16:38:17 -0600231 if (pAllocInfo) { // MEM alloc created by xglWsiX11CreatePresentableImage() doesn't have alloc info struct
Tobin Ehlis62086412014-11-19 16:19:28 -0700232 memcpy(&pTrav->allocInfo, pAllocInfo, sizeof(XGL_MEMORY_ALLOC_INFO));
Mark Lobodzinski15427102015-02-18 16:38:17 -0600233 // TODO: Update for real hardware, actually process allocation info structures
234 pTrav->allocInfo.pNext = NULL;
Tobin Ehlis2836a7d2015-01-08 15:22:32 -0700235 }
Mark Lobodzinski15427102015-02-18 16:38:17 -0600236 pTrav->mem = mem;
Tobin Ehlis62086412014-11-19 16:19:28 -0700237 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700238}
239
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700240// Find Global CB Node and add mem binding to mini LL
241// Find Global Mem Obj Node and add CB binding to mini LL
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600242static bool32_t updateCBBinding(const XGL_CMD_BUFFER cb, const XGL_GPU_MEMORY mem)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700243{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600244 bool32_t result = XGL_FALSE;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700245 // First update CB binding in MemObj mini CB list
246 GLOBAL_MEM_OBJ_NODE* pMemTrav = getGlobalMemNode(mem);
247 if (!pMemTrav) {
Tobin Ehlis62086412014-11-19 16:19:28 -0700248 char str[1024];
249 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);
250 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600251 result = XGL_FALSE;
252 } else {
253 result = insertMiniNode(&pMemTrav->pCmdBufferBindings, cb, &pMemTrav->refCount);
254 if (XGL_TRUE == result) {
255 // Now update Global CB's Mini Mem binding list
256 GLOBAL_CB_NODE* pCBTrav = getGlobalCBNode(cb);
257 if (!pCBTrav) {
258 char str[1024];
259 sprintf(str, "Trying to bind mem obj %p to CB %p but no Node for that CB. Was it CB incorrectly destroyed?", mem, cb);
260 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
261 result = XGL_FALSE;
262 } else {
263 uint32_t dontCare;
264 result = insertMiniNode(&pCBTrav->pMemObjList, mem, &dontCare);
265 }
266 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700267 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600268 return result;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700269}
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600270
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700271// Clear the CB Binding for mem
Tobin Ehlis77b3abb2015-03-04 08:38:22 -0700272// Calls to this function should be wrapped in mutex
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700273static void clearCBBinding(const XGL_CMD_BUFFER cb, const XGL_GPU_MEMORY mem)
274{
275 GLOBAL_MEM_OBJ_NODE* pTrav = getGlobalMemNode(mem);
Tobin Ehlis77b3abb2015-03-04 08:38:22 -0700276 // TODO : Having this check is not ideal, really if mem node was deleted,
277 // its CB bindings should be cleared and then freeCBBindings wouldn't call
278 // us here with stale mem objs
279 if (pTrav) {
280 MINI_NODE* pMiniCB = pTrav->pCmdBufferBindings;
281 MINI_NODE* pPrev = pMiniCB;
282 while (pMiniCB && (cb != pMiniCB->cmdBuffer)) {
283 pPrev = pMiniCB;
284 pMiniCB = pMiniCB->pNext;
285 }
Mark Lobodzinski1c114f82015-03-05 10:07:53 -0600286 if (pMiniCB) { // remove node from list & decrement refCount
Tobin Ehlis77b3abb2015-03-04 08:38:22 -0700287 pPrev->pNext = pMiniCB->pNext;
288 if (pMiniCB == pTrav->pCmdBufferBindings)
289 pTrav->pCmdBufferBindings = NULL;
290 free(pMiniCB);
291 pTrav->refCount--;
292 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700293 }
294}
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600295
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700296// Free bindings related to CB
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600297static bool32_t freeCBBindings(const XGL_CMD_BUFFER cb)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700298{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600299 bool32_t result = XGL_TRUE;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700300 GLOBAL_CB_NODE* pCBTrav = getGlobalCBNode(cb);
301 if (!pCBTrav) {
Tobin Ehlis62086412014-11-19 16:19:28 -0700302 char str[1024];
303 sprintf(str, "Unable to find global CB node %p for deletion", cb);
304 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_INVALID_CB, "MEM", str);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600305 result = XGL_FALSE;
306 } else {
307 if ((pCBTrav->fence != NULL) && (pCBTrav->localFlag == XGL_TRUE)) {
308 nextTable.DestroyObject(pCBTrav->fence);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600309 pCBTrav->localFlag = XGL_FALSE;
310 }
Tobin Ehlis77b3abb2015-03-04 08:38:22 -0700311 pCBTrav->fence = NULL;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600312 MINI_NODE* pMemTrav = pCBTrav->pMemObjList;
313 MINI_NODE* pDeleteMe = NULL;
314 // We traverse LL in order and free nodes as they're cleared
315 while (pMemTrav) {
316 pDeleteMe = pMemTrav;
317 if (pMemTrav->mem)
318 clearCBBinding(cb, pMemTrav->mem);
319 pMemTrav = pMemTrav->pNext;
320 free(pDeleteMe);
321 }
322 pCBTrav->pMemObjList = NULL;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700323 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600324 return result;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700325}
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600326
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700327// Delete Global CB Node from list along with all of it's mini mem obj node
328// and also clear Global mem references to CB
329// TODO : When should this be called? There's no Destroy of CBs that I see
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600330static bool32_t deleteGlobalCBNode(const XGL_CMD_BUFFER cb)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700331{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600332 bool32_t result = XGL_TRUE;
333 result = freeCBBindings(cb);
334 if (result == XGL_TRUE) {
335 // Delete the Global CB node
336 GLOBAL_CB_NODE* pCBTrav = getGlobalCBNode(cb);
337 pCBTrav = pGlobalCBHead;
338 GLOBAL_CB_NODE* pPrev = pCBTrav;
339 while (pCBTrav && (cb != pCBTrav->cmdBuffer)) {
340 pPrev = pCBTrav;
341 pCBTrav = pCBTrav->pNextGlobalCBNode;
342 }
343 assert(cb); // We found node at start of function so it should still be here
344 pPrev->pNextGlobalCBNode = pCBTrav->pNextGlobalCBNode;
345 if (pCBTrav == pGlobalCBHead) {
346 pGlobalCBHead = pCBTrav->pNextGlobalCBNode;
347 }
348 free(pCBTrav);
Ian Elliott81ac44c2015-01-13 17:52:38 -0700349 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600350 return result;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700351}
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600352
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700353// Delete the entire CB list
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600354static bool32_t deleteGlobalCBList()
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700355{
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600356 bool32_t result = XGL_TRUE;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700357 GLOBAL_CB_NODE* pCBTrav = pGlobalCBHead;
358 while (pCBTrav) {
Tobin Ehlisa747e682014-11-25 14:47:20 -0700359 XGL_CMD_BUFFER cbToDelete = pCBTrav->cmdBuffer;
360 pCBTrav = pCBTrav->pNextGlobalCBNode;
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600361 bool32_t tmpResult = deleteGlobalCBNode(cbToDelete);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700362 // If any result is FALSE, final result should be FALSE
363 if ((XGL_FALSE == tmpResult) || (XGL_FALSE == result))
364 result = XGL_FALSE;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700365 }
366 return result;
367}
368
369// For given MemObj node, report Obj & CB bindings
370static void reportMemReferences(const GLOBAL_MEM_OBJ_NODE* pMemObjTrav)
371{
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600372 uint32_t refCount = 0; // Count found references
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700373 MINI_NODE* pObjTrav = pMemObjTrav->pObjBindings;
374 MINI_NODE* pCBTrav = pMemObjTrav->pCmdBufferBindings;
375 while (pCBTrav) {
376 refCount++;
Tobin Ehlis62086412014-11-19 16:19:28 -0700377 char str[1024];
378 sprintf(str, "Command Buffer %p has reference to mem obj %p", pCBTrav->cmdBuffer, pMemObjTrav->mem);
379 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, pCBTrav->cmdBuffer, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700380 pCBTrav = pCBTrav->pNext;
381 }
382 while (pObjTrav) {
383 refCount++;
Tobin Ehlis62086412014-11-19 16:19:28 -0700384 char str[1024];
385 sprintf(str, "XGL Object %p has reference to mem obj %p", pObjTrav->object, pMemObjTrav->mem);
386 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, pObjTrav->object, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700387 pObjTrav = pObjTrav->pNext;
388 }
389 if (refCount != pMemObjTrav->refCount) {
Tobin Ehlis62086412014-11-19 16:19:28 -0700390 char str[1024];
391 sprintf(str, "Refcount of %u for Mem Obj %p does't match reported refs of %u", pMemObjTrav->refCount, pMemObjTrav->mem, refCount);
Mark Lobodzinski6338b312015-02-26 15:18:57 -0600392 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, pMemObjTrav->mem, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700393 }
394}
395
396static void deleteGlobalMemNode(XGL_GPU_MEMORY mem)
397{
398 GLOBAL_MEM_OBJ_NODE* pTrav = pGlobalMemObjHead;
399 GLOBAL_MEM_OBJ_NODE* pPrev = pTrav;
400 while (pTrav && (pTrav->mem != mem)) {
401 pPrev = pTrav;
402 pTrav = pTrav->pNextGlobalNode;
403 }
404 if (pTrav) {
405 pPrev->pNextGlobalNode = pTrav->pNextGlobalNode;
406 if (pGlobalMemObjHead == pTrav)
407 pGlobalMemObjHead = pTrav->pNextGlobalNode;
408 free(pTrav);
409 }
410 else {
Tobin Ehlis62086412014-11-19 16:19:28 -0700411 char str[1024];
412 sprintf(str, "Could not find global mem obj node for %p to delete!", mem);
413 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700414 }
415}
416// Check if fence for given CB is completed
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600417static bool32_t checkCBCompleted(const XGL_CMD_BUFFER cb)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700418{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600419 bool32_t result = XGL_TRUE;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700420 GLOBAL_CB_NODE* pCBTrav = getGlobalCBNode(cb);
421 if (!pCBTrav) {
Tobin Ehlis62086412014-11-19 16:19:28 -0700422 char str[1024];
423 sprintf(str, "Unable to find global CB node %p to check for completion", cb);
424 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_INVALID_CB, "MEM", str);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600425 result = XGL_FALSE;
426 } else {
Mark Lobodzinski1c114f82015-03-05 10:07:53 -0600427 if (pCBTrav->fence) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600428 if (XGL_SUCCESS != nextTable.GetFenceStatus(pCBTrav->fence)) {
429 char str[1024];
430 sprintf(str, "Fence %p for CB %p has not completed", pCBTrav->fence, cb);
431 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_NONE, "MEM", str);
432 result = XGL_FALSE;
433 }
434 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700435 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600436 return result;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700437}
438
Tobin Ehlis77b3abb2015-03-04 08:38:22 -0700439static void clearCBFence(const XGL_FENCE fence)
440{
441 // TODO : This is slow and stupid
442 // Ultimately would like a quick fence lookup w/ all of the CBs using that fence
443 // We have to loop every CB for now b/c multiple CBs may use same fence
444 GLOBAL_CB_NODE* pCBTrav = pGlobalCBHead;
445 while (pCBTrav) {
446 if (pCBTrav->fence == fence) {
447 pCBTrav->fence = NULL;
448 }
449 pCBTrav = pCBTrav->pNextGlobalCBNode;
450 }
451}
452
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600453static bool32_t freeMemNode(XGL_GPU_MEMORY mem)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700454{
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600455 bool32_t result = XGL_TRUE;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700456 // Parse global list to find node w/ mem
457 GLOBAL_MEM_OBJ_NODE* pTrav = getGlobalMemNode(mem);
458 if (!pTrav) {
Tobin Ehlis62086412014-11-19 16:19:28 -0700459 char str[1024];
460 sprintf(str, "Couldn't find mem node object for %p\n Was %p never allocated or previously freed?", (void*)mem, (void*)mem);
461 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600462 result = XGL_FALSE;
463 } else {
Mark Lobodzinskidaa1d432015-02-18 18:06:24 -0600464 if (pTrav->allocInfo.allocationSize == 0) {
465 char str[1024];
466 sprintf(str, "Attempting to free memory associated with a Presentable Image, %p, this should not be explicitly freed\n", (void*)mem);
Mark Lobodzinskiacb93682015-03-05 12:39:33 -0600467 layerCbMsg(XGL_DBG_MSG_WARNING, XGL_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700468 result = XGL_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600469 } else {
470 // Clear any CB bindings for completed CBs
471 // TODO : Is there a better place to do this?
472 MINI_NODE* pMiniCB = pTrav->pCmdBufferBindings;
473 while (pMiniCB) {
474 XGL_CMD_BUFFER curCB = pMiniCB->cmdBuffer;
475 pMiniCB = pMiniCB->pNext;
476 if (XGL_TRUE == checkCBCompleted(curCB)) {
477 freeCBBindings(curCB);
478 }
479 }
480 // Now verify that no references to this mem obj remain
481 if (0 != pTrav->refCount) {
482 // If references remain, report the error and can search down CB LL to find references
483 char str[1024];
484 sprintf(str, "Freeing mem obj %p while it still has references", (void*)mem);
485 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_FREED_MEM_REF, "MEM", str);
486 reportMemReferences(pTrav);
487 result = XGL_FALSE;
488 }
489 // Delete global node
490 deleteGlobalMemNode(mem);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700491 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700492 }
493 return result;
494}
495
496// Return object node for 'object' or return NULL if no node exists
497static GLOBAL_OBJECT_NODE* getGlobalObjectNode(const XGL_OBJECT object)
498{
499 GLOBAL_OBJECT_NODE* pTrav = pGlobalObjectHead;
500 while (pTrav && (object != pTrav->object)) {
501 pTrav = pTrav->pNext;
502 }
503 return pTrav;
504}
505
Tobin Ehlis6aa77422015-01-07 17:49:29 -0700506static GLOBAL_OBJECT_NODE* insertGlobalObjectNode(XGL_OBJECT object, XGL_STRUCTURE_TYPE sType, const void *pCreateInfo, const int struct_size, char *name_prefix)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700507{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600508 GLOBAL_OBJECT_NODE* newNode = NULL;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700509 GLOBAL_OBJECT_NODE* pTrav = pGlobalObjectHead;
510 if (!pTrav) {
511 pTrav = (GLOBAL_OBJECT_NODE*)malloc(sizeof(GLOBAL_OBJECT_NODE));
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700512 memset(pTrav, 0, sizeof(GLOBAL_OBJECT_NODE));
513 pGlobalObjectHead = pTrav;
514 }
515 else {
516 GLOBAL_OBJECT_NODE* pPrev = pTrav;
517 while (pTrav) {
518 pPrev = pTrav;
519 pTrav = pTrav->pNext;
520 }
521 pTrav = (GLOBAL_OBJECT_NODE*)malloc(sizeof(GLOBAL_OBJECT_NODE));
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700522 memset(pTrav, 0, sizeof(GLOBAL_OBJECT_NODE));
523 pPrev->pNext = pTrav;
524 }
Tobin Ehlis62086412014-11-19 16:19:28 -0700525 if (!pTrav) {
526 char str[1024];
527 sprintf(str, "Malloc failed to alloc node for XGL Object %p", (void*)object);
528 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, object, 0, MEMTRACK_OUT_OF_MEMORY_ERROR, "MEM", str);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600529 } else {
Tobin Ehlis62086412014-11-19 16:19:28 -0700530 numObjectNodes++;
531 pTrav->object = object;
Tobin Ehlis6aa77422015-01-07 17:49:29 -0700532 pTrav->ref_count = 1;
533 pTrav->sType = sType;
534 memcpy(&pTrav->create_info, pCreateInfo, struct_size);
535 sprintf(pTrav->object_name, "%s_%p", name_prefix, object);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600536 newNode = pTrav;
Tobin Ehlis62086412014-11-19 16:19:28 -0700537 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600538 return newNode;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700539}
540
541// Remove object binding performs 3 tasks:
542// 1. Remove object node from Global Mem Obj mini LL of obj bindings & free it
543// 2. Decrement refCount for Global Mem Obj
544// 3. Clear Global Mem Obj ptr from Global Object Node
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600545static bool32_t clearObjectBinding(XGL_OBJECT object)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700546{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600547 bool32_t result = XGL_FALSE;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700548 GLOBAL_OBJECT_NODE* pGlobalObjTrav = getGlobalObjectNode(object);
549 if (!pGlobalObjTrav) {
Tobin Ehlis62086412014-11-19 16:19:28 -0700550 char str[1024];
Mark Lobodzinski15427102015-02-18 16:38:17 -0600551 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);
552 layerCbMsg(XGL_DBG_MSG_WARNING, XGL_VALIDATION_LEVEL_0, object, 0, MEMTRACK_INVALID_OBJECT, "MEM", str);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600553 } else {
554 if (!pGlobalObjTrav->pMemNode) {
555 char str[1024];
556 sprintf(str, "Attempting to clear mem binding on obj %p but it has no binding.", (void*)object);
557 layerCbMsg(XGL_DBG_MSG_WARNING, XGL_VALIDATION_LEVEL_0, object, 0, MEMTRACK_MEM_OBJ_CLEAR_EMPTY_BINDINGS, "MEM", str);
558 } else {
559 MINI_NODE* pObjTrav = pGlobalObjTrav->pMemNode->pObjBindings;
560 MINI_NODE* pPrevObj = pObjTrav;
561 while (pObjTrav && (result == XGL_FALSE)) {
562 if (object == pObjTrav->object) {
563 pPrevObj->pNext = pObjTrav->pNext;
564 // check if HEAD needs to be updated
565 if (pGlobalObjTrav->pMemNode->pObjBindings == pObjTrav)
566 pGlobalObjTrav->pMemNode->pObjBindings = pObjTrav->pNext;
567 free(pObjTrav);
568 pGlobalObjTrav->pMemNode->refCount--;
569 pGlobalObjTrav->pMemNode = NULL;
570 result = XGL_TRUE;
571 }
572 pPrevObj = pObjTrav;
573 pObjTrav = pObjTrav->pNext;
574 }
575 if (result == XGL_FALSE) {
576 char str[1024];
577 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);
578 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, object, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
579 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700580 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700581 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600582 return result;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700583}
584
585// For NULL mem case, clear any previous binding Else...
586// Make sure given object is in global object LL
Tobin Ehlis62086412014-11-19 16:19:28 -0700587// IF a previous binding existed, clear it
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700588// Add link from global object node to global memory node
589// Add mini-object node & reference off of global obj node
590// Return XGL_TRUE if addition is successful, XGL_FALSE otherwise
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600591static bool32_t updateObjectBinding(XGL_OBJECT object, XGL_GPU_MEMORY mem)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700592{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600593 bool32_t result = XGL_FALSE;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700594 // Handle NULL case separately, just clear previous binding & decrement reference
595 if (mem == XGL_NULL_HANDLE) {
596 clearObjectBinding(object);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600597 result = XGL_TRUE;
598 } else {
599 char str[1024];
600 GLOBAL_OBJECT_NODE* pGlobalObjTrav = getGlobalObjectNode(object);
601 if (!pGlobalObjTrav) {
602 sprintf(str, "Attempting to update Binding of Obj(%p) that's not in global list()", (void*)object);
603 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, object, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
604 return XGL_FALSE;
605 }
606 // non-null case so should have real mem obj
607 GLOBAL_MEM_OBJ_NODE* pTrav = getGlobalMemNode(mem);
608 if (!pTrav) {
609 sprintf(str, "While trying to bind mem for obj %p, couldn't find node for mem obj %p", (void*)object, (void*)mem);
610 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
611 } else {
612 result = insertMiniNode(&pTrav->pObjBindings, object, &pTrav->refCount);
613 if (XGL_TRUE == result) {
614 if (pGlobalObjTrav->pMemNode) {
615 clearObjectBinding(object); // Need to clear the previous object binding before setting new binding
616 sprintf(str, "Updating memory binding for object %p from mem obj %p to %p", object, pGlobalObjTrav->pMemNode->mem, mem);
617 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, object, 0, MEMTRACK_NONE, "MEM", str);
618 }
619 // For image objects, make sure default memory state is correctly set
620 // TODO : What's the best/correct way to handle this?
621 if (XGL_STRUCTURE_TYPE_IMAGE_CREATE_INFO == pGlobalObjTrav->sType) {
622 if (pGlobalObjTrav->create_info.image_create_info.usage & (XGL_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | XGL_IMAGE_USAGE_DEPTH_STENCIL_BIT)) {
623 // TODO:: More memory state transition stuff.
624 }
625 }
626 pGlobalObjTrav->pMemNode = pTrav;
627 }
Tobin Ehlis6aa77422015-01-07 17:49:29 -0700628 }
629 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700630 return XGL_TRUE;
631}
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600632
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700633// Print details of global Obj tracking list
634static void printObjList()
635{
636 GLOBAL_OBJECT_NODE* pGlobalObjTrav = pGlobalObjectHead;
637 if (!pGlobalObjTrav) {
Tobin Ehlis62086412014-11-19 16:19:28 -0700638 char str[1024];
639 sprintf(str, "Global Object list is empty :(\n");
640 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700641 }
642 else {
Tobin Ehlis62086412014-11-19 16:19:28 -0700643 char str[1024];
644 sprintf(str, "Details of Global Object list w/ HEAD at %p", (void*)pGlobalObjTrav);
645 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700646 while (pGlobalObjTrav) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600647 sprintf(str, " GlobObjNode %p has object %p, pNext %p, pMemNode %p",
648 pGlobalObjTrav, pGlobalObjTrav->object, pGlobalObjTrav->pNext, pGlobalObjTrav->pMemNode);
Tobin Ehlis62086412014-11-19 16:19:28 -0700649 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, pGlobalObjTrav->object, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700650 pGlobalObjTrav = pGlobalObjTrav->pNext;
651 }
652 }
653}
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600654
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700655// For given Object, get 'mem' obj that it's bound to or NULL if no binding
656static XGL_GPU_MEMORY getMemBindingFromObject(const XGL_OBJECT object)
657{
658 XGL_GPU_MEMORY mem = NULL;
659 GLOBAL_OBJECT_NODE* pObjNode = getGlobalObjectNode(object);
660 if (pObjNode) {
661 if (pObjNode->pMemNode) {
662 mem = pObjNode->pMemNode->mem;
663 }
664 else {
Tobin Ehlis62086412014-11-19 16:19:28 -0700665 char str[1024];
666 sprintf(str, "Trying to get mem binding for object %p but object has no mem binding", (void*)object);
667 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, object, 0, MEMTRACK_MISSING_MEM_BINDINGS, "MEM", str);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700668 printObjList();
669 }
670 }
671 else {
Tobin Ehlis62086412014-11-19 16:19:28 -0700672 char str[1024];
673 sprintf(str, "Trying to get mem binding for object %p but no such object in global list", (void*)object);
674 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, object, 0, MEMTRACK_INVALID_OBJECT, "MEM", str);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700675 printObjList();
676 }
677 return mem;
678}
679// Print details of global Mem Obj list
680static void printMemList()
681{
682 GLOBAL_MEM_OBJ_NODE* pTrav = pGlobalMemObjHead;
Tobin Ehlis62086412014-11-19 16:19:28 -0700683 // Just printing each msg individually for now, may want to package these into single large print
684 char str[1024];
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700685 if (!pTrav) {
Tobin Ehlis62086412014-11-19 16:19:28 -0700686 sprintf(str, "MEM INFO : Global Memory Object list is empty :(\n");
687 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700688 }
689 else {
Tobin Ehlis62086412014-11-19 16:19:28 -0700690 sprintf(str, "MEM INFO : Details of Global Memory Object list w/ HEAD at %p", (void*)pTrav);
691 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700692 while (pTrav) {
Tobin Ehlis62086412014-11-19 16:19:28 -0700693 sprintf(str, " ===MemObj Node at %p===", (void*)pTrav);
694 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
695 sprintf(str, " Mem object: %p", (void*)pTrav->mem);
696 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
697 sprintf(str, " Ref Count: %u", pTrav->refCount);
698 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
699 sprintf(str, " pNext Mem Obj Node: %p", (void*)pTrav->pNextGlobalNode);
700 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinski32790592015-02-26 18:33:10 -0600701 if (0 != pTrav->allocInfo.allocationSize) {
702 char* pAllocInfoMsg = xgl_print_xgl_memory_alloc_info(&pTrav->allocInfo, "{MEM}INFO : ");
703 sprintf(str, " Mem Alloc info:\n%s", pAllocInfoMsg);
704 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
705 free(pAllocInfoMsg);
706 } else {
Tobin Ehlis62086412014-11-19 16:19:28 -0700707 sprintf(str, " Mem Alloc info is NULL (alloc done by xglWsiX11CreatePresentableImage())");
Mark Lobodzinski32790592015-02-26 18:33:10 -0600708 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
709 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700710 MINI_NODE* pObjTrav = pTrav->pObjBindings;
Tobin Ehlis62086412014-11-19 16:19:28 -0700711 if (!pObjTrav) {
712 sprintf(str, " No XGL Object bindings");
713 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
714 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700715 else {
Tobin Ehlis62086412014-11-19 16:19:28 -0700716 sprintf(str, " XGL OBJECT Binding list w/ HEAD at %p:", pObjTrav);
717 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700718 while (pObjTrav) {
Tobin Ehlis62086412014-11-19 16:19:28 -0700719 sprintf(str, " OBJ_NODE(%p): XGL OBJECT %p, pNext %p", pObjTrav, pObjTrav->object, pObjTrav->pNext);
720 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700721 pObjTrav = pObjTrav->pNext;
722 }
723 }
724 MINI_NODE* pCBTrav = pTrav->pCmdBufferBindings;
Tobin Ehlis62086412014-11-19 16:19:28 -0700725 if (!pCBTrav) {
726 sprintf(str, " No Command Buffer bindings");
727 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
728 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700729 else {
Tobin Ehlis62086412014-11-19 16:19:28 -0700730 sprintf(str, " XGL Command Buffer (CB) binding list w/ HEAD at %p:", pCBTrav);
731 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700732 while (pCBTrav) {
Tobin Ehlis62086412014-11-19 16:19:28 -0700733 sprintf(str, " CB_NODE(%p): XGL CB %p, pNext %p", pCBTrav, pCBTrav->cmdBuffer, pCBTrav->pNext);
734 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700735 pCBTrav = pCBTrav->pNext;
736 }
737 }
738 pTrav = pTrav->pNextGlobalNode;
739 }
740 }
741}
742
743static void printGlobalCB()
744{
Tobin Ehlis62086412014-11-19 16:19:28 -0700745 char str[1024] = {0};
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700746 GLOBAL_CB_NODE* pTrav = pGlobalCBHead;
747 if (!pTrav) {
Tobin Ehlis62086412014-11-19 16:19:28 -0700748 sprintf(str, "Global Command Buffer (CB) list is empty :(\n");
749 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700750 }
751 else {
Tobin Ehlis62086412014-11-19 16:19:28 -0700752 sprintf(str, "Details of Global CB list w/ HEAD at %p:", (void*)pTrav);
753 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700754 while (pTrav) {
Tobin Ehlisa747e682014-11-25 14:47:20 -0700755 sprintf(str, " Global CB Node (%p) w/ pNextGlobalCBNode (%p) has CB %p, fence %p, and pMemObjList %p", (void*)pTrav, (void*)pTrav->pNextGlobalCBNode, (void*)pTrav->cmdBuffer, (void*)pTrav->fence, (void*)pTrav->pMemObjList);
Tobin Ehlis62086412014-11-19 16:19:28 -0700756 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700757 MINI_NODE* pMemObjTrav = pTrav->pMemObjList;
758 while (pMemObjTrav) {
Tobin Ehlis62086412014-11-19 16:19:28 -0700759 sprintf(str, " MEM_NODE(%p): Mem obj %p, pNext %p", (void*)pMemObjTrav, (void*)pMemObjTrav->mem, (void*)pMemObjTrav->pNext);
760 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700761 pMemObjTrav = pMemObjTrav->pNext;
762 }
763 pTrav = pTrav->pNextGlobalCBNode;
764 }
765 }
766}
767
768static XGL_FENCE createLocalFence()
769{
770 XGL_FENCE_CREATE_INFO fci;
771 fci.sType = XGL_STRUCTURE_TYPE_FENCE_CREATE_INFO;
772 fci.pNext = NULL;
773 fci.flags = 0;
774 XGL_FENCE fence;
775 nextTable.CreateFence(globalDevice, &fci, &fence);
776 return fence;
777}
778
Mark Lobodzinski15427102015-02-18 16:38:17 -0600779static void initMemTracker(void)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700780{
Jon Ashburnf57ea372014-12-22 13:24:15 -0700781 const char *strOpt;
782 // initialize MemTracker options
Ian Elliott7d0b5d22015-03-06 13:50:05 -0700783 getLayerOptionEnum("MemTrackerReportLevel", (uint32_t *) &g_reportingLevel);
784 g_actionIsDefault = getLayerOptionEnum("MemTrackerDebugAction", (uint32_t *) &g_debugAction);
Tobin Ehlis5b7acaa2015-01-08 14:26:53 -0700785
Jon Ashburnf57ea372014-12-22 13:24:15 -0700786 if (g_debugAction & XGL_DBG_LAYER_ACTION_LOG_MSG)
787 {
788 strOpt = getLayerOption("MemTrackerLogFilename");
789 if (strOpt)
790 {
791 g_logFile = fopen(strOpt, "w");
Jon Ashburnf57ea372014-12-22 13:24:15 -0700792 }
793 if (g_logFile == NULL)
794 g_logFile = stdout;
795 }
796
797 // initialize Layer dispatch table
798 // TODO handle multiple GPUs
Mark Lobodzinski953a1692015-01-09 15:12:03 -0600799 xglGetProcAddrType fpNextGPA;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700800 fpNextGPA = pCurObj->pGPA;
801 assert(fpNextGPA);
802
Chia-I Wu0f65b1e2015-01-04 23:11:43 +0800803 layer_initialize_dispatch_table(&nextTable, fpNextGPA, (XGL_PHYSICAL_GPU) pCurObj->nextObject);
804
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600805 xglGetProcAddrType fpGetProcAddr = fpNextGPA((XGL_PHYSICAL_GPU) pCurObj->nextObject, (char *) "xglGetProcAddr");
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700806 nextTable.GetProcAddr = fpGetProcAddr;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600807
808 if (!globalLockInitialized)
809 {
810 // TODO/TBD: Need to delete this mutex sometime. How??? One
811 // suggestion is to call this during xglCreateInstance(), and then we
812 // can clean it up during xglDestroyInstance(). However, that requires
813 // that the layer have per-instance locks. We need to come back and
814 // address this soon.
815 loader_platform_thread_create_mutex(&globalLock);
816 globalLockInitialized = 1;
817 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700818}
819
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700820XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateDevice(XGL_PHYSICAL_GPU gpu, const XGL_DEVICE_CREATE_INFO* pCreateInfo, XGL_DEVICE* pDevice)
821{
822 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
823 pCurObj = gpuw;
Ian Elliott81ac44c2015-01-13 17:52:38 -0700824 loader_platform_thread_once(&g_initOnce, initMemTracker);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700825 XGL_RESULT result = nextTable.CreateDevice((XGL_PHYSICAL_GPU)gpuw->nextObject, pCreateInfo, pDevice);
826 // Save off device in case we need it to create Fences
827 globalDevice = *pDevice;
828 return result;
829}
830
831XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglDestroyDevice(XGL_DEVICE device)
832{
Tobin Ehlis62086412014-11-19 16:19:28 -0700833 char str[1024];
834 sprintf(str, "Printing List details prior to xglDestroyDevice()");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600835 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis62086412014-11-19 16:19:28 -0700836 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, device, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700837 printMemList();
838 printGlobalCB();
839 printObjList();
Tobin Ehlis62086412014-11-19 16:19:28 -0700840 if (XGL_FALSE == deleteGlobalCBList()) {
841 sprintf(str, "Issue deleting global CB list in xglDestroyDevice()");
842 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, device, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
843 }
Tobin Ehlis22d03232014-11-25 18:01:12 -0700844 // Report any memory leaks
845 GLOBAL_MEM_OBJ_NODE* pTrav = pGlobalMemObjHead;
846 while (pTrav) {
Mark Lobodzinskidaa1d432015-02-18 18:06:24 -0600847 if (pTrav->allocInfo.allocationSize != 0) {
848 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);
849 layerCbMsg(XGL_DBG_MSG_WARNING, XGL_VALIDATION_LEVEL_0, pTrav->mem, 0, MEMTRACK_MEMORY_LEAK, "MEM", str);
850 }
Tobin Ehlis22d03232014-11-25 18:01:12 -0700851 pTrav = pTrav->pNextGlobalNode;
852 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600853 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700854 XGL_RESULT result = nextTable.DestroyDevice(device);
855 return result;
856}
857
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600858XGL_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 Ehlis791a49c2014-11-10 12:29:12 -0700859{
Jon Ashburn451c16f2014-11-25 11:08:42 -0700860 if (gpu != NULL)
861 {
862 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
863 pCurObj = gpuw;
Ian Elliott81ac44c2015-01-13 17:52:38 -0700864 loader_platform_thread_once(&g_initOnce, initMemTracker);
Mark Lobodzinski953a1692015-01-09 15:12:03 -0600865 XGL_RESULT result = nextTable.EnumerateLayers((XGL_PHYSICAL_GPU)gpuw->nextObject, maxLayerCount, maxStringSize, pOutLayerCount, pOutLayers, pReserved);
Jon Ashburn451c16f2014-11-25 11:08:42 -0700866 return result;
867 } else
868 {
869 if (pOutLayerCount == NULL || pOutLayers == NULL || pOutLayers[0] == NULL)
870 return XGL_ERROR_INVALID_POINTER;
871 // This layer compatible with all GPUs
872 *pOutLayerCount = 1;
Chia-I Wua837c522014-12-16 10:47:33 +0800873 strncpy((char *) pOutLayers[0], "MemTracker", maxStringSize);
Jon Ashburn451c16f2014-11-25 11:08:42 -0700874 return XGL_SUCCESS;
875 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700876}
877
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600878XGL_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 Ehlis791a49c2014-11-10 12:29:12 -0700879{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600880 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski821b57f2015-02-25 18:11:05 -0600881 bool32_t localFlag = XGL_FALSE;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700882 // TODO : Need to track fence and clear mem references when fence clears
883 XGL_FENCE localFence = fence;
884 if (XGL_NULL_HANDLE == fence) { // allocate our own fence to track cmd buffer
885 localFence = createLocalFence();
Mark Lobodzinski821b57f2015-02-25 18:11:05 -0600886 localFlag = XGL_TRUE;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700887 }
Tobin Ehlis62086412014-11-19 16:19:28 -0700888 char str[1024];
889 sprintf(str, "In xglQueueSubmit(), checking %u cmdBuffers with %u memRefs", cmdBufferCount, memRefCount);
890 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, queue, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700891 printMemList();
892 printGlobalCB();
893 for (uint32_t i = 0; i < cmdBufferCount; i++) {
Mark Lobodzinski821b57f2015-02-25 18:11:05 -0600894 setCBFence(pCmdBuffers[i], localFence, localFlag);
Tobin Ehlis62086412014-11-19 16:19:28 -0700895 sprintf(str, "Verifying mem refs for CB %p", pCmdBuffers[i]);
896 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, pCmdBuffers[i], 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700897 if (XGL_FALSE == validateCBMemRef(pCmdBuffers[i], memRefCount, pMemRefs)) {
Tobin Ehlis62086412014-11-19 16:19:28 -0700898 sprintf(str, "Unable to verify memory references for CB %p", (void*)pCmdBuffers[i]);
899 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, pCmdBuffers[i], 0, MEMTRACK_CB_MISSING_MEM_REF, "MEM", str);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700900 }
901 }
902 printGlobalCB();
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600903 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700904 XGL_RESULT result = nextTable.QueueSubmit(queue, cmdBufferCount, pCmdBuffers, memRefCount, pMemRefs, localFence);
905 return result;
906}
907
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600908XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglQueueSetGlobalMemReferences(XGL_QUEUE queue, uint32_t memRefCount, const XGL_MEMORY_REF* pMemRefs)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700909{
910 // TODO : Use global mem references as part of list checked on QueueSubmit above
911 XGL_RESULT result = nextTable.QueueSetGlobalMemReferences(queue, memRefCount, pMemRefs);
912 return result;
913}
914
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700915XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglAllocMemory(XGL_DEVICE device, const XGL_MEMORY_ALLOC_INFO* pAllocInfo, XGL_GPU_MEMORY* pMem)
916{
917 XGL_RESULT result = nextTable.AllocMemory(device, pAllocInfo, pMem);
918 // TODO : Track allocations and overall size here
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600919 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -0600920 insertGlobalMemObj(*pMem, pAllocInfo);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700921 printMemList();
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600922 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700923 return result;
924}
925
926XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglFreeMemory(XGL_GPU_MEMORY mem)
927{
Tobin Ehlisa747e682014-11-25 14:47:20 -0700928 /* From spec : A memory object is freed by calling xglFreeMemory() when it is no longer needed. Before
929 * freeing a memory object, an application must ensure the memory object is unbound from
930 * all API objects referencing it and that it is not referenced by any queued command buffers
931 */
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600932 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis62086412014-11-19 16:19:28 -0700933 if (XGL_FALSE == freeMemNode(mem)) {
934 char str[1024];
935 sprintf(str, "Issue while freeing mem obj %p", (void*)mem);
936 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_FREE_MEM_ERROR, "MEM", str);
937 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700938 printMemList();
939 printObjList();
940 printGlobalCB();
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600941 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700942 XGL_RESULT result = nextTable.FreeMemory(mem);
943 return result;
944}
945
946XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglSetMemoryPriority(XGL_GPU_MEMORY mem, XGL_MEMORY_PRIORITY priority)
947{
948 // TODO : Update tracking for this alloc
949 // Make sure memory is not pinned, which can't have priority set
950 XGL_RESULT result = nextTable.SetMemoryPriority(mem, priority);
951 return result;
952}
953
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600954XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglMapMemory(XGL_GPU_MEMORY mem, XGL_FLAGS flags, void** ppData)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700955{
956 // TODO : Track when memory is mapped
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600957 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski06f60b82015-02-25 12:16:04 -0600958 GLOBAL_MEM_OBJ_NODE *pMemObj = getGlobalMemNode(mem);
959 if ((pMemObj->allocInfo.memProps & XGL_MEMORY_PROPERTY_CPU_VISIBLE_BIT) == 0) {
960 char str[1024];
961 sprintf(str, "Mapping Memory (%p) without XGL_MEMORY_PROPERTY_CPU_VISIBLE_BIT set", (void*)mem);
962 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_STATE, "MEM", str);
963 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600964 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700965 XGL_RESULT result = nextTable.MapMemory(mem, flags, ppData);
966 return result;
967}
968
969XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglUnmapMemory(XGL_GPU_MEMORY mem)
970{
971 // TODO : Track as memory gets unmapped, do we want to check what changed following map?
972 // Make sure that memory was ever mapped to begin with
973 XGL_RESULT result = nextTable.UnmapMemory(mem);
974 return result;
975}
976
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600977XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglPinSystemMemory(XGL_DEVICE device, const void* pSysMem, size_t memSize, XGL_GPU_MEMORY* pMem)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700978{
979 // TODO : Track this
980 // Verify that memory is actually pinnable
981 XGL_RESULT result = nextTable.PinSystemMemory(device, pSysMem, memSize, pMem);
982 return result;
983}
984
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700985XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglOpenSharedMemory(XGL_DEVICE device, const XGL_MEMORY_OPEN_INFO* pOpenInfo, XGL_GPU_MEMORY* pMem)
986{
987 // TODO : Track this
988 XGL_RESULT result = nextTable.OpenSharedMemory(device, pOpenInfo, pMem);
989 return result;
990}
991
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700992XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglOpenPeerMemory(XGL_DEVICE device, const XGL_PEER_MEMORY_OPEN_INFO* pOpenInfo, XGL_GPU_MEMORY* pMem)
993{
994 // TODO : Track this
995 XGL_RESULT result = nextTable.OpenPeerMemory(device, pOpenInfo, pMem);
996 return result;
997}
998
999XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglOpenPeerImage(XGL_DEVICE device, const XGL_PEER_IMAGE_OPEN_INFO* pOpenInfo, XGL_IMAGE* pImage, XGL_GPU_MEMORY* pMem)
1000{
1001 // TODO : Track this
1002 XGL_RESULT result = nextTable.OpenPeerImage(device, pOpenInfo, pImage, pMem);
1003 return result;
1004}
1005
1006XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglDestroyObject(XGL_OBJECT object)
1007{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001008 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlise6884ef2014-11-27 07:52:04 -07001009 // First check if this is a CmdBuffer
1010 if (NULL != getGlobalCBNode((XGL_CMD_BUFFER)object)) {
1011 deleteGlobalCBNode((XGL_CMD_BUFFER)object);
1012 }
1013 // Now locate node in global list along with prev node
Tobin Ehlis580c1b32014-11-25 12:27:38 -07001014 GLOBAL_OBJECT_NODE* pTrav = pGlobalObjectHead;
1015 GLOBAL_OBJECT_NODE* pPrev = pTrav;
Tobin Ehlis580c1b32014-11-25 12:27:38 -07001016 while (pTrav) {
1017 if (object == pTrav->object)
1018 break;
1019 pPrev = pTrav;
1020 pTrav = pTrav->pNext;
1021 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001022 if (pTrav) {
1023 if (pTrav->pMemNode) {
Tobin Ehlise6884ef2014-11-27 07:52:04 -07001024 // Wsi allocated Memory is tied to image object so clear the binding and free that memory automatically
1025 if (0 == pTrav->pMemNode->allocInfo.allocationSize) { // Wsi allocated memory has NULL allocInfo w/ 0 size
1026 XGL_GPU_MEMORY memToFree = pTrav->pMemNode->mem;
1027 clearObjectBinding(object);
1028 freeMemNode(memToFree);
1029 }
1030 else {
1031 char str[1024];
1032 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);
1033 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, object, 0, MEMTRACK_DESTROY_OBJECT_ERROR, "MEM", str);
1034 // From the spec : If an object has previous memory binding, it is required to unbind memory from an API object before it is destroyed.
1035 clearObjectBinding(object);
1036 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001037 }
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001038 if (XGL_STRUCTURE_TYPE_FENCE_CREATE_INFO == pTrav->sType) {
1039 clearCBFence((XGL_FENCE)object);
1040 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001041 if (pGlobalObjectHead == pTrav) // update HEAD if needed
1042 pGlobalObjectHead = pTrav->pNext;
Tobin Ehlis580c1b32014-11-25 12:27:38 -07001043 // Delete the obj node from global list
1044 pPrev->pNext = pTrav->pNext;
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001045 free(pTrav);
1046 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001047 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001048 XGL_RESULT result = nextTable.DestroyObject(object);
1049 return result;
1050}
1051
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001052XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglGetObjectInfo(XGL_BASE_OBJECT object, XGL_OBJECT_INFO_TYPE infoType, size_t* pDataSize, void* pData)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001053{
1054 // TODO : What to track here?
1055 // Could potentially save returned mem requirements and validate values passed into BindObjectMemory for this object
Tobin Ehlis62086412014-11-19 16:19:28 -07001056 // From spec : The only objects that are guaranteed to have no external memory requirements are devices, queues, command buffers, shaders and memory objects.
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001057 XGL_RESULT result = nextTable.GetObjectInfo(object, infoType, pDataSize, pData);
1058 return result;
1059}
1060
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001061XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglBindObjectMemory(XGL_OBJECT object, uint32_t allocationIdx, XGL_GPU_MEMORY mem, XGL_GPU_SIZE offset)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001062{
Jon Ashburned62b412015-01-15 10:39:19 -07001063 XGL_RESULT result = nextTable.BindObjectMemory(object, allocationIdx, mem, offset);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001064 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001065 // Track objects tied to memory
Tobin Ehlis62086412014-11-19 16:19:28 -07001066 if (XGL_FALSE == updateObjectBinding(object, mem)) {
1067 char str[1024];
1068 sprintf(str, "Unable to set object %p binding to mem obj %p", (void*)object, (void*)mem);
1069 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, object, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1070 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001071 printObjList();
1072 printMemList();
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001073 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001074 return result;
1075}
1076
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001077XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateFence(XGL_DEVICE device, const XGL_FENCE_CREATE_INFO* pCreateInfo, XGL_FENCE* pFence)
1078{
1079 XGL_RESULT result = nextTable.CreateFence(device, pCreateInfo, pFence);
1080 if (XGL_SUCCESS == result) {
1081 loader_platform_thread_lock_mutex(&globalLock);
1082 insertGlobalObjectNode(*pFence, pCreateInfo->sType, pCreateInfo, sizeof(XGL_FENCE_CREATE_INFO), "fence");
1083 loader_platform_thread_unlock_mutex(&globalLock);
1084 }
1085 return result;
1086}
1087
1088XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglGetFenceStatus(XGL_FENCE fence)
1089{
1090 XGL_RESULT result = nextTable.GetFenceStatus(fence);
1091 if (XGL_SUCCESS == result) {
1092 // TODO : Properly we should add validation to make sure app is checking fence
1093 // on CB before Reset/Begin CB call is made
1094 clearCBFence(fence);
1095 }
1096 return result;
1097}
1098
1099XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglWaitForFences(XGL_DEVICE device, uint32_t fenceCount, const XGL_FENCE* pFences, bool32_t waitAll, uint64_t timeout)
1100{
1101 XGL_RESULT result = nextTable.WaitForFences(device, fenceCount, pFences, waitAll, timeout);
1102 if (XGL_SUCCESS == result) {
1103 // TODO : Properly we should add validation to make sure app is checking fence
1104 // on CB before Reset/Begin CB call is made
1105 if (waitAll) { // Clear all the fences
1106 for(uint32_t i = 0; i < fenceCount; i++) {
1107 clearCBFence(pFences[i]);
1108 }
1109 }
1110 else { // Clear only completed fences
1111 for(uint32_t i = 0; i < fenceCount; i++) {
1112 if (XGL_SUCCESS == nextTable.GetFenceStatus(pFences[i])) {
1113 clearCBFence(pFences[i]);
1114 }
1115 }
1116 }
1117 }
1118 return result;
1119}
1120
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001121XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateEvent(XGL_DEVICE device, const XGL_EVENT_CREATE_INFO* pCreateInfo, XGL_EVENT* pEvent)
1122{
1123 XGL_RESULT result = nextTable.CreateEvent(device, pCreateInfo, pEvent);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001124 if (XGL_SUCCESS == result) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001125 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001126 insertGlobalObjectNode(*pEvent, pCreateInfo->sType, pCreateInfo, sizeof(XGL_EVENT_CREATE_INFO), "event");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001127 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001128 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001129 return result;
1130}
1131
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001132XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateQueryPool(XGL_DEVICE device, const XGL_QUERY_POOL_CREATE_INFO* pCreateInfo, XGL_QUERY_POOL* pQueryPool)
1133{
1134 XGL_RESULT result = nextTable.CreateQueryPool(device, pCreateInfo, pQueryPool);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001135 if (XGL_SUCCESS == result) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001136 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001137 insertGlobalObjectNode(*pQueryPool, pCreateInfo->sType, pCreateInfo, sizeof(XGL_QUERY_POOL_CREATE_INFO), "query_pool");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001138 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001139 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001140 return result;
1141}
1142
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001143XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateBuffer(XGL_DEVICE device, const XGL_BUFFER_CREATE_INFO* pCreateInfo, XGL_BUFFER* pBuffer)
1144{
1145 XGL_RESULT result = nextTable.CreateBuffer(device, pCreateInfo, pBuffer);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001146 if (XGL_SUCCESS == result) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001147 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001148 insertGlobalObjectNode(*pBuffer, pCreateInfo->sType, pCreateInfo, sizeof(XGL_BUFFER_CREATE_INFO), "buffer");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001149 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001150 }
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001151 return result;
1152}
1153
1154XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateBufferView(XGL_DEVICE device, const XGL_BUFFER_VIEW_CREATE_INFO* pCreateInfo, XGL_BUFFER_VIEW* pView)
1155{
1156 XGL_RESULT result = nextTable.CreateBufferView(device, pCreateInfo, pView);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001157 if (result == XGL_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001158 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001159 insertGlobalObjectNode(*pView, pCreateInfo->sType, pCreateInfo, sizeof(XGL_BUFFER_VIEW_CREATE_INFO), "buffer_view");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001160 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001161 }
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001162 return result;
1163}
1164
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001165XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateImage(XGL_DEVICE device, const XGL_IMAGE_CREATE_INFO* pCreateInfo, XGL_IMAGE* pImage)
1166{
1167 XGL_RESULT result = nextTable.CreateImage(device, pCreateInfo, pImage);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001168 if (XGL_SUCCESS == result) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001169 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001170 insertGlobalObjectNode(*pImage, pCreateInfo->sType, pCreateInfo, sizeof(XGL_IMAGE_CREATE_INFO), "image");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001171 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001172 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001173 return result;
1174}
1175
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001176XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateImageView(XGL_DEVICE device, const XGL_IMAGE_VIEW_CREATE_INFO* pCreateInfo, XGL_IMAGE_VIEW* pView)
1177{
1178 XGL_RESULT result = nextTable.CreateImageView(device, pCreateInfo, pView);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001179 if (result == XGL_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001180 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001181 insertGlobalObjectNode(*pView, pCreateInfo->sType, pCreateInfo, sizeof(XGL_IMAGE_VIEW_CREATE_INFO), "image_view");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001182 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001183 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001184 return result;
1185}
1186
1187XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateColorAttachmentView(XGL_DEVICE device, const XGL_COLOR_ATTACHMENT_VIEW_CREATE_INFO* pCreateInfo, XGL_COLOR_ATTACHMENT_VIEW* pView)
1188{
1189 XGL_RESULT result = nextTable.CreateColorAttachmentView(device, pCreateInfo, pView);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001190 if (result == XGL_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001191 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001192 insertGlobalObjectNode(*pView, pCreateInfo->sType, pCreateInfo, sizeof(XGL_COLOR_ATTACHMENT_VIEW_CREATE_INFO), "color_attachment_view");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001193 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001194 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001195 return result;
1196}
1197
1198XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateDepthStencilView(XGL_DEVICE device, const XGL_DEPTH_STENCIL_VIEW_CREATE_INFO* pCreateInfo, XGL_DEPTH_STENCIL_VIEW* pView)
1199{
1200 XGL_RESULT result = nextTable.CreateDepthStencilView(device, pCreateInfo, pView);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001201 if (result == XGL_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001202 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001203 insertGlobalObjectNode(*pView, pCreateInfo->sType, pCreateInfo, sizeof(XGL_DEPTH_STENCIL_VIEW_CREATE_INFO), "ds_view");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001204 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001205 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001206 return result;
1207}
1208
1209XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateShader(XGL_DEVICE device, const XGL_SHADER_CREATE_INFO* pCreateInfo, XGL_SHADER* pShader)
1210{
1211 XGL_RESULT result = nextTable.CreateShader(device, pCreateInfo, pShader);
1212 return result;
1213}
1214
1215XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateGraphicsPipeline(XGL_DEVICE device, const XGL_GRAPHICS_PIPELINE_CREATE_INFO* pCreateInfo, XGL_PIPELINE* pPipeline)
1216{
1217 XGL_RESULT result = nextTable.CreateGraphicsPipeline(device, pCreateInfo, pPipeline);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001218 if (result == XGL_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001219 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001220 insertGlobalObjectNode(*pPipeline, pCreateInfo->sType, pCreateInfo, sizeof(XGL_GRAPHICS_PIPELINE_CREATE_INFO), "graphics_pipeline");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001221 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001222 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001223 return result;
1224}
1225
1226XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateComputePipeline(XGL_DEVICE device, const XGL_COMPUTE_PIPELINE_CREATE_INFO* pCreateInfo, XGL_PIPELINE* pPipeline)
1227{
1228 XGL_RESULT result = nextTable.CreateComputePipeline(device, pCreateInfo, pPipeline);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001229 if (result == XGL_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001230 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001231 insertGlobalObjectNode(*pPipeline, pCreateInfo->sType, pCreateInfo, sizeof(XGL_COMPUTE_PIPELINE_CREATE_INFO), "compute_pipeline");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001232 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001233 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001234 return result;
1235}
1236
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001237XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateSampler(XGL_DEVICE device, const XGL_SAMPLER_CREATE_INFO* pCreateInfo, XGL_SAMPLER* pSampler)
1238{
1239 XGL_RESULT result = nextTable.CreateSampler(device, pCreateInfo, pSampler);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001240 if (result == XGL_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001241 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001242 insertGlobalObjectNode(*pSampler, pCreateInfo->sType, pCreateInfo, sizeof(XGL_SAMPLER_CREATE_INFO), "sampler");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001243 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001244 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001245 return result;
1246}
1247
Mark Lobodzinski15427102015-02-18 16:38:17 -06001248XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateDynamicViewportState(XGL_DEVICE device, const XGL_DYNAMIC_VP_STATE_CREATE_INFO* pCreateInfo, XGL_DYNAMIC_VP_STATE_OBJECT* pState)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001249{
Mark Lobodzinski15427102015-02-18 16:38:17 -06001250 XGL_RESULT result = nextTable.CreateDynamicViewportState(device, pCreateInfo, pState);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001251 if (result == XGL_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001252 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001253 insertGlobalObjectNode(*pState, pCreateInfo->sType, pCreateInfo, sizeof(XGL_DYNAMIC_VP_STATE_CREATE_INFO), "viewport_state");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001254 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001255 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001256 return result;
1257}
1258
Mark Lobodzinski15427102015-02-18 16:38:17 -06001259XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateDynamicRasterState(XGL_DEVICE device, const XGL_DYNAMIC_RS_STATE_CREATE_INFO* pCreateInfo, XGL_DYNAMIC_RS_STATE_OBJECT* pState)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001260{
Mark Lobodzinski15427102015-02-18 16:38:17 -06001261 XGL_RESULT result = nextTable.CreateDynamicRasterState(device, pCreateInfo, pState);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001262 if (result == XGL_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001263 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001264 insertGlobalObjectNode(*pState, pCreateInfo->sType, pCreateInfo, sizeof(XGL_DYNAMIC_RS_STATE_CREATE_INFO), "raster_state");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001265 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001266 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001267 return result;
1268}
1269
Mark Lobodzinski15427102015-02-18 16:38:17 -06001270XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateDynamicColorBlendState(XGL_DEVICE device, const XGL_DYNAMIC_CB_STATE_CREATE_INFO* pCreateInfo, XGL_DYNAMIC_CB_STATE_OBJECT* pState)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001271{
Mark Lobodzinski15427102015-02-18 16:38:17 -06001272 XGL_RESULT result = nextTable.CreateDynamicColorBlendState(device, pCreateInfo, pState);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001273 if (result == XGL_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001274 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001275 insertGlobalObjectNode(*pState, pCreateInfo->sType, pCreateInfo, sizeof(XGL_DYNAMIC_CB_STATE_CREATE_INFO), "cb_state");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001276 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001277 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001278 return result;
1279}
1280
Mark Lobodzinski15427102015-02-18 16:38:17 -06001281XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateDynamicDepthStencilState(XGL_DEVICE device, const XGL_DYNAMIC_DS_STATE_CREATE_INFO* pCreateInfo, XGL_DYNAMIC_DS_STATE_OBJECT* pState)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001282{
Mark Lobodzinski15427102015-02-18 16:38:17 -06001283 XGL_RESULT result = nextTable.CreateDynamicDepthStencilState(device, pCreateInfo, pState);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001284 if (result == XGL_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001285 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001286 insertGlobalObjectNode(*pState, pCreateInfo->sType, pCreateInfo, sizeof(XGL_DYNAMIC_DS_STATE_CREATE_INFO), "ds_state");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001287 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001288 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001289 return result;
1290}
1291
1292XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateCommandBuffer(XGL_DEVICE device, const XGL_CMD_BUFFER_CREATE_INFO* pCreateInfo, XGL_CMD_BUFFER* pCmdBuffer)
1293{
1294 XGL_RESULT result = nextTable.CreateCommandBuffer(device, pCreateInfo, pCmdBuffer);
1295 // At time of cmd buffer creation, create global cmd buffer node for the returned cmd buffer
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001296 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001297 if (*pCmdBuffer)
1298 insertGlobalCB(*pCmdBuffer);
1299 printGlobalCB();
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001300 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001301 return result;
1302}
1303
Jon Ashburn57ba18d2014-12-31 17:11:49 -07001304XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglBeginCommandBuffer(XGL_CMD_BUFFER cmdBuffer, const XGL_CMD_BUFFER_BEGIN_INFO* pBeginInfo)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001305{
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001306 // This implicitly resets the Cmd Buffer so make sure any fence is done and then clear memory references
1307 GLOBAL_CB_NODE* pCBTrav = getGlobalCBNode(cmdBuffer);
1308 if (pCBTrav && pCBTrav->fence) {
1309 bool32_t cbDone = checkCBCompleted(cmdBuffer);
1310 if (XGL_FALSE == cbDone) {
1311 char str[1024];
1312 sprintf(str, "Calling xglBeginCommandBuffer() on active CB %p before it has completed. You must check CB flag before this call.", cmdBuffer);
1313 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_RESET_CB_WHILE_IN_FLIGHT, "MEM", str);
1314 }
1315 }
Jon Ashburn57ba18d2014-12-31 17:11:49 -07001316 XGL_RESULT result = nextTable.BeginCommandBuffer(cmdBuffer, pBeginInfo);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001317 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001318 freeCBBindings(cmdBuffer);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001319 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001320 return result;
1321}
1322
1323XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglEndCommandBuffer(XGL_CMD_BUFFER cmdBuffer)
1324{
1325 // TODO : Anything to do here?
1326 XGL_RESULT result = nextTable.EndCommandBuffer(cmdBuffer);
1327 return result;
1328}
1329
1330XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglResetCommandBuffer(XGL_CMD_BUFFER cmdBuffer)
1331{
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001332 // Verify that CB is complete (not in-flight)
1333 GLOBAL_CB_NODE* pCBTrav = getGlobalCBNode(cmdBuffer);
1334 if (pCBTrav && pCBTrav->fence) {
1335 bool32_t cbDone = checkCBCompleted(cmdBuffer);
1336 if (XGL_FALSE == cbDone) {
1337 char str[1024];
1338 sprintf(str, "Resetting CB %p before it has completed. You must check CB flag before calling xglResetCommandBuffer().", cmdBuffer);
1339 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_RESET_CB_WHILE_IN_FLIGHT, "MEM", str);
1340 }
1341 }
1342 // Clear memory references as this point.
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001343 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001344 freeCBBindings(cmdBuffer);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001345 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001346 XGL_RESULT result = nextTable.ResetCommandBuffer(cmdBuffer);
1347 return result;
1348}
1349// TODO : For any xglCmdBind* calls that include an object which has mem bound to it,
1350// need to account for that mem now having binding to given cmdBuffer
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001351XGL_LAYER_EXPORT void XGLAPI xglCmdBindPipeline(XGL_CMD_BUFFER cmdBuffer, XGL_PIPELINE_BIND_POINT pipelineBindPoint, XGL_PIPELINE pipeline)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001352{
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001353#if 0
1354 // TODO : If memory bound to pipeline, then need to tie that mem to cmdBuffer
1355 if (getPipeline(pipeline)) {
1356 GLOBAL_CB_NODE *pCBTrav = getGlobalCBNode(cmdBuffer);
1357 if (pCBTrav) {
1358 pCBTrav->pipelines[pipelineBindPoint] = pipeline;
1359 } else {
1360 char str[1024];
1361 sprintf(str, "Attempt to bind Pipeline %p to non-existant command buffer %p!", (void*)pipeline, cmdBuffer);
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001362 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_INVALID_CB, (char *) "DS", (char *) str);
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001363 }
1364 }
1365 else {
1366 char str[1024];
1367 sprintf(str, "Attempt to bind Pipeline %p that doesn't exist!", (void*)pipeline);
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001368 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, pipeline, 0, MEMTRACK_INVALID_OBJECT, (char *) "DS", (char *) str);
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001369 }
1370#endif
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001371 nextTable.CmdBindPipeline(cmdBuffer, pipelineBindPoint, pipeline);
1372}
1373
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001374XGL_LAYER_EXPORT void XGLAPI xglCmdBindDynamicStateObject(XGL_CMD_BUFFER cmdBuffer, XGL_STATE_BIND_POINT stateBindPoint, XGL_DYNAMIC_STATE_OBJECT state)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001375{
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001376 GLOBAL_OBJECT_NODE *pNode;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001377 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001378 GLOBAL_CB_NODE *pCmdBuf = getGlobalCBNode(cmdBuffer);
1379 if (!pCmdBuf) {
1380 char str[1024];
1381 sprintf(str, "Unable to find command buffer object %p, was it ever created?", (void*)cmdBuffer);
1382 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_INVALID_CB, "DD", str);
1383 }
1384 pNode = getGlobalObjectNode(state);
1385 if (!pNode) {
1386 char str[1024];
1387 sprintf(str, "Unable to find dynamic state object %p, was it ever created?", (void*)state);
1388 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, state, 0, MEMTRACK_INVALID_OBJECT, "DD", str);
1389 }
1390 pCmdBuf->pDynamicState[stateBindPoint] = pNode;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001391 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001392 nextTable.CmdBindDynamicStateObject(cmdBuffer, stateBindPoint, state);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001393}
1394
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001395XGL_LAYER_EXPORT void XGLAPI xglCmdBindDescriptorSet(XGL_CMD_BUFFER cmdBuffer, XGL_PIPELINE_BIND_POINT pipelineBindPoint, XGL_DESCRIPTOR_SET descriptorSet, const uint32_t* pUserData)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001396{
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001397 // TODO : Somewhere need to verify that all textures referenced by shaders in DS are in some type of *SHADER_READ* state
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001398 nextTable.CmdBindDescriptorSet(cmdBuffer, pipelineBindPoint, descriptorSet, pUserData);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001399}
1400
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001401XGL_LAYER_EXPORT void XGLAPI xglCmdBindVertexBuffer(XGL_CMD_BUFFER cmdBuffer, XGL_BUFFER buffer, XGL_GPU_SIZE offset, uint32_t binding)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001402{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001403 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001404 XGL_GPU_MEMORY mem = getMemBindingFromObject(buffer);
1405 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
Chia-I Wufb5062e2015-01-05 13:42:56 +08001406 char str[1024];
Mark Lobodzinski15427102015-02-18 16:38:17 -06001407 sprintf(str, "In xglCmdBindVertexBuffer() call unable to update binding of buffer %p to cmdBuffer %p", buffer, cmdBuffer);
Chia-I Wufb5062e2015-01-05 13:42:56 +08001408 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1409 }
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001410 // Now update CB's vertex binding list
1411 GLOBAL_CB_NODE* pCBTrav = getGlobalCBNode(cmdBuffer);
1412 if (!pCBTrav) {
1413 char str[1024];
Mark Lobodzinski15427102015-02-18 16:38:17 -06001414 sprintf(str, "Trying to BindVertexuffer obj %p to CB %p but no Node for that CB. Was CB incorrectly destroyed?", buffer, cmdBuffer);
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001415 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_INVALID_CB, "MEM", str);
1416 } else {
1417 MEMORY_BINDING *pBindInfo;
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001418 uint32_t dontCare;
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001419 pBindInfo = malloc(sizeof(MEMORY_BINDING));
1420 pBindInfo->offset = offset;
1421 pBindInfo->binding = binding;
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001422 pBindInfo->buffer = buffer;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001423 if (XGL_FALSE == insertMiniNode(&pCBTrav->pVertexBufList, pBindInfo, &dontCare)) {
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001424 char str[1024];
Mark Lobodzinski15427102015-02-18 16:38:17 -06001425 sprintf(str, "In xglCmdBindVertexBuffer and ran out of memory to track binding. CmdBuffer: %p, buffer %p", cmdBuffer, buffer);
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001426 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_OUT_OF_MEMORY_ERROR, "MEM", str);
1427 }
1428 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001429 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001430 nextTable.CmdBindVertexBuffer(cmdBuffer, buffer, offset, binding);
Chia-I Wufb5062e2015-01-05 13:42:56 +08001431}
1432
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001433XGL_LAYER_EXPORT void XGLAPI xglCmdBindIndexBuffer(XGL_CMD_BUFFER cmdBuffer, XGL_BUFFER buffer, XGL_GPU_SIZE offset, XGL_INDEX_TYPE indexType)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001434{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001435 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001436 // Track this buffer. What exactly is this call doing?
Mark Lobodzinski15427102015-02-18 16:38:17 -06001437 XGL_GPU_MEMORY mem = getMemBindingFromObject(buffer);
1438 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001439 char str[1024];
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001440 sprintf(str, "In xglCmdBindIndexData() call unable to update binding of buffer %p to cmdBuffer %p", buffer, cmdBuffer);
Tobin Ehlis62086412014-11-19 16:19:28 -07001441 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1442 }
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001443 // Now update CB's index binding list
1444 GLOBAL_CB_NODE* pCBTrav = getGlobalCBNode(cmdBuffer);
1445 if (!pCBTrav) {
1446 char str[1024];
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001447 sprintf(str, "Trying to BindIndexData buffer obj %p to CB %p but no Node for that CB. Was CB incorrectly destroyed?", buffer, cmdBuffer);
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001448 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_INVALID_MEM_OBJ, (char *) "MEM", (char *) str);
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001449 } else {
1450 MEMORY_BINDING *pBindInfo;
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001451 uint32_t dontCare;
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001452 pBindInfo = malloc(sizeof(MEMORY_BINDING));
1453 pBindInfo->indexType = indexType;
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001454 pBindInfo->buffer = buffer;
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001455 pBindInfo->offset = offset;
1456 pBindInfo->binding = 0;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001457 if (XGL_FALSE == insertMiniNode(&pCBTrav->pIndexBufList, pBindInfo, &dontCare)) {
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001458 char str[1024];
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001459 sprintf(str, "In xglCmdBindIndexData and ran out of memory to track binding. CmdBuffer: %p, buffer %p", cmdBuffer, buffer);
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001460 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_OUT_OF_MEMORY_ERROR, "MEM", str);
1461 }
1462 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001463 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001464 nextTable.CmdBindIndexBuffer(cmdBuffer, buffer, offset, indexType);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001465}
1466
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001467XGL_LAYER_EXPORT void XGLAPI xglCmdDrawIndirect(XGL_CMD_BUFFER cmdBuffer, XGL_BUFFER buffer, XGL_GPU_SIZE offset, uint32_t count, uint32_t stride)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001468{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001469 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001470 XGL_GPU_MEMORY mem = getMemBindingFromObject(buffer);
1471 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001472 char str[1024];
Mark Lobodzinski15427102015-02-18 16:38:17 -06001473 sprintf(str, "In xglCmdDrawIndirect() call unable to update binding of buffer %p to cmdBuffer %p", buffer, cmdBuffer);
Tobin Ehlis62086412014-11-19 16:19:28 -07001474 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1475 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001476 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001477 nextTable.CmdDrawIndirect(cmdBuffer, buffer, offset, count, stride);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001478}
1479
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001480XGL_LAYER_EXPORT void XGLAPI xglCmdDrawIndexedIndirect(XGL_CMD_BUFFER cmdBuffer, XGL_BUFFER buffer, XGL_GPU_SIZE offset, uint32_t count, uint32_t stride)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001481{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001482 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001483 XGL_GPU_MEMORY mem = getMemBindingFromObject(buffer);
1484 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001485 char str[1024];
Mark Lobodzinski15427102015-02-18 16:38:17 -06001486 sprintf(str, "In xglCmdDrawIndexedIndirect() call unable to update binding of buffer %p to cmdBuffer %p", buffer, cmdBuffer);
Tobin Ehlis62086412014-11-19 16:19:28 -07001487 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1488 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001489 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001490 nextTable.CmdDrawIndexedIndirect(cmdBuffer, buffer, offset, count, stride);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001491}
1492
Mark Lobodzinski15427102015-02-18 16:38:17 -06001493XGL_LAYER_EXPORT void XGLAPI xglCmdDispatchIndirect(XGL_CMD_BUFFER cmdBuffer, XGL_BUFFER buffer, XGL_GPU_SIZE offset)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001494{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001495 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001496 XGL_GPU_MEMORY mem = getMemBindingFromObject(buffer);
Tobin Ehlis62086412014-11-19 16:19:28 -07001497 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1498 char str[1024];
Mark Lobodzinski15427102015-02-18 16:38:17 -06001499 sprintf(str, "In xglCmdDispatchIndirect() call unable to update binding of buffer %p to cmdBuffer %p", buffer, cmdBuffer);
Tobin Ehlis62086412014-11-19 16:19:28 -07001500 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1501 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001502 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001503 nextTable.CmdDispatchIndirect(cmdBuffer, buffer, offset);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001504}
1505
Mark Lobodzinski15427102015-02-18 16:38:17 -06001506XGL_LAYER_EXPORT void XGLAPI xglCmdCopyBuffer(XGL_CMD_BUFFER cmdBuffer, XGL_BUFFER srcBuffer, XGL_BUFFER destBuffer, uint32_t regionCount, const XGL_BUFFER_COPY* pRegions)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001507{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001508 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001509 XGL_GPU_MEMORY mem = getMemBindingFromObject(srcBuffer);
1510 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001511 char str[1024];
Mark Lobodzinski15427102015-02-18 16:38:17 -06001512 sprintf(str, "In xglCmdCopyBuffer() call unable to update binding of srcBuffer %p to cmdBuffer %p", srcBuffer, cmdBuffer);
Tobin Ehlis62086412014-11-19 16:19:28 -07001513 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1514 }
Mark Lobodzinski15427102015-02-18 16:38:17 -06001515 mem = getMemBindingFromObject(destBuffer);
1516 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001517 char str[1024];
Mark Lobodzinski15427102015-02-18 16:38:17 -06001518 sprintf(str, "In xglCmdCopyBuffer() call unable to update binding of destBuffer %p to cmdBuffer %p", destBuffer, cmdBuffer);
Tobin Ehlis62086412014-11-19 16:19:28 -07001519 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1520 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001521 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001522 nextTable.CmdCopyBuffer(cmdBuffer, srcBuffer, destBuffer, regionCount, pRegions);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001523}
1524
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001525XGL_LAYER_EXPORT void XGLAPI xglCmdCopyImage(XGL_CMD_BUFFER cmdBuffer, XGL_IMAGE srcImage, XGL_IMAGE destImage, uint32_t regionCount, const XGL_IMAGE_COPY* pRegions)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001526{
1527 // TODO : Each image will have mem mapping so track them
1528 nextTable.CmdCopyImage(cmdBuffer, srcImage, destImage, regionCount, pRegions);
1529}
1530
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001531XGL_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 Ehlis791a49c2014-11-10 12:29:12 -07001532{
1533 // TODO : Track this
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001534 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001535 XGL_GPU_MEMORY mem = getMemBindingFromObject(destImage);
Tobin Ehlis62086412014-11-19 16:19:28 -07001536 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1537 char str[1024];
Mark Lobodzinski15427102015-02-18 16:38:17 -06001538 sprintf(str, "In xglCmdCopyMemoryToImage() call unable to update binding of destImage buffer %p to cmdBuffer %p", destImage, cmdBuffer);
Tobin Ehlis62086412014-11-19 16:19:28 -07001539 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1540 }
Mark Lobodzinski15427102015-02-18 16:38:17 -06001541
1542 mem = getMemBindingFromObject(srcBuffer);
1543 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001544 char str[1024];
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001545 sprintf(str, "In xglCmdCopyMemoryToImage() call unable to update binding of srcBuffer %p to cmdBuffer %p", srcBuffer, cmdBuffer);
Tobin Ehlis62086412014-11-19 16:19:28 -07001546 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1547 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001548 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001549 nextTable.CmdCopyBufferToImage(cmdBuffer, srcBuffer, destImage, regionCount, pRegions);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001550}
1551
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001552XGL_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 Ehlis791a49c2014-11-10 12:29:12 -07001553{
1554 // TODO : Track this
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001555 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001556 XGL_GPU_MEMORY mem = getMemBindingFromObject(srcImage);
Tobin Ehlis62086412014-11-19 16:19:28 -07001557 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1558 char str[1024];
Mark Lobodzinski15427102015-02-18 16:38:17 -06001559 sprintf(str, "In xglCmdCopyImageToMemory() call unable to update binding of srcImage buffer %p to cmdBuffer %p", srcImage, cmdBuffer);
Tobin Ehlis62086412014-11-19 16:19:28 -07001560 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1561 }
Mark Lobodzinski15427102015-02-18 16:38:17 -06001562 mem = getMemBindingFromObject(destBuffer);
1563 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001564 char str[1024];
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001565 sprintf(str, "In xglCmdCopyImageToMemory() call unable to update binding of destBuffer %p to cmdBuffer %p", destBuffer, cmdBuffer);
Tobin Ehlis62086412014-11-19 16:19:28 -07001566 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1567 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001568 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001569 nextTable.CmdCopyImageToBuffer(cmdBuffer, srcImage, destBuffer, regionCount, pRegions);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001570}
1571
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001572XGL_LAYER_EXPORT void XGLAPI xglCmdCloneImageData(XGL_CMD_BUFFER cmdBuffer, XGL_IMAGE srcImage, XGL_IMAGE_LAYOUT srcImageLayout, XGL_IMAGE destImage, XGL_IMAGE_LAYOUT destImageLayout)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001573{
1574 // TODO : Each image will have mem mapping so track them
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001575 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001576 XGL_GPU_MEMORY mem = getMemBindingFromObject(srcImage);
Tobin Ehlis62086412014-11-19 16:19:28 -07001577 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1578 char str[1024];
Mark Lobodzinski15427102015-02-18 16:38:17 -06001579 sprintf(str, "In xglCmdCloneImageData() call unable to update binding of srcImage buffer %p to cmdBuffer %p", srcImage, cmdBuffer);
Tobin Ehlis62086412014-11-19 16:19:28 -07001580 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1581 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001582 mem = getMemBindingFromObject(destImage);
Tobin Ehlis62086412014-11-19 16:19:28 -07001583 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1584 char str[1024];
Mark Lobodzinski15427102015-02-18 16:38:17 -06001585 sprintf(str, "In xglCmdCloneImageData() call unable to update binding of destImage buffer %p to cmdBuffer %p", destImage, cmdBuffer);
Tobin Ehlis62086412014-11-19 16:19:28 -07001586 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1587 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001588 loader_platform_thread_unlock_mutex(&globalLock);
Mike Stroyan55658c22014-12-04 11:08:39 +00001589 nextTable.CmdCloneImageData(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001590}
1591
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001592XGL_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 Ehlis791a49c2014-11-10 12:29:12 -07001593{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001594 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001595 XGL_GPU_MEMORY mem = getMemBindingFromObject(destBuffer);
1596 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001597 char str[1024];
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001598 sprintf(str, "In xglCmdUpdateMemory() call unable to update binding of destBuffer %p to cmdBuffer %p", destBuffer, cmdBuffer);
Tobin Ehlis62086412014-11-19 16:19:28 -07001599 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1600 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001601 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001602 nextTable.CmdUpdateBuffer(cmdBuffer, destBuffer, destOffset, dataSize, pData);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001603}
1604
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001605XGL_LAYER_EXPORT void XGLAPI xglCmdFillBuffer(XGL_CMD_BUFFER cmdBuffer, XGL_BUFFER destBuffer, XGL_GPU_SIZE destOffset, XGL_GPU_SIZE fillSize, uint32_t data)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001606{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001607 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001608 XGL_GPU_MEMORY mem = getMemBindingFromObject(destBuffer);
1609 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001610 char str[1024];
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001611 sprintf(str, "In xglCmdFillMemory() call unable to update binding of destBuffer %p to cmdBuffer %p", destBuffer, cmdBuffer);
Tobin Ehlis62086412014-11-19 16:19:28 -07001612 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1613 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001614 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001615 nextTable.CmdFillBuffer(cmdBuffer, destBuffer, destOffset, fillSize, data);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001616}
1617
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001618XGL_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 Ehlis791a49c2014-11-10 12:29:12 -07001619{
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001620 // TODO : Verify memory is in XGL_IMAGE_STATE_CLEAR state
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001621 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001622 XGL_GPU_MEMORY mem = getMemBindingFromObject(image);
Tobin Ehlis62086412014-11-19 16:19:28 -07001623 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1624 char str[1024];
Mark Lobodzinski15427102015-02-18 16:38:17 -06001625 sprintf(str, "In xglCmdClearColorImage() call unable to update binding of image buffer %p to cmdBuffer %p", image, cmdBuffer);
Tobin Ehlis62086412014-11-19 16:19:28 -07001626 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1627 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001628 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001629 nextTable.CmdClearColorImage(cmdBuffer, image, color, rangeCount, pRanges);
1630}
1631
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001632XGL_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 Ehlis791a49c2014-11-10 12:29:12 -07001633{
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001634 // TODO : Verify memory is in XGL_IMAGE_STATE_CLEAR state
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001635 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001636 XGL_GPU_MEMORY mem = getMemBindingFromObject(image);
Tobin Ehlis62086412014-11-19 16:19:28 -07001637 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1638 char str[1024];
Mark Lobodzinski15427102015-02-18 16:38:17 -06001639 sprintf(str, "In xglCmdClearColorImageRaw() call unable to update binding of image buffer %p to cmdBuffer %p", image, cmdBuffer);
Tobin Ehlis62086412014-11-19 16:19:28 -07001640 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1641 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001642 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001643 nextTable.CmdClearColorImageRaw(cmdBuffer, image, color, rangeCount, pRanges);
1644}
1645
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001646XGL_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 Ehlis791a49c2014-11-10 12:29:12 -07001647{
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001648 // TODO : Verify memory is in XGL_IMAGE_STATE_CLEAR state
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001649 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001650 XGL_GPU_MEMORY mem = getMemBindingFromObject(image);
Tobin Ehlis62086412014-11-19 16:19:28 -07001651 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1652 char str[1024];
Mark Lobodzinski15427102015-02-18 16:38:17 -06001653 sprintf(str, "In xglCmdClearDepthStencil() call unable to update binding of image buffer %p to cmdBuffer %p", image, cmdBuffer);
Tobin Ehlis62086412014-11-19 16:19:28 -07001654 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1655 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001656 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001657 nextTable.CmdClearDepthStencil(cmdBuffer, image, depth, stencil, rangeCount, pRanges);
1658}
1659
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001660XGL_LAYER_EXPORT void XGLAPI xglCmdResolveImage(XGL_CMD_BUFFER cmdBuffer, XGL_IMAGE srcImage, XGL_IMAGE destImage, uint32_t rectCount, const XGL_IMAGE_RESOLVE* pRects)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001661{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001662 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001663 XGL_GPU_MEMORY mem = getMemBindingFromObject(srcImage);
Tobin Ehlis62086412014-11-19 16:19:28 -07001664 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1665 char str[1024];
Mark Lobodzinski15427102015-02-18 16:38:17 -06001666 sprintf(str, "In xglCmdResolveImage() call unable to update binding of srcImage buffer %p to cmdBuffer %p", srcImage, cmdBuffer);
Tobin Ehlis62086412014-11-19 16:19:28 -07001667 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1668 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001669 mem = getMemBindingFromObject(destImage);
Tobin Ehlis62086412014-11-19 16:19:28 -07001670 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1671 char str[1024];
Mark Lobodzinski15427102015-02-18 16:38:17 -06001672 sprintf(str, "In xglCmdResolveImage() call unable to update binding of destImage buffer %p to cmdBuffer %p", destImage, cmdBuffer);
Tobin Ehlis62086412014-11-19 16:19:28 -07001673 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1674 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001675 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001676 nextTable.CmdResolveImage(cmdBuffer, srcImage, destImage, rectCount, pRects);
1677}
1678
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001679XGL_LAYER_EXPORT void XGLAPI xglCmdBeginQuery(XGL_CMD_BUFFER cmdBuffer, XGL_QUERY_POOL queryPool, uint32_t slot, XGL_FLAGS flags)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001680{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001681 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001682 XGL_GPU_MEMORY mem = getMemBindingFromObject(queryPool);
Tobin Ehlis62086412014-11-19 16:19:28 -07001683 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1684 char str[1024];
Mark Lobodzinski15427102015-02-18 16:38:17 -06001685 sprintf(str, "In xglCmdBeginQuery() call unable to update binding of queryPool buffer %p to cmdBuffer %p", queryPool, cmdBuffer);
Tobin Ehlis62086412014-11-19 16:19:28 -07001686 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1687 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001688 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001689 nextTable.CmdBeginQuery(cmdBuffer, queryPool, slot, flags);
1690}
1691
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001692XGL_LAYER_EXPORT void XGLAPI xglCmdEndQuery(XGL_CMD_BUFFER cmdBuffer, XGL_QUERY_POOL queryPool, uint32_t slot)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001693{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001694 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001695 XGL_GPU_MEMORY mem = getMemBindingFromObject(queryPool);
Tobin Ehlis62086412014-11-19 16:19:28 -07001696 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1697 char str[1024];
Mark Lobodzinski15427102015-02-18 16:38:17 -06001698 sprintf(str, "In xglCmdEndQuery() call unable to update binding of queryPool buffer %p to cmdBuffer %p", queryPool, cmdBuffer);
Tobin Ehlis62086412014-11-19 16:19:28 -07001699 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1700 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001701 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001702 nextTable.CmdEndQuery(cmdBuffer, queryPool, slot);
1703}
1704
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001705XGL_LAYER_EXPORT void XGLAPI xglCmdResetQueryPool(XGL_CMD_BUFFER cmdBuffer, XGL_QUERY_POOL queryPool, uint32_t startQuery, uint32_t queryCount)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001706{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001707 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001708 XGL_GPU_MEMORY mem = getMemBindingFromObject(queryPool);
Tobin Ehlis62086412014-11-19 16:19:28 -07001709 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1710 char str[1024];
Mark Lobodzinski15427102015-02-18 16:38:17 -06001711 sprintf(str, "In xglCmdResetQueryPool() call unable to update binding of queryPool buffer %p to cmdBuffer %p", queryPool, cmdBuffer);
Tobin Ehlis62086412014-11-19 16:19:28 -07001712 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1713 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001714 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001715 nextTable.CmdResetQueryPool(cmdBuffer, queryPool, startQuery, queryCount);
1716}
1717
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001718XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglDbgRegisterMsgCallback(XGL_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback, void* pUserData)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001719{
Tobin Ehlis62086412014-11-19 16:19:28 -07001720 // This layer intercepts callbacks
1721 XGL_LAYER_DBG_FUNCTION_NODE *pNewDbgFuncNode = (XGL_LAYER_DBG_FUNCTION_NODE*)malloc(sizeof(XGL_LAYER_DBG_FUNCTION_NODE));
1722 if (!pNewDbgFuncNode)
1723 return XGL_ERROR_OUT_OF_MEMORY;
1724 pNewDbgFuncNode->pfnMsgCallback = pfnMsgCallback;
1725 pNewDbgFuncNode->pUserData = pUserData;
Jon Ashburnf57ea372014-12-22 13:24:15 -07001726 pNewDbgFuncNode->pNext = g_pDbgFunctionHead;
1727 g_pDbgFunctionHead = pNewDbgFuncNode;
Jon Ashburne4722392015-03-03 15:07:15 -07001728 // force callbacks if DebugAction hasn't been set already other than initial value
Courtney Goeltzenleuchter9e3aafa2015-03-04 15:47:34 -07001729 if (g_actionIsDefault) {
Jon Ashburne4722392015-03-03 15:07:15 -07001730 g_debugAction = XGL_DBG_LAYER_ACTION_CALLBACK;
Courtney Goeltzenleuchter9e3aafa2015-03-04 15:47:34 -07001731 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001732 XGL_RESULT result = nextTable.DbgRegisterMsgCallback(pfnMsgCallback, pUserData);
1733 return result;
1734}
1735
1736XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglDbgUnregisterMsgCallback(XGL_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback)
1737{
Jon Ashburnf57ea372014-12-22 13:24:15 -07001738 XGL_LAYER_DBG_FUNCTION_NODE *pTrav = g_pDbgFunctionHead;
Tobin Ehlis62086412014-11-19 16:19:28 -07001739 XGL_LAYER_DBG_FUNCTION_NODE *pPrev = pTrav;
1740 while (pTrav) {
1741 if (pTrav->pfnMsgCallback == pfnMsgCallback) {
1742 pPrev->pNext = pTrav->pNext;
Jon Ashburnf57ea372014-12-22 13:24:15 -07001743 if (g_pDbgFunctionHead == pTrav)
1744 g_pDbgFunctionHead = pTrav->pNext;
Tobin Ehlis62086412014-11-19 16:19:28 -07001745 free(pTrav);
1746 break;
1747 }
1748 pPrev = pTrav;
1749 pTrav = pTrav->pNext;
1750 }
Jon Ashburne4722392015-03-03 15:07:15 -07001751 if (g_pDbgFunctionHead == NULL)
1752 {
1753 if (g_actionIsDefault)
1754 g_debugAction = XGL_DBG_LAYER_ACTION_LOG_MSG;
1755 else
1756 g_debugAction &= ~XGL_DBG_LAYER_ACTION_CALLBACK;
1757 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001758 XGL_RESULT result = nextTable.DbgUnregisterMsgCallback(pfnMsgCallback);
1759 return result;
1760}
1761
Jon Ashburndc899962015-03-02 16:51:38 -07001762#if !defined(WIN32)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001763XGL_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)
1764{
1765 XGL_RESULT result = nextTable.WsiX11CreatePresentableImage(device, pCreateInfo, pImage, pMem);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001766 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001767 if (XGL_SUCCESS == result) {
1768 // Add image object, then insert the new Mem Object and then bind it to created image
1769 insertGlobalObjectNode(*pImage, _XGL_STRUCTURE_TYPE_MAX_ENUM, pCreateInfo, sizeof(XGL_WSI_X11_PRESENTABLE_IMAGE_CREATE_INFO), "wsi_x11_image");
Mark Lobodzinski15427102015-02-18 16:38:17 -06001770 insertGlobalMemObj(*pMem, NULL);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001771 if (XGL_FALSE == updateObjectBinding(*pImage, *pMem)) {
1772 char str[1024];
1773 sprintf(str, "In xglWsiX11CreatePresentableImage(), unable to set image %p binding to mem obj %p", (void*)*pImage, (void*)*pMem);
1774 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, *pImage, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1775 }
Tobin Ehlis62086412014-11-19 16:19:28 -07001776 }
1777 printObjList();
1778 printMemList();
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001779 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001780 return result;
1781}
Ian Elliott81ac44c2015-01-13 17:52:38 -07001782#endif // WIN32
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001783
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001784XGL_LAYER_EXPORT void* XGLAPI xglGetProcAddr(XGL_PHYSICAL_GPU gpu, const char* funcName)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001785{
1786 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
Chia-I Wu706533e2015-01-05 13:18:57 +08001787
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001788 if (gpu == NULL)
1789 return NULL;
1790 pCurObj = gpuw;
Ian Elliott81ac44c2015-01-13 17:52:38 -07001791 loader_platform_thread_once(&g_initOnce, initMemTracker);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001792
Jon Ashburndc899962015-03-02 16:51:38 -07001793 if (!strcmp(funcName, "xglGetProcAddr"))
1794 return (void *) xglGetProcAddr;
1795 if (!strcmp(funcName, "xglCreateDevice"))
1796 return (void*) xglCreateDevice;
1797 if (!strcmp(funcName, "xglDestroyDevice"))
1798 return (void*) xglDestroyDevice;
1799 if (!strcmp(funcName, "xglEnumerateLayers"))
1800 return (void*) xglEnumerateLayers;
1801 if (!strcmp(funcName, "xglQueueSubmit"))
1802 return (void*) xglQueueSubmit;
1803 if (!strcmp(funcName, "xglQueueSetGlobalMemReferences"))
1804 return (void*) xglQueueSetGlobalMemReferences;
1805 if (!strcmp(funcName, "xglAllocMemory"))
1806 return (void*) xglAllocMemory;
1807 if (!strcmp(funcName, "xglFreeMemory"))
1808 return (void*) xglFreeMemory;
1809 if (!strcmp(funcName, "xglSetMemoryPriority"))
1810 return (void*) xglSetMemoryPriority;
1811 if (!strcmp(funcName, "xglMapMemory"))
1812 return (void*) xglMapMemory;
1813 if (!strcmp(funcName, "xglUnmapMemory"))
1814 return (void*) xglUnmapMemory;
1815 if (!strcmp(funcName, "xglPinSystemMemory"))
1816 return (void*) xglPinSystemMemory;
1817 if (!strcmp(funcName, "xglOpenSharedMemory"))
1818 return (void*) xglOpenSharedMemory;
1819 if (!strcmp(funcName, "xglOpenPeerMemory"))
1820 return (void*) xglOpenPeerMemory;
1821 if (!strcmp(funcName, "xglOpenPeerImage"))
1822 return (void*) xglOpenPeerImage;
1823 if (!strcmp(funcName, "xglDestroyObject"))
1824 return (void*) xglDestroyObject;
1825 if (!strcmp(funcName, "xglGetObjectInfo"))
1826 return (void*) xglGetObjectInfo;
1827 if (!strcmp(funcName, "xglBindObjectMemory"))
1828 return (void*) xglBindObjectMemory;
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001829 if (!strcmp(funcName, "xglCreateFence"))
1830 return (void*) xglCreateFence;
1831 if (!strcmp(funcName, "xglGetFenceStatus"))
1832 return (void*) xglGetFenceStatus;
1833 if (!strcmp(funcName, "xglWaitForFences"))
1834 return (void*) xglWaitForFences;
Jon Ashburndc899962015-03-02 16:51:38 -07001835 if (!strcmp(funcName, "xglCreateEvent"))
1836 return (void*) xglCreateEvent;
1837 if (!strcmp(funcName, "xglCreateQueryPool"))
1838 return (void*) xglCreateQueryPool;
1839 if (!strcmp(funcName, "xglCreateBuffer"))
1840 return (void*) xglCreateBuffer;
1841 if (!strcmp(funcName, "xglCreateBufferView"))
1842 return (void*) xglCreateBufferView;
1843 if (!strcmp(funcName, "xglCreateImage"))
1844 return (void*) xglCreateImage;
1845 if (!strcmp(funcName, "xglCreateImageView"))
1846 return (void*) xglCreateImageView;
1847 if (!strcmp(funcName, "xglCreateColorAttachmentView"))
1848 return (void*) xglCreateColorAttachmentView;
1849 if (!strcmp(funcName, "xglCreateDepthStencilView"))
1850 return (void*) xglCreateDepthStencilView;
1851 if (!strcmp(funcName, "xglCreateShader"))
1852 return (void*) xglCreateShader;
1853 if (!strcmp(funcName, "xglCreateGraphicsPipeline"))
1854 return (void*) xglCreateGraphicsPipeline;
1855 if (!strcmp(funcName, "xglCreateComputePipeline"))
1856 return (void*) xglCreateComputePipeline;
1857 if (!strcmp(funcName, "xglCreateSampler"))
1858 return (void*) xglCreateSampler;
1859 if (!strcmp(funcName, "xglCreateDynamicViewportState"))
1860 return (void*) xglCreateDynamicViewportState;
1861 if (!strcmp(funcName, "xglCreateDynamicRasterState"))
1862 return (void*) xglCreateDynamicRasterState;
1863 if (!strcmp(funcName, "xglCreateDynamicColorBlendState"))
1864 return (void*) xglCreateDynamicColorBlendState;
1865 if (!strcmp(funcName, "xglCreateDynamicDepthStencilState"))
1866 return (void*) xglCreateDynamicDepthStencilState;
1867 if (!strcmp(funcName, "xglCreateCommandBuffer"))
1868 return (void*) xglCreateCommandBuffer;
1869 if (!strcmp(funcName, "xglBeginCommandBuffer"))
1870 return (void*) xglBeginCommandBuffer;
1871 if (!strcmp(funcName, "xglEndCommandBuffer"))
1872 return (void*) xglEndCommandBuffer;
1873 if (!strcmp(funcName, "xglResetCommandBuffer"))
1874 return (void*) xglResetCommandBuffer;
1875 if (!strcmp(funcName, "xglCmdBindPipeline"))
1876 return (void*) xglCmdBindPipeline;
1877 if (!strcmp(funcName, "xglCmdBindDynamicStateObject"))
1878 return (void*) xglCmdBindDynamicStateObject;
1879 if (!strcmp(funcName, "xglCmdBindDescriptorSet"))
1880 return (void*) xglCmdBindDescriptorSet;
1881 if (!strcmp(funcName, "xglCmdBindVertexBuffer"))
1882 return (void*) xglCmdBindVertexBuffer;
1883 if (!strcmp(funcName, "xglCmdBindIndexBuffer"))
1884 return (void*) xglCmdBindIndexBuffer;
1885 if (!strcmp(funcName, "xglCmdDrawIndirect"))
1886 return (void*) xglCmdDrawIndirect;
1887 if (!strcmp(funcName, "xglCmdDrawIndexedIndirect"))
1888 return (void*) xglCmdDrawIndexedIndirect;
1889 if (!strcmp(funcName, "xglCmdDispatchIndirect"))
1890 return (void*) xglCmdDispatchIndirect;
1891 if (!strcmp(funcName, "xglCmdCopyBuffer"))
1892 return (void*) xglCmdCopyBuffer;
1893 if (!strcmp(funcName, "xglCmdCopyImage"))
1894 return (void*) xglCmdCopyImage;
1895 if (!strcmp(funcName, "xglCmdCopyBufferToImage"))
1896 return (void*) xglCmdCopyBufferToImage;
1897 if (!strcmp(funcName, "xglCmdCopyImageToBuffer"))
1898 return (void*) xglCmdCopyImageToBuffer;
1899 if (!strcmp(funcName, "xglCmdCloneImageData"))
1900 return (void*) xglCmdCloneImageData;
1901 if (!strcmp(funcName, "xglCmdUpdateBuffer"))
1902 return (void*) xglCmdUpdateBuffer;
1903 if (!strcmp(funcName, "xglCmdFillBuffer"))
1904 return (void*) xglCmdFillBuffer;
1905 if (!strcmp(funcName, "xglCmdClearColorImage"))
1906 return (void*) xglCmdClearColorImage;
1907 if (!strcmp(funcName, "xglCmdClearColorImageRaw"))
1908 return (void*) xglCmdClearColorImageRaw;
1909 if (!strcmp(funcName, "xglCmdClearDepthStencil"))
1910 return (void*) xglCmdClearDepthStencil;
1911 if (!strcmp(funcName, "xglCmdResolveImage"))
1912 return (void*) xglCmdResolveImage;
1913 if (!strcmp(funcName, "xglCmdBeginQuery"))
1914 return (void*) xglCmdBeginQuery;
1915 if (!strcmp(funcName, "xglCmdEndQuery"))
1916 return (void*) xglCmdEndQuery;
1917 if (!strcmp(funcName, "xglCmdResetQueryPool"))
1918 return (void*) xglCmdResetQueryPool;
1919 if (!strcmp(funcName, "xglDbgRegisterMsgCallback"))
1920 return (void*) xglDbgRegisterMsgCallback;
1921 if (!strcmp(funcName, "xglDbgUnregisterMsgCallback"))
1922 return (void*) xglDbgUnregisterMsgCallback;
1923#if !defined(WIN32)
1924 if (!strcmp(funcName, "xglWsiX11CreatePresentableImage"))
1925 return (void*) xglWsiX11CreatePresentableImage;
1926#endif
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001927 else {
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001928 if (gpuw->pGPA == NULL)
1929 return NULL;
1930 return gpuw->pGPA(gpuw->nextObject, funcName);
1931 }
1932}