layers:  Validate mem ref counts in queueSubmit call

    Grab and save max from GetGpuInfo, use this to validate count in
    QueueSubmit call, warn if GetGpuInfo wasn't called beforehand.
diff --git a/layers/object_track.h b/layers/object_track.h
index b64e634..0ab7d44 100644
--- a/layers/object_track.h
+++ b/layers/object_track.h
@@ -39,6 +39,8 @@
     OBJTRACK_COLOR_BLEND_NOT_BOUND,             // Draw submitted with no color blend state object bound
     OBJTRACK_DEPTH_STENCIL_NOT_BOUND,           // Draw submitted with no depth-stencil state object bound
     OBJTRACK_GPU_MEM_MAPPED,                    // Mem object ref'd in cmd buff is still mapped
+    OBJTRACK_GETGPUINFO_NOT_CALLED,             // Gpu Information has not been requested before drawing
+    OBJTRACK_MEMREFCOUNT_MAX_EXCEEDED,          // Number of QueueSubmit memory references exceeds GPU maximum
 } OBJECT_TRACK_ERROR;
 
 // Object Status -- used to track state of individual objects
@@ -163,9 +165,11 @@
     uint64_t        numUses;
     OBJECT_STATUS   status;
 } OBJTRACK_NODE;
+
 // prototype for extension functions
 uint64_t objTrackGetObjectCount(XGL_OBJECT_TYPE type);
 XGL_RESULT objTrackGetObjects(XGL_OBJECT_TYPE type, uint64_t objCount, OBJTRACK_NODE* pObjNodeArray);
+
 // Func ptr typedefs
 typedef uint64_t (*OBJ_TRACK_GET_OBJECT_COUNT)(XGL_OBJECT_TYPE);
 typedef XGL_RESULT (*OBJ_TRACK_GET_OBJECTS)(XGL_OBJECT_TYPE, uint64_t, OBJTRACK_NODE*);
diff --git a/xgl-layer-generate.py b/xgl-layer-generate.py
index fd23635..bf17f68 100755
--- a/xgl-layer-generate.py
+++ b/xgl-layer-generate.py
@@ -641,6 +641,7 @@
                     if 'QueueSubmit' in proto.name:
                         using_line += '    set_status((void*)fence, XGL_OBJECT_TYPE_FENCE, OBJSTATUS_FENCE_IS_SUBMITTED);\n'
                         using_line += '    validate_memory_mapping_status(pMemRefs, memRefCount);\n'
+                        using_line += '    validate_mem_ref_count(memRefCount);\n'
                     elif 'GetFenceStatus' in proto.name:
                         using_line += '    // Warn if submitted_flag is not set\n'
                         using_line += '    validate_status((void*)fence, XGL_OBJECT_TYPE_FENCE, OBJSTATUS_FENCE_IS_SUBMITTED, OBJSTATUS_FENCE_IS_SUBMITTED, XGL_DBG_MSG_ERROR, OBJTRACK_INVALID_FENCE, "Status Requested for Unsubmitted Fence");\n'
@@ -714,6 +715,13 @@
                                  '}' % (qual, decl, using_line, ret_val, proto.c_call(), create_line, destroy_line, stmt))
                     else:
                         c_call = proto.c_call().replace("(" + proto.params[0].name, "((XGL_PHYSICAL_GPU)gpuw->nextObject", 1)
+                        gpu_state = ''
+                        if 'GetGpuInfo' in proto.name:
+                            gpu_state =  '    if (infoType == XGL_INFO_TYPE_PHYSICAL_GPU_PROPERTIES) {\n'
+                            gpu_state += '        if (pData != NULL) {\n'
+                            gpu_state += '            setGpuInfoState(pData);\n'
+                            gpu_state += '        }\n'
+                            gpu_state += '    }\n'
                         funcs.append('%s%s\n'
                                  '{\n'
                                  '    XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) %s;\n'
@@ -723,7 +731,8 @@
                                  '    %snextTable.%s;\n'
                                  '%s%s'
                                  '%s'
-                                 '}' % (qual, decl, proto.params[0].name, using_line, ret_val, c_call, create_line, destroy_line, stmt))
+                                 '%s'
+                                 '}' % (qual, decl, proto.params[0].name, using_line, ret_val, c_call, create_line, destroy_line, gpu_state, stmt))
                     if 'WsiX11QueuePresent' == proto.name:
                         funcs.append("#endif")
                 elif "ParamChecker" == layer:
@@ -1194,6 +1203,7 @@
         header_txt.append('static objNode *pGlobalHead = NULL;')
         header_txt.append('static uint64_t numObjs[XGL_NUM_OBJECT_TYPE] = {0};')
         header_txt.append('static uint64_t numTotalObjs = 0;')
+        header_txt.append('static uint32_t maxMemRefsPerSubmission = 0;')
         header_txt.append('// Debug function to print global list and each individual object list')
         header_txt.append('static void ll_print_lists()')
         header_txt.append('{')
@@ -1425,6 +1435,24 @@
         header_txt.append('        validate_status((void *)pMemRefs[i].mem, XGL_OBJECT_TYPE_GPU_MEMORY, OBJSTATUS_GPU_MEM_MAPPED, OBJSTATUS_NONE, XGL_DBG_MSG_ERROR, OBJTRACK_GPU_MEM_MAPPED, "A Mapped Memory Object was referenced in a command buffer");')
         header_txt.append('    }')
         header_txt.append('}')
+        header_txt.append('')
+        header_txt.append('static void validate_mem_ref_count(uint32_t numRefs) {')
+        header_txt.append('    if (maxMemRefsPerSubmission == 0) {')
+        header_txt.append('        char str[1024];')
+        header_txt.append('        sprintf(str, "xglQueueSubmit called before calling xglGetGpuInfo");')
+        header_txt.append('        layerCbMsg(XGL_DBG_MSG_WARNING, XGL_VALIDATION_LEVEL_0, NULL, 0, OBJTRACK_GETGPUINFO_NOT_CALLED, "OBJTRACK", str);')
+        header_txt.append('    } else {')
+        header_txt.append('        if (numRefs > maxMemRefsPerSubmission) {')
+        header_txt.append('            char str[1024];')
+        header_txt.append('            sprintf(str, "xglQueueSubmit Memory reference count (%d) exceeds allowable GPU limit (%d)", numRefs, maxMemRefsPerSubmission);')
+        header_txt.append('            layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, NULL, 0, OBJTRACK_MEMREFCOUNT_MAX_EXCEEDED, "OBJTRACK", str);')
+        header_txt.append('        }')
+        header_txt.append('    }')
+        header_txt.append('}')
+        header_txt.append('')
+        header_txt.append('static void setGpuInfoState(void *pData) {')
+        header_txt.append('    maxMemRefsPerSubmission = ((XGL_PHYSICAL_GPU_PROPERTIES *)pData)->maxMemRefsPerSubmission;')
+        header_txt.append('}')
         return "\n".join(header_txt)
 
     def generate_body(self):