Updated header file to version 67 (xglResetFences)
Added changes to fence semantics for this revision.
tests: Create contructor with no args
intel: Added Tony's patch for ResetFences support in the ICD.
v2: reset fence in intel_fence_seq_seqno(). We need the reset to make
xglQueueWaitIdle() work (olv)
layers: Added ResetFences support to MemTracker
Add new entrypoint and fence semantics for fence status flags.
layers: Completed changed fence semantics for MemTracker
Completed the changes for xgl header revision 67, adding resetFences.
layers: Changes to support xglResetFences
v2: squashed into one commit (olv)
diff --git a/include/xgl.h b/include/xgl.h
index 5857b42..92fb1cc 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, 65, 0)
+#define XGL_API_VERSION XGL_MAKE_VERSION(0, 67, 0)
#ifdef __cplusplus
extern "C"
@@ -1220,6 +1220,13 @@
XGL_MAX_ENUM(_XGL_PIPELINE_CREATE_FLAGS)
} XGL_PIPELINE_CREATE_FLAGS;
+// Fence creation flags
+typedef enum _XGL_FENCE_CREATE_FLAGS
+{
+ XGL_FENCE_CREATE_SIGNALED_BIT = 0x00000001,
+ XGL_MAX_ENUM(_XGL_FENCE_CREATE_FLAGS)
+} XGL_FENCE_CREATE_FLAGS;
+
// Semaphore creation flags
typedef enum _XGL_SEMAPHORE_CREATE_FLAGS
{
@@ -1877,8 +1884,7 @@
const void* pNext; // Pointer to next structure
XGL_PIPELINE_SHADER cs;
XGL_FLAGS flags; // XGL_PIPELINE_CREATE_FLAGS
- XGL_DESCRIPTOR_SET_LAYOUT_CHAIN setLayoutChain;
- // For local size fields zero is treated an invalid value
+ XGL_DESCRIPTOR_SET_LAYOUT_CHAIN setLayoutChain; // For local size fields zero is treated an invalid value
uint32_t localSizeX;
uint32_t localSizeY;
uint32_t localSizeZ;
@@ -2164,7 +2170,7 @@
{
XGL_STRUCTURE_TYPE sType; // Must be XGL_STRUCTURE_TYPE_FENCE_CREATE_INFO
const void* pNext; // Pointer to next structure
- XGL_FLAGS flags; // Reserved
+ XGL_FENCE_CREATE_FLAGS flags; // XGL_FENCE_CREATE_FLAGS
} XGL_FENCE_CREATE_INFO;
typedef struct _XGL_SEMAPHORE_CREATE_INFO
@@ -2278,6 +2284,7 @@
typedef XGL_RESULT (XGLAPI *xglBindObjectMemoryRangeType)(XGL_OBJECT object, uint32_t allocationIdx, XGL_GPU_SIZE rangeOffset,XGL_GPU_SIZE rangeSize, XGL_GPU_MEMORY mem, XGL_GPU_SIZE memOffset);
typedef XGL_RESULT (XGLAPI *xglBindImageMemoryRangeType)(XGL_IMAGE image, uint32_t allocationIdx, const XGL_IMAGE_MEMORY_BIND_INFO* bindInfo, XGL_GPU_MEMORY mem, XGL_GPU_SIZE memOffset);
typedef XGL_RESULT (XGLAPI *xglCreateFenceType)(XGL_DEVICE device, const XGL_FENCE_CREATE_INFO* pCreateInfo, XGL_FENCE* pFence);
+typedef XGL_RESULT (XGLAPI *xglResetFencesType)(XGL_DEVICE device, uint32_t fenceCount, XGL_FENCE* pFences);
typedef XGL_RESULT (XGLAPI *xglGetFenceStatusType)(XGL_FENCE fence);
typedef XGL_RESULT (XGLAPI *xglWaitForFencesType)(XGL_DEVICE device, uint32_t fenceCount, const XGL_FENCE* pFences, bool32_t waitAll, uint64_t timeout);
typedef XGL_RESULT (XGLAPI *xglCreateSemaphoreType)(XGL_DEVICE device, const XGL_SEMAPHORE_CREATE_INFO* pCreateInfo, XGL_SEMAPHORE* pSemaphore);
@@ -2537,6 +2544,11 @@
const XGL_FENCE_CREATE_INFO* pCreateInfo,
XGL_FENCE* pFence);
+XGL_RESULT XGLAPI xglResetFences(
+ XGL_DEVICE device,
+ uint32_t fenceCount,
+ XGL_FENCE* pFences);
+
XGL_RESULT XGLAPI xglGetFenceStatus(
XGL_FENCE fence);
diff --git a/include/xglLayer.h b/include/xglLayer.h
index 897fe90..c3d63a6 100644
--- a/include/xglLayer.h
+++ b/include/xglLayer.h
@@ -60,6 +60,7 @@
xglBindImageMemoryRangeType BindImageMemoryRange;
xglCreateFenceType CreateFence;
xglGetFenceStatusType GetFenceStatus;
+ xglResetFencesType ResetFences;
xglWaitForFencesType WaitForFences;
xglCreateSemaphoreType CreateSemaphore;
xglQueueSignalSemaphoreType QueueSignalSemaphore;
diff --git a/layers/mem_tracker.cpp b/layers/mem_tracker.cpp
index 83cff67..a6bc088 100644
--- a/layers/mem_tracker.cpp
+++ b/layers/mem_tracker.cpp
@@ -97,6 +97,32 @@
return pCBInfo;
}
+// Return object info for 'object' or return NULL if no info exists
+static MT_OBJ_INFO* getObjectInfo(const XGL_OBJECT object)
+{
+ MT_OBJ_INFO* pObjInfo = NULL;
+
+ if (objectMap.find(object) != objectMap.end()) {
+ pObjInfo = objectMap[object];
+ }
+ return pObjInfo;
+}
+
+static MT_OBJ_INFO* addObjectInfo(XGL_OBJECT object, XGL_STRUCTURE_TYPE sType, const void *pCreateInfo, const int struct_size, const char *name_prefix)
+{
+ MT_OBJ_INFO* pInfo = new MT_OBJ_INFO;
+ memset(pInfo, 0, sizeof(MT_OBJ_INFO));
+ memcpy(&pInfo->create_info, pCreateInfo, struct_size);
+ sprintf(pInfo->object_name, "%s_%p", name_prefix, object);
+
+ pInfo->object = object;
+ pInfo->ref_count = 1;
+ pInfo->sType = sType;
+ objectMap[object] = pInfo;
+
+ return pInfo;
+}
+
// Add a fence, creating one if necessary to our list of fences/fenceIds
static uint64_t addFenceInfo(XGL_FENCE fence, XGL_QUEUE queue)
{
@@ -110,8 +136,9 @@
XGL_FENCE_CREATE_INFO fci;
fci.sType = XGL_STRUCTURE_TYPE_FENCE_CREATE_INFO;
fci.pNext = NULL;
- fci.flags = 0;
+ fci.flags = static_cast<XGL_FENCE_CREATE_FLAGS>(0);
nextTable.CreateFence(globalDevice, &fci, &pFenceInfo->fence);
+ addObjectInfo(pFenceInfo->fence, fci.sType, &fci, sizeof(XGL_FENCE_CREATE_INFO), "internalFence");
pFenceInfo->localFence = XGL_TRUE;
} else {
pFenceInfo->localFence = XGL_FALSE;
@@ -159,6 +186,11 @@
} else {
deleteFenceInfo((*ii).first);
}
+ // Update fence state in fenceCreateInfo structure
+ MT_OBJ_INFO* pObjectInfo = getObjectInfo(fence);
+ if (pObjectInfo != NULL) {
+ pObjectInfo->create_info.fence_create_info.flags = XGL_FENCE_CREATE_SIGNALED_BIT;
+ }
}
}
}
@@ -241,8 +273,8 @@
MT_QUEUE_INFO *pQueueInfo = queueMap[queue];
for (it = pQueueInfo->pMemRefList.begin(); it != pQueueInfo->pMemRefList.end(); ++it) {
if ((*it) == mem) {
- result = XGL_TRUE;
- break;
+ result = XGL_TRUE;
+ break;
}
}
return result;
@@ -261,7 +293,7 @@
char str[1024];
sprintf(str, "Unknown Queue %p specified in xglQueueSubmit", queue);
layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, queue, 0, MEMTRACK_INVALID_QUEUE, "MEM", str);
- }
+ }
else {
// Iterate through all CBs in pCmdBuffers
for (uint32_t i = 0; i < cmdBufferCount; i++) {
@@ -549,32 +581,6 @@
return result;
}
-// Return object info for 'object' or return NULL if no info exists
-static MT_OBJ_INFO* getObjectInfo(const XGL_OBJECT object)
-{
- MT_OBJ_INFO* pObjInfo = NULL;
-
- if (objectMap.find(object) != objectMap.end()) {
- pObjInfo = objectMap[object];
- }
- return pObjInfo;
-}
-
-static MT_OBJ_INFO* addObjectInfo(XGL_OBJECT object, XGL_STRUCTURE_TYPE sType, const void *pCreateInfo, const int struct_size, const char *name_prefix)
-{
- MT_OBJ_INFO* pInfo = new MT_OBJ_INFO;
- memset(pInfo, 0, sizeof(MT_OBJ_INFO));
- memcpy(&pInfo->create_info, pCreateInfo, struct_size);
- sprintf(pInfo->object_name, "%s_%p", name_prefix, object);
-
- pInfo->object = object;
- pInfo->ref_count = 1;
- pInfo->sType = sType;
- objectMap[object] = pInfo;
-
- return pInfo;
-}
-
// Remove object binding performs 3 tasks:
// 1. Remove ObjectInfo from MemObjInfo list container of obj bindings & free it
// 2. Decrement refCount for MemObjInfo
@@ -903,10 +909,10 @@
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 {
if (checkMemRef(queue, mem) == XGL_TRUE) {
- // Alread in list, just warn
+ // Alread in list, just warn
char str[1024];
sprintf(str, "Request to add a memory reference (%p) to Queue %p -- ref is already present in the queue's reference list", mem, queue);
layerCbMsg(XGL_DBG_MSG_WARNING, XGL_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_MEM_REF, "MEM", str);
@@ -927,13 +933,13 @@
XGL_RESULT result = nextTable.QueueRemoveMemReference(queue, mem);
if (result == XGL_SUCCESS) {
loader_platform_thread_lock_mutex(&globalLock);
-
+
MT_QUEUE_INFO *pQueueInfo = queueMap[queue];
if (pQueueInfo == 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 {
for (list<XGL_GPU_MEMORY>::iterator it = pQueueInfo->pMemRefList.begin(); it != pQueueInfo->pMemRefList.end(); ++it) {
if ((*it) == mem) {
@@ -1137,6 +1143,24 @@
return result;
}
+XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglResetFences(XGL_DEVICE device, uint32_t fenceCount, XGL_FENCE* pFences)
+{
+ XGL_RESULT result = nextTable.ResetFences(device, fenceCount, pFences);
+ if (XGL_SUCCESS == result) {
+ loader_platform_thread_lock_mutex(&globalLock);
+ // Reset fence state in fenceCreateInfo structure
+ for (uint32_t i = 0; i < fenceCount; i++) {
+ MT_OBJ_INFO* pObjectInfo = getObjectInfo(pFences[i]);
+ if (pObjectInfo != NULL) {
+ pObjectInfo->create_info.fence_create_info.flags =
+ static_cast<XGL_FENCE_CREATE_FLAGS>(pObjectInfo->create_info.fence_create_info.flags & ~XGL_FENCE_CREATE_SIGNALED_BIT);
+ }
+ }
+ loader_platform_thread_unlock_mutex(&globalLock);
+ }
+ return result;
+}
+
XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglGetFenceStatus(XGL_FENCE fence)
{
XGL_RESULT result = nextTable.GetFenceStatus(fence);
@@ -1150,6 +1174,18 @@
XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglWaitForFences(XGL_DEVICE device, uint32_t fenceCount, const XGL_FENCE* pFences, bool32_t waitAll, uint64_t timeout)
{
+ // Verify fence status of submitted fences
+ for(uint32_t i = 0; i < fenceCount; i++) {
+ MT_OBJ_INFO* pObjectInfo = getObjectInfo(pFences[i]);
+ if (pObjectInfo != NULL) {
+ if (pObjectInfo->create_info.fence_create_info.flags == XGL_FENCE_CREATE_SIGNALED_BIT) {
+ char str[1024];
+ sprintf(str, "xglWaitForFences specified signaled-state Fence %p. Fences must be reset before being submitted", pFences[i]);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, pFences[i], 0, MEMTRACK_INVALID_FENCE_STATE, "MEM", str);
+ }
+ }
+ }
+
XGL_RESULT result = nextTable.WaitForFences(device, fenceCount, pFences, waitAll, timeout);
loader_platform_thread_lock_mutex(&globalLock);
@@ -1896,6 +1932,8 @@
return (void*) xglCreateFence;
if (!strcmp(funcName, "xglGetFenceStatus"))
return (void*) xglGetFenceStatus;
+ if (!strcmp(funcName, "xglResetFences"))
+ return (void*) xglResetFences;
if (!strcmp(funcName, "xglWaitForFences"))
return (void*) xglWaitForFences;
if (!strcmp(funcName, "xglQueueWaitIdle"))
diff --git a/layers/mem_tracker.h b/layers/mem_tracker.h
index 91cc434..2548036 100644
--- a/layers/mem_tracker.h
+++ b/layers/mem_tracker.h
@@ -49,6 +49,7 @@
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, // Invalid queue requested or selected
+ MEMTRACK_INVALID_FENCE_STATE = 18, // Invalid Fence State signaled or used
} MEM_TRACK_ERROR;
/*
diff --git a/layers/param_checker.cpp b/layers/param_checker.cpp
index b7b15ac..6da0f0c 100644
--- a/layers/param_checker.cpp
+++ b/layers/param_checker.cpp
@@ -519,6 +519,13 @@
return result;
}
+XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglResetFences(XGL_DEVICE device, uint32_t fenceCount, XGL_FENCE* pFences)
+{
+
+ XGL_RESULT result = nextTable.ResetFences(device, fenceCount, pFences);
+ return result;
+}
+
XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateSemaphore(XGL_DEVICE device, const XGL_SEMAPHORE_CREATE_INFO* pCreateInfo, XGL_SEMAPHORE* pSemaphore)
{
char str[1024];
diff --git a/tests/xglrenderframework.cpp b/tests/xglrenderframework.cpp
index 5c02fdd..e07a7b5 100644
--- a/tests/xglrenderframework.cpp
+++ b/tests/xglrenderframework.cpp
@@ -797,7 +797,7 @@
if (!m_commandBuffer)
{
- m_fence.init(*m_device, xgl_testing::Fence::create_info(0));
+ m_fence.init(*m_device, xgl_testing::Fence::create_info());
m_commandBuffer = new XglCommandBufferObj(m_device);
}
diff --git a/tests/xgltestbinding.h b/tests/xgltestbinding.h
index ae3fbba..387bde3 100644
--- a/tests/xgltestbinding.h
+++ b/tests/xgltestbinding.h
@@ -312,7 +312,8 @@
// xglGetFenceStatus()
XGL_RESULT status() const { return xglGetFenceStatus(obj()); }
- static XGL_FENCE_CREATE_INFO create_info(XGL_FLAGS flags);
+ static XGL_FENCE_CREATE_INFO create_info(XGL_FENCE_CREATE_FLAGS flags);
+ static XGL_FENCE_CREATE_INFO create_info();
};
class Semaphore : public DerivedObject<XGL_SEMAPHORE, Object> {
@@ -641,7 +642,7 @@
return info;
}
-inline XGL_FENCE_CREATE_INFO Fence::create_info(XGL_FLAGS flags)
+inline XGL_FENCE_CREATE_INFO Fence::create_info(XGL_FENCE_CREATE_FLAGS flags)
{
XGL_FENCE_CREATE_INFO info = {};
info.sType = XGL_STRUCTURE_TYPE_FENCE_CREATE_INFO;
@@ -649,6 +650,13 @@
return info;
}
+inline XGL_FENCE_CREATE_INFO Fence::create_info()
+{
+ XGL_FENCE_CREATE_INFO info = {};
+ info.sType = XGL_STRUCTURE_TYPE_FENCE_CREATE_INFO;
+ return info;
+}
+
inline XGL_SEMAPHORE_CREATE_INFO Semaphore::create_info(uint32_t init_count, XGL_FLAGS flags)
{
XGL_SEMAPHORE_CREATE_INFO info = {};
diff --git a/xgl.py b/xgl.py
index 70e3c00..1b372f0 100644
--- a/xgl.py
+++ b/xgl.py
@@ -374,6 +374,11 @@
Param("const XGL_FENCE_CREATE_INFO*", "pCreateInfo"),
Param("XGL_FENCE*", "pFence")]),
+ Proto("XGL_RESULT", "ResetFences",
+ [Param("XGL_DEVICE", "device"),
+ Param("uint32_t", "fenceCount"),
+ Param("XGL_FENCE*", "pFences")]),
+
Proto("XGL_RESULT", "GetFenceStatus",
[Param("XGL_FENCE", "fence")]),