blob: 7b2e009c38c54efce89826ede100b798b2b51503 [file] [log] [blame]
Tobin Ehlis6663f492014-11-10 12:29:12 -07001/*
2 * XGL
3 *
4 * Copyright (C) 2014 LunarG, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
28#include <assert.h>
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070029#include "loader_platform.h"
Chia-I Wuaa4121f2015-01-04 23:11:43 +080030#include "xgl_dispatch_table_helper.h"
Tobin Ehlis6663f492014-11-10 12:29:12 -070031#include "xgl_struct_string_helper.h"
Tobin Ehliscd9223b2014-11-19 16:19:28 -070032#include "mem_tracker.h"
Jon Ashburn7d7b3cf2014-12-22 13:24:15 -070033#include "layers_config.h"
Ian Elliott655cad72015-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 Ashburn2e672892015-02-16 08:46:53 -070037#include "layers_msg.h"
Tobin Ehlis6663f492014-11-10 12:29:12 -070038
39static XGL_LAYER_DISPATCH_TABLE nextTable;
40static XGL_BASE_LAYER_OBJECT *pCurObj;
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070041static LOADER_PLATFORM_THREAD_ONCE_DECLARATION(g_initOnce);
Mark Lobodzinski93f494b2015-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 Ashburn7d7b3cf2014-12-22 13:24:15 -070045
Jon Ashburn7d7b3cf2014-12-22 13:24:15 -070046
Tobin Ehlisc145be82015-01-08 15:22:32 -070047#define MAX_BINDING 0xFFFFFFFF
Tobin Ehlisc145be82015-01-08 15:22:32 -070048
Tobin Ehlis6663f492014-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 Ehliscd9223b2014-11-19 16:19:28 -070053static uint64_t numCBNodes = 0;
54static uint64_t numMemObjNodes = 0;
55static uint64_t numObjectNodes = 0;
Mark Lobodzinskic52b7752015-02-18 16:38:17 -060056
Tobin Ehlis6663f492014-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 Ehliscd9223b2014-11-19 16:19:28 -070059// Increment 'insert' if new node was inserted
Tobin Ehlis6663f492014-11-10 12:29:12 -070060// return XGL_SUCCESS if no errors occur
Mark Lobodzinski93f494b2015-03-02 20:23:52 -060061static bool32_t insertMiniNode(MINI_NODE** pHEAD, const XGL_BASE_OBJECT data, uint32_t* insert)
Tobin Ehlis6663f492014-11-10 12:29:12 -070062{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -060063 bool32_t result = XGL_TRUE;
Tobin Ehlis6663f492014-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 Lobodzinski93f494b2015-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 Ehlis6663f492014-11-10 12:29:12 -070094 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -060095 return result;
Tobin Ehlis6663f492014-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 Ehliscd9223b2014-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 Ehlis6663f492014-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 Lobodzinski93f494b2015-03-02 20:23:52 -0600128 while (pTrav && (pTrav->cmdBuffer != cb)) {
Tobin Ehlis6663f492014-11-10 12:29:12 -0700129 pTrav = pTrav->pNextGlobalCBNode;
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600130 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700131 return pTrav;
132}
133// Set fence for given cb in global cb node
Mark Lobodzinskibe24fd92015-02-25 18:11:05 -0600134static bool32_t setCBFence(const XGL_CMD_BUFFER cb, const XGL_FENCE fence, bool32_t localFlag)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700135{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600136
Tobin Ehlis6663f492014-11-10 12:29:12 -0700137 GLOBAL_CB_NODE* pTrav = getGlobalCBNode(cb);
138 if (!pTrav) {
Tobin Ehliscd9223b2014-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 Ehlis6663f492014-11-10 12:29:12 -0700142 return XGL_FALSE;
143 }
144 pTrav->fence = fence;
Mark Lobodzinskibe24fd92015-02-25 18:11:05 -0600145 pTrav->localFlag = localFlag;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700146 return XGL_TRUE;
147}
148
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600149static bool32_t validateCBMemRef(const XGL_CMD_BUFFER cb, uint32_t memRefCount, const XGL_MEMORY_REF* pMemRefs)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700150{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600151 bool32_t result = XGL_TRUE;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700152 GLOBAL_CB_NODE* pTrav = getGlobalCBNode(cb);
153 if (!pTrav) {
Tobin Ehliscd9223b2014-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 Lobodzinski93f494b2015-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 Ehliscd9223b2014-11-19 16:19:28 -0700177 char str[1024];
Mark Lobodzinski93f494b2015-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 Ehliscd9223b2014-11-19 16:19:28 -0700193 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700194 }
195 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700196 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600197 return result;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700198}
Tobin Ehlisc145be82015-01-08 15:22:32 -0700199// Return ptr to node in global LL containing mem, or NULL if not found
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -0700200// Calls to this function should be wrapped in mutex
Tobin Ehlisc145be82015-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 Lobodzinski93f494b2015-03-02 20:23:52 -0600204 while (pTrav && (pTrav->mem != mem)) {
Tobin Ehlisc145be82015-01-08 15:22:32 -0700205 pTrav = pTrav->pNextGlobalNode;
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600206 }
Tobin Ehlisc145be82015-01-08 15:22:32 -0700207 return pTrav;
208}
209
Mark Lobodzinskic52b7752015-02-18 16:38:17 -0600210static void insertGlobalMemObj(const XGL_GPU_MEMORY mem, const XGL_MEMORY_ALLOC_INFO* pAllocInfo)
Tobin Ehlis6663f492014-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 Ehliscd9223b2014-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 Lobodzinskic52b7752015-02-18 16:38:17 -0600231 if (pAllocInfo) { // MEM alloc created by xglWsiX11CreatePresentableImage() doesn't have alloc info struct
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700232 memcpy(&pTrav->allocInfo, pAllocInfo, sizeof(XGL_MEMORY_ALLOC_INFO));
Mark Lobodzinskic52b7752015-02-18 16:38:17 -0600233 // TODO: Update for real hardware, actually process allocation info structures
234 pTrav->allocInfo.pNext = NULL;
Tobin Ehlisc145be82015-01-08 15:22:32 -0700235 }
Mark Lobodzinskic52b7752015-02-18 16:38:17 -0600236 pTrav->mem = mem;
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700237 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700238}
239
Tobin Ehlis6663f492014-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 Lobodzinski17caf572015-01-29 08:55:56 -0600242static bool32_t updateCBBinding(const XGL_CMD_BUFFER cb, const XGL_GPU_MEMORY mem)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700243{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600244 bool32_t result = XGL_FALSE;
Tobin Ehlis6663f492014-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 Ehliscd9223b2014-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 Lobodzinski93f494b2015-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 Ehlis6663f492014-11-10 12:29:12 -0700267 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600268 return result;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700269}
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600270
Tobin Ehlis6663f492014-11-10 12:29:12 -0700271// Clear the CB Binding for mem
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -0700272// Calls to this function should be wrapped in mutex
Tobin Ehlis6663f492014-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 Ehlisc9dbcd52015-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 }
286 if (!pMiniCB) {
287 char str[1024];
288 sprintf(str, "Trying to clear CB binding but CB %p not in binding list for mem obj %p", cb, mem);
289 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
290 } else { // remove node from list & decrement refCount
291 pPrev->pNext = pMiniCB->pNext;
292 if (pMiniCB == pTrav->pCmdBufferBindings)
293 pTrav->pCmdBufferBindings = NULL;
294 free(pMiniCB);
295 pTrav->refCount--;
296 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700297 }
298}
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600299
Tobin Ehlis6663f492014-11-10 12:29:12 -0700300// Free bindings related to CB
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600301static bool32_t freeCBBindings(const XGL_CMD_BUFFER cb)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700302{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600303 bool32_t result = XGL_TRUE;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700304 GLOBAL_CB_NODE* pCBTrav = getGlobalCBNode(cb);
305 if (!pCBTrav) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700306 char str[1024];
307 sprintf(str, "Unable to find global CB node %p for deletion", cb);
308 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_INVALID_CB, "MEM", str);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600309 result = XGL_FALSE;
310 } else {
311 if ((pCBTrav->fence != NULL) && (pCBTrav->localFlag == XGL_TRUE)) {
312 nextTable.DestroyObject(pCBTrav->fence);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600313 pCBTrav->localFlag = XGL_FALSE;
314 }
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -0700315 pCBTrav->fence = NULL;
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600316 MINI_NODE* pMemTrav = pCBTrav->pMemObjList;
317 MINI_NODE* pDeleteMe = NULL;
318 // We traverse LL in order and free nodes as they're cleared
319 while (pMemTrav) {
320 pDeleteMe = pMemTrav;
321 if (pMemTrav->mem)
322 clearCBBinding(cb, pMemTrav->mem);
323 pMemTrav = pMemTrav->pNext;
324 free(pDeleteMe);
325 }
326 pCBTrav->pMemObjList = NULL;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700327 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600328 return result;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700329}
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600330
Tobin Ehlis6663f492014-11-10 12:29:12 -0700331// Delete Global CB Node from list along with all of it's mini mem obj node
332// and also clear Global mem references to CB
333// TODO : When should this be called? There's no Destroy of CBs that I see
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600334static bool32_t deleteGlobalCBNode(const XGL_CMD_BUFFER cb)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700335{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600336 bool32_t result = XGL_TRUE;
337 result = freeCBBindings(cb);
338 if (result == XGL_TRUE) {
339 // Delete the Global CB node
340 GLOBAL_CB_NODE* pCBTrav = getGlobalCBNode(cb);
341 pCBTrav = pGlobalCBHead;
342 GLOBAL_CB_NODE* pPrev = pCBTrav;
343 while (pCBTrav && (cb != pCBTrav->cmdBuffer)) {
344 pPrev = pCBTrav;
345 pCBTrav = pCBTrav->pNextGlobalCBNode;
346 }
347 assert(cb); // We found node at start of function so it should still be here
348 pPrev->pNextGlobalCBNode = pCBTrav->pNextGlobalCBNode;
349 if (pCBTrav == pGlobalCBHead) {
350 pGlobalCBHead = pCBTrav->pNextGlobalCBNode;
351 }
352 free(pCBTrav);
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700353 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600354 return result;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700355}
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600356
Tobin Ehlis6663f492014-11-10 12:29:12 -0700357// Delete the entire CB list
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600358static bool32_t deleteGlobalCBList()
Tobin Ehlis6663f492014-11-10 12:29:12 -0700359{
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600360 bool32_t result = XGL_TRUE;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700361 GLOBAL_CB_NODE* pCBTrav = pGlobalCBHead;
362 while (pCBTrav) {
Tobin Ehlisc0418f92014-11-25 14:47:20 -0700363 XGL_CMD_BUFFER cbToDelete = pCBTrav->cmdBuffer;
364 pCBTrav = pCBTrav->pNextGlobalCBNode;
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600365 bool32_t tmpResult = deleteGlobalCBNode(cbToDelete);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700366 // If any result is FALSE, final result should be FALSE
367 if ((XGL_FALSE == tmpResult) || (XGL_FALSE == result))
368 result = XGL_FALSE;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700369 }
370 return result;
371}
372
373// For given MemObj node, report Obj & CB bindings
374static void reportMemReferences(const GLOBAL_MEM_OBJ_NODE* pMemObjTrav)
375{
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600376 uint32_t refCount = 0; // Count found references
Tobin Ehlis6663f492014-11-10 12:29:12 -0700377 MINI_NODE* pObjTrav = pMemObjTrav->pObjBindings;
378 MINI_NODE* pCBTrav = pMemObjTrav->pCmdBufferBindings;
379 while (pCBTrav) {
380 refCount++;
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700381 char str[1024];
382 sprintf(str, "Command Buffer %p has reference to mem obj %p", pCBTrav->cmdBuffer, pMemObjTrav->mem);
383 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, pCBTrav->cmdBuffer, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700384 pCBTrav = pCBTrav->pNext;
385 }
386 while (pObjTrav) {
387 refCount++;
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700388 char str[1024];
389 sprintf(str, "XGL Object %p has reference to mem obj %p", pObjTrav->object, pMemObjTrav->mem);
390 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, pObjTrav->object, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700391 pObjTrav = pObjTrav->pNext;
392 }
393 if (refCount != pMemObjTrav->refCount) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700394 char str[1024];
395 sprintf(str, "Refcount of %u for Mem Obj %p does't match reported refs of %u", pMemObjTrav->refCount, pMemObjTrav->mem, refCount);
Mark Lobodzinskiae5f13b2015-02-26 15:18:57 -0600396 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, pMemObjTrav->mem, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700397 }
398}
399
400static void deleteGlobalMemNode(XGL_GPU_MEMORY mem)
401{
402 GLOBAL_MEM_OBJ_NODE* pTrav = pGlobalMemObjHead;
403 GLOBAL_MEM_OBJ_NODE* pPrev = pTrav;
404 while (pTrav && (pTrav->mem != mem)) {
405 pPrev = pTrav;
406 pTrav = pTrav->pNextGlobalNode;
407 }
408 if (pTrav) {
409 pPrev->pNextGlobalNode = pTrav->pNextGlobalNode;
410 if (pGlobalMemObjHead == pTrav)
411 pGlobalMemObjHead = pTrav->pNextGlobalNode;
412 free(pTrav);
413 }
414 else {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700415 char str[1024];
416 sprintf(str, "Could not find global mem obj node for %p to delete!", mem);
417 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700418 }
419}
420// Check if fence for given CB is completed
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600421static bool32_t checkCBCompleted(const XGL_CMD_BUFFER cb)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700422{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600423 bool32_t result = XGL_TRUE;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700424 GLOBAL_CB_NODE* pCBTrav = getGlobalCBNode(cb);
425 if (!pCBTrav) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700426 char str[1024];
427 sprintf(str, "Unable to find global CB node %p to check for completion", cb);
428 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_INVALID_CB, "MEM", str);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600429 result = XGL_FALSE;
430 } else {
431 if (!pCBTrav->fence) {
432 char str[1024];
433 sprintf(str, "No fence found for CB %p to check for completion", cb);
434 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_CB_MISSING_FENCE, "MEM", str);
435 result = XGL_FALSE;
436 } else {
437 if (XGL_SUCCESS != nextTable.GetFenceStatus(pCBTrav->fence)) {
438 char str[1024];
439 sprintf(str, "Fence %p for CB %p has not completed", pCBTrav->fence, cb);
440 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_NONE, "MEM", str);
441 result = XGL_FALSE;
442 }
443 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700444 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600445 return result;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700446}
447
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -0700448static void clearCBFence(const XGL_FENCE fence)
449{
450 // TODO : This is slow and stupid
451 // Ultimately would like a quick fence lookup w/ all of the CBs using that fence
452 // We have to loop every CB for now b/c multiple CBs may use same fence
453 GLOBAL_CB_NODE* pCBTrav = pGlobalCBHead;
454 while (pCBTrav) {
455 if (pCBTrav->fence == fence) {
456 pCBTrav->fence = NULL;
457 }
458 pCBTrav = pCBTrav->pNextGlobalCBNode;
459 }
460}
461
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600462static bool32_t freeMemNode(XGL_GPU_MEMORY mem)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700463{
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600464 bool32_t result = XGL_TRUE;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700465 // Parse global list to find node w/ mem
466 GLOBAL_MEM_OBJ_NODE* pTrav = getGlobalMemNode(mem);
467 if (!pTrav) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700468 char str[1024];
469 sprintf(str, "Couldn't find mem node object for %p\n Was %p never allocated or previously freed?", (void*)mem, (void*)mem);
470 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600471 result = XGL_FALSE;
472 } else {
Mark Lobodzinski2f3b19b2015-02-18 18:06:24 -0600473 if (pTrav->allocInfo.allocationSize == 0) {
474 char str[1024];
475 sprintf(str, "Attempting to free memory associated with a Presentable Image, %p, this should not be explicitly freed\n", (void*)mem);
Mark Lobodzinski78a21972015-03-05 12:39:33 -0600476 layerCbMsg(XGL_DBG_MSG_WARNING, XGL_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700477 result = XGL_FALSE;
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600478 } else {
479 // Clear any CB bindings for completed CBs
480 // TODO : Is there a better place to do this?
481 MINI_NODE* pMiniCB = pTrav->pCmdBufferBindings;
482 while (pMiniCB) {
483 XGL_CMD_BUFFER curCB = pMiniCB->cmdBuffer;
484 pMiniCB = pMiniCB->pNext;
485 if (XGL_TRUE == checkCBCompleted(curCB)) {
486 freeCBBindings(curCB);
487 }
488 }
489 // Now verify that no references to this mem obj remain
490 if (0 != pTrav->refCount) {
491 // If references remain, report the error and can search down CB LL to find references
492 char str[1024];
493 sprintf(str, "Freeing mem obj %p while it still has references", (void*)mem);
494 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_FREED_MEM_REF, "MEM", str);
495 reportMemReferences(pTrav);
496 result = XGL_FALSE;
497 }
498 // Delete global node
499 deleteGlobalMemNode(mem);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700500 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700501 }
502 return result;
503}
504
505// Return object node for 'object' or return NULL if no node exists
506static GLOBAL_OBJECT_NODE* getGlobalObjectNode(const XGL_OBJECT object)
507{
508 GLOBAL_OBJECT_NODE* pTrav = pGlobalObjectHead;
509 while (pTrav && (object != pTrav->object)) {
510 pTrav = pTrav->pNext;
511 }
512 return pTrav;
513}
514
Tobin Ehlis8be20fd2015-01-07 17:49:29 -0700515static GLOBAL_OBJECT_NODE* insertGlobalObjectNode(XGL_OBJECT object, XGL_STRUCTURE_TYPE sType, const void *pCreateInfo, const int struct_size, char *name_prefix)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700516{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600517 GLOBAL_OBJECT_NODE* newNode = NULL;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700518 GLOBAL_OBJECT_NODE* pTrav = pGlobalObjectHead;
519 if (!pTrav) {
520 pTrav = (GLOBAL_OBJECT_NODE*)malloc(sizeof(GLOBAL_OBJECT_NODE));
Tobin Ehlis6663f492014-11-10 12:29:12 -0700521 memset(pTrav, 0, sizeof(GLOBAL_OBJECT_NODE));
522 pGlobalObjectHead = pTrav;
523 }
524 else {
525 GLOBAL_OBJECT_NODE* pPrev = pTrav;
526 while (pTrav) {
527 pPrev = pTrav;
528 pTrav = pTrav->pNext;
529 }
530 pTrav = (GLOBAL_OBJECT_NODE*)malloc(sizeof(GLOBAL_OBJECT_NODE));
Tobin Ehlis6663f492014-11-10 12:29:12 -0700531 memset(pTrav, 0, sizeof(GLOBAL_OBJECT_NODE));
532 pPrev->pNext = pTrav;
533 }
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700534 if (!pTrav) {
535 char str[1024];
536 sprintf(str, "Malloc failed to alloc node for XGL Object %p", (void*)object);
537 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, object, 0, MEMTRACK_OUT_OF_MEMORY_ERROR, "MEM", str);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600538 } else {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700539 numObjectNodes++;
540 pTrav->object = object;
Tobin Ehlis8be20fd2015-01-07 17:49:29 -0700541 pTrav->ref_count = 1;
542 pTrav->sType = sType;
543 memcpy(&pTrav->create_info, pCreateInfo, struct_size);
544 sprintf(pTrav->object_name, "%s_%p", name_prefix, object);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600545 newNode = pTrav;
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700546 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600547 return newNode;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700548}
549
550// Remove object binding performs 3 tasks:
551// 1. Remove object node from Global Mem Obj mini LL of obj bindings & free it
552// 2. Decrement refCount for Global Mem Obj
553// 3. Clear Global Mem Obj ptr from Global Object Node
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600554static bool32_t clearObjectBinding(XGL_OBJECT object)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700555{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600556 bool32_t result = XGL_FALSE;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700557 GLOBAL_OBJECT_NODE* pGlobalObjTrav = getGlobalObjectNode(object);
558 if (!pGlobalObjTrav) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700559 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -0600560 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);
561 layerCbMsg(XGL_DBG_MSG_WARNING, XGL_VALIDATION_LEVEL_0, object, 0, MEMTRACK_INVALID_OBJECT, "MEM", str);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600562 } else {
563 if (!pGlobalObjTrav->pMemNode) {
564 char str[1024];
565 sprintf(str, "Attempting to clear mem binding on obj %p but it has no binding.", (void*)object);
566 layerCbMsg(XGL_DBG_MSG_WARNING, XGL_VALIDATION_LEVEL_0, object, 0, MEMTRACK_MEM_OBJ_CLEAR_EMPTY_BINDINGS, "MEM", str);
567 } else {
568 MINI_NODE* pObjTrav = pGlobalObjTrav->pMemNode->pObjBindings;
569 MINI_NODE* pPrevObj = pObjTrav;
570 while (pObjTrav && (result == XGL_FALSE)) {
571 if (object == pObjTrav->object) {
572 pPrevObj->pNext = pObjTrav->pNext;
573 // check if HEAD needs to be updated
574 if (pGlobalObjTrav->pMemNode->pObjBindings == pObjTrav)
575 pGlobalObjTrav->pMemNode->pObjBindings = pObjTrav->pNext;
576 free(pObjTrav);
577 pGlobalObjTrav->pMemNode->refCount--;
578 pGlobalObjTrav->pMemNode = NULL;
579 result = XGL_TRUE;
580 }
581 pPrevObj = pObjTrav;
582 pObjTrav = pObjTrav->pNext;
583 }
584 if (result == XGL_FALSE) {
585 char str[1024];
586 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);
587 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, object, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
588 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700589 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700590 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600591 return result;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700592}
593
594// For NULL mem case, clear any previous binding Else...
595// Make sure given object is in global object LL
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700596// IF a previous binding existed, clear it
Tobin Ehlis6663f492014-11-10 12:29:12 -0700597// Add link from global object node to global memory node
598// Add mini-object node & reference off of global obj node
599// Return XGL_TRUE if addition is successful, XGL_FALSE otherwise
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600600static bool32_t updateObjectBinding(XGL_OBJECT object, XGL_GPU_MEMORY mem)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700601{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600602 bool32_t result = XGL_FALSE;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700603 // Handle NULL case separately, just clear previous binding & decrement reference
604 if (mem == XGL_NULL_HANDLE) {
605 clearObjectBinding(object);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600606 result = XGL_TRUE;
607 } else {
608 char str[1024];
609 GLOBAL_OBJECT_NODE* pGlobalObjTrav = getGlobalObjectNode(object);
610 if (!pGlobalObjTrav) {
611 sprintf(str, "Attempting to update Binding of Obj(%p) that's not in global list()", (void*)object);
612 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, object, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
613 return XGL_FALSE;
614 }
615 // non-null case so should have real mem obj
616 GLOBAL_MEM_OBJ_NODE* pTrav = getGlobalMemNode(mem);
617 if (!pTrav) {
618 sprintf(str, "While trying to bind mem for obj %p, couldn't find node for mem obj %p", (void*)object, (void*)mem);
619 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
620 } else {
621 result = insertMiniNode(&pTrav->pObjBindings, object, &pTrav->refCount);
622 if (XGL_TRUE == result) {
623 if (pGlobalObjTrav->pMemNode) {
624 clearObjectBinding(object); // Need to clear the previous object binding before setting new binding
625 sprintf(str, "Updating memory binding for object %p from mem obj %p to %p", object, pGlobalObjTrav->pMemNode->mem, mem);
626 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, object, 0, MEMTRACK_NONE, "MEM", str);
627 }
628 // For image objects, make sure default memory state is correctly set
629 // TODO : What's the best/correct way to handle this?
630 if (XGL_STRUCTURE_TYPE_IMAGE_CREATE_INFO == pGlobalObjTrav->sType) {
631 if (pGlobalObjTrav->create_info.image_create_info.usage & (XGL_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | XGL_IMAGE_USAGE_DEPTH_STENCIL_BIT)) {
632 // TODO:: More memory state transition stuff.
633 }
634 }
635 pGlobalObjTrav->pMemNode = pTrav;
636 }
Tobin Ehlis8be20fd2015-01-07 17:49:29 -0700637 }
638 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700639 return XGL_TRUE;
640}
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600641
Tobin Ehlis6663f492014-11-10 12:29:12 -0700642// Print details of global Obj tracking list
643static void printObjList()
644{
645 GLOBAL_OBJECT_NODE* pGlobalObjTrav = pGlobalObjectHead;
646 if (!pGlobalObjTrav) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700647 char str[1024];
648 sprintf(str, "Global Object list is empty :(\n");
649 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700650 }
651 else {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700652 char str[1024];
653 sprintf(str, "Details of Global Object list w/ HEAD at %p", (void*)pGlobalObjTrav);
654 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700655 while (pGlobalObjTrav) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600656 sprintf(str, " GlobObjNode %p has object %p, pNext %p, pMemNode %p",
657 pGlobalObjTrav, pGlobalObjTrav->object, pGlobalObjTrav->pNext, pGlobalObjTrav->pMemNode);
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700658 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, pGlobalObjTrav->object, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700659 pGlobalObjTrav = pGlobalObjTrav->pNext;
660 }
661 }
662}
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600663
Tobin Ehlis6663f492014-11-10 12:29:12 -0700664// For given Object, get 'mem' obj that it's bound to or NULL if no binding
665static XGL_GPU_MEMORY getMemBindingFromObject(const XGL_OBJECT object)
666{
667 XGL_GPU_MEMORY mem = NULL;
668 GLOBAL_OBJECT_NODE* pObjNode = getGlobalObjectNode(object);
669 if (pObjNode) {
670 if (pObjNode->pMemNode) {
671 mem = pObjNode->pMemNode->mem;
672 }
673 else {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700674 char str[1024];
675 sprintf(str, "Trying to get mem binding for object %p but object has no mem binding", (void*)object);
676 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, object, 0, MEMTRACK_MISSING_MEM_BINDINGS, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700677 printObjList();
678 }
679 }
680 else {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700681 char str[1024];
682 sprintf(str, "Trying to get mem binding for object %p but no such object in global list", (void*)object);
683 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, object, 0, MEMTRACK_INVALID_OBJECT, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700684 printObjList();
685 }
686 return mem;
687}
688// Print details of global Mem Obj list
689static void printMemList()
690{
691 GLOBAL_MEM_OBJ_NODE* pTrav = pGlobalMemObjHead;
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700692 // Just printing each msg individually for now, may want to package these into single large print
693 char str[1024];
Tobin Ehlis6663f492014-11-10 12:29:12 -0700694 if (!pTrav) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700695 sprintf(str, "MEM INFO : Global Memory Object list is empty :(\n");
696 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700697 }
698 else {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700699 sprintf(str, "MEM INFO : Details of Global Memory Object list w/ HEAD at %p", (void*)pTrav);
700 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700701 while (pTrav) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700702 sprintf(str, " ===MemObj Node at %p===", (void*)pTrav);
703 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
704 sprintf(str, " Mem object: %p", (void*)pTrav->mem);
705 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
706 sprintf(str, " Ref Count: %u", pTrav->refCount);
707 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
708 sprintf(str, " pNext Mem Obj Node: %p", (void*)pTrav->pNextGlobalNode);
709 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinskic815b002015-02-26 18:33:10 -0600710 if (0 != pTrav->allocInfo.allocationSize) {
711 char* pAllocInfoMsg = xgl_print_xgl_memory_alloc_info(&pTrav->allocInfo, "{MEM}INFO : ");
712 sprintf(str, " Mem Alloc info:\n%s", pAllocInfoMsg);
713 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
714 free(pAllocInfoMsg);
715 } else {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700716 sprintf(str, " Mem Alloc info is NULL (alloc done by xglWsiX11CreatePresentableImage())");
Mark Lobodzinskic815b002015-02-26 18:33:10 -0600717 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
718 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700719 MINI_NODE* pObjTrav = pTrav->pObjBindings;
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700720 if (!pObjTrav) {
721 sprintf(str, " No XGL Object bindings");
722 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
723 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700724 else {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700725 sprintf(str, " XGL OBJECT Binding list w/ HEAD at %p:", pObjTrav);
726 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700727 while (pObjTrav) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700728 sprintf(str, " OBJ_NODE(%p): XGL OBJECT %p, pNext %p", pObjTrav, pObjTrav->object, pObjTrav->pNext);
729 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700730 pObjTrav = pObjTrav->pNext;
731 }
732 }
733 MINI_NODE* pCBTrav = pTrav->pCmdBufferBindings;
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700734 if (!pCBTrav) {
735 sprintf(str, " No Command Buffer bindings");
736 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
737 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700738 else {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700739 sprintf(str, " XGL Command Buffer (CB) binding list w/ HEAD at %p:", pCBTrav);
740 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700741 while (pCBTrav) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700742 sprintf(str, " CB_NODE(%p): XGL CB %p, pNext %p", pCBTrav, pCBTrav->cmdBuffer, pCBTrav->pNext);
743 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700744 pCBTrav = pCBTrav->pNext;
745 }
746 }
747 pTrav = pTrav->pNextGlobalNode;
748 }
749 }
750}
751
752static void printGlobalCB()
753{
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700754 char str[1024] = {0};
Tobin Ehlis6663f492014-11-10 12:29:12 -0700755 GLOBAL_CB_NODE* pTrav = pGlobalCBHead;
756 if (!pTrav) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700757 sprintf(str, "Global Command Buffer (CB) list is empty :(\n");
758 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700759 }
760 else {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700761 sprintf(str, "Details of Global CB list w/ HEAD at %p:", (void*)pTrav);
762 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700763 while (pTrav) {
Tobin Ehlisc0418f92014-11-25 14:47:20 -0700764 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 Ehliscd9223b2014-11-19 16:19:28 -0700765 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700766 MINI_NODE* pMemObjTrav = pTrav->pMemObjList;
767 while (pMemObjTrav) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700768 sprintf(str, " MEM_NODE(%p): Mem obj %p, pNext %p", (void*)pMemObjTrav, (void*)pMemObjTrav->mem, (void*)pMemObjTrav->pNext);
769 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700770 pMemObjTrav = pMemObjTrav->pNext;
771 }
772 pTrav = pTrav->pNextGlobalCBNode;
773 }
774 }
775}
776
777static XGL_FENCE createLocalFence()
778{
779 XGL_FENCE_CREATE_INFO fci;
780 fci.sType = XGL_STRUCTURE_TYPE_FENCE_CREATE_INFO;
781 fci.pNext = NULL;
782 fci.flags = 0;
783 XGL_FENCE fence;
784 nextTable.CreateFence(globalDevice, &fci, &fence);
785 return fence;
786}
787
Mark Lobodzinskic52b7752015-02-18 16:38:17 -0600788static void initMemTracker(void)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700789{
Jon Ashburn7d7b3cf2014-12-22 13:24:15 -0700790 const char *strOpt;
791 // initialize MemTracker options
Ian Elliotte7826712015-03-06 13:50:05 -0700792 getLayerOptionEnum("MemTrackerReportLevel", (uint32_t *) &g_reportingLevel);
793 g_actionIsDefault = getLayerOptionEnum("MemTrackerDebugAction", (uint32_t *) &g_debugAction);
Tobin Ehlisee702232015-01-08 14:26:53 -0700794
Jon Ashburn7d7b3cf2014-12-22 13:24:15 -0700795 if (g_debugAction & XGL_DBG_LAYER_ACTION_LOG_MSG)
796 {
797 strOpt = getLayerOption("MemTrackerLogFilename");
798 if (strOpt)
799 {
800 g_logFile = fopen(strOpt, "w");
Jon Ashburn7d7b3cf2014-12-22 13:24:15 -0700801 }
802 if (g_logFile == NULL)
803 g_logFile = stdout;
804 }
805
806 // initialize Layer dispatch table
807 // TODO handle multiple GPUs
Mark Lobodzinski391bb6d2015-01-09 15:12:03 -0600808 xglGetProcAddrType fpNextGPA;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700809 fpNextGPA = pCurObj->pGPA;
810 assert(fpNextGPA);
811
Chia-I Wuaa4121f2015-01-04 23:11:43 +0800812 layer_initialize_dispatch_table(&nextTable, fpNextGPA, (XGL_PHYSICAL_GPU) pCurObj->nextObject);
813
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600814 xglGetProcAddrType fpGetProcAddr = fpNextGPA((XGL_PHYSICAL_GPU) pCurObj->nextObject, (char *) "xglGetProcAddr");
Tobin Ehlis6663f492014-11-10 12:29:12 -0700815 nextTable.GetProcAddr = fpGetProcAddr;
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600816
817 if (!globalLockInitialized)
818 {
819 // TODO/TBD: Need to delete this mutex sometime. How??? One
820 // suggestion is to call this during xglCreateInstance(), and then we
821 // can clean it up during xglDestroyInstance(). However, that requires
822 // that the layer have per-instance locks. We need to come back and
823 // address this soon.
824 loader_platform_thread_create_mutex(&globalLock);
825 globalLockInitialized = 1;
826 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700827}
828
Tobin Ehlis6663f492014-11-10 12:29:12 -0700829XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateDevice(XGL_PHYSICAL_GPU gpu, const XGL_DEVICE_CREATE_INFO* pCreateInfo, XGL_DEVICE* pDevice)
830{
831 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
832 pCurObj = gpuw;
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700833 loader_platform_thread_once(&g_initOnce, initMemTracker);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700834 XGL_RESULT result = nextTable.CreateDevice((XGL_PHYSICAL_GPU)gpuw->nextObject, pCreateInfo, pDevice);
835 // Save off device in case we need it to create Fences
836 globalDevice = *pDevice;
837 return result;
838}
839
840XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglDestroyDevice(XGL_DEVICE device)
841{
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700842 char str[1024];
843 sprintf(str, "Printing List details prior to xglDestroyDevice()");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600844 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700845 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, device, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700846 printMemList();
847 printGlobalCB();
848 printObjList();
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700849 if (XGL_FALSE == deleteGlobalCBList()) {
850 sprintf(str, "Issue deleting global CB list in xglDestroyDevice()");
851 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, device, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
852 }
Tobin Ehlisb54ef782014-11-25 18:01:12 -0700853 // Report any memory leaks
854 GLOBAL_MEM_OBJ_NODE* pTrav = pGlobalMemObjHead;
855 while (pTrav) {
Mark Lobodzinski2f3b19b2015-02-18 18:06:24 -0600856 if (pTrav->allocInfo.allocationSize != 0) {
857 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);
858 layerCbMsg(XGL_DBG_MSG_WARNING, XGL_VALIDATION_LEVEL_0, pTrav->mem, 0, MEMTRACK_MEMORY_LEAK, "MEM", str);
859 }
Tobin Ehlisb54ef782014-11-25 18:01:12 -0700860 pTrav = pTrav->pNextGlobalNode;
861 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600862 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700863 XGL_RESULT result = nextTable.DestroyDevice(device);
864 return result;
865}
866
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600867XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglEnumerateLayers(XGL_PHYSICAL_GPU gpu, size_t maxLayerCount, size_t maxStringSize, size_t* pOutLayerCount, char* const* pOutLayers, void* pReserved)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700868{
Jon Ashburnf7a08742014-11-25 11:08:42 -0700869 if (gpu != NULL)
870 {
871 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
872 pCurObj = gpuw;
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700873 loader_platform_thread_once(&g_initOnce, initMemTracker);
Mark Lobodzinski391bb6d2015-01-09 15:12:03 -0600874 XGL_RESULT result = nextTable.EnumerateLayers((XGL_PHYSICAL_GPU)gpuw->nextObject, maxLayerCount, maxStringSize, pOutLayerCount, pOutLayers, pReserved);
Jon Ashburnf7a08742014-11-25 11:08:42 -0700875 return result;
876 } else
877 {
878 if (pOutLayerCount == NULL || pOutLayers == NULL || pOutLayers[0] == NULL)
879 return XGL_ERROR_INVALID_POINTER;
880 // This layer compatible with all GPUs
881 *pOutLayerCount = 1;
Chia-I Wu1da4b9f2014-12-16 10:47:33 +0800882 strncpy((char *) pOutLayers[0], "MemTracker", maxStringSize);
Jon Ashburnf7a08742014-11-25 11:08:42 -0700883 return XGL_SUCCESS;
884 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700885}
886
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600887XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglQueueSubmit(XGL_QUEUE queue, uint32_t cmdBufferCount, const XGL_CMD_BUFFER* pCmdBuffers, uint32_t memRefCount, const XGL_MEMORY_REF* pMemRefs, XGL_FENCE fence)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700888{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600889 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskibe24fd92015-02-25 18:11:05 -0600890 bool32_t localFlag = XGL_FALSE;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700891 // TODO : Need to track fence and clear mem references when fence clears
892 XGL_FENCE localFence = fence;
893 if (XGL_NULL_HANDLE == fence) { // allocate our own fence to track cmd buffer
894 localFence = createLocalFence();
Mark Lobodzinskibe24fd92015-02-25 18:11:05 -0600895 localFlag = XGL_TRUE;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700896 }
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700897 char str[1024];
898 sprintf(str, "In xglQueueSubmit(), checking %u cmdBuffers with %u memRefs", cmdBufferCount, memRefCount);
899 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, queue, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700900 printMemList();
901 printGlobalCB();
902 for (uint32_t i = 0; i < cmdBufferCount; i++) {
Mark Lobodzinskibe24fd92015-02-25 18:11:05 -0600903 setCBFence(pCmdBuffers[i], localFence, localFlag);
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700904 sprintf(str, "Verifying mem refs for CB %p", pCmdBuffers[i]);
905 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, pCmdBuffers[i], 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700906 if (XGL_FALSE == validateCBMemRef(pCmdBuffers[i], memRefCount, pMemRefs)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700907 sprintf(str, "Unable to verify memory references for CB %p", (void*)pCmdBuffers[i]);
908 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, pCmdBuffers[i], 0, MEMTRACK_CB_MISSING_MEM_REF, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700909 }
910 }
911 printGlobalCB();
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600912 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700913 XGL_RESULT result = nextTable.QueueSubmit(queue, cmdBufferCount, pCmdBuffers, memRefCount, pMemRefs, localFence);
914 return result;
915}
916
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600917XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglQueueSetGlobalMemReferences(XGL_QUEUE queue, uint32_t memRefCount, const XGL_MEMORY_REF* pMemRefs)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700918{
919 // TODO : Use global mem references as part of list checked on QueueSubmit above
920 XGL_RESULT result = nextTable.QueueSetGlobalMemReferences(queue, memRefCount, pMemRefs);
921 return result;
922}
923
Tobin Ehlis6663f492014-11-10 12:29:12 -0700924XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglAllocMemory(XGL_DEVICE device, const XGL_MEMORY_ALLOC_INFO* pAllocInfo, XGL_GPU_MEMORY* pMem)
925{
926 XGL_RESULT result = nextTable.AllocMemory(device, pAllocInfo, pMem);
927 // TODO : Track allocations and overall size here
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600928 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -0600929 insertGlobalMemObj(*pMem, pAllocInfo);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700930 printMemList();
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600931 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700932 return result;
933}
934
935XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglFreeMemory(XGL_GPU_MEMORY mem)
936{
Tobin Ehlisc0418f92014-11-25 14:47:20 -0700937 /* From spec : A memory object is freed by calling xglFreeMemory() when it is no longer needed. Before
938 * freeing a memory object, an application must ensure the memory object is unbound from
939 * all API objects referencing it and that it is not referenced by any queued command buffers
940 */
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600941 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700942 if (XGL_FALSE == freeMemNode(mem)) {
943 char str[1024];
944 sprintf(str, "Issue while freeing mem obj %p", (void*)mem);
945 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_FREE_MEM_ERROR, "MEM", str);
946 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700947 printMemList();
948 printObjList();
949 printGlobalCB();
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600950 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700951 XGL_RESULT result = nextTable.FreeMemory(mem);
952 return result;
953}
954
955XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglSetMemoryPriority(XGL_GPU_MEMORY mem, XGL_MEMORY_PRIORITY priority)
956{
957 // TODO : Update tracking for this alloc
958 // Make sure memory is not pinned, which can't have priority set
959 XGL_RESULT result = nextTable.SetMemoryPriority(mem, priority);
960 return result;
961}
962
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600963XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglMapMemory(XGL_GPU_MEMORY mem, XGL_FLAGS flags, void** ppData)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700964{
965 // TODO : Track when memory is mapped
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600966 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski95152dc2015-02-25 12:16:04 -0600967 GLOBAL_MEM_OBJ_NODE *pMemObj = getGlobalMemNode(mem);
968 if ((pMemObj->allocInfo.memProps & XGL_MEMORY_PROPERTY_CPU_VISIBLE_BIT) == 0) {
969 char str[1024];
970 sprintf(str, "Mapping Memory (%p) without XGL_MEMORY_PROPERTY_CPU_VISIBLE_BIT set", (void*)mem);
971 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_STATE, "MEM", str);
972 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600973 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700974 XGL_RESULT result = nextTable.MapMemory(mem, flags, ppData);
975 return result;
976}
977
978XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglUnmapMemory(XGL_GPU_MEMORY mem)
979{
980 // TODO : Track as memory gets unmapped, do we want to check what changed following map?
981 // Make sure that memory was ever mapped to begin with
982 XGL_RESULT result = nextTable.UnmapMemory(mem);
983 return result;
984}
985
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600986XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglPinSystemMemory(XGL_DEVICE device, const void* pSysMem, size_t memSize, XGL_GPU_MEMORY* pMem)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700987{
988 // TODO : Track this
989 // Verify that memory is actually pinnable
990 XGL_RESULT result = nextTable.PinSystemMemory(device, pSysMem, memSize, pMem);
991 return result;
992}
993
Tobin Ehlis6663f492014-11-10 12:29:12 -0700994XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglOpenSharedMemory(XGL_DEVICE device, const XGL_MEMORY_OPEN_INFO* pOpenInfo, XGL_GPU_MEMORY* pMem)
995{
996 // TODO : Track this
997 XGL_RESULT result = nextTable.OpenSharedMemory(device, pOpenInfo, pMem);
998 return result;
999}
1000
Tobin Ehlis6663f492014-11-10 12:29:12 -07001001XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglOpenPeerMemory(XGL_DEVICE device, const XGL_PEER_MEMORY_OPEN_INFO* pOpenInfo, XGL_GPU_MEMORY* pMem)
1002{
1003 // TODO : Track this
1004 XGL_RESULT result = nextTable.OpenPeerMemory(device, pOpenInfo, pMem);
1005 return result;
1006}
1007
1008XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglOpenPeerImage(XGL_DEVICE device, const XGL_PEER_IMAGE_OPEN_INFO* pOpenInfo, XGL_IMAGE* pImage, XGL_GPU_MEMORY* pMem)
1009{
1010 // TODO : Track this
1011 XGL_RESULT result = nextTable.OpenPeerImage(device, pOpenInfo, pImage, pMem);
1012 return result;
1013}
1014
1015XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglDestroyObject(XGL_OBJECT object)
1016{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001017 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlisa98df732014-11-27 07:52:04 -07001018 // First check if this is a CmdBuffer
1019 if (NULL != getGlobalCBNode((XGL_CMD_BUFFER)object)) {
1020 deleteGlobalCBNode((XGL_CMD_BUFFER)object);
1021 }
1022 // Now locate node in global list along with prev node
Tobin Ehlisa6c0e3c2014-11-25 12:27:38 -07001023 GLOBAL_OBJECT_NODE* pTrav = pGlobalObjectHead;
1024 GLOBAL_OBJECT_NODE* pPrev = pTrav;
Tobin Ehlisa6c0e3c2014-11-25 12:27:38 -07001025 while (pTrav) {
1026 if (object == pTrav->object)
1027 break;
1028 pPrev = pTrav;
1029 pTrav = pTrav->pNext;
1030 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001031 if (pTrav) {
1032 if (pTrav->pMemNode) {
Tobin Ehlisa98df732014-11-27 07:52:04 -07001033 // Wsi allocated Memory is tied to image object so clear the binding and free that memory automatically
1034 if (0 == pTrav->pMemNode->allocInfo.allocationSize) { // Wsi allocated memory has NULL allocInfo w/ 0 size
1035 XGL_GPU_MEMORY memToFree = pTrav->pMemNode->mem;
1036 clearObjectBinding(object);
1037 freeMemNode(memToFree);
1038 }
1039 else {
1040 char str[1024];
1041 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);
1042 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, object, 0, MEMTRACK_DESTROY_OBJECT_ERROR, "MEM", str);
1043 // From the spec : If an object has previous memory binding, it is required to unbind memory from an API object before it is destroyed.
1044 clearObjectBinding(object);
1045 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001046 }
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07001047 if (XGL_STRUCTURE_TYPE_FENCE_CREATE_INFO == pTrav->sType) {
1048 clearCBFence((XGL_FENCE)object);
1049 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001050 if (pGlobalObjectHead == pTrav) // update HEAD if needed
1051 pGlobalObjectHead = pTrav->pNext;
Tobin Ehlisa6c0e3c2014-11-25 12:27:38 -07001052 // Delete the obj node from global list
1053 pPrev->pNext = pTrav->pNext;
Tobin Ehlis6663f492014-11-10 12:29:12 -07001054 free(pTrav);
1055 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001056 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001057 XGL_RESULT result = nextTable.DestroyObject(object);
1058 return result;
1059}
1060
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001061XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglGetObjectInfo(XGL_BASE_OBJECT object, XGL_OBJECT_INFO_TYPE infoType, size_t* pDataSize, void* pData)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001062{
1063 // TODO : What to track here?
1064 // Could potentially save returned mem requirements and validate values passed into BindObjectMemory for this object
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001065 // From spec : The only objects that are guaranteed to have no external memory requirements are devices, queues, command buffers, shaders and memory objects.
Tobin Ehlis6663f492014-11-10 12:29:12 -07001066 XGL_RESULT result = nextTable.GetObjectInfo(object, infoType, pDataSize, pData);
1067 return result;
1068}
1069
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001070XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglBindObjectMemory(XGL_OBJECT object, uint32_t allocationIdx, XGL_GPU_MEMORY mem, XGL_GPU_SIZE offset)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001071{
Jon Ashburn9b6eae52015-01-15 10:39:19 -07001072 XGL_RESULT result = nextTable.BindObjectMemory(object, allocationIdx, mem, offset);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001073 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001074 // Track objects tied to memory
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001075 if (XGL_FALSE == updateObjectBinding(object, mem)) {
1076 char str[1024];
1077 sprintf(str, "Unable to set object %p binding to mem obj %p", (void*)object, (void*)mem);
1078 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, object, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1079 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001080 printObjList();
1081 printMemList();
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001082 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001083 return result;
1084}
1085
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07001086XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateFence(XGL_DEVICE device, const XGL_FENCE_CREATE_INFO* pCreateInfo, XGL_FENCE* pFence)
1087{
1088 XGL_RESULT result = nextTable.CreateFence(device, pCreateInfo, pFence);
1089 if (XGL_SUCCESS == result) {
1090 loader_platform_thread_lock_mutex(&globalLock);
1091 insertGlobalObjectNode(*pFence, pCreateInfo->sType, pCreateInfo, sizeof(XGL_FENCE_CREATE_INFO), "fence");
1092 loader_platform_thread_unlock_mutex(&globalLock);
1093 }
1094 return result;
1095}
1096
1097XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglGetFenceStatus(XGL_FENCE fence)
1098{
1099 XGL_RESULT result = nextTable.GetFenceStatus(fence);
1100 if (XGL_SUCCESS == result) {
1101 // TODO : Properly we should add validation to make sure app is checking fence
1102 // on CB before Reset/Begin CB call is made
1103 clearCBFence(fence);
1104 }
1105 return result;
1106}
1107
1108XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglWaitForFences(XGL_DEVICE device, uint32_t fenceCount, const XGL_FENCE* pFences, bool32_t waitAll, uint64_t timeout)
1109{
1110 XGL_RESULT result = nextTable.WaitForFences(device, fenceCount, pFences, waitAll, timeout);
1111 if (XGL_SUCCESS == result) {
1112 // TODO : Properly we should add validation to make sure app is checking fence
1113 // on CB before Reset/Begin CB call is made
1114 if (waitAll) { // Clear all the fences
1115 for(uint32_t i = 0; i < fenceCount; i++) {
1116 clearCBFence(pFences[i]);
1117 }
1118 }
1119 else { // Clear only completed fences
1120 for(uint32_t i = 0; i < fenceCount; i++) {
1121 if (XGL_SUCCESS == nextTable.GetFenceStatus(pFences[i])) {
1122 clearCBFence(pFences[i]);
1123 }
1124 }
1125 }
1126 }
1127 return result;
1128}
1129
Tobin Ehlis6663f492014-11-10 12:29:12 -07001130XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateEvent(XGL_DEVICE device, const XGL_EVENT_CREATE_INFO* pCreateInfo, XGL_EVENT* pEvent)
1131{
1132 XGL_RESULT result = nextTable.CreateEvent(device, pCreateInfo, pEvent);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001133 if (XGL_SUCCESS == result) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001134 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001135 insertGlobalObjectNode(*pEvent, pCreateInfo->sType, pCreateInfo, sizeof(XGL_EVENT_CREATE_INFO), "event");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001136 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001137 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001138 return result;
1139}
1140
Tobin Ehlis6663f492014-11-10 12:29:12 -07001141XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateQueryPool(XGL_DEVICE device, const XGL_QUERY_POOL_CREATE_INFO* pCreateInfo, XGL_QUERY_POOL* pQueryPool)
1142{
1143 XGL_RESULT result = nextTable.CreateQueryPool(device, pCreateInfo, pQueryPool);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001144 if (XGL_SUCCESS == result) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001145 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001146 insertGlobalObjectNode(*pQueryPool, pCreateInfo->sType, pCreateInfo, sizeof(XGL_QUERY_POOL_CREATE_INFO), "query_pool");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001147 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001148 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001149 return result;
1150}
1151
Tobin Ehlis7265e832015-01-19 08:42:29 -07001152XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateBuffer(XGL_DEVICE device, const XGL_BUFFER_CREATE_INFO* pCreateInfo, XGL_BUFFER* pBuffer)
1153{
1154 XGL_RESULT result = nextTable.CreateBuffer(device, pCreateInfo, pBuffer);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001155 if (XGL_SUCCESS == result) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001156 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001157 insertGlobalObjectNode(*pBuffer, pCreateInfo->sType, pCreateInfo, sizeof(XGL_BUFFER_CREATE_INFO), "buffer");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001158 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001159 }
Tobin Ehlis7265e832015-01-19 08:42:29 -07001160 return result;
1161}
1162
1163XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateBufferView(XGL_DEVICE device, const XGL_BUFFER_VIEW_CREATE_INFO* pCreateInfo, XGL_BUFFER_VIEW* pView)
1164{
1165 XGL_RESULT result = nextTable.CreateBufferView(device, pCreateInfo, pView);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001166 if (result == XGL_SUCCESS) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001167 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001168 insertGlobalObjectNode(*pView, pCreateInfo->sType, pCreateInfo, sizeof(XGL_BUFFER_VIEW_CREATE_INFO), "buffer_view");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001169 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001170 }
Tobin Ehlis7265e832015-01-19 08:42:29 -07001171 return result;
1172}
1173
Tobin Ehlis6663f492014-11-10 12:29:12 -07001174XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateImage(XGL_DEVICE device, const XGL_IMAGE_CREATE_INFO* pCreateInfo, XGL_IMAGE* pImage)
1175{
1176 XGL_RESULT result = nextTable.CreateImage(device, pCreateInfo, pImage);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001177 if (XGL_SUCCESS == result) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001178 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001179 insertGlobalObjectNode(*pImage, pCreateInfo->sType, pCreateInfo, sizeof(XGL_IMAGE_CREATE_INFO), "image");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001180 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001181 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001182 return result;
1183}
1184
Tobin Ehlis6663f492014-11-10 12:29:12 -07001185XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateImageView(XGL_DEVICE device, const XGL_IMAGE_VIEW_CREATE_INFO* pCreateInfo, XGL_IMAGE_VIEW* pView)
1186{
1187 XGL_RESULT result = nextTable.CreateImageView(device, pCreateInfo, pView);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001188 if (result == XGL_SUCCESS) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001189 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001190 insertGlobalObjectNode(*pView, pCreateInfo->sType, pCreateInfo, sizeof(XGL_IMAGE_VIEW_CREATE_INFO), "image_view");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001191 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001192 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001193 return result;
1194}
1195
1196XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateColorAttachmentView(XGL_DEVICE device, const XGL_COLOR_ATTACHMENT_VIEW_CREATE_INFO* pCreateInfo, XGL_COLOR_ATTACHMENT_VIEW* pView)
1197{
1198 XGL_RESULT result = nextTable.CreateColorAttachmentView(device, pCreateInfo, pView);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001199 if (result == XGL_SUCCESS) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001200 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001201 insertGlobalObjectNode(*pView, pCreateInfo->sType, pCreateInfo, sizeof(XGL_COLOR_ATTACHMENT_VIEW_CREATE_INFO), "color_attachment_view");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001202 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001203 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001204 return result;
1205}
1206
1207XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateDepthStencilView(XGL_DEVICE device, const XGL_DEPTH_STENCIL_VIEW_CREATE_INFO* pCreateInfo, XGL_DEPTH_STENCIL_VIEW* pView)
1208{
1209 XGL_RESULT result = nextTable.CreateDepthStencilView(device, pCreateInfo, pView);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001210 if (result == XGL_SUCCESS) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001211 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001212 insertGlobalObjectNode(*pView, pCreateInfo->sType, pCreateInfo, sizeof(XGL_DEPTH_STENCIL_VIEW_CREATE_INFO), "ds_view");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001213 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001214 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001215 return result;
1216}
1217
1218XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateShader(XGL_DEVICE device, const XGL_SHADER_CREATE_INFO* pCreateInfo, XGL_SHADER* pShader)
1219{
1220 XGL_RESULT result = nextTable.CreateShader(device, pCreateInfo, pShader);
1221 return result;
1222}
1223
1224XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateGraphicsPipeline(XGL_DEVICE device, const XGL_GRAPHICS_PIPELINE_CREATE_INFO* pCreateInfo, XGL_PIPELINE* pPipeline)
1225{
1226 XGL_RESULT result = nextTable.CreateGraphicsPipeline(device, pCreateInfo, pPipeline);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001227 if (result == XGL_SUCCESS) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001228 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001229 insertGlobalObjectNode(*pPipeline, pCreateInfo->sType, pCreateInfo, sizeof(XGL_GRAPHICS_PIPELINE_CREATE_INFO), "graphics_pipeline");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001230 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001231 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001232 return result;
1233}
1234
1235XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateComputePipeline(XGL_DEVICE device, const XGL_COMPUTE_PIPELINE_CREATE_INFO* pCreateInfo, XGL_PIPELINE* pPipeline)
1236{
1237 XGL_RESULT result = nextTable.CreateComputePipeline(device, pCreateInfo, pPipeline);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001238 if (result == XGL_SUCCESS) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001239 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001240 insertGlobalObjectNode(*pPipeline, pCreateInfo->sType, pCreateInfo, sizeof(XGL_COMPUTE_PIPELINE_CREATE_INFO), "compute_pipeline");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001241 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001242 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001243 return result;
1244}
1245
Tobin Ehlis6663f492014-11-10 12:29:12 -07001246XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateSampler(XGL_DEVICE device, const XGL_SAMPLER_CREATE_INFO* pCreateInfo, XGL_SAMPLER* pSampler)
1247{
1248 XGL_RESULT result = nextTable.CreateSampler(device, pCreateInfo, pSampler);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001249 if (result == XGL_SUCCESS) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001250 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001251 insertGlobalObjectNode(*pSampler, pCreateInfo->sType, pCreateInfo, sizeof(XGL_SAMPLER_CREATE_INFO), "sampler");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001252 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001253 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001254 return result;
1255}
1256
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001257XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateDynamicViewportState(XGL_DEVICE device, const XGL_DYNAMIC_VP_STATE_CREATE_INFO* pCreateInfo, XGL_DYNAMIC_VP_STATE_OBJECT* pState)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001258{
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001259 XGL_RESULT result = nextTable.CreateDynamicViewportState(device, pCreateInfo, pState);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001260 if (result == XGL_SUCCESS) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001261 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001262 insertGlobalObjectNode(*pState, pCreateInfo->sType, pCreateInfo, sizeof(XGL_DYNAMIC_VP_STATE_CREATE_INFO), "viewport_state");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001263 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001264 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001265 return result;
1266}
1267
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001268XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateDynamicRasterState(XGL_DEVICE device, const XGL_DYNAMIC_RS_STATE_CREATE_INFO* pCreateInfo, XGL_DYNAMIC_RS_STATE_OBJECT* pState)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001269{
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001270 XGL_RESULT result = nextTable.CreateDynamicRasterState(device, pCreateInfo, pState);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001271 if (result == XGL_SUCCESS) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001272 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001273 insertGlobalObjectNode(*pState, pCreateInfo->sType, pCreateInfo, sizeof(XGL_DYNAMIC_RS_STATE_CREATE_INFO), "raster_state");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001274 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001275 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001276 return result;
1277}
1278
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001279XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateDynamicColorBlendState(XGL_DEVICE device, const XGL_DYNAMIC_CB_STATE_CREATE_INFO* pCreateInfo, XGL_DYNAMIC_CB_STATE_OBJECT* pState)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001280{
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001281 XGL_RESULT result = nextTable.CreateDynamicColorBlendState(device, pCreateInfo, pState);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001282 if (result == XGL_SUCCESS) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001283 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001284 insertGlobalObjectNode(*pState, pCreateInfo->sType, pCreateInfo, sizeof(XGL_DYNAMIC_CB_STATE_CREATE_INFO), "cb_state");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001285 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001286 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001287 return result;
1288}
1289
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001290XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateDynamicDepthStencilState(XGL_DEVICE device, const XGL_DYNAMIC_DS_STATE_CREATE_INFO* pCreateInfo, XGL_DYNAMIC_DS_STATE_OBJECT* pState)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001291{
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001292 XGL_RESULT result = nextTable.CreateDynamicDepthStencilState(device, pCreateInfo, pState);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001293 if (result == XGL_SUCCESS) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001294 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001295 insertGlobalObjectNode(*pState, pCreateInfo->sType, pCreateInfo, sizeof(XGL_DYNAMIC_DS_STATE_CREATE_INFO), "ds_state");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001296 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001297 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001298 return result;
1299}
1300
1301XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateCommandBuffer(XGL_DEVICE device, const XGL_CMD_BUFFER_CREATE_INFO* pCreateInfo, XGL_CMD_BUFFER* pCmdBuffer)
1302{
1303 XGL_RESULT result = nextTable.CreateCommandBuffer(device, pCreateInfo, pCmdBuffer);
1304 // At time of cmd buffer creation, create global cmd buffer node for the returned cmd buffer
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001305 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001306 if (*pCmdBuffer)
1307 insertGlobalCB(*pCmdBuffer);
1308 printGlobalCB();
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001309 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001310 return result;
1311}
1312
Jon Ashburn86522372014-12-31 17:11:49 -07001313XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglBeginCommandBuffer(XGL_CMD_BUFFER cmdBuffer, const XGL_CMD_BUFFER_BEGIN_INFO* pBeginInfo)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001314{
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07001315 // This implicitly resets the Cmd Buffer so make sure any fence is done and then clear memory references
1316 GLOBAL_CB_NODE* pCBTrav = getGlobalCBNode(cmdBuffer);
1317 if (pCBTrav && pCBTrav->fence) {
1318 bool32_t cbDone = checkCBCompleted(cmdBuffer);
1319 if (XGL_FALSE == cbDone) {
1320 char str[1024];
1321 sprintf(str, "Calling xglBeginCommandBuffer() on active CB %p before it has completed. You must check CB flag before this call.", cmdBuffer);
1322 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_RESET_CB_WHILE_IN_FLIGHT, "MEM", str);
1323 }
1324 }
Jon Ashburn86522372014-12-31 17:11:49 -07001325 XGL_RESULT result = nextTable.BeginCommandBuffer(cmdBuffer, pBeginInfo);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001326 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis7265e832015-01-19 08:42:29 -07001327 freeCBBindings(cmdBuffer);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001328 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001329 return result;
1330}
1331
1332XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglEndCommandBuffer(XGL_CMD_BUFFER cmdBuffer)
1333{
1334 // TODO : Anything to do here?
1335 XGL_RESULT result = nextTable.EndCommandBuffer(cmdBuffer);
1336 return result;
1337}
1338
1339XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglResetCommandBuffer(XGL_CMD_BUFFER cmdBuffer)
1340{
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07001341 // Verify that CB is complete (not in-flight)
1342 GLOBAL_CB_NODE* pCBTrav = getGlobalCBNode(cmdBuffer);
1343 if (pCBTrav && pCBTrav->fence) {
1344 bool32_t cbDone = checkCBCompleted(cmdBuffer);
1345 if (XGL_FALSE == cbDone) {
1346 char str[1024];
1347 sprintf(str, "Resetting CB %p before it has completed. You must check CB flag before calling xglResetCommandBuffer().", cmdBuffer);
1348 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_RESET_CB_WHILE_IN_FLIGHT, "MEM", str);
1349 }
1350 }
1351 // Clear memory references as this point.
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001352 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001353 freeCBBindings(cmdBuffer);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001354 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001355 XGL_RESULT result = nextTable.ResetCommandBuffer(cmdBuffer);
1356 return result;
1357}
1358// TODO : For any xglCmdBind* calls that include an object which has mem bound to it,
1359// need to account for that mem now having binding to given cmdBuffer
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001360XGL_LAYER_EXPORT void XGLAPI xglCmdBindPipeline(XGL_CMD_BUFFER cmdBuffer, XGL_PIPELINE_BIND_POINT pipelineBindPoint, XGL_PIPELINE pipeline)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001361{
Tobin Ehlisc145be82015-01-08 15:22:32 -07001362#if 0
1363 // TODO : If memory bound to pipeline, then need to tie that mem to cmdBuffer
1364 if (getPipeline(pipeline)) {
1365 GLOBAL_CB_NODE *pCBTrav = getGlobalCBNode(cmdBuffer);
1366 if (pCBTrav) {
1367 pCBTrav->pipelines[pipelineBindPoint] = pipeline;
1368 } else {
1369 char str[1024];
1370 sprintf(str, "Attempt to bind Pipeline %p to non-existant command buffer %p!", (void*)pipeline, cmdBuffer);
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001371 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_INVALID_CB, (char *) "DS", (char *) str);
Tobin Ehlisc145be82015-01-08 15:22:32 -07001372 }
1373 }
1374 else {
1375 char str[1024];
1376 sprintf(str, "Attempt to bind Pipeline %p that doesn't exist!", (void*)pipeline);
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001377 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, pipeline, 0, MEMTRACK_INVALID_OBJECT, (char *) "DS", (char *) str);
Tobin Ehlisc145be82015-01-08 15:22:32 -07001378 }
1379#endif
Tobin Ehlis6663f492014-11-10 12:29:12 -07001380 nextTable.CmdBindPipeline(cmdBuffer, pipelineBindPoint, pipeline);
1381}
1382
Tobin Ehlis7265e832015-01-19 08:42:29 -07001383XGL_LAYER_EXPORT void XGLAPI xglCmdBindDynamicStateObject(XGL_CMD_BUFFER cmdBuffer, XGL_STATE_BIND_POINT stateBindPoint, XGL_DYNAMIC_STATE_OBJECT state)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001384{
Tobin Ehlisc145be82015-01-08 15:22:32 -07001385 GLOBAL_OBJECT_NODE *pNode;
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001386 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlisc145be82015-01-08 15:22:32 -07001387 GLOBAL_CB_NODE *pCmdBuf = getGlobalCBNode(cmdBuffer);
1388 if (!pCmdBuf) {
1389 char str[1024];
1390 sprintf(str, "Unable to find command buffer object %p, was it ever created?", (void*)cmdBuffer);
1391 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_INVALID_CB, "DD", str);
1392 }
1393 pNode = getGlobalObjectNode(state);
1394 if (!pNode) {
1395 char str[1024];
1396 sprintf(str, "Unable to find dynamic state object %p, was it ever created?", (void*)state);
1397 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, state, 0, MEMTRACK_INVALID_OBJECT, "DD", str);
1398 }
1399 pCmdBuf->pDynamicState[stateBindPoint] = pNode;
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001400 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001401 nextTable.CmdBindDynamicStateObject(cmdBuffer, stateBindPoint, state);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001402}
1403
Tobin Ehlis7265e832015-01-19 08:42:29 -07001404XGL_LAYER_EXPORT void XGLAPI xglCmdBindDescriptorSet(XGL_CMD_BUFFER cmdBuffer, XGL_PIPELINE_BIND_POINT pipelineBindPoint, XGL_DESCRIPTOR_SET descriptorSet, const uint32_t* pUserData)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001405{
Tobin Ehlisc145be82015-01-08 15:22:32 -07001406 // TODO : Somewhere need to verify that all textures referenced by shaders in DS are in some type of *SHADER_READ* state
Tobin Ehlis7265e832015-01-19 08:42:29 -07001407 nextTable.CmdBindDescriptorSet(cmdBuffer, pipelineBindPoint, descriptorSet, pUserData);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001408}
1409
Tobin Ehlis7265e832015-01-19 08:42:29 -07001410XGL_LAYER_EXPORT void XGLAPI xglCmdBindVertexBuffer(XGL_CMD_BUFFER cmdBuffer, XGL_BUFFER buffer, XGL_GPU_SIZE offset, uint32_t binding)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001411{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001412 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001413 XGL_GPU_MEMORY mem = getMemBindingFromObject(buffer);
1414 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
Chia-I Wu19156822015-01-05 13:42:56 +08001415 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001416 sprintf(str, "In xglCmdBindVertexBuffer() call unable to update binding of buffer %p to cmdBuffer %p", buffer, cmdBuffer);
Chia-I Wu19156822015-01-05 13:42:56 +08001417 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1418 }
Tobin Ehlisc145be82015-01-08 15:22:32 -07001419 // Now update CB's vertex binding list
1420 GLOBAL_CB_NODE* pCBTrav = getGlobalCBNode(cmdBuffer);
1421 if (!pCBTrav) {
1422 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001423 sprintf(str, "Trying to BindVertexuffer obj %p to CB %p but no Node for that CB. Was CB incorrectly destroyed?", buffer, cmdBuffer);
Tobin Ehlisc145be82015-01-08 15:22:32 -07001424 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_INVALID_CB, "MEM", str);
1425 } else {
1426 MEMORY_BINDING *pBindInfo;
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001427 uint32_t dontCare;
Tobin Ehlisc145be82015-01-08 15:22:32 -07001428 pBindInfo = malloc(sizeof(MEMORY_BINDING));
1429 pBindInfo->offset = offset;
1430 pBindInfo->binding = binding;
Tobin Ehlis7265e832015-01-19 08:42:29 -07001431 pBindInfo->buffer = buffer;
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001432 if (XGL_FALSE == insertMiniNode(&pCBTrav->pVertexBufList, pBindInfo, &dontCare)) {
Tobin Ehlisc145be82015-01-08 15:22:32 -07001433 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001434 sprintf(str, "In xglCmdBindVertexBuffer and ran out of memory to track binding. CmdBuffer: %p, buffer %p", cmdBuffer, buffer);
Tobin Ehlisc145be82015-01-08 15:22:32 -07001435 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_OUT_OF_MEMORY_ERROR, "MEM", str);
1436 }
1437 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001438 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis7265e832015-01-19 08:42:29 -07001439 nextTable.CmdBindVertexBuffer(cmdBuffer, buffer, offset, binding);
Chia-I Wu19156822015-01-05 13:42:56 +08001440}
1441
Tobin Ehlis7265e832015-01-19 08:42:29 -07001442XGL_LAYER_EXPORT void XGLAPI xglCmdBindIndexBuffer(XGL_CMD_BUFFER cmdBuffer, XGL_BUFFER buffer, XGL_GPU_SIZE offset, XGL_INDEX_TYPE indexType)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001443{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001444 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis7265e832015-01-19 08:42:29 -07001445 // Track this buffer. What exactly is this call doing?
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001446 XGL_GPU_MEMORY mem = getMemBindingFromObject(buffer);
1447 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001448 char str[1024];
Tobin Ehlis7265e832015-01-19 08:42:29 -07001449 sprintf(str, "In xglCmdBindIndexData() call unable to update binding of buffer %p to cmdBuffer %p", buffer, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001450 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1451 }
Tobin Ehlisc145be82015-01-08 15:22:32 -07001452 // Now update CB's index binding list
1453 GLOBAL_CB_NODE* pCBTrav = getGlobalCBNode(cmdBuffer);
1454 if (!pCBTrav) {
1455 char str[1024];
Tobin Ehlis7265e832015-01-19 08:42:29 -07001456 sprintf(str, "Trying to BindIndexData buffer obj %p to CB %p but no Node for that CB. Was CB incorrectly destroyed?", buffer, cmdBuffer);
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001457 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_INVALID_MEM_OBJ, (char *) "MEM", (char *) str);
Tobin Ehlisc145be82015-01-08 15:22:32 -07001458 } else {
1459 MEMORY_BINDING *pBindInfo;
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001460 uint32_t dontCare;
Tobin Ehlisc145be82015-01-08 15:22:32 -07001461 pBindInfo = malloc(sizeof(MEMORY_BINDING));
1462 pBindInfo->indexType = indexType;
Tobin Ehlis7265e832015-01-19 08:42:29 -07001463 pBindInfo->buffer = buffer;
Tobin Ehlisc145be82015-01-08 15:22:32 -07001464 pBindInfo->offset = offset;
1465 pBindInfo->binding = 0;
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001466 if (XGL_FALSE == insertMiniNode(&pCBTrav->pIndexBufList, pBindInfo, &dontCare)) {
Tobin Ehlisc145be82015-01-08 15:22:32 -07001467 char str[1024];
Tobin Ehlis7265e832015-01-19 08:42:29 -07001468 sprintf(str, "In xglCmdBindIndexData and ran out of memory to track binding. CmdBuffer: %p, buffer %p", cmdBuffer, buffer);
Tobin Ehlisc145be82015-01-08 15:22:32 -07001469 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_OUT_OF_MEMORY_ERROR, "MEM", str);
1470 }
1471 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001472 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis7265e832015-01-19 08:42:29 -07001473 nextTable.CmdBindIndexBuffer(cmdBuffer, buffer, offset, indexType);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001474}
1475
Tobin Ehlis7265e832015-01-19 08:42:29 -07001476XGL_LAYER_EXPORT void XGLAPI xglCmdDrawIndirect(XGL_CMD_BUFFER cmdBuffer, XGL_BUFFER buffer, XGL_GPU_SIZE offset, uint32_t count, uint32_t stride)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001477{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001478 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001479 XGL_GPU_MEMORY mem = getMemBindingFromObject(buffer);
1480 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001481 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001482 sprintf(str, "In xglCmdDrawIndirect() call unable to update binding of buffer %p to cmdBuffer %p", buffer, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001483 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1484 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001485 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis7265e832015-01-19 08:42:29 -07001486 nextTable.CmdDrawIndirect(cmdBuffer, buffer, offset, count, stride);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001487}
1488
Tobin Ehlis7265e832015-01-19 08:42:29 -07001489XGL_LAYER_EXPORT void XGLAPI xglCmdDrawIndexedIndirect(XGL_CMD_BUFFER cmdBuffer, XGL_BUFFER buffer, XGL_GPU_SIZE offset, uint32_t count, uint32_t stride)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001490{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001491 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001492 XGL_GPU_MEMORY mem = getMemBindingFromObject(buffer);
1493 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001494 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001495 sprintf(str, "In xglCmdDrawIndexedIndirect() call unable to update binding of buffer %p to cmdBuffer %p", buffer, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001496 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1497 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001498 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis7265e832015-01-19 08:42:29 -07001499 nextTable.CmdDrawIndexedIndirect(cmdBuffer, buffer, offset, count, stride);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001500}
1501
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001502XGL_LAYER_EXPORT void XGLAPI xglCmdDispatchIndirect(XGL_CMD_BUFFER cmdBuffer, XGL_BUFFER buffer, XGL_GPU_SIZE offset)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001503{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001504 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001505 XGL_GPU_MEMORY mem = getMemBindingFromObject(buffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001506 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1507 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001508 sprintf(str, "In xglCmdDispatchIndirect() call unable to update binding of buffer %p to cmdBuffer %p", buffer, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001509 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1510 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001511 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001512 nextTable.CmdDispatchIndirect(cmdBuffer, buffer, offset);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001513}
1514
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001515XGL_LAYER_EXPORT void XGLAPI xglCmdCopyBuffer(XGL_CMD_BUFFER cmdBuffer, XGL_BUFFER srcBuffer, XGL_BUFFER destBuffer, uint32_t regionCount, const XGL_BUFFER_COPY* pRegions)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001516{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001517 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001518 XGL_GPU_MEMORY mem = getMemBindingFromObject(srcBuffer);
1519 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001520 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001521 sprintf(str, "In xglCmdCopyBuffer() call unable to update binding of srcBuffer %p to cmdBuffer %p", srcBuffer, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001522 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1523 }
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001524 mem = getMemBindingFromObject(destBuffer);
1525 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001526 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001527 sprintf(str, "In xglCmdCopyBuffer() call unable to update binding of destBuffer %p to cmdBuffer %p", destBuffer, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001528 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1529 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001530 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001531 nextTable.CmdCopyBuffer(cmdBuffer, srcBuffer, destBuffer, regionCount, pRegions);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001532}
1533
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001534XGL_LAYER_EXPORT void XGLAPI xglCmdCopyImage(XGL_CMD_BUFFER cmdBuffer, XGL_IMAGE srcImage, XGL_IMAGE destImage, uint32_t regionCount, const XGL_IMAGE_COPY* pRegions)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001535{
1536 // TODO : Each image will have mem mapping so track them
1537 nextTable.CmdCopyImage(cmdBuffer, srcImage, destImage, regionCount, pRegions);
1538}
1539
Tobin Ehlis7265e832015-01-19 08:42:29 -07001540XGL_LAYER_EXPORT void XGLAPI xglCmdCopyBufferToImage(XGL_CMD_BUFFER cmdBuffer, XGL_BUFFER srcBuffer, XGL_IMAGE destImage, uint32_t regionCount, const XGL_BUFFER_IMAGE_COPY* pRegions)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001541{
1542 // TODO : Track this
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001543 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001544 XGL_GPU_MEMORY mem = getMemBindingFromObject(destImage);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001545 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1546 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001547 sprintf(str, "In xglCmdCopyMemoryToImage() call unable to update binding of destImage buffer %p to cmdBuffer %p", destImage, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001548 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1549 }
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001550
1551 mem = getMemBindingFromObject(srcBuffer);
1552 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001553 char str[1024];
Tobin Ehlis7265e832015-01-19 08:42:29 -07001554 sprintf(str, "In xglCmdCopyMemoryToImage() call unable to update binding of srcBuffer %p to cmdBuffer %p", srcBuffer, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001555 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1556 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001557 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis7265e832015-01-19 08:42:29 -07001558 nextTable.CmdCopyBufferToImage(cmdBuffer, srcBuffer, destImage, regionCount, pRegions);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001559}
1560
Tobin Ehlis7265e832015-01-19 08:42:29 -07001561XGL_LAYER_EXPORT void XGLAPI xglCmdCopyImageToBuffer(XGL_CMD_BUFFER cmdBuffer, XGL_IMAGE srcImage, XGL_BUFFER destBuffer, uint32_t regionCount, const XGL_BUFFER_IMAGE_COPY* pRegions)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001562{
1563 // TODO : Track this
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001564 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001565 XGL_GPU_MEMORY mem = getMemBindingFromObject(srcImage);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001566 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1567 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001568 sprintf(str, "In xglCmdCopyImageToMemory() call unable to update binding of srcImage buffer %p to cmdBuffer %p", srcImage, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001569 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1570 }
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001571 mem = getMemBindingFromObject(destBuffer);
1572 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001573 char str[1024];
Tobin Ehlis7265e832015-01-19 08:42:29 -07001574 sprintf(str, "In xglCmdCopyImageToMemory() call unable to update binding of destBuffer %p to cmdBuffer %p", destBuffer, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001575 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1576 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001577 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis7265e832015-01-19 08:42:29 -07001578 nextTable.CmdCopyImageToBuffer(cmdBuffer, srcImage, destBuffer, regionCount, pRegions);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001579}
1580
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001581XGL_LAYER_EXPORT void XGLAPI xglCmdCloneImageData(XGL_CMD_BUFFER cmdBuffer, XGL_IMAGE srcImage, XGL_IMAGE_LAYOUT srcImageLayout, XGL_IMAGE destImage, XGL_IMAGE_LAYOUT destImageLayout)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001582{
1583 // TODO : Each image will have mem mapping so track them
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001584 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001585 XGL_GPU_MEMORY mem = getMemBindingFromObject(srcImage);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001586 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1587 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001588 sprintf(str, "In xglCmdCloneImageData() call unable to update binding of srcImage buffer %p to cmdBuffer %p", srcImage, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001589 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1590 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001591 mem = getMemBindingFromObject(destImage);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001592 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1593 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001594 sprintf(str, "In xglCmdCloneImageData() call unable to update binding of destImage buffer %p to cmdBuffer %p", destImage, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001595 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1596 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001597 loader_platform_thread_unlock_mutex(&globalLock);
Mike Stroyanfb80d5f2014-12-04 11:08:39 +00001598 nextTable.CmdCloneImageData(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001599}
1600
Tobin Ehlis7265e832015-01-19 08:42:29 -07001601XGL_LAYER_EXPORT void XGLAPI xglCmdUpdateBuffer(XGL_CMD_BUFFER cmdBuffer, XGL_BUFFER destBuffer, XGL_GPU_SIZE destOffset, XGL_GPU_SIZE dataSize, const uint32_t* pData)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001602{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001603 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001604 XGL_GPU_MEMORY mem = getMemBindingFromObject(destBuffer);
1605 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001606 char str[1024];
Tobin Ehlis7265e832015-01-19 08:42:29 -07001607 sprintf(str, "In xglCmdUpdateMemory() call unable to update binding of destBuffer %p to cmdBuffer %p", destBuffer, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001608 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1609 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001610 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis7265e832015-01-19 08:42:29 -07001611 nextTable.CmdUpdateBuffer(cmdBuffer, destBuffer, destOffset, dataSize, pData);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001612}
1613
Tobin Ehlis7265e832015-01-19 08:42:29 -07001614XGL_LAYER_EXPORT void XGLAPI xglCmdFillBuffer(XGL_CMD_BUFFER cmdBuffer, XGL_BUFFER destBuffer, XGL_GPU_SIZE destOffset, XGL_GPU_SIZE fillSize, uint32_t data)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001615{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001616 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001617 XGL_GPU_MEMORY mem = getMemBindingFromObject(destBuffer);
1618 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001619 char str[1024];
Tobin Ehlis7265e832015-01-19 08:42:29 -07001620 sprintf(str, "In xglCmdFillMemory() call unable to update binding of destBuffer %p to cmdBuffer %p", destBuffer, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001621 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1622 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001623 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis7265e832015-01-19 08:42:29 -07001624 nextTable.CmdFillBuffer(cmdBuffer, destBuffer, destOffset, fillSize, data);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001625}
1626
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001627XGL_LAYER_EXPORT void XGLAPI xglCmdClearColorImage(XGL_CMD_BUFFER cmdBuffer, XGL_IMAGE image, const float color[4], uint32_t rangeCount, const XGL_IMAGE_SUBRESOURCE_RANGE* pRanges)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001628{
Tobin Ehlisc145be82015-01-08 15:22:32 -07001629 // TODO : Verify memory is in XGL_IMAGE_STATE_CLEAR state
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001630 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001631 XGL_GPU_MEMORY mem = getMemBindingFromObject(image);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001632 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1633 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001634 sprintf(str, "In xglCmdClearColorImage() call unable to update binding of image buffer %p to cmdBuffer %p", image, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001635 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1636 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001637 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001638 nextTable.CmdClearColorImage(cmdBuffer, image, color, rangeCount, pRanges);
1639}
1640
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001641XGL_LAYER_EXPORT void XGLAPI xglCmdClearColorImageRaw(XGL_CMD_BUFFER cmdBuffer, XGL_IMAGE image, const uint32_t color[4], uint32_t rangeCount, const XGL_IMAGE_SUBRESOURCE_RANGE* pRanges)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001642{
Tobin Ehlisc145be82015-01-08 15:22:32 -07001643 // TODO : Verify memory is in XGL_IMAGE_STATE_CLEAR state
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001644 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001645 XGL_GPU_MEMORY mem = getMemBindingFromObject(image);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001646 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1647 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001648 sprintf(str, "In xglCmdClearColorImageRaw() call unable to update binding of image buffer %p to cmdBuffer %p", image, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001649 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1650 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001651 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001652 nextTable.CmdClearColorImageRaw(cmdBuffer, image, color, rangeCount, pRanges);
1653}
1654
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001655XGL_LAYER_EXPORT void XGLAPI xglCmdClearDepthStencil(XGL_CMD_BUFFER cmdBuffer, XGL_IMAGE image, float depth, uint32_t stencil, uint32_t rangeCount, const XGL_IMAGE_SUBRESOURCE_RANGE* pRanges)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001656{
Tobin Ehlisc145be82015-01-08 15:22:32 -07001657 // TODO : Verify memory is in XGL_IMAGE_STATE_CLEAR state
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001658 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001659 XGL_GPU_MEMORY mem = getMemBindingFromObject(image);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001660 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1661 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001662 sprintf(str, "In xglCmdClearDepthStencil() call unable to update binding of image buffer %p to cmdBuffer %p", image, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001663 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1664 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001665 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001666 nextTable.CmdClearDepthStencil(cmdBuffer, image, depth, stencil, rangeCount, pRanges);
1667}
1668
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001669XGL_LAYER_EXPORT void XGLAPI xglCmdResolveImage(XGL_CMD_BUFFER cmdBuffer, XGL_IMAGE srcImage, XGL_IMAGE destImage, uint32_t rectCount, const XGL_IMAGE_RESOLVE* pRects)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001670{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001671 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001672 XGL_GPU_MEMORY mem = getMemBindingFromObject(srcImage);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001673 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1674 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001675 sprintf(str, "In xglCmdResolveImage() call unable to update binding of srcImage buffer %p to cmdBuffer %p", srcImage, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001676 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1677 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001678 mem = getMemBindingFromObject(destImage);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001679 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1680 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001681 sprintf(str, "In xglCmdResolveImage() call unable to update binding of destImage buffer %p to cmdBuffer %p", destImage, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001682 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1683 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001684 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001685 nextTable.CmdResolveImage(cmdBuffer, srcImage, destImage, rectCount, pRects);
1686}
1687
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001688XGL_LAYER_EXPORT void XGLAPI xglCmdBeginQuery(XGL_CMD_BUFFER cmdBuffer, XGL_QUERY_POOL queryPool, uint32_t slot, XGL_FLAGS flags)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001689{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001690 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001691 XGL_GPU_MEMORY mem = getMemBindingFromObject(queryPool);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001692 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1693 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001694 sprintf(str, "In xglCmdBeginQuery() call unable to update binding of queryPool buffer %p to cmdBuffer %p", queryPool, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001695 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1696 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001697 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001698 nextTable.CmdBeginQuery(cmdBuffer, queryPool, slot, flags);
1699}
1700
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001701XGL_LAYER_EXPORT void XGLAPI xglCmdEndQuery(XGL_CMD_BUFFER cmdBuffer, XGL_QUERY_POOL queryPool, uint32_t slot)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001702{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001703 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001704 XGL_GPU_MEMORY mem = getMemBindingFromObject(queryPool);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001705 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1706 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001707 sprintf(str, "In xglCmdEndQuery() call unable to update binding of queryPool buffer %p to cmdBuffer %p", queryPool, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001708 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1709 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001710 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001711 nextTable.CmdEndQuery(cmdBuffer, queryPool, slot);
1712}
1713
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001714XGL_LAYER_EXPORT void XGLAPI xglCmdResetQueryPool(XGL_CMD_BUFFER cmdBuffer, XGL_QUERY_POOL queryPool, uint32_t startQuery, uint32_t queryCount)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001715{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001716 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001717 XGL_GPU_MEMORY mem = getMemBindingFromObject(queryPool);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001718 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1719 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001720 sprintf(str, "In xglCmdResetQueryPool() call unable to update binding of queryPool buffer %p to cmdBuffer %p", queryPool, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001721 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1722 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001723 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001724 nextTable.CmdResetQueryPool(cmdBuffer, queryPool, startQuery, queryCount);
1725}
1726
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001727XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglDbgRegisterMsgCallback(XGL_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback, void* pUserData)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001728{
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001729 // This layer intercepts callbacks
1730 XGL_LAYER_DBG_FUNCTION_NODE *pNewDbgFuncNode = (XGL_LAYER_DBG_FUNCTION_NODE*)malloc(sizeof(XGL_LAYER_DBG_FUNCTION_NODE));
1731 if (!pNewDbgFuncNode)
1732 return XGL_ERROR_OUT_OF_MEMORY;
1733 pNewDbgFuncNode->pfnMsgCallback = pfnMsgCallback;
1734 pNewDbgFuncNode->pUserData = pUserData;
Jon Ashburn7d7b3cf2014-12-22 13:24:15 -07001735 pNewDbgFuncNode->pNext = g_pDbgFunctionHead;
1736 g_pDbgFunctionHead = pNewDbgFuncNode;
Jon Ashburna8aa8372015-03-03 15:07:15 -07001737 // force callbacks if DebugAction hasn't been set already other than initial value
Courtney Goeltzenleuchter90d93202015-03-04 15:47:34 -07001738 if (g_actionIsDefault) {
Jon Ashburna8aa8372015-03-03 15:07:15 -07001739 g_debugAction = XGL_DBG_LAYER_ACTION_CALLBACK;
Courtney Goeltzenleuchter90d93202015-03-04 15:47:34 -07001740 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001741 XGL_RESULT result = nextTable.DbgRegisterMsgCallback(pfnMsgCallback, pUserData);
1742 return result;
1743}
1744
1745XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglDbgUnregisterMsgCallback(XGL_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback)
1746{
Jon Ashburn7d7b3cf2014-12-22 13:24:15 -07001747 XGL_LAYER_DBG_FUNCTION_NODE *pTrav = g_pDbgFunctionHead;
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001748 XGL_LAYER_DBG_FUNCTION_NODE *pPrev = pTrav;
1749 while (pTrav) {
1750 if (pTrav->pfnMsgCallback == pfnMsgCallback) {
1751 pPrev->pNext = pTrav->pNext;
Jon Ashburn7d7b3cf2014-12-22 13:24:15 -07001752 if (g_pDbgFunctionHead == pTrav)
1753 g_pDbgFunctionHead = pTrav->pNext;
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001754 free(pTrav);
1755 break;
1756 }
1757 pPrev = pTrav;
1758 pTrav = pTrav->pNext;
1759 }
Jon Ashburna8aa8372015-03-03 15:07:15 -07001760 if (g_pDbgFunctionHead == NULL)
1761 {
1762 if (g_actionIsDefault)
1763 g_debugAction = XGL_DBG_LAYER_ACTION_LOG_MSG;
1764 else
1765 g_debugAction &= ~XGL_DBG_LAYER_ACTION_CALLBACK;
1766 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001767 XGL_RESULT result = nextTable.DbgUnregisterMsgCallback(pfnMsgCallback);
1768 return result;
1769}
1770
Jon Ashburn71c2b152015-03-02 16:51:38 -07001771#if !defined(WIN32)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001772XGL_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)
1773{
1774 XGL_RESULT result = nextTable.WsiX11CreatePresentableImage(device, pCreateInfo, pImage, pMem);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001775 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001776 if (XGL_SUCCESS == result) {
1777 // Add image object, then insert the new Mem Object and then bind it to created image
1778 insertGlobalObjectNode(*pImage, _XGL_STRUCTURE_TYPE_MAX_ENUM, pCreateInfo, sizeof(XGL_WSI_X11_PRESENTABLE_IMAGE_CREATE_INFO), "wsi_x11_image");
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001779 insertGlobalMemObj(*pMem, NULL);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001780 if (XGL_FALSE == updateObjectBinding(*pImage, *pMem)) {
1781 char str[1024];
1782 sprintf(str, "In xglWsiX11CreatePresentableImage(), unable to set image %p binding to mem obj %p", (void*)*pImage, (void*)*pMem);
1783 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, *pImage, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1784 }
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001785 }
1786 printObjList();
1787 printMemList();
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001788 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001789 return result;
1790}
Ian Elliott2d4ab1e2015-01-13 17:52:38 -07001791#endif // WIN32
Tobin Ehlis6663f492014-11-10 12:29:12 -07001792
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001793XGL_LAYER_EXPORT void* XGLAPI xglGetProcAddr(XGL_PHYSICAL_GPU gpu, const char* funcName)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001794{
1795 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
Chia-I Wu4d11dcc2015-01-05 13:18:57 +08001796
Tobin Ehlis6663f492014-11-10 12:29:12 -07001797 if (gpu == NULL)
1798 return NULL;
1799 pCurObj = gpuw;
Ian Elliott2d4ab1e2015-01-13 17:52:38 -07001800 loader_platform_thread_once(&g_initOnce, initMemTracker);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001801
Jon Ashburn71c2b152015-03-02 16:51:38 -07001802 if (!strcmp(funcName, "xglGetProcAddr"))
1803 return (void *) xglGetProcAddr;
1804 if (!strcmp(funcName, "xglCreateDevice"))
1805 return (void*) xglCreateDevice;
1806 if (!strcmp(funcName, "xglDestroyDevice"))
1807 return (void*) xglDestroyDevice;
1808 if (!strcmp(funcName, "xglEnumerateLayers"))
1809 return (void*) xglEnumerateLayers;
1810 if (!strcmp(funcName, "xglQueueSubmit"))
1811 return (void*) xglQueueSubmit;
1812 if (!strcmp(funcName, "xglQueueSetGlobalMemReferences"))
1813 return (void*) xglQueueSetGlobalMemReferences;
1814 if (!strcmp(funcName, "xglAllocMemory"))
1815 return (void*) xglAllocMemory;
1816 if (!strcmp(funcName, "xglFreeMemory"))
1817 return (void*) xglFreeMemory;
1818 if (!strcmp(funcName, "xglSetMemoryPriority"))
1819 return (void*) xglSetMemoryPriority;
1820 if (!strcmp(funcName, "xglMapMemory"))
1821 return (void*) xglMapMemory;
1822 if (!strcmp(funcName, "xglUnmapMemory"))
1823 return (void*) xglUnmapMemory;
1824 if (!strcmp(funcName, "xglPinSystemMemory"))
1825 return (void*) xglPinSystemMemory;
1826 if (!strcmp(funcName, "xglOpenSharedMemory"))
1827 return (void*) xglOpenSharedMemory;
1828 if (!strcmp(funcName, "xglOpenPeerMemory"))
1829 return (void*) xglOpenPeerMemory;
1830 if (!strcmp(funcName, "xglOpenPeerImage"))
1831 return (void*) xglOpenPeerImage;
1832 if (!strcmp(funcName, "xglDestroyObject"))
1833 return (void*) xglDestroyObject;
1834 if (!strcmp(funcName, "xglGetObjectInfo"))
1835 return (void*) xglGetObjectInfo;
1836 if (!strcmp(funcName, "xglBindObjectMemory"))
1837 return (void*) xglBindObjectMemory;
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07001838 if (!strcmp(funcName, "xglCreateFence"))
1839 return (void*) xglCreateFence;
1840 if (!strcmp(funcName, "xglGetFenceStatus"))
1841 return (void*) xglGetFenceStatus;
1842 if (!strcmp(funcName, "xglWaitForFences"))
1843 return (void*) xglWaitForFences;
Jon Ashburn71c2b152015-03-02 16:51:38 -07001844 if (!strcmp(funcName, "xglCreateEvent"))
1845 return (void*) xglCreateEvent;
1846 if (!strcmp(funcName, "xglCreateQueryPool"))
1847 return (void*) xglCreateQueryPool;
1848 if (!strcmp(funcName, "xglCreateBuffer"))
1849 return (void*) xglCreateBuffer;
1850 if (!strcmp(funcName, "xglCreateBufferView"))
1851 return (void*) xglCreateBufferView;
1852 if (!strcmp(funcName, "xglCreateImage"))
1853 return (void*) xglCreateImage;
1854 if (!strcmp(funcName, "xglCreateImageView"))
1855 return (void*) xglCreateImageView;
1856 if (!strcmp(funcName, "xglCreateColorAttachmentView"))
1857 return (void*) xglCreateColorAttachmentView;
1858 if (!strcmp(funcName, "xglCreateDepthStencilView"))
1859 return (void*) xglCreateDepthStencilView;
1860 if (!strcmp(funcName, "xglCreateShader"))
1861 return (void*) xglCreateShader;
1862 if (!strcmp(funcName, "xglCreateGraphicsPipeline"))
1863 return (void*) xglCreateGraphicsPipeline;
1864 if (!strcmp(funcName, "xglCreateComputePipeline"))
1865 return (void*) xglCreateComputePipeline;
1866 if (!strcmp(funcName, "xglCreateSampler"))
1867 return (void*) xglCreateSampler;
1868 if (!strcmp(funcName, "xglCreateDynamicViewportState"))
1869 return (void*) xglCreateDynamicViewportState;
1870 if (!strcmp(funcName, "xglCreateDynamicRasterState"))
1871 return (void*) xglCreateDynamicRasterState;
1872 if (!strcmp(funcName, "xglCreateDynamicColorBlendState"))
1873 return (void*) xglCreateDynamicColorBlendState;
1874 if (!strcmp(funcName, "xglCreateDynamicDepthStencilState"))
1875 return (void*) xglCreateDynamicDepthStencilState;
1876 if (!strcmp(funcName, "xglCreateCommandBuffer"))
1877 return (void*) xglCreateCommandBuffer;
1878 if (!strcmp(funcName, "xglBeginCommandBuffer"))
1879 return (void*) xglBeginCommandBuffer;
1880 if (!strcmp(funcName, "xglEndCommandBuffer"))
1881 return (void*) xglEndCommandBuffer;
1882 if (!strcmp(funcName, "xglResetCommandBuffer"))
1883 return (void*) xglResetCommandBuffer;
1884 if (!strcmp(funcName, "xglCmdBindPipeline"))
1885 return (void*) xglCmdBindPipeline;
1886 if (!strcmp(funcName, "xglCmdBindDynamicStateObject"))
1887 return (void*) xglCmdBindDynamicStateObject;
1888 if (!strcmp(funcName, "xglCmdBindDescriptorSet"))
1889 return (void*) xglCmdBindDescriptorSet;
1890 if (!strcmp(funcName, "xglCmdBindVertexBuffer"))
1891 return (void*) xglCmdBindVertexBuffer;
1892 if (!strcmp(funcName, "xglCmdBindIndexBuffer"))
1893 return (void*) xglCmdBindIndexBuffer;
1894 if (!strcmp(funcName, "xglCmdDrawIndirect"))
1895 return (void*) xglCmdDrawIndirect;
1896 if (!strcmp(funcName, "xglCmdDrawIndexedIndirect"))
1897 return (void*) xglCmdDrawIndexedIndirect;
1898 if (!strcmp(funcName, "xglCmdDispatchIndirect"))
1899 return (void*) xglCmdDispatchIndirect;
1900 if (!strcmp(funcName, "xglCmdCopyBuffer"))
1901 return (void*) xglCmdCopyBuffer;
1902 if (!strcmp(funcName, "xglCmdCopyImage"))
1903 return (void*) xglCmdCopyImage;
1904 if (!strcmp(funcName, "xglCmdCopyBufferToImage"))
1905 return (void*) xglCmdCopyBufferToImage;
1906 if (!strcmp(funcName, "xglCmdCopyImageToBuffer"))
1907 return (void*) xglCmdCopyImageToBuffer;
1908 if (!strcmp(funcName, "xglCmdCloneImageData"))
1909 return (void*) xglCmdCloneImageData;
1910 if (!strcmp(funcName, "xglCmdUpdateBuffer"))
1911 return (void*) xglCmdUpdateBuffer;
1912 if (!strcmp(funcName, "xglCmdFillBuffer"))
1913 return (void*) xglCmdFillBuffer;
1914 if (!strcmp(funcName, "xglCmdClearColorImage"))
1915 return (void*) xglCmdClearColorImage;
1916 if (!strcmp(funcName, "xglCmdClearColorImageRaw"))
1917 return (void*) xglCmdClearColorImageRaw;
1918 if (!strcmp(funcName, "xglCmdClearDepthStencil"))
1919 return (void*) xglCmdClearDepthStencil;
1920 if (!strcmp(funcName, "xglCmdResolveImage"))
1921 return (void*) xglCmdResolveImage;
1922 if (!strcmp(funcName, "xglCmdBeginQuery"))
1923 return (void*) xglCmdBeginQuery;
1924 if (!strcmp(funcName, "xglCmdEndQuery"))
1925 return (void*) xglCmdEndQuery;
1926 if (!strcmp(funcName, "xglCmdResetQueryPool"))
1927 return (void*) xglCmdResetQueryPool;
1928 if (!strcmp(funcName, "xglDbgRegisterMsgCallback"))
1929 return (void*) xglDbgRegisterMsgCallback;
1930 if (!strcmp(funcName, "xglDbgUnregisterMsgCallback"))
1931 return (void*) xglDbgUnregisterMsgCallback;
1932#if !defined(WIN32)
1933 if (!strcmp(funcName, "xglWsiX11CreatePresentableImage"))
1934 return (void*) xglWsiX11CreatePresentableImage;
1935#endif
Tobin Ehlis6663f492014-11-10 12:29:12 -07001936 else {
Tobin Ehlis6663f492014-11-10 12:29:12 -07001937 if (gpuw->pGPA == NULL)
1938 return NULL;
1939 return gpuw->pGPA(gpuw->nextObject, funcName);
1940 }
1941}