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")]),