aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTobin Ehlis <tobin@lunarg.com>2015-01-14 12:47:30 -0700
committerCourtney Goeltzenleuchter <courtney@LunarG.com>2015-02-04 17:58:07 -0700
commit99d23b698552a2692084492f1c999987caac60f8 (patch)
treede423bf4af46f40122310d2c273a4cd4b72ce5d2
parent8aab78e92e5350f3b0734eefdbf68bb1a5da2332 (diff)
downloadusermoji-99d23b698552a2692084492f1c999987caac60f8.tar.xz
layers: Updated MemTracker to track per-region memory transition states for allocations
-rw-r--r--demos/tri.c7
-rw-r--r--layers/mem_tracker.c53
-rw-r--r--layers/mem_tracker.h8
3 files changed, 53 insertions, 15 deletions
diff --git a/demos/tri.c b/demos/tri.c
index 0059e037..3a89bf1b 100644
--- a/demos/tri.c
+++ b/demos/tri.c
@@ -153,7 +153,8 @@ static void demo_draw(struct demo *demo)
err = xglWaitForFences(demo->device, 1, &fence, XGL_TRUE, ~((XGL_UINT64) 0));
assert(err == XGL_SUCCESS || err == XGL_ERROR_UNAVAILABLE);
- XGL_MEMORY_REF memRefs[4];
+ static const uint32_t NUM_MEM_REFS = 5;
+ XGL_MEMORY_REF memRefs[NUM_MEM_REFS];
memRefs[0].mem = demo->depth.mem;
memRefs[0].flags = 0;
memRefs[1].mem = demo->textures[0].mem;
@@ -162,8 +163,10 @@ static void demo_draw(struct demo *demo)
memRefs[2].flags = 0;
memRefs[3].mem = demo->buffers[1].mem;
memRefs[3].flags = 0;
+ memRefs[4].mem = demo->vertices.mem;
+ memRefs[4].flags = 0;
err = xglQueueSubmit(demo->queue, 1, &demo->cmd,
- 4, memRefs, XGL_NULL_HANDLE);
+ NUM_MEM_REFS, memRefs, XGL_NULL_HANDLE);
assert(!err);
err = xglWsiX11QueuePresent(demo->queue, &present, fence);
diff --git a/layers/mem_tracker.c b/layers/mem_tracker.c
index 42f26b33..cd09b789 100644
--- a/layers/mem_tracker.c
+++ b/layers/mem_tracker.c
@@ -257,11 +257,11 @@ static void setMemTransition(const XGL_GPU_MEMORY mem, const XGL_MEMORY_STATE_TR
// TODO : Flag error for missing node
}
else {
- MEM_STATE_TRANSITION_NODE* pMTNode = pTrav->pTransitions;
+ MEM_STATE_TRANSITION_NODE* pMTNode = pTrav->pRegions;
MEM_STATE_TRANSITION_NODE* pPrevMTNode = pMTNode;
// TODO : Not sure of best way (or need) to distinguish mem from image here
// Verify that it's being used as memory (not image)
- //if (!pTrav->pTransitions.isMem) {
+ //if (!pTrav->pRegions.isMem) {
// TODO : Flag error for setting mem transition on image memory
//}
// Basic state update algorithm
@@ -280,8 +280,10 @@ static void setMemTransition(const XGL_GPU_MEMORY mem, const XGL_MEMORY_STATE_TR
MEM_STATE_TRANSITION_NODE* pNewNode = (MEM_STATE_TRANSITION_NODE*)malloc(sizeof(MEM_STATE_TRANSITION_NODE));
memset(pNewNode, 0, sizeof(MEM_STATE_TRANSITION_NODE));
memcpy(&pNewNode->transition, pTransition, sizeof(XGL_MEMORY_STATE_TRANSITION));
+ // Increment numRegions here and will be appropriately decremented below if needed
+ pTrav->numRegions++;
if (!pMTNode) { // Initialization case, just set HEAD ptr to new node
- pTrav->pTransitions = pNewNode;
+ pTrav->pRegions = pNewNode;
}
else {
// If offset of new state is less than current offset, insert it & update state after it as needed
@@ -295,14 +297,21 @@ static void setMemTransition(const XGL_GPU_MEMORY mem, const XGL_MEMORY_STATE_TR
saveStartNode = 1;
pMTNode->transition.memory.regionSize = pTransition->offset - pMTNode->transition.memory.offset;
pMTNode->pNext = pNewNode;
+ // TODO: Verify that prev newState matches new oldState
}
else { // start point of regions are equal
// Prev ptr now points to new region
- if (pPrevMTNode == pTrav->pTransitions)
- pTrav->pTransitions = pNewNode;
+ if (pPrevMTNode == pTrav->pRegions)
+ pTrav->pRegions = pNewNode;
else
pPrevMTNode->pNext = pNewNode;
}
+ // New region is overlaying old region so make sure states match
+ if (pMTNode->transition.memory.newState != pNewNode->transition.memory.oldState) {
+ char str[1024];
+ sprintf(str, "Setting Memory state transition for mem %p, current newState of %s doesn't match overlapping transition oldState of %s", mem, string_XGL_MEMORY_STATE(pMTNode->transition.memory.newState), string_XGL_MEMORY_STATE(pNewNode->transition.memory.oldState));
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_STATE, "MEM", str);
+ }
// Start point insertion complete, find end point
XGL_GPU_SIZE newEndPoint = pTransition->offset + pTransition->regionSize;
XGL_GPU_SIZE curEndPoint = pMTNode->transition.memory.offset + pMTNode->transition.memory.regionSize;
@@ -316,6 +325,11 @@ static void setMemTransition(const XGL_GPU_MEMORY mem, const XGL_MEMORY_STATE_TR
pMTNode = pMTNode->pNext;
// TODO : Handle NULL pMTNode case
curEndPoint = pMTNode->transition.memory.offset + pMTNode->transition.memory.regionSize;
+ if (pMTNode->transition.memory.newState != pNewNode->transition.memory.oldState) {
+ char str[1024];
+ sprintf(str, "Setting Memory state transition for mem %p, current newState of %s doesn't match overlapping transition oldState of %s", mem, string_XGL_MEMORY_STATE(pMTNode->transition.memory.newState), string_XGL_MEMORY_STATE(pNewNode->transition.memory.oldState));
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_STATE, "MEM", str);
+ }
}
if (newEndPoint < curEndPoint) {
// split end region
@@ -329,8 +343,11 @@ static void setMemTransition(const XGL_GPU_MEMORY mem, const XGL_MEMORY_STATE_TR
pFreeMe = pMTNode;
}
// Free any regions that are no longer needed
- if ((1 == saveStartNode) && (NULL != pFreeMe))
+ if ((1 == saveStartNode) && (NULL != pFreeMe)) {
pFreeMe = pFreeMe->pNext;
+ numToFree--;
+ }
+ pTrav->numRegions -= numToFree;
MEM_STATE_TRANSITION_NODE* pNodeToFree;
while (numToFree) {
pNodeToFree = pFreeMe;
@@ -369,6 +386,7 @@ static void insertGlobalMemObj(const XGL_GPU_MEMORY mem, const XGL_MEMORY_ALLOC_
if (pAllocInfo) { // TODO : How to handle Wsi-created alloc?
// Create initial state node that covers entire allocation
// TODO : How to handle image memory?
+ pTrav->numRegions = 0; // This will be updated during setMemTransition call
XGL_MEMORY_STATE_TRANSITION initMemStateTrans;
memset(&initMemStateTrans, 0, sizeof(XGL_MEMORY_STATE_TRANSITION));
initMemStateTrans.sType = XGL_STRUCTURE_TYPE_MEMORY_STATE_TRANSITION;
@@ -538,7 +556,7 @@ static void deleteGlobalMemNode(XGL_GPU_MEMORY mem)
if (pGlobalMemObjHead == pTrav)
pGlobalMemObjHead = pTrav->pNextGlobalNode;
// delete transition list off of this node
- MEM_STATE_TRANSITION_NODE* pMSTNode = pTrav->pTransitions;
+ MEM_STATE_TRANSITION_NODE* pMSTNode = pTrav->pRegions;
MEM_STATE_TRANSITION_NODE* pPrevMSTNode = pMSTNode;
while(pMSTNode) {
pPrevMSTNode = pMSTNode;
@@ -744,8 +762,11 @@ static XGL_BOOL updateObjectBinding(XGL_OBJECT object, XGL_GPU_MEMORY mem)
XGL_MEMORY_STATE_TRANSITION initMemStateTrans;
memset(&initMemStateTrans, 0, sizeof(XGL_MEMORY_STATE_TRANSITION));
initMemStateTrans.mem = mem;
- initMemStateTrans.oldState = XGL_IMAGE_STATE_UNINITIALIZED_TARGET;
- initMemStateTrans.newState = XGL_IMAGE_STATE_UNINITIALIZED_TARGET;
+ //initMemStateTrans.oldState = XGL_IMAGE_STATE_UNINITIALIZED_TARGET;
+ //initMemStateTrans.newState = XGL_IMAGE_STATE_UNINITIALIZED_TARGET;
+ // TODO : For now just using initial memory state
+ initMemStateTrans.oldState = XGL_MEMORY_STATE_DATA_TRANSFER;
+ initMemStateTrans.newState = XGL_MEMORY_STATE_DATA_TRANSFER;
initMemStateTrans.offset = 0;
initMemStateTrans.regionSize = pTrav->allocInfo.allocationSize;
setMemTransition(mem, &initMemStateTrans);
@@ -857,6 +878,20 @@ static void printMemList()
pCBTrav = pCBTrav->pNext;
}
}
+ MEM_STATE_TRANSITION_NODE* pTrans = pTrav->pRegions;
+ if (!pTrans) {
+ sprintf(str, " No regions");
+ layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
+ }
+ else {
+ sprintf(str, " XGL_MEMORY_STATE_TRANSITION (MST) regions list w/ HEAD at %p:", pTrans);
+ layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
+ while (pTrans) {
+ sprintf(str, " MST_NODE(%p):\n%s", pTrans, xgl_print_xgl_memory_state_transition(&pTrans->transition.memory, "{MEM}INFO : "));
+ layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
+ pTrans = pTrans->pNext;
+ }
+ }
pTrav = pTrav->pNextGlobalNode;
}
}
diff --git a/layers/mem_tracker.h b/layers/mem_tracker.h
index 7196b9db..61951a96 100644
--- a/layers/mem_tracker.h
+++ b/layers/mem_tracker.h
@@ -40,7 +40,7 @@ typedef enum _MEM_TRACK_ERROR
MEMTRACK_MEMORY_BINDING_ERROR = 12, // Error during one of many calls that bind memory to object or CB
MEMTRACK_OUT_OF_MEMORY_ERROR = 13, // malloc failed
MEMTRACK_MEMORY_LEAK = 14, // Failure to call xglFreeMemory on Mem Obj prior to DestroyDevice
- MEMTRACK_INVALID_STATE = 15, // Failure to call xglFreeMemory on Mem Obj prior to DestroyDevice
+ MEMTRACK_INVALID_STATE = 15, // Memory not in the correct state
} MEM_TRACK_ERROR;
/*
@@ -94,8 +94,7 @@ struct GLOBAL_MEM_OBJ_NODE;
// Store a linked-list of transition nodes to account for different states across a single mem obj
typedef struct _MEM_STATE_TRANSITION_NODE {
struct _MEM_STATE_TRANSITION_NODE* pNext;
- uint32_t numRegions; // Allocation may be broken into various regions
- uint32_t isMem; // 1 for memory, 0 for image
+ //uint32_t isMem; // 1 for memory, 0 for image
union {
XGL_MEMORY_STATE_TRANSITION memory;
XGL_IMAGE_STATE_TRANSITION image; // use when img attached to this mem obj
@@ -110,7 +109,8 @@ typedef struct _GLOBAL_MEM_OBJ_NODE {
XGL_UINT refCount; // Count of references (obj bindings or CB use)
XGL_GPU_MEMORY mem;
XGL_MEMORY_ALLOC_INFO allocInfo;
- MEM_STATE_TRANSITION_NODE* pTransitions; // LL of transitions for this Mem Obj
+ uint32_t numRegions; // Allocation may be broken into various regions
+ MEM_STATE_TRANSITION_NODE* pRegions; // LL of transitions for this Mem Obj
} GLOBAL_MEM_OBJ_NODE;
typedef struct _GLOBAL_OBJECT_NODE {