layers: Update MemTracker to support dbg Callbacks and a few bug fixes
MemTracker now handles creation of Image and Mem binding done by xglWsiX11CreatePresentableImage() call, and it also correctly clears a previous mem binding on object if one existed.
diff --git a/layers/mem_tracker.c b/layers/mem_tracker.c
index 1bffdd0..22da4d2 100644
--- a/layers/mem_tracker.c
+++ b/layers/mem_tracker.c
@@ -29,13 +29,48 @@
#include <string.h>
#include <assert.h>
#include <pthread.h>
-#include "xglLayer.h"
#include "xgl_struct_string_helper.h"
+#include "mem_tracker.h"
static XGL_LAYER_DISPATCH_TABLE nextTable;
static XGL_BASE_LAYER_OBJECT *pCurObj;
static pthread_once_t tabOnce = PTHREAD_ONCE_INIT;
-
+// Ptr to LL of dbg functions
+static XGL_LAYER_DBG_FUNCTION_NODE *pDbgFunctionHead = NULL;
+// Utility function to handle reporting
+// If callbacks are enabled, use them, otherwise use printf
+static XGL_VOID layerCbMsg(XGL_DBG_MSG_TYPE msgType,
+ XGL_VALIDATION_LEVEL validationLevel,
+ XGL_BASE_OBJECT srcObject,
+ XGL_SIZE location,
+ XGL_INT msgCode,
+ const XGL_CHAR* pLayerPrefix,
+ const XGL_CHAR* pMsg)
+{
+ XGL_LAYER_DBG_FUNCTION_NODE *pTrav = pDbgFunctionHead;
+ if (pTrav) {
+ while (pTrav) {
+ pTrav->pfnMsgCallback(msgType, validationLevel, srcObject, location, msgCode, pMsg, pTrav->pUserData);
+ pTrav = pTrav->pNext;
+ }
+ }
+ else {
+ switch (msgType) {
+ case XGL_DBG_MSG_ERROR:
+ printf("{%s}ERROR : %s\n", pLayerPrefix, pMsg);
+ break;
+ case XGL_DBG_MSG_WARNING:
+ printf("{%s}WARN : %s\n", pLayerPrefix, pMsg);
+ break;
+ case XGL_DBG_MSG_PERF_WARNING:
+ printf("{%s}PERF_WARN : %s\n", pLayerPrefix, pMsg);
+ break;
+ default:
+ printf("{%s}INFO : %s\n", pLayerPrefix, pMsg);
+ break;
+ }
+ }
+}
/*
* Data Structure overview
* There are 3 global Linked-Lists (LLs)
@@ -113,10 +148,12 @@
static GLOBAL_MEM_OBJ_NODE* pGlobalMemObjHead = NULL;
static GLOBAL_OBJECT_NODE* pGlobalObjectHead = NULL;
static XGL_DEVICE globalDevice = NULL;
-
+static uint64_t numCBNodes = 0;
+static uint64_t numMemObjNodes = 0;
+static uint64_t numObjectNodes = 0;
// Check list for data and if it's not included insert new node
// into HEAD of list pointed to by pHEAD & update pHEAD
-// Set 'insert' to XGL_TRUE if new node was inserted
+// Increment 'insert' if new node was inserted
// return XGL_SUCCESS if no errors occur
static XGL_RESULT insertMiniNode(MINI_NODE** pHEAD, const XGL_BASE_OBJECT data, XGL_UINT* insert)
{
@@ -134,11 +171,13 @@
*pHEAD = pTrav;
*insert += 1;
//pMemTrav->refCount++;
- //printf("MEM INFO : Incremented refCount for mem obj %p to %u\n", (void*)mem, pMemTrav->refCount);
+ //sprintf(str, "MEM INFO : Incremented refCount for mem obj %p to %u", (void*)mem, pMemTrav->refCount);
}
if (pTrav->data) { // This is just FYI
assert(data == pTrav->data);
- printf("MEM INFO : Data %p is already in data LL w/ HEAD at %p\n", data, *pHEAD);
+ char str[1024];
+ sprintf(str, "Data %p is already in data LL w/ HEAD at %p", data, *pHEAD);
+ layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, data, 0, MEMTRACK_NONE, "MEM", str);
}
pTrav->data = data;
return XGL_SUCCESS;
@@ -158,8 +197,16 @@
pTrav->pNextGlobalCBNode = (GLOBAL_CB_NODE*)malloc(sizeof(GLOBAL_CB_NODE));
pTrav = pTrav->pNextGlobalCBNode;
}
- memset(pTrav, 0, sizeof(GLOBAL_CB_NODE));
- pTrav->cmdBuffer = cb;
+ if (!pTrav) {
+ char str[1024];
+ sprintf(str, "Malloc failed to alloc node for Cmd Buffer %p", (void*)cb);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_OUT_OF_MEMORY_ERROR, "MEM", str);
+ }
+ else {
+ numCBNodes++;
+ memset(pTrav, 0, sizeof(GLOBAL_CB_NODE));
+ pTrav->cmdBuffer = cb;
+ }
}
// Return ptr to node in global LL containing cb, or NULL if not found
@@ -175,7 +222,9 @@
{
GLOBAL_CB_NODE* pTrav = getGlobalCBNode(cb);
if (!pTrav) {
- printf("MEM ERROR : Unable to find node for CB %p in order to set fence to %p\n", (void*)cb, (void*)fence);
+ char str[1024];
+ sprintf(str, "Unable to find node for CB %p in order to set fence to %p", (void*)cb, (void*)fence);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_INVALID_CB, "MEM", str);
return XGL_FALSE;
}
pTrav->fence = fence;
@@ -186,7 +235,9 @@
{
GLOBAL_CB_NODE* pTrav = getGlobalCBNode(cb);
if (!pTrav) {
- printf("MEM ERROR : Unable to find node for CB %p in order to check memory references\n", (void*)cb);
+ char str[1024];
+ sprintf(str, "Unable to find node for CB %p in order to check memory references", (void*)cb);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_INVALID_CB, "MEM", str);
return XGL_FALSE;
}
// Validate that all actual references are accounted for in pMemRefs
@@ -198,23 +249,31 @@
// TODO : Improve this algorithm
for (i = 0; i < memRefCount; i++) {
if (pMemNode->mem == pMemRefs[i].mem) {
- printf("MEM INFO : Found Mem Obj %p binding to CB %p\n", pMemNode->mem, cb);
+ char str[1024];
+ sprintf(str, "Found Mem Obj %p binding to CB %p", pMemNode->mem, cb);
+ layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_NONE, "MEM", str);
found = 1;
foundCount++;
}
}
if (!found) {
- printf("MEM ERROR : Memory reference list for Command Buffer %p is missing ref to mem obj %p\n", cb, pMemNode->mem);
+ char str[1024];
+ sprintf(str, "Memory reference list for Command Buffer %p is missing ref to mem obj %p", cb, pMemNode->mem);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_CB_MISSING_MEM_REF, "MEM", str);
return XGL_FALSE;
}
found = 0;
pMemNode = pMemNode->pNext;
}
- printf("MEM INFO : Verified all %lu memory dependencies for CB %p are included in pMemRefs list\n", foundCount, cb);
+ char str[1024];
+ sprintf(str, "Verified all %lu memory dependencies for CB %p are included in pMemRefs list", foundCount, cb);
+ layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_NONE, "MEM", str);
// TODO : Could report mem refs in pMemRefs that AREN'T in mem LL, that would be primarily informational
// Currently just noting that there is a difference
- if (foundCount != memRefCount)
- printf("MEM INFO : Note that %u mem refs included in pMemRefs list, but only %lu appear to be required\n", memRefCount, foundCount);
+ if (foundCount != memRefCount) {
+ sprintf(str, "Note that %u mem refs included in pMemRefs list, but only %lu appear to be required", memRefCount, foundCount);
+ layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_NONE, "MEM", str);
+ }
return XGL_TRUE;
}
@@ -231,9 +290,18 @@
pTrav->pNextGlobalNode = (GLOBAL_MEM_OBJ_NODE*)malloc(sizeof(GLOBAL_MEM_OBJ_NODE));
pTrav = pTrav->pNextGlobalNode;
}
- memset(pTrav, 0, sizeof(GLOBAL_MEM_OBJ_NODE));
- memcpy(&pTrav->allocInfo, pAllocInfo, sizeof(XGL_MEMORY_ALLOC_INFO));
- pTrav->mem = mem;
+ if (!pTrav) {
+ char str[1024];
+ sprintf(str, "Malloc failed to alloc node for Mem Object %p", (void*)mem);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_OUT_OF_MEMORY_ERROR, "MEM", str);
+ }
+ else {
+ numMemObjNodes++;
+ memset(pTrav, 0, sizeof(GLOBAL_MEM_OBJ_NODE));
+ if (pAllocInfo) // MEM alloc created by xglWsiX11CreatePresentableImage() doesn't have alloc info struct
+ memcpy(&pTrav->allocInfo, pAllocInfo, sizeof(XGL_MEMORY_ALLOC_INFO));
+ pTrav->mem = mem;
+ }
}
// Return ptr to node in global LL containing mem, or NULL if not found
@@ -252,8 +320,9 @@
// First update CB binding in MemObj mini CB list
GLOBAL_MEM_OBJ_NODE* pMemTrav = getGlobalMemNode(mem);
if (!pMemTrav) {
- printf("MEM ERROR : Trying to bind mem obj %p to CB %p but no Node for that mem obj.\n", mem, cb);
- printf(" Was it correctly allocated? Did it already get freed?\n");
+ char str[1024];
+ 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);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
return XGL_FALSE;
}
@@ -264,8 +333,9 @@
// Now update Global CB's Mini Mem binding list
GLOBAL_CB_NODE* pCBTrav = getGlobalCBNode(cb);
if (!pCBTrav) {
- printf("MEM ERROR : Trying to bind mem obj %p to CB %p but no Node for that CB.\n", mem, cb);
- printf(" Was it CB incorrectly destroyed?\n");
+ char str[1024];
+ sprintf(str, "Trying to bind mem obj %p to CB %p but no Node for that CB. Was it CB incorrectly destroyed?", mem, cb);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
return XGL_FALSE;
}
XGL_UINT dontCare;
@@ -286,7 +356,9 @@
pMiniCB = pMiniCB->pNext;
}
if (!pMiniCB) {
- printf("MEM ERROR : Trying to clear CB binding but CB %p not in binding list for mem obj %p\n", cb, mem);
+ char str[1024];
+ sprintf(str, "Trying to clear CB binding but CB %p not in binding list for mem obj %p", cb, mem);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
}
else { // remove node from list & decrement refCount
pPrev->pNext = pMiniCB->pNext;
@@ -301,7 +373,9 @@
{
GLOBAL_CB_NODE* pCBTrav = getGlobalCBNode(cb);
if (!pCBTrav) {
- printf("MEM ERROR : Unable to find global CB node %p for deletion\n", cb);
+ char str[1024];
+ sprintf(str, "Unable to find global CB node %p for deletion", cb);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_INVALID_CB, "MEM", str);
return XGL_FALSE;
}
MINI_NODE* pMemTrav = pCBTrav->pMemObjList;
@@ -362,16 +436,22 @@
MINI_NODE* pCBTrav = pMemObjTrav->pCmdBufferBindings;
while (pCBTrav) {
refCount++;
- printf("MEM INFO : Command Buffer %p has reference to mem obj %p\n", pCBTrav->cmdBuffer, pMemObjTrav->mem);
+ char str[1024];
+ sprintf(str, "Command Buffer %p has reference to mem obj %p", pCBTrav->cmdBuffer, pMemObjTrav->mem);
+ layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, pCBTrav->cmdBuffer, 0, MEMTRACK_NONE, "MEM", str);
pCBTrav = pCBTrav->pNext;
}
while (pObjTrav) {
refCount++;
- printf("MEM INFO : XGL Object %p has reference to mem obj %p\n", pObjTrav->object, pMemObjTrav->mem);
+ char str[1024];
+ sprintf(str, "XGL Object %p has reference to mem obj %p", pObjTrav->object, pMemObjTrav->mem);
+ layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, pObjTrav->object, 0, MEMTRACK_NONE, "MEM", str);
pObjTrav = pObjTrav->pNext;
}
if (refCount != pMemObjTrav->refCount) {
- printf("MEM INFO INTERNAL ERROR : Refcount of %u for Mem Obj %p does't match reported refs of %u\n", pMemObjTrav->refCount, pMemObjTrav->mem, refCount);
+ char str[1024];
+ sprintf(str, "Refcount of %u for Mem Obj %p does't match reported refs of %u", pMemObjTrav->refCount, pMemObjTrav->mem, refCount);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, pObjTrav->object, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
}
}
@@ -390,7 +470,9 @@
free(pTrav);
}
else {
- printf("MEM ERROR : Could not find global mem obj node for %p to delete!\n", mem);
+ char str[1024];
+ sprintf(str, "Could not find global mem obj node for %p to delete!", mem);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
}
}
// Check if fence for given CB is completed
@@ -398,15 +480,21 @@
{
GLOBAL_CB_NODE* pCBTrav = getGlobalCBNode(cb);
if (!pCBTrav) {
- printf("MEM ERROR : Unable to find global CB node %p to check for completion\n", cb);
+ char str[1024];
+ sprintf(str, "Unable to find global CB node %p to check for completion", cb);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_INVALID_CB, "MEM", str);
return XGL_FALSE;
}
if (!pCBTrav->fence) {
- printf("MEM ERROR : No fence found for CB %p to check for completion\n", cb);
+ char str[1024];
+ sprintf(str, "No fence found for CB %p to check for completion", cb);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_CB_MISSING_FENCE, "MEM", str);
return XGL_FALSE;
}
if (XGL_SUCCESS != nextTable.GetFenceStatus(pCBTrav->fence)) {
- printf("MEM INFO : Fence %p for CB %p has not completed\n", pCBTrav->fence, cb);
+ char str[1024];
+ sprintf(str, "Fence %p for CB %p has not completed", pCBTrav->fence, cb);
+ layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_NONE, "MEM", str);
return XGL_FALSE;
}
return XGL_TRUE;
@@ -418,8 +506,9 @@
// Parse global list to find node w/ mem
GLOBAL_MEM_OBJ_NODE* pTrav = getGlobalMemNode(mem);
if (!pTrav) {
- printf("MEM ERROR : Couldn't find mem node object for %p\n", (void*)mem);
- printf("MEM ERROR : Was %p never allocated or previously freed?\n", (void*)mem);
+ char str[1024];
+ sprintf(str, "Couldn't find mem node object for %p\n Was %p never allocated or previously freed?", (void*)mem, (void*)mem);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
return XGL_FALSE;
}
else {
@@ -437,7 +526,9 @@
if (0 != pTrav->refCount) {
// If references remain, report the error and can search down CB LL to find references
result = XGL_FALSE;
- printf("MEM ERROR : Freeing mem obj %p while it still has references\n", (void*)mem);
+ char str[1024];
+ sprintf(str, "Freeing mem obj %p while it still has references", (void*)mem);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_FREED_MEM_REF, "MEM", str);
reportMemReferences(pTrav);
}
// Delete global node
@@ -461,8 +552,6 @@
GLOBAL_OBJECT_NODE* pTrav = pGlobalObjectHead;
if (!pTrav) {
pTrav = (GLOBAL_OBJECT_NODE*)malloc(sizeof(GLOBAL_OBJECT_NODE));
- if (!pTrav)
- return NULL;
memset(pTrav, 0, sizeof(GLOBAL_OBJECT_NODE));
pGlobalObjectHead = pTrav;
}
@@ -473,13 +562,20 @@
pTrav = pTrav->pNext;
}
pTrav = (GLOBAL_OBJECT_NODE*)malloc(sizeof(GLOBAL_OBJECT_NODE));
- if (!pTrav)
- return NULL;
memset(pTrav, 0, sizeof(GLOBAL_OBJECT_NODE));
pPrev->pNext = pTrav;
}
- pTrav->object = object;
- return pTrav;
+ if (!pTrav) {
+ char str[1024];
+ sprintf(str, "Malloc failed to alloc node for XGL Object %p", (void*)object);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, object, 0, MEMTRACK_OUT_OF_MEMORY_ERROR, "MEM", str);
+ return NULL;
+ }
+ else {
+ numObjectNodes++;
+ pTrav->object = object;
+ return pTrav;
+ }
}
// Remove object binding performs 3 tasks:
@@ -490,11 +586,15 @@
{
GLOBAL_OBJECT_NODE* pGlobalObjTrav = getGlobalObjectNode(object);
if (!pGlobalObjTrav) {
- printf("MEM ERROR : Attempting to clear mem binding for object %p\n", object);
+ char str[1024];
+ sprintf(str, "Attempting to clear mem binding for object %p", object);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, object, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
return XGL_FALSE;
}
if (!pGlobalObjTrav->pMemNode) {
- printf("MEM WARN : Attempting to clear mem binding on obj %p but it has no binding.\n", (void*)object);
+ char str[1024];
+ sprintf(str, "Attempting to clear mem binding on obj %p but it has no binding.", (void*)object);
+ layerCbMsg(XGL_DBG_MSG_WARNING, XGL_VALIDATION_LEVEL_0, object, 0, MEMTRACK_MEM_OBJ_CLEAR_EMPTY_BINDINGS, "MEM", str);
return XGL_FALSE;
}
MINI_NODE* pObjTrav = pGlobalObjTrav->pMemNode->pObjBindings;
@@ -513,12 +613,15 @@
pPrevObj = pObjTrav;
pObjTrav = pObjTrav->pNext;
}
- printf("MEM ERROR : While trying to clear mem binding for object %p, unable to find mem ref %p\n", object, pGlobalObjTrav->pMemNode->mem);
+ char str[1024];
+ 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);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, object, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
return XGL_FALSE;
}
// For NULL mem case, clear any previous binding Else...
// Make sure given object is in global object LL
+// IF a previous binding existed, clear it
// Add link from global object node to global memory node
// Add mini-object node & reference off of global obj node
// Return XGL_TRUE if addition is successful, XGL_FALSE otherwise
@@ -537,15 +640,21 @@
// non-null case so should have real mem obj
GLOBAL_MEM_OBJ_NODE* pTrav = getGlobalMemNode(mem);
if (!pTrav) {
- printf("MEM ERROR : While trying to bind mem for obj %p, couldn't find node for mem obj %p\n", (void*)object, (void*)mem);
+ char str[1024];
+ sprintf(str, "While trying to bind mem for obj %p, couldn't find node for mem obj %p", (void*)object, (void*)mem);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
return XGL_FALSE;
}
XGL_RESULT result = insertMiniNode(&pTrav->pObjBindings, object, &pTrav->refCount);
if (XGL_SUCCESS != result)
return result;
- if (pGlobalObjTrav->pMemNode)
- printf("MEM INFO : Updating memory binding for object %p from mem obj %p to %p\n", object, pGlobalObjTrav->pMemNode->mem, mem);
+ if (pGlobalObjTrav->pMemNode) {
+ clearObjectBinding(object); // Need to clear the previous object binding before setting new binding
+ char str[1024];
+ sprintf(str, "Updating memory binding for object %p from mem obj %p to %p", object, pGlobalObjTrav->pMemNode->mem, mem);
+ layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, object, 0, MEMTRACK_NONE, "MEM", str);
+ }
pGlobalObjTrav->pMemNode = pTrav;
return XGL_TRUE;
}
@@ -554,12 +663,17 @@
{
GLOBAL_OBJECT_NODE* pGlobalObjTrav = pGlobalObjectHead;
if (!pGlobalObjTrav) {
- printf("MEM INFO : Global Object list is empty :(\n");
+ char str[1024];
+ sprintf(str, "Global Object list is empty :(\n");
+ layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
}
else {
- printf("MEM INFO : Details of Global Object list w/ HEAD at %p\n", (void*)pGlobalObjTrav);
+ char str[1024];
+ sprintf(str, "Details of Global Object list w/ HEAD at %p", (void*)pGlobalObjTrav);
+ layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
while (pGlobalObjTrav) {
- printf(" GlobObjNode %p has object %p, pNext %p, pMemNode %p\n", pGlobalObjTrav, pGlobalObjTrav->object, pGlobalObjTrav->pNext, pGlobalObjTrav->pMemNode);
+ sprintf(str, " GlobObjNode %p has object %p, pNext %p, pMemNode %p", pGlobalObjTrav, pGlobalObjTrav->object, pGlobalObjTrav->pNext, pGlobalObjTrav->pMemNode);
+ layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, pGlobalObjTrav->object, 0, MEMTRACK_NONE, "MEM", str);
pGlobalObjTrav = pGlobalObjTrav->pNext;
}
}
@@ -574,12 +688,16 @@
mem = pObjNode->pMemNode->mem;
}
else {
- printf("MEM ERROR : Trying to get mem binding for object %p but object has no mem binding\n", (void*)object);
+ char str[1024];
+ sprintf(str, "Trying to get mem binding for object %p but object has no mem binding", (void*)object);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, object, 0, MEMTRACK_MISSING_MEM_BINDINGS, "MEM", str);
printObjList();
}
}
else {
- printf("MEM ERROR : Trying to get mem binding for object %p but no such object in global list\n", (void*)object);
+ char str[1024];
+ sprintf(str, "Trying to get mem binding for object %p but no such object in global list", (void*)object);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, object, 0, MEMTRACK_INVALID_OBJECT, "MEM", str);
printObjList();
}
return mem;
@@ -588,34 +706,54 @@
static void printMemList()
{
GLOBAL_MEM_OBJ_NODE* pTrav = pGlobalMemObjHead;
+ // Just printing each msg individually for now, may want to package these into single large print
+ char str[1024];
if (!pTrav) {
- printf("MEM INFO : Global Memory Object list is empty :(\n");
+ sprintf(str, "MEM INFO : Global Memory Object list is empty :(\n");
+ layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
}
else {
- printf("MEM INFO : Details of Global Memory Object list w/ HEAD at %p\n", (void*)pTrav);
+ sprintf(str, "MEM INFO : Details of Global Memory Object list w/ HEAD at %p", (void*)pTrav);
+ layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
while (pTrav) {
- printf(" ===MemObj Node at %p===\n", (void*)pTrav);
- printf(" Mem object: %p\n", (void*)pTrav->mem);
- printf(" Ref Count: %u\n", pTrav->refCount);
- printf(" pNext Mem Obj Node: %p\n", (void*)pTrav->pNextGlobalNode);
- printf(" Mem Alloc info:\n%s", xgl_print_xgl_memory_alloc_info(&pTrav->allocInfo, " "));
+ sprintf(str, " ===MemObj Node at %p===", (void*)pTrav);
+ layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
+ sprintf(str, " Mem object: %p", (void*)pTrav->mem);
+ layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
+ sprintf(str, " Ref Count: %u", pTrav->refCount);
+ layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
+ sprintf(str, " pNext Mem Obj Node: %p", (void*)pTrav->pNextGlobalNode);
+ layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
+ if (0 != pTrav->allocInfo.allocationSize)
+ sprintf(str, " Mem Alloc info:\n%s", xgl_print_xgl_memory_alloc_info(&pTrav->allocInfo, "{MEM}INFO : "));
+ else
+ sprintf(str, " Mem Alloc info is NULL (alloc done by xglWsiX11CreatePresentableImage())");
+ layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
MINI_NODE* pObjTrav = pTrav->pObjBindings;
- if (!pObjTrav)
- printf(" No XGL Object bindings\n");
+ if (!pObjTrav) {
+ sprintf(str, " No XGL Object bindings");
+ layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
+ }
else {
- printf(" XGL OBJECT Binding list w/ HEAD at %p:\n", pObjTrav);
+ sprintf(str, " XGL OBJECT Binding list w/ HEAD at %p:", pObjTrav);
+ layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
while (pObjTrav) {
- printf(" OBJ_NODE(%p): XGL OBJECT %p, pNext %p\n", pObjTrav, pObjTrav->object, pObjTrav->pNext);
+ sprintf(str, " OBJ_NODE(%p): XGL OBJECT %p, pNext %p", pObjTrav, pObjTrav->object, pObjTrav->pNext);
+ layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
pObjTrav = pObjTrav->pNext;
}
}
MINI_NODE* pCBTrav = pTrav->pCmdBufferBindings;
- if (!pCBTrav)
- printf(" No Command Buffer bindings\n");
+ if (!pCBTrav) {
+ sprintf(str, " No Command Buffer bindings");
+ layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
+ }
else {
- printf(" XGL Command Buffer (CB) binding list w/ HEAD at %p:\n", pCBTrav);
+ sprintf(str, " XGL Command Buffer (CB) binding list w/ HEAD at %p:", pCBTrav);
+ layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
while (pCBTrav) {
- printf(" CB_NODE(%p): XGL CB %p, pNext %p\n", pCBTrav, pCBTrav->cmdBuffer, pCBTrav->pNext);
+ sprintf(str, " CB_NODE(%p): XGL CB %p, pNext %p", pCBTrav, pCBTrav->cmdBuffer, pCBTrav->pNext);
+ layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
pCBTrav = pCBTrav->pNext;
}
}
@@ -626,17 +764,22 @@
static void printGlobalCB()
{
+ char str[1024] = {0};
GLOBAL_CB_NODE* pTrav = pGlobalCBHead;
if (!pTrav) {
- printf("MEM INFO : Global Command Buffer (CB) list is empty :(\n");
+ sprintf(str, "Global Command Buffer (CB) list is empty :(\n");
+ layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
}
else {
- printf("MEM INFO : Details of Global CB list w/ HEAD at %p:\n", (void*)pTrav);
+ sprintf(str, "Details of Global CB list w/ HEAD at %p:", (void*)pTrav);
+ layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
while (pTrav) {
- printf(" Global CB Node (%p) has CB %p, fence %p, and pMemObjList %p\n", (void*)pTrav, (void*)pTrav->cmdBuffer, (void*)pTrav->fence, (void*)pTrav->pMemObjList);
+ sprintf(str, " Global CB Node (%p) has CB %p, fence %p, and pMemObjList %p", (void*)pTrav, (void*)pTrav->cmdBuffer, (void*)pTrav->fence, (void*)pTrav->pMemObjList);
+ layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
MINI_NODE* pMemObjTrav = pTrav->pMemObjList;
while (pMemObjTrav) {
- printf(" MEM_NODE(%p): Mem obj %p, pNext %p\n", (void*)pMemObjTrav, (void*)pMemObjTrav->mem, (void*)pMemObjTrav->pNext);
+ sprintf(str, " MEM_NODE(%p): Mem obj %p, pNext %p", (void*)pMemObjTrav, (void*)pMemObjTrav->mem, (void*)pMemObjTrav->pNext);
+ layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
pMemObjTrav = pMemObjTrav->pNext;
}
pTrav = pTrav->pNextGlobalCBNode;
@@ -926,12 +1069,16 @@
XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglDestroyDevice(XGL_DEVICE device)
{
- printf("MEM INFO : Printing List details prior to xglDestroyDevice()\n");
+ char str[1024];
+ sprintf(str, "Printing List details prior to xglDestroyDevice()");
+ layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, device, 0, MEMTRACK_NONE, "MEM", str);
printMemList();
printGlobalCB();
printObjList();
- if (XGL_FALSE == deleteGlobalCBList())
- printf("MEM ERROR : Issue deleting global CB list in xglDestroyDevice()\n");
+ if (XGL_FALSE == deleteGlobalCBList()) {
+ sprintf(str, "Issue deleting global CB list in xglDestroyDevice()");
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, device, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
+ }
XGL_RESULT result = nextTable.DestroyDevice(device);
return result;
}
@@ -967,15 +1114,18 @@
if (XGL_NULL_HANDLE == fence) { // allocate our own fence to track cmd buffer
localFence = createLocalFence();
}
- // TODO : Verify that the list of memory references here matches what the cmd buffers require
- printf("MEM INFO : In xglQueueSubmit(), checking %u cmdBuffers with %u memRefs\n", cmdBufferCount, memRefCount);
+ char str[1024];
+ sprintf(str, "In xglQueueSubmit(), checking %u cmdBuffers with %u memRefs", cmdBufferCount, memRefCount);
+ layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, queue, 0, MEMTRACK_NONE, "MEM", str);
printMemList();
printGlobalCB();
for (uint32_t i = 0; i < cmdBufferCount; i++) {
setCBFence(pCmdBuffers[i], localFence);
- printf("MEM INFO : Verifying mem refs for CB %p\n", pCmdBuffers[i]);
+ sprintf(str, "Verifying mem refs for CB %p", pCmdBuffers[i]);
+ layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, pCmdBuffers[i], 0, MEMTRACK_NONE, "MEM", str);
if (XGL_FALSE == validateCBMemRef(pCmdBuffers[i], memRefCount, pMemRefs)) {
- printf("MEM ERROR : Unable to verify memory references for CB %p\n", (void*)pCmdBuffers[i]);
+ sprintf(str, "Unable to verify memory references for CB %p", (void*)pCmdBuffers[i]);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, pCmdBuffers[i], 0, MEMTRACK_CB_MISSING_MEM_REF, "MEM", str);
}
}
printGlobalCB();
@@ -1030,9 +1180,11 @@
// TODO : Pick up frees here
// Make sure mem object is unbound from any other objects
// Make sure mem object not referenced by any queued command buffers
- if (XGL_FALSE == freeMemNode(mem))
- printf("MEM ERROR : Issue while freeing mem obj %p\n", (void*)mem);
-
+ if (XGL_FALSE == freeMemNode(mem)) {
+ char str[1024];
+ sprintf(str, "Issue while freeing mem obj %p", (void*)mem);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_FREE_MEM_ERROR, "MEM", str);
+ }
printMemList();
printObjList();
printGlobalCB();
@@ -1120,8 +1272,10 @@
GLOBAL_OBJECT_NODE* pTrav = getGlobalObjectNode(object);
if (pTrav) {
if (pTrav->pMemNode) {
- printf("MEM ERROR : Destroying obj %p that is still bound to memory object %p\n", object, (void*)pTrav->pMemNode->mem);
- printf("MEM ERROR : You should first clear binding by calling xglBindObjectMemory(%p, 0, XGL_NULL_HANDLE)\n", object);
+ char str[1024];
+ 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);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, object, 0, MEMTRACK_DESTROY_OBJECT_ERROR, "MEM", str);
+ // From the spec : If an object has previous memory binding, it is required to unbind memory from an API object before it is destroyed.
clearObjectBinding(object);
}
if (pGlobalObjectHead == pTrav) // update HEAD if needed
@@ -1137,6 +1291,7 @@
{
// TODO : What to track here?
// Could potentially save returned mem requirements and validate values passed into BindObjectMemory for this object
+ // From spec : The only objects that are guaranteed to have no external memory requirements are devices, queues, command buffers, shaders and memory objects.
XGL_RESULT result = nextTable.GetObjectInfo(object, infoType, pDataSize, pData);
return result;
}
@@ -1145,8 +1300,11 @@
{
XGL_RESULT result = nextTable.BindObjectMemory(object, mem, offset);
// Track objects tied to memory
- if (XGL_FALSE == updateObjectBinding(object, mem))
- printf("MEM ERROR : Unable to set object %p binding to mem obj %p\n", (void*)object, (void*)mem);
+ if (XGL_FALSE == updateObjectBinding(object, mem)) {
+ char str[1024];
+ sprintf(str, "Unable to set object %p binding to mem obj %p", (void*)object, (void*)mem);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, object, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
+ }
printObjList();
printMemList();
return result;
@@ -1435,8 +1593,11 @@
XGL_LAYER_EXPORT XGL_VOID XGLAPI xglCmdBindIndexData(XGL_CMD_BUFFER cmdBuffer, XGL_GPU_MEMORY mem, XGL_GPU_SIZE offset, XGL_INDEX_TYPE indexType)
{
// Track this memory. What exactly is this call doing?
- if (XGL_FALSE == updateCBBinding(cmdBuffer, mem))
- printf("MEM ERROR : In xglCmdBindIndexData() call unable to update binding of mem %p to cmdBuffer %p\n", mem, cmdBuffer);
+ if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
+ char str[1024];
+ sprintf(str, "In xglCmdBindIndexData() call unable to update binding of mem %p to cmdBuffer %p", mem, cmdBuffer);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
+ }
nextTable.CmdBindIndexData(cmdBuffer, mem, offset, indexType);
}
@@ -1450,8 +1611,11 @@
// TODO : Track memory state transitions
// Flag incorrect transitions when states don't match
XGL_GPU_MEMORY mem = pStateTransitions->mem;
- if (XGL_FALSE == updateCBBinding(cmdBuffer, mem))
- printf("MEM ERROR : In xglCmdPrepareMemoryRegions() call unable to update binding of mem %p to cmdBuffer %p\n", mem, cmdBuffer);
+ if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
+ char str[1024];
+ sprintf(str, "In xglCmdPrepareMemoryRegions() call unable to update binding of mem %p to cmdBuffer %p", mem, cmdBuffer);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
+ }
nextTable.CmdPrepareMemoryRegions(cmdBuffer, transitionCount, pStateTransitions);
}
@@ -1460,8 +1624,11 @@
// TODO : This will have an image object that's bound to memory in the pStateTransitions struct
// Need to pull object based on image and then pull mem mapping from that object
XGL_GPU_MEMORY mem = getMemBindingFromObject((XGL_OBJECT)pStateTransitions->image);
- if (XGL_FALSE == updateCBBinding(cmdBuffer, mem))
- printf("MEM ERROR : In xglCmdPrepareImages() call unable to update binding of mem %p to cmdBuffer %p\n", mem, cmdBuffer);
+ if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
+ char str[1024];
+ sprintf(str, "In xglCmdPrepareImages() call unable to update binding of mem %p to cmdBuffer %p", mem, cmdBuffer);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
+ }
nextTable.CmdPrepareImages(cmdBuffer, transitionCount, pStateTransitions);
}
@@ -1477,17 +1644,21 @@
XGL_LAYER_EXPORT XGL_VOID XGLAPI xglCmdDrawIndirect(XGL_CMD_BUFFER cmdBuffer, XGL_GPU_MEMORY mem, XGL_GPU_SIZE offset, XGL_UINT32 count, XGL_UINT32 stride)
{
- // TODO : Track this
- if (XGL_FALSE == updateCBBinding(cmdBuffer, mem))
- printf("MEM ERROR : In xglCmdDrawIndirect() call unable to update binding of mem %p to cmdBuffer %p\n", mem, cmdBuffer);
+ if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
+ char str[1024];
+ sprintf(str, "In xglCmdDrawIndirect() call unable to update binding of mem %p to cmdBuffer %p", mem, cmdBuffer);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
+ }
nextTable.CmdDrawIndirect(cmdBuffer, mem, offset, count, stride);
}
XGL_LAYER_EXPORT XGL_VOID XGLAPI xglCmdDrawIndexedIndirect(XGL_CMD_BUFFER cmdBuffer, XGL_GPU_MEMORY mem, XGL_GPU_SIZE offset, XGL_UINT32 count, XGL_UINT32 stride)
{
- // TODO : Track this
- if (XGL_FALSE == updateCBBinding(cmdBuffer, mem))
- printf("MEM ERROR : In xglCmdDrawIndexedIndirect() call unable to update binding of mem %p to cmdBuffer %p\n", mem, cmdBuffer);
+ if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
+ char str[1024];
+ sprintf(str, "In xglCmdDrawIndexedIndirect() call unable to update binding of mem %p to cmdBuffer %p", mem, cmdBuffer);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
+ }
nextTable.CmdDrawIndexedIndirect(cmdBuffer, mem, offset, count, stride);
}
@@ -1498,19 +1669,26 @@
XGL_LAYER_EXPORT XGL_VOID XGLAPI xglCmdDispatchIndirect(XGL_CMD_BUFFER cmdBuffer, XGL_GPU_MEMORY mem, XGL_GPU_SIZE offset)
{
- // TODO : Track this
- if (XGL_FALSE == updateCBBinding(cmdBuffer, mem))
- printf("MEM ERROR : In xglCmdDispatchIndirect() call unable to update binding of mem %p to cmdBuffer %p\n", mem, cmdBuffer);
+ if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
+ char str[1024];
+ sprintf(str, "In xglCmdDispatchIndirect() call unable to update binding of mem %p to cmdBuffer %p", mem, cmdBuffer);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
+ }
nextTable.CmdDispatchIndirect(cmdBuffer, mem, offset);
}
XGL_LAYER_EXPORT XGL_VOID XGLAPI xglCmdCopyMemory(XGL_CMD_BUFFER cmdBuffer, XGL_GPU_MEMORY srcMem, XGL_GPU_MEMORY destMem, XGL_UINT regionCount, const XGL_MEMORY_COPY* pRegions)
{
- // TODO : Track this
- if (XGL_FALSE == updateCBBinding(cmdBuffer, srcMem))
- printf("MEM ERROR : In xglCmdCopyMemory() call unable to update binding of srcMem %p to cmdBuffer %p\n", srcMem, cmdBuffer);
- if (XGL_FALSE == updateCBBinding(cmdBuffer, destMem))
- printf("MEM ERROR : In xglCmdCopyMemory() call unable to update binding of destMem %p to cmdBuffer %p\n", destMem, cmdBuffer);
+ if (XGL_FALSE == updateCBBinding(cmdBuffer, srcMem)) {
+ char str[1024];
+ sprintf(str, "In xglCmdCopyMemory() call unable to update binding of srcMem %p to cmdBuffer %p", srcMem, cmdBuffer);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
+ }
+ if (XGL_FALSE == updateCBBinding(cmdBuffer, destMem)) {
+ char str[1024];
+ sprintf(str, "In xglCmdCopyMemory() call unable to update binding of destMem %p to cmdBuffer %p", destMem, cmdBuffer);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
+ }
nextTable.CmdCopyMemory(cmdBuffer, srcMem, destMem, regionCount, pRegions);
}
@@ -1524,10 +1702,16 @@
{
// TODO : Track this
XGL_GPU_MEMORY mem = getMemBindingFromObject(destImage);
- if (XGL_FALSE == updateCBBinding(cmdBuffer, mem))
- printf("MEM ERROR : In xglCmdCopyMemoryToImage() call unable to update binding of destImage mem %p to cmdBuffer %p\n", mem, cmdBuffer);
- if (XGL_FALSE == updateCBBinding(cmdBuffer, srcMem))
- printf("MEM ERROR : In xglCmdCopyMemoryToImage() call unable to update binding of srcMem %p to cmdBuffer %p\n", srcMem, cmdBuffer);
+ if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
+ char str[1024];
+ sprintf(str, "In xglCmdCopyMemoryToImage() call unable to update binding of destImage mem %p to cmdBuffer %p", mem, cmdBuffer);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
+ }
+ if (XGL_FALSE == updateCBBinding(cmdBuffer, srcMem)) {
+ char str[1024];
+ sprintf(str, "In xglCmdCopyMemoryToImage() call unable to update binding of srcMem %p to cmdBuffer %p", srcMem, cmdBuffer);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
+ }
nextTable.CmdCopyMemoryToImage(cmdBuffer, srcMem, destImage, regionCount, pRegions);
}
@@ -1535,10 +1719,16 @@
{
// TODO : Track this
XGL_GPU_MEMORY mem = getMemBindingFromObject(srcImage);
- if (XGL_FALSE == updateCBBinding(cmdBuffer, mem))
- printf("MEM ERROR : In xglCmdCopyImageToMemory() call unable to update binding of srcImage mem %p to cmdBuffer %p\n", mem, cmdBuffer);
- if (XGL_FALSE == updateCBBinding(cmdBuffer, destMem))
- printf("MEM ERROR : In xglCmdCopyImageToMemory() call unable to update binding of destMem %p to cmdBuffer %p\n", destMem, cmdBuffer);
+ if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
+ char str[1024];
+ sprintf(str, "In xglCmdCopyImageToMemory() call unable to update binding of srcImage mem %p to cmdBuffer %p", mem, cmdBuffer);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
+ }
+ if (XGL_FALSE == updateCBBinding(cmdBuffer, destMem)) {
+ char str[1024];
+ sprintf(str, "In xglCmdCopyImageToMemory() call unable to update binding of destMem %p to cmdBuffer %p", destMem, cmdBuffer);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
+ }
nextTable.CmdCopyImageToMemory(cmdBuffer, srcImage, destMem, regionCount, pRegions);
}
@@ -1546,60 +1736,87 @@
{
// TODO : Each image will have mem mapping so track them
XGL_GPU_MEMORY mem = getMemBindingFromObject(srcImage);
- if (XGL_FALSE == updateCBBinding(cmdBuffer, mem))
- printf("MEM ERROR : In xglCmdCloneImageData() call unable to update binding of srcImage mem %p to cmdBuffer %p\n", mem, cmdBuffer);
+ if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
+ char str[1024];
+ sprintf(str, "In xglCmdCloneImageData() call unable to update binding of srcImage mem %p to cmdBuffer %p", mem, cmdBuffer);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
+ }
mem = getMemBindingFromObject(destImage);
- if (XGL_FALSE == updateCBBinding(cmdBuffer, mem))
- printf("MEM ERROR : In xglCmdCloneImageData() call unable to update binding of destImage mem %p to cmdBuffer %p\n", mem, cmdBuffer);
+ if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
+ char str[1024];
+ sprintf(str, "In xglCmdCloneImageData() call unable to update binding of destImage mem %p to cmdBuffer %p", mem, cmdBuffer);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
+ }
nextTable.CmdCloneImageData(cmdBuffer, srcImage, srcImageState, destImage, destImageState);
}
XGL_LAYER_EXPORT XGL_VOID XGLAPI xglCmdUpdateMemory(XGL_CMD_BUFFER cmdBuffer, XGL_GPU_MEMORY destMem, XGL_GPU_SIZE destOffset, XGL_GPU_SIZE dataSize, const XGL_UINT32* pData)
{
- if (XGL_FALSE == updateCBBinding(cmdBuffer, destMem))
- printf("MEM ERROR : In xglCmdUpdateMemory() call unable to update binding of destMem %p to cmdBuffer %p\n", destMem, cmdBuffer);
+ if (XGL_FALSE == updateCBBinding(cmdBuffer, destMem)) {
+ char str[1024];
+ sprintf(str, "In xglCmdUpdateMemory() call unable to update binding of destMem %p to cmdBuffer %p", destMem, cmdBuffer);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
+ }
nextTable.CmdUpdateMemory(cmdBuffer, destMem, destOffset, dataSize, pData);
}
XGL_LAYER_EXPORT XGL_VOID XGLAPI xglCmdFillMemory(XGL_CMD_BUFFER cmdBuffer, XGL_GPU_MEMORY destMem, XGL_GPU_SIZE destOffset, XGL_GPU_SIZE fillSize, XGL_UINT32 data)
{
- if (XGL_FALSE == updateCBBinding(cmdBuffer, destMem))
- printf("MEM ERROR : In xglCmdFillMemory() call unable to update binding of destMem %p to cmdBuffer %p\n", destMem, cmdBuffer);
+ if (XGL_FALSE == updateCBBinding(cmdBuffer, destMem)) {
+ char str[1024];
+ sprintf(str, "In xglCmdFillMemory() call unable to update binding of destMem %p to cmdBuffer %p", destMem, cmdBuffer);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
+ }
nextTable.CmdFillMemory(cmdBuffer, destMem, destOffset, fillSize, data);
}
XGL_LAYER_EXPORT XGL_VOID XGLAPI xglCmdClearColorImage(XGL_CMD_BUFFER cmdBuffer, XGL_IMAGE image, const XGL_FLOAT color[4], XGL_UINT rangeCount, const XGL_IMAGE_SUBRESOURCE_RANGE* pRanges)
{
XGL_GPU_MEMORY mem = getMemBindingFromObject(image);
- if (XGL_FALSE == updateCBBinding(cmdBuffer, mem))
- printf("MEM ERROR : In xglCmdClearColorImage() call unable to update binding of image mem %p to cmdBuffer %p\n", mem, cmdBuffer);
+ if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
+ char str[1024];
+ sprintf(str, "In xglCmdClearColorImage() call unable to update binding of image mem %p to cmdBuffer %p", mem, cmdBuffer);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
+ }
nextTable.CmdClearColorImage(cmdBuffer, image, color, rangeCount, pRanges);
}
XGL_LAYER_EXPORT XGL_VOID XGLAPI xglCmdClearColorImageRaw(XGL_CMD_BUFFER cmdBuffer, XGL_IMAGE image, const XGL_UINT32 color[4], XGL_UINT rangeCount, const XGL_IMAGE_SUBRESOURCE_RANGE* pRanges)
{
XGL_GPU_MEMORY mem = getMemBindingFromObject(image);
- if (XGL_FALSE == updateCBBinding(cmdBuffer, mem))
- printf("MEM ERROR : In xglCmdClearColorImageRaw() call unable to update binding of image mem %p to cmdBuffer %p\n", mem, cmdBuffer);
+ if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
+ char str[1024];
+ sprintf(str, "In xglCmdClearColorImageRaw() call unable to update binding of image mem %p to cmdBuffer %p", mem, cmdBuffer);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
+ }
nextTable.CmdClearColorImageRaw(cmdBuffer, image, color, rangeCount, pRanges);
}
XGL_LAYER_EXPORT XGL_VOID XGLAPI xglCmdClearDepthStencil(XGL_CMD_BUFFER cmdBuffer, XGL_IMAGE image, XGL_FLOAT depth, XGL_UINT32 stencil, XGL_UINT rangeCount, const XGL_IMAGE_SUBRESOURCE_RANGE* pRanges)
{
XGL_GPU_MEMORY mem = getMemBindingFromObject(image);
- if (XGL_FALSE == updateCBBinding(cmdBuffer, mem))
- printf("MEM ERROR : In xglCmdClearDepthStencil() call unable to update binding of image mem %p to cmdBuffer %p\n", mem, cmdBuffer);
+ if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
+ char str[1024];
+ sprintf(str, "In xglCmdClearDepthStencil() call unable to update binding of image mem %p to cmdBuffer %p", mem, cmdBuffer);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
+ }
nextTable.CmdClearDepthStencil(cmdBuffer, image, depth, stencil, rangeCount, pRanges);
}
XGL_LAYER_EXPORT XGL_VOID XGLAPI xglCmdResolveImage(XGL_CMD_BUFFER cmdBuffer, XGL_IMAGE srcImage, XGL_IMAGE destImage, XGL_UINT rectCount, const XGL_IMAGE_RESOLVE* pRects)
{
XGL_GPU_MEMORY mem = getMemBindingFromObject(srcImage);
- if (XGL_FALSE == updateCBBinding(cmdBuffer, mem))
- printf("MEM ERROR : In xglCmdResolveImage() call unable to update binding of srcImage mem %p to cmdBuffer %p\n", mem, cmdBuffer);
+ if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
+ char str[1024];
+ sprintf(str, "In xglCmdResolveImage() call unable to update binding of srcImage mem %p to cmdBuffer %p", mem, cmdBuffer);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
+ }
mem = getMemBindingFromObject(destImage);
- if (XGL_FALSE == updateCBBinding(cmdBuffer, mem))
- printf("MEM ERROR : In xglCmdResolveImage() call unable to update binding of destImage mem %p to cmdBuffer %p\n", mem, cmdBuffer);
+ if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
+ char str[1024];
+ sprintf(str, "In xglCmdResolveImage() call unable to update binding of destImage mem %p to cmdBuffer %p", mem, cmdBuffer);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
+ }
nextTable.CmdResolveImage(cmdBuffer, srcImage, destImage, rectCount, pRects);
}
@@ -1615,39 +1832,54 @@
XGL_LAYER_EXPORT XGL_VOID XGLAPI xglCmdMemoryAtomic(XGL_CMD_BUFFER cmdBuffer, XGL_GPU_MEMORY destMem, XGL_GPU_SIZE destOffset, XGL_UINT64 srcData, XGL_ATOMIC_OP atomicOp)
{
- if (XGL_FALSE == updateCBBinding(cmdBuffer, destMem))
- printf("MEM ERROR : In xglCmdMemoryAtomic() call unable to update binding of destMem %p to cmdBuffer %p\n", destMem, cmdBuffer);
+ if (XGL_FALSE == updateCBBinding(cmdBuffer, destMem)) {
+ char str[1024];
+ sprintf(str, "In xglCmdMemoryAtomic() call unable to update binding of destMem %p to cmdBuffer %p", destMem, cmdBuffer);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
+ }
nextTable.CmdMemoryAtomic(cmdBuffer, destMem, destOffset, srcData, atomicOp);
}
XGL_LAYER_EXPORT XGL_VOID XGLAPI xglCmdBeginQuery(XGL_CMD_BUFFER cmdBuffer, XGL_QUERY_POOL queryPool, XGL_UINT slot, XGL_FLAGS flags)
{
XGL_GPU_MEMORY mem = getMemBindingFromObject(queryPool);
- if (XGL_FALSE == updateCBBinding(cmdBuffer, mem))
- printf("MEM ERROR : In xglCmdBeginQuery() call unable to update binding of queryPool mem %p to cmdBuffer %p\n", mem, cmdBuffer);
+ if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
+ char str[1024];
+ sprintf(str, "In xglCmdBeginQuery() call unable to update binding of queryPool mem %p to cmdBuffer %p", mem, cmdBuffer);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
+ }
nextTable.CmdBeginQuery(cmdBuffer, queryPool, slot, flags);
}
XGL_LAYER_EXPORT XGL_VOID XGLAPI xglCmdEndQuery(XGL_CMD_BUFFER cmdBuffer, XGL_QUERY_POOL queryPool, XGL_UINT slot)
{
XGL_GPU_MEMORY mem = getMemBindingFromObject(queryPool);
- if (XGL_FALSE == updateCBBinding(cmdBuffer, mem))
- printf("MEM ERROR : In xglCmdEndQuery() call unable to update binding of queryPool mem %p to cmdBuffer %p\n", mem, cmdBuffer);
+ if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
+ char str[1024];
+ sprintf(str, "In xglCmdEndQuery() call unable to update binding of queryPool mem %p to cmdBuffer %p", mem, cmdBuffer);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
+ }
nextTable.CmdEndQuery(cmdBuffer, queryPool, slot);
}
XGL_LAYER_EXPORT XGL_VOID XGLAPI xglCmdResetQueryPool(XGL_CMD_BUFFER cmdBuffer, XGL_QUERY_POOL queryPool, XGL_UINT startQuery, XGL_UINT queryCount)
{
XGL_GPU_MEMORY mem = getMemBindingFromObject(queryPool);
- if (XGL_FALSE == updateCBBinding(cmdBuffer, mem))
- printf("MEM ERROR : In xglCmdResetQueryPool() call unable to update binding of queryPool mem %p to cmdBuffer %p\n", mem, cmdBuffer);
+ if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
+ char str[1024];
+ sprintf(str, "In xglCmdResetQueryPool() call unable to update binding of queryPool mem %p to cmdBuffer %p", mem, cmdBuffer);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
+ }
nextTable.CmdResetQueryPool(cmdBuffer, queryPool, startQuery, queryCount);
}
XGL_LAYER_EXPORT XGL_VOID XGLAPI xglCmdWriteTimestamp(XGL_CMD_BUFFER cmdBuffer, XGL_TIMESTAMP_TYPE timestampType, XGL_GPU_MEMORY destMem, XGL_GPU_SIZE destOffset)
{
- if (XGL_FALSE == updateCBBinding(cmdBuffer, destMem))
- printf("MEM ERROR : In xglCmdWriteTimestamp() call unable to update binding of destMem %p to cmdBuffer %p\n", destMem, cmdBuffer);
+ if (XGL_FALSE == updateCBBinding(cmdBuffer, destMem)) {
+ char str[1024];
+ sprintf(str, "In xglCmdWriteTimestamp() call unable to update binding of destMem %p to cmdBuffer %p", destMem, cmdBuffer);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
+ }
nextTable.CmdWriteTimestamp(cmdBuffer, timestampType, destMem, destOffset);
}
@@ -1658,15 +1890,21 @@
XGL_LAYER_EXPORT XGL_VOID XGLAPI xglCmdLoadAtomicCounters(XGL_CMD_BUFFER cmdBuffer, XGL_PIPELINE_BIND_POINT pipelineBindPoint, XGL_UINT startCounter, XGL_UINT counterCount, XGL_GPU_MEMORY srcMem, XGL_GPU_SIZE srcOffset)
{
- if (XGL_FALSE == updateCBBinding(cmdBuffer, srcMem))
- printf("MEM ERROR : In xglCmdLoadAtomicCounters() call unable to update binding of srcMem %p to cmdBuffer %p\n", srcMem, cmdBuffer);
+ if (XGL_FALSE == updateCBBinding(cmdBuffer, srcMem)) {
+ char str[1024];
+ sprintf(str, "In xglCmdLoadAtomicCounters() call unable to update binding of srcMem %p to cmdBuffer %p", srcMem, cmdBuffer);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
+ }
nextTable.CmdLoadAtomicCounters(cmdBuffer, pipelineBindPoint, startCounter, counterCount, srcMem, srcOffset);
}
XGL_LAYER_EXPORT XGL_VOID XGLAPI xglCmdSaveAtomicCounters(XGL_CMD_BUFFER cmdBuffer, XGL_PIPELINE_BIND_POINT pipelineBindPoint, XGL_UINT startCounter, XGL_UINT counterCount, XGL_GPU_MEMORY destMem, XGL_GPU_SIZE destOffset)
{
- if (XGL_FALSE == updateCBBinding(cmdBuffer, destMem))
- printf("MEM ERROR : In xglCmdSaveAtomicCounters() call unable to update binding of destMem %p to cmdBuffer %p\n", destMem, cmdBuffer);
+ if (XGL_FALSE == updateCBBinding(cmdBuffer, destMem)) {
+ char str[1024];
+ sprintf(str, "In xglCmdSaveAtomicCounters() call unable to update binding of destMem %p to cmdBuffer %p", destMem, cmdBuffer);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
+ }
nextTable.CmdSaveAtomicCounters(cmdBuffer, pipelineBindPoint, startCounter, counterCount, destMem, destOffset);
}
@@ -1678,12 +1916,33 @@
XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglDbgRegisterMsgCallback(XGL_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback, XGL_VOID* pUserData)
{
+ // This layer intercepts callbacks
+ XGL_LAYER_DBG_FUNCTION_NODE *pNewDbgFuncNode = (XGL_LAYER_DBG_FUNCTION_NODE*)malloc(sizeof(XGL_LAYER_DBG_FUNCTION_NODE));
+ if (!pNewDbgFuncNode)
+ return XGL_ERROR_OUT_OF_MEMORY;
+ pNewDbgFuncNode->pfnMsgCallback = pfnMsgCallback;
+ pNewDbgFuncNode->pUserData = pUserData;
+ pNewDbgFuncNode->pNext = pDbgFunctionHead;
+ pDbgFunctionHead = pNewDbgFuncNode;
XGL_RESULT result = nextTable.DbgRegisterMsgCallback(pfnMsgCallback, pUserData);
return result;
}
XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglDbgUnregisterMsgCallback(XGL_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback)
{
+ XGL_LAYER_DBG_FUNCTION_NODE *pTrav = pDbgFunctionHead;
+ XGL_LAYER_DBG_FUNCTION_NODE *pPrev = pTrav;
+ while (pTrav) {
+ if (pTrav->pfnMsgCallback == pfnMsgCallback) {
+ pPrev->pNext = pTrav->pNext;
+ if (pDbgFunctionHead == pTrav)
+ pDbgFunctionHead = pTrav->pNext;
+ free(pTrav);
+ break;
+ }
+ pPrev = pTrav;
+ pTrav = pTrav->pNext;
+ }
XGL_RESULT result = nextTable.DbgUnregisterMsgCallback(pfnMsgCallback);
return result;
}
@@ -1725,11 +1984,9 @@
XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglWsiX11AssociateConnection(XGL_PHYSICAL_GPU gpu, const XGL_WSI_X11_CONNECTION_INFO* pConnectionInfo)
{
XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
- printf("At start of layered WsiX11AssociateConnection\n");
pCurObj = gpuw;
pthread_once(&tabOnce, initLayerTable);
XGL_RESULT result = nextTable.WsiX11AssociateConnection((XGL_PHYSICAL_GPU)gpuw->nextObject, pConnectionInfo);
- printf("Completed layered WsiX11AssociateConnection\n");
return result;
}
@@ -1742,6 +1999,15 @@
XGL_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)
{
XGL_RESULT result = nextTable.WsiX11CreatePresentableImage(device, pCreateInfo, pImage, pMem);
+ // First insert the new Mem Object and then bind it to created image
+ insertGlobalMemObj(*pMem, NULL);
+ if (XGL_FALSE == updateObjectBinding(*pImage, *pMem)) {
+ char str[1024];
+ sprintf(str, "In xglWsiX11CreatePresentableImage(), unable to set image %p binding to mem obj %p", (void*)*pImage, (void*)*pMem);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, *pImage, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
+ }
+ printObjList();
+ printMemList();
return result;
}
@@ -2006,4 +2272,3 @@
return gpuw->pGPA(gpuw->nextObject, funcName);
}
}
-