xgl: Add QueueMemReference functions
diff --git a/icd/intel/queue.c b/icd/intel/queue.c
index 0bef4e3..354efe7 100644
--- a/icd/intel/queue.c
+++ b/icd/intel/queue.c
@@ -324,7 +324,29 @@
const XGL_MEMORY_REF* pMemRefs)
{
/*
- * The winwys maintains the list of memory references. These are ignored
+ * The winsys maintains the list of memory references. These are ignored
+ * until we move away from the winsys.
+ */
+ return XGL_SUCCESS;
+}
+
+ICD_EXPORT XGL_RESULT XGLAPI xglQueueAddMemReference(
+ XGL_QUEUE queue,
+ XGL_GPU_MEMORY mem)
+{
+ /*
+ * The winsys maintains the list of memory references. These are ignored
+ * until we move away from the winsys.
+ */
+ return XGL_SUCCESS;
+}
+
+ICD_EXPORT XGL_RESULT XGLAPI xglQueueRemoveMemReference(
+ XGL_QUEUE queue,
+ XGL_GPU_MEMORY mem)
+{
+ /*
+ * The winsys maintains the list of memory references. These are ignored
* until we move away from the winsys.
*/
return XGL_SUCCESS;
diff --git a/icd/nulldrv/nulldrv.c b/icd/nulldrv/nulldrv.c
index 4943922..84e3197 100644
--- a/icd/nulldrv/nulldrv.c
+++ b/icd/nulldrv/nulldrv.c
@@ -1727,6 +1727,22 @@
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 bae9c3f..05c2d2c 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 *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 @@
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 6111bcb..e569aa9 100644
--- a/include/xglLayer.h
+++ b/include/xglLayer.h
@@ -39,6 +39,8 @@
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 6bd2b77..38a4ff1 100644
--- a/layers/mem_tracker.cpp
+++ b/layers/mem_tracker.cpp
@@ -97,6 +97,70 @@
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 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 @@
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 @@
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 @@
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 eb4deb4..7d23fac 100644
--- a/layers/mem_tracker.h
+++ b/layers/mem_tracker.h
@@ -48,6 +48,7 @@
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 @@
list<XGL_CMD_BUFFER> 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 afeb55b..881bd2c 100755
--- a/xgl-layer-generate.py
+++ b/xgl-layer-generate.py
@@ -1283,7 +1283,7 @@
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 02e386a..6cc463f 100644
--- a/xgl.py
+++ b/xgl.py
@@ -280,6 +280,14 @@
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")]),