From 10bafe36f6fe2d860b6b9a50754d3f2241dbf72c Mon Sep 17 00:00:00 2001 From: Courtney Goeltzenleuchter Date: Thu, 2 Apr 2015 13:39:07 -0600 Subject: xgl: Add QueueMemReference functions --- icd/nulldrv/nulldrv.c | 16 ++++++ include/xgl.h | 12 +++- include/xglLayer.h | 2 + layers/mem_tracker.cpp | 149 ++++++++++++++++++++++++++++++++++++++++++++++--- layers/mem_tracker.h | 9 +++ xgl-layer-generate.py | 2 +- xgl.py | 8 +++ 7 files changed, 187 insertions(+), 11 deletions(-) diff --git a/icd/nulldrv/nulldrv.c b/icd/nulldrv/nulldrv.c index 49439222..84e3197c 100644 --- a/icd/nulldrv/nulldrv.c +++ b/icd/nulldrv/nulldrv.c @@ -1727,6 +1727,22 @@ ICD_EXPORT XGL_RESULT XGLAPI xglQueueSetGlobalMemReferences( return XGL_SUCCESS; } +ICD_EXPORT XGL_RESULT XGLAPI xglQueueAddMemReference( + XGL_QUEUE queue, + XGL_GPU_MEMORY mem) +{ + NULLDRV_LOG_FUNC; + return XGL_SUCCESS; +} + +ICD_EXPORT XGL_RESULT XGLAPI xglQueueRemoveMemReference( + XGL_QUEUE queue, + XGL_GPU_MEMORY mem) +{ + NULLDRV_LOG_FUNC; + return XGL_SUCCESS; +} + ICD_EXPORT XGL_RESULT XGLAPI xglQueueWaitIdle( XGL_QUEUE queue_) { diff --git a/include/xgl.h b/include/xgl.h index bae9c3fb..05c2d2c7 100644 --- a/include/xgl.h +++ b/include/xgl.h @@ -33,7 +33,7 @@ #include "xglPlatform.h" // XGL API version supported by this file -#define XGL_API_VERSION XGL_MAKE_VERSION(0, 64, 0) +#define XGL_API_VERSION XGL_MAKE_VERSION(0, 65, 0) #ifdef __cplusplus extern "C" @@ -2271,6 +2271,8 @@ typedef XGL_RESULT (XGLAPI *xglEnumerateLayersType)(XGL_PHYSICAL_GPU gpu, size_t typedef XGL_RESULT (XGLAPI *xglGetDeviceQueueType)(XGL_DEVICE device, uint32_t queueNodeIndex, uint32_t queueIndex, XGL_QUEUE* pQueue); typedef XGL_RESULT (XGLAPI *xglQueueSubmitType)(XGL_QUEUE queue, uint32_t cmdBufferCount, const XGL_CMD_BUFFER* pCmdBuffers, uint32_t memRefCount, const XGL_MEMORY_REF* pMemRefs, XGL_FENCE fence); typedef XGL_RESULT (XGLAPI *xglQueueSetGlobalMemReferencesType)(XGL_QUEUE queue, uint32_t memRefCount, const XGL_MEMORY_REF* pMemRefs); +typedef XGL_RESULT (XGLAPI *xglQueueAddMemReferenceType)(XGL_QUEUE queue, XGL_GPU_MEMORY mem); +typedef XGL_RESULT (XGLAPI *xglQueueRemoveMemReferenceType)(XGL_QUEUE queue, XGL_GPU_MEMORY mem); typedef XGL_RESULT (XGLAPI *xglQueueWaitIdleType)(XGL_QUEUE queue); typedef XGL_RESULT (XGLAPI *xglDeviceWaitIdleType)(XGL_DEVICE device); typedef XGL_RESULT (XGLAPI *xglAllocMemoryType)(XGL_DEVICE device, const XGL_MEMORY_ALLOC_INFO* pAllocInfo, XGL_GPU_MEMORY* pMem); @@ -2447,6 +2449,14 @@ XGL_RESULT XGLAPI xglQueueSetGlobalMemReferences( uint32_t memRefCount, const XGL_MEMORY_REF* pMemRefs); +XGL_RESULT XGLAPI xglQueueAddMemReference( + XGL_QUEUE queue, + XGL_GPU_MEMORY mem); + +XGL_RESULT XGLAPI xglQueueRemoveMemReference( + XGL_QUEUE queue, + XGL_GPU_MEMORY mem); + XGL_RESULT XGLAPI xglQueueWaitIdle( XGL_QUEUE queue); diff --git a/include/xglLayer.h b/include/xglLayer.h index 6111bcb9..e569aa9f 100644 --- a/include/xglLayer.h +++ b/include/xglLayer.h @@ -39,6 +39,8 @@ typedef struct _XGL_LAYER_DISPATCH_TABLE xglGetDeviceQueueType GetDeviceQueue; xglQueueSubmitType QueueSubmit; xglQueueSetGlobalMemReferencesType QueueSetGlobalMemReferences; + xglQueueAddMemReferenceType QueueAddMemReference; + xglQueueRemoveMemReferenceType QueueRemoveMemReference; xglQueueWaitIdleType QueueWaitIdle; xglDeviceWaitIdleType DeviceWaitIdle; xglAllocMemoryType AllocMemory; diff --git a/layers/mem_tracker.cpp b/layers/mem_tracker.cpp index 6bd2b77b..38a4ff12 100644 --- a/layers/mem_tracker.cpp +++ b/layers/mem_tracker.cpp @@ -97,6 +97,70 @@ static MT_CB_INFO* getCBInfo(const XGL_CMD_BUFFER cb) return pCBInfo; } +// Add new Queue node for this cb at end of global CB LL +static void insertGlobalQueue(const XGL_QUEUE queue) +{ +#if 0 // TODO: Add tracking of Queue's + MT_QUEUE_NODE* pTrav = pGlobalQueueHead; + if (!pTrav) { + pTrav = (MT_QUEUE_NODE*)malloc(sizeof(MT_QUEUE_NODE)); + pGlobalQueueHead = pTrav; + } + else { + while (NULL != pTrav->pNextGlobalQueueNode) + pTrav = pTrav->pNextGlobalQueueNode; + pTrav->pNextGlobalQueueNode = (MT_QUEUE_NODE*)malloc(sizeof(MT_QUEUE_NODE)); + pTrav = pTrav->pNextGlobalQueueNode; + } + if (!pTrav) { + char str[1024]; + sprintf(str, "Malloc failed to alloc node for Queue %p", (void*)queue); + layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, queue, 0, MEMTRACK_OUT_OF_MEMORY_ERROR, "MEM", str); + } + else { + numQueueNodes++; + memset(pTrav, 0, sizeof(MT_QUEUE_NODE)); + pTrav->queue = queue; + } +#endif +} + +// Return ptr to node in global LL containing cb, or NULL if not found +static MT_QUEUE_NODE* getGlobalQueueNode(const XGL_QUEUE queue) +{ +#if 0 + MT_QUEUE_NODE* pTrav = pGlobalQueueHead; + while (pTrav && (pTrav->queue != queue)) { + pTrav = pTrav->pNextGlobalQueueNode; + } + return pTrav; +#endif +} + +static void insertQueueMemRef(MT_QUEUE_NODE *pQueueNode, XGL_GPU_MEMORY mem) +{ +#if 0 + if (pQueueNode->numMemRefs >= pQueueNode->refListSize) { + pQueueNode->refListSize += 16; + pQueueNode->pMemRefList = realloc(pQueueNode->pMemRefList, pQueueNode->refListSize); + } + pQueueNode->pMemRefList[pQueueNode->numMemRefs++] = mem; +#endif +} + +static void removeQueueMemRef(MT_QUEUE_NODE *pQueueNode, XGL_GPU_MEMORY mem) +{ + uint32_t idx; + + for (idx = 0; idx < pQueueNode->numMemRefs; idx++) { + if (pQueueNode->pMemRefList[idx] == mem) { + pQueueNode->numMemRefs--; + memcpy(&pQueueNode->pMemRefList[idx], pQueueNode->pMemRefList[idx+1], + pQueueNode->numMemRefs * sizeof(XGL_GPU_MEMORY)); + } + } +} + // Add a fence, creating one if necessary to our list of fences/fenceIds static uint64_t addFenceInfo(XGL_FENCE fence, XGL_QUEUE queue) { @@ -859,13 +923,6 @@ XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglEnumerateLayers(XGL_PHYSICAL_GPU gpu, size } } -XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglGetDeviceQueue(XGL_DEVICE device, uint32_t queueNodeIndex, uint32_t queueIndex, XGL_QUEUE* pQueue) -{ - XGL_RESULT result = nextTable.GetDeviceQueue(device, queueNodeIndex, queueIndex, pQueue); - addQueueInfo(*pQueue); - return result; -} - XGL_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) { @@ -901,6 +958,76 @@ XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglQueueSetGlobalMemReferences(XGL_QUEUE queu return result; } +XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglGetDeviceQueue( + XGL_DEVICE device, + uint32_t queueNodeIndex, + uint32_t queueIndex, + XGL_QUEUE* pQueue) +{ + XGL_RESULT result = nextTable.GetDeviceQueue(device, queueNodeIndex, queueIndex, pQueue); + if (result == XGL_SUCCESS) { + loader_platform_thread_lock_mutex(&globalLock); + MT_QUEUE_NODE *pQueueNode = getGlobalQueueNode(*pQueue); + if (pQueueNode == NULL) { + addQueueInfo(*pQueue); + insertGlobalQueue(*pQueue); + } + loader_platform_thread_unlock_mutex(&globalLock); + } + return result; +} + +XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglQueueAddMemReference(XGL_QUEUE queue, XGL_GPU_MEMORY mem) +{ + XGL_RESULT result = nextTable.QueueAddMemReference(queue, mem); + if (result == XGL_SUCCESS) { + loader_platform_thread_lock_mutex(&globalLock); + MT_QUEUE_NODE *pQueueNode = getGlobalQueueNode(queue); + if (pQueueNode == NULL) { + char str[1024]; + sprintf(str, "Unknown Queue %p", queue); + layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, queue, 0, MEMTRACK_INVALID_QUEUE, "MEM", str); + } else { + MT_MEM_OBJ_INFO *pMem = getMemObjInfo(mem); + if (pMem == NULL) { + char str[1024]; + sprintf(str, "Unknown GPU Memory Object %p", mem); + layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str); + } else { + insertQueueMemRef(pQueueNode, mem); + } + } + loader_platform_thread_unlock_mutex(&globalLock); + } + return result; +} + +XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglQueueRemoveMemReference(XGL_QUEUE queue, XGL_GPU_MEMORY mem) +{ + // TODO : Decrement ref count for this memory reference on this queue. Remove if ref count is zero. + XGL_RESULT result = nextTable.QueueRemoveMemReference(queue, mem); + if (result == XGL_SUCCESS) { + loader_platform_thread_lock_mutex(&globalLock); + MT_QUEUE_NODE *pQueueNode = getGlobalQueueNode(queue); + if (pQueueNode == NULL) { + char str[1024]; + sprintf(str, "Unknown Queue %p", queue); + layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, queue, 0, MEMTRACK_INVALID_QUEUE, "MEM", str); + } else { + MT_MEM_OBJ_INFO *pMem = getMemObjInfo(mem); + if (pMem == NULL) { + char str[1024]; + sprintf(str, "Unknown GPU Memory Object %p", mem); + layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str); + } else { + removeQueueMemRef(pQueueNode, mem); + } + } + loader_platform_thread_unlock_mutex(&globalLock); + } + return result; +} + XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglAllocMemory(XGL_DEVICE device, const XGL_MEMORY_ALLOC_INFO* pAllocInfo, XGL_GPU_MEMORY* pMem) { XGL_RESULT result = nextTable.AllocMemory(device, pAllocInfo, pMem); @@ -1797,6 +1924,12 @@ XGL_LAYER_EXPORT void* XGLAPI xglGetProcAddr(XGL_PHYSICAL_GPU gpu, const char* f return (void*) xglQueueSubmit; if (!strcmp(funcName, "xglQueueSetGlobalMemReferences")) return (void*) xglQueueSetGlobalMemReferences; + if (!strcmp(funcName, "xglGetDeviceQueue")) + return (void*) xglGetDeviceQueue; + if (!strcmp(funcName, "xglQueueAddMemReference")) + return (void*) xglQueueAddMemReference; + if (!strcmp(funcName, "xglQueueRemoveMemReference")) + return (void*) xglQueueRemoveMemReference; if (!strcmp(funcName, "xglAllocMemory")) return (void*) xglAllocMemory; if (!strcmp(funcName, "xglFreeMemory")) @@ -1919,8 +2052,6 @@ XGL_LAYER_EXPORT void* XGLAPI xglGetProcAddr(XGL_PHYSICAL_GPU gpu, const char* f return (void*) xglDbgRegisterMsgCallback; if (!strcmp(funcName, "xglDbgUnregisterMsgCallback")) return (void*) xglDbgUnregisterMsgCallback; - if (!strcmp(funcName, "xglGetDeviceQueue")) - return (void*) xglGetDeviceQueue; #if !defined(WIN32) if (!strcmp(funcName, "xglWsiX11CreatePresentableImage")) return (void*) xglWsiX11CreatePresentableImage; diff --git a/layers/mem_tracker.h b/layers/mem_tracker.h index eb4deb47..7d23fac7 100644 --- a/layers/mem_tracker.h +++ b/layers/mem_tracker.h @@ -48,6 +48,7 @@ typedef enum _MEM_TRACK_ERROR MEMTRACK_MEMORY_LEAK = 14, // Failure to call xglFreeMemory on Mem Obj prior to DestroyDevice MEMTRACK_INVALID_STATE = 15, // Memory not in the correct state MEMTRACK_RESET_CB_WHILE_IN_FLIGHT = 16, // xglResetCommandBuffer() called on a CB that hasn't completed + MEMTRACK_INVALID_QUEUE = 17, // Unknown Queue object } MEM_TRACK_ERROR; /* @@ -140,6 +141,14 @@ struct MT_QUEUE_INFO { list pQueueCmdBuffers; }; +struct MT_QUEUE_NODE { + struct _MT_QUEUE_NODE* pNextGlobalQueueNode; + XGL_QUEUE queue; + uint32_t numMemRefs; + uint32_t refListSize; + XGL_GPU_MEMORY *pMemRefList; +}; + #ifdef __cplusplus } #endif diff --git a/xgl-layer-generate.py b/xgl-layer-generate.py index afeb55b4..881bd2cb 100755 --- a/xgl-layer-generate.py +++ b/xgl-layer-generate.py @@ -1283,7 +1283,7 @@ class ObjectTrackerSubcommand(Subcommand): destroy_line = '' funcs = [] # Special cases for API funcs that don't use an object as first arg - if True in [no_use_proto in proto.name for no_use_proto in ['GlobalOption', 'CreateInstance', 'QueueSubmit', 'QueueSetGlobalMemReferences', 'QueueWaitIdle', 'CreateDevice', 'GetGpuInfo', 'QueueSignalSemaphore', 'QueueWaitSemaphore', 'WsiX11QueuePresent']]: + if True in [no_use_proto in proto.name for no_use_proto in ['GlobalOption', 'CreateInstance', 'QueueSubmit', 'QueueSetGlobalMemReferences', 'QueueAddMemReference', 'QueueRemoveMemReference', 'QueueWaitIdle', 'CreateDevice', 'GetGpuInfo', 'QueueSignalSemaphore', 'QueueWaitSemaphore', 'WsiX11QueuePresent']]: using_line = '' else: using_line = ' loader_platform_thread_lock_mutex(&objLock);\n' diff --git a/xgl.py b/xgl.py index 02e386a3..6cc463f9 100644 --- a/xgl.py +++ b/xgl.py @@ -280,6 +280,14 @@ core = Extension( Param("uint32_t", "memRefCount"), Param("const XGL_MEMORY_REF*", "pMemRefs")]), + Proto("XGL_RESULT", "QueueAddMemReference", + [Param("XGL_QUEUE", "queue"), + Param("XGL_GPU_MEMORY", "mem")]), + + Proto("XGL_RESULT", "QueueRemoveMemReference", + [Param("XGL_QUEUE", "queue"), + Param("XGL_GPU_MEMORY", "mem")]), + Proto("XGL_RESULT", "QueueWaitIdle", [Param("XGL_QUEUE", "queue")]), -- cgit v1.2.3