glave: Add ability for replay memory allocations and mapping to be pending
diff --git a/glave-generate.py b/glave-generate.py
index 1e3422e..2cbc544 100755
--- a/glave-generate.py
+++ b/glave-generate.py
@@ -1759,13 +1759,23 @@
         cd_body.append('};\n')
         cd_body.append('class gpuMemory {')
         cd_body.append('public:')
-        cd_body.append('    gpuMemory() : m_pData(NULL) {m_allocInfo.allocationSize = 0;}')
+        cd_body.append('    gpuMemory() : m_pendingAlloc(false) {m_allocInfo.allocationSize = 0;}')
         cd_body.append('    ~gpuMemory() {}')
-        cd_body.append('    void setAllocInfo(const XGL_MEMORY_ALLOC_INFO *info);')
+        cd_body.append('    bool isPendingAlloc();')
+        cd_body.append('    void setAllocInfo(const XGL_MEMORY_ALLOC_INFO *info, const bool pending);')
         cd_body.append('    void setMemoryDataAddr(void *pBuf);')
+        cd_body.append('    void setMemoryMapRange(void *pBuf, const size_t size, const size_t offset, const bool pending);')
         cd_body.append('    void copyMappingData(const void *pSrcData);')
+        cd_body.append('    size_t getMemoryMapSize();')
         cd_body.append('private:')
-        cd_body.append('    void *m_pData;')
+        cd_body.append('    bool m_pendingAlloc;')
+        cd_body.append('    struct mapRange {')
+        cd_body.append('        bool pending;')
+        cd_body.append('        size_t size;')
+        cd_body.append('        size_t offset;')
+        cd_body.append('        void *pData;')
+        cd_body.append('    };')
+        cd_body.append('    std::vector<struct mapRange> m_mapRange;')
         cd_body.append('    XGL_MEMORY_ALLOC_INFO m_allocInfo;')
         cd_body.append('};\n')
         return "\n".join(cd_body)
@@ -2253,31 +2263,62 @@
         rof_body.append('}\n')
         # Custom code for memory mapping functions for app writes into mapped memory
         rof_body.append('    // memory mapping functions for app writes into mapped memory')
-        rof_body.append('    void gpuMemory::setAllocInfo(const XGL_MEMORY_ALLOC_INFO *info)')
+        rof_body.append('    bool gpuMemory::isPendingAlloc()')
         rof_body.append('    {')
+        rof_body.append('        return m_pendingAlloc;')
+        rof_body.append('    }\n')
+        rof_body.append('    void gpuMemory::setAllocInfo(const XGL_MEMORY_ALLOC_INFO *info, const bool pending)')
+        rof_body.append('    {')
+        rof_body.append('        m_pendingAlloc = pending;')
         rof_body.append('        m_allocInfo = *info;')
         rof_body.append('    }\n')
         rof_body.append('    void gpuMemory::setMemoryDataAddr(void *pBuf)')
         rof_body.append('    {')
-        rof_body.append('        if (m_pData != NULL)')
+        rof_body.append('        if (m_mapRange.empty())')
+        rof_body.append('        {')
+        rof_body.append('            glv_LogError("gpuMemory::setMemoryDataAddr() m_mapRange is empty\\n");')
+        rof_body.append('            return;')
+        rof_body.append('        }')
+        rof_body.append('        struct mapRange mr = m_mapRange.back();')
+        rof_body.append('        if (mr.pData != NULL)')
         rof_body.append('            glv_LogWarn("gpuMemory::setMemoryDataAddr() data already mapped overwrite old mapping\\n");')
         rof_body.append('        else if (pBuf == NULL)')
         rof_body.append('            glv_LogWarn("gpuMemory::setMemoryDataAddr() adding NULL pointer\\n");')
-        rof_body.append('        m_pData = pBuf;')
+        rof_body.append('        mr.pData = pBuf;')
+        rof_body.append('    }\n')
+        rof_body.append('    void gpuMemory::setMemoryMapRange(void *pBuf, const size_t size, const size_t offset, const bool pending)')
+        rof_body.append('    {')
+        rof_body.append('        struct mapRange mr;')
+        rof_body.append('        mr.pData = pBuf;')
+        rof_body.append('        mr.size = size;')
+        rof_body.append('        mr.offset = offset;')
+        rof_body.append('        mr.pending = pending;')
+        rof_body.append('        m_mapRange.push_back(mr);')
         rof_body.append('    }\n')
         rof_body.append('    void gpuMemory::copyMappingData(const void* pSrcData)')
         rof_body.append('    {')
-        rof_body.append('        if (!pSrcData || !m_pData)')
+        rof_body.append('        if (m_mapRange.empty())')
         rof_body.append('        {')
-        rof_body.append('            if (!pSrcData)')
-        rof_body.append('                glv_LogWarn("gpuMemory::copyMappingData() null src pointer\\n");')
-        rof_body.append('            else')
-        rof_body.append('                glv_LogWarn("gpuMemory::copyMappingData() null dest pointer size=%u\\n", m_allocInfo.allocationSize);')
-        rof_body.append('            m_pData = NULL;')
+        rof_body.append('            glv_LogError("gpuMemory::copyMappingData() m_mapRange is empty\\n");')
         rof_body.append('            return;')
         rof_body.append('        }')
-        rof_body.append('        memcpy(m_pData, pSrcData, m_allocInfo.allocationSize);')
-        rof_body.append('        m_pData = NULL;')
+        rof_body.append('        struct mapRange mr = m_mapRange.back();')
+        rof_body.append('        if (!pSrcData || !mr.pData)')
+        rof_body.append('        {')
+        rof_body.append('            if (!pSrcData)')
+        rof_body.append('                glv_LogError("gpuMemory::copyMappingData() null src pointer\\n");')
+        rof_body.append('            else')
+        rof_body.append('                glv_LogError("gpuMemory::copyMappingData() null dest pointer size=%u\\n", m_allocInfo.allocationSize);')
+        rof_body.append('            m_mapRange.pop_back();')
+        rof_body.append('            return;')
+        rof_body.append('        }')
+        rof_body.append('        memcpy(mr.pData, pSrcData, m_allocInfo.allocationSize);')
+        rof_body.append('        if (!mr.pending)')
+        rof_body.append('          m_mapRange.pop_back();')
+        rof_body.append('    }\n')
+        rof_body.append('    size_t gpuMemory::getMemoryMapSize()')
+        rof_body.append('    {')
+        rof_body.append('        return (!m_mapRange.empty()) ? m_mapRange.back().size : 0;')
         rof_body.append('    }\n')
         return "\n".join(rof_body)
 
@@ -3239,12 +3280,13 @@
     def _gen_replay_alloc_memory(self):
         am_body = []
         am_body.append('            struct gpuMemObj local_mem;')
-        am_body.append('            replayResult = m_xglFuncs.real_xglAllocMemory(remap(pPacket->device), pPacket->pAllocInfo, &local_mem.replayGpuMem);')
-        am_body.append('            if (replayResult == XGL_SUCCESS)')
+        am_body.append('            if (!m_adjustForGPU)')
+        am_body.append('                replayResult = m_xglFuncs.real_xglAllocMemory(remap(pPacket->device), pPacket->pAllocInfo, &local_mem.replayGpuMem);')
+        am_body.append('            if (replayResult == XGL_SUCCESS || m_adjustForGPU)')
         am_body.append('            {')
         am_body.append('                local_mem.pGpuMem = new (gpuMemory);')
         am_body.append('                if (local_mem.pGpuMem)')
-        am_body.append('                    local_mem.pGpuMem->setAllocInfo(pPacket->pAllocInfo);')
+        am_body.append('                    local_mem.pGpuMem->setAllocInfo(pPacket->pAllocInfo, m_adjustForGPU);')
         am_body.append('                add_to_map(pPacket->pMem, &local_mem);')
         am_body.append('            }')
         return "\n".join(am_body)
@@ -3253,6 +3295,7 @@
         fm_body = []
         fm_body.append('            struct gpuMemObj local_mem;')
         fm_body.append('            local_mem = m_gpuMemorys.find(pPacket->mem)->second;')
+        fm_body.append('            // TODO how/when to free pendingAlloc that did not use and existing gpuMemObj')
         fm_body.append('            replayResult = m_xglFuncs.real_xglFreeMemory(local_mem.replayGpuMem);')
         fm_body.append('            if (replayResult == XGL_SUCCESS) ')
         fm_body.append('            {')
@@ -3265,25 +3308,46 @@
         mm_body = []
         mm_body.append('            struct gpuMemObj local_mem = m_gpuMemorys.find(pPacket->mem)->second;')
         mm_body.append('            void* pData;')
-        mm_body.append('            replayResult = m_xglFuncs.real_xglMapMemory(local_mem.replayGpuMem, pPacket->flags, &pData);')
-        mm_body.append('            if (replayResult == XGL_SUCCESS)')
+        mm_body.append('            if (!local_mem.pGpuMem->isPendingAlloc())')
+        mm_body.append('            {')
+        mm_body.append('                replayResult = m_xglFuncs.real_xglMapMemory(local_mem.replayGpuMem, pPacket->flags, &pData);')
+        mm_body.append('                if (replayResult == XGL_SUCCESS)')
+        mm_body.append('                {')
+        mm_body.append('                    if (local_mem.pGpuMem)')
+        mm_body.append('                        local_mem.pGpuMem->setMemoryMapRange(pData, 0, 0, false);')
+        mm_body.append('                }')
+        mm_body.append('            } else')
         mm_body.append('            {')
         mm_body.append('                if (local_mem.pGpuMem)')
-        mm_body.append('                    local_mem.pGpuMem->setMemoryDataAddr(pData);')
+        mm_body.append('                        local_mem.pGpuMem->setMemoryMapRange(NULL, 0, 0, true);')
         mm_body.append('            }')
         return "\n".join(mm_body)
         
     def _gen_replay_unmap_memory(self):
         um_body = []
         um_body.append('            struct gpuMemObj local_mem = m_gpuMemorys.find(pPacket->mem)->second;')
-        um_body.append('            if (local_mem.pGpuMem)')
-        um_body.append('                local_mem.pGpuMem->copyMappingData(pPacket->pData);  // copies data from packet into memory buffer')
-        um_body.append('            replayResult = m_xglFuncs.real_xglUnmapMemory(local_mem.replayGpuMem);')
+        um_body.append('            if (!local_mem.pGpuMem->isPendingAlloc())')
+        um_body.append('            {')
+        um_body.append('                if (local_mem.pGpuMem)')
+        um_body.append('                    local_mem.pGpuMem->copyMappingData(pPacket->pData);  // copies data from packet into memory buffer')
+        um_body.append('                replayResult = m_xglFuncs.real_xglUnmapMemory(local_mem.replayGpuMem);')
+        um_body.append('            } else')
+        um_body.append('            {')
+        um_body.append('                if (local_mem.pGpuMem)')
+        um_body.append('                {')
+        um_body.append('                    unsigned char *pBuf = (unsigned char *) glv_malloc(local_mem.pGpuMem->getMemoryMapSize());')
+        um_body.append('                    if (!pBuf)')
+        um_body.append('                        glv_LogError("vkUnmapMemory() malloc failed");')
+        um_body.append('                    local_mem.pGpuMem->setMemoryDataAddr(pBuf);')
+        um_body.append('                    local_mem.pGpuMem->copyMappingData(pPacket->pData);')
+        um_body.append('                }')
+        um_body.append('            }')
         return "\n".join(um_body)
 
     def _gen_replay_pin_system_memory(self):
         psm_body = []
         psm_body.append('            struct gpuMemObj local_mem;')
+        psm_body.append('            /* TODO do we need to skip (make pending) this call for m_adjustForGPU */')
         psm_body.append('            replayResult = m_xglFuncs.real_xglPinSystemMemory(remap(pPacket->device), pPacket->pSysMem, pPacket->memSize, &local_mem.replayGpuMem);')
         psm_body.append('            if (replayResult == XGL_SUCCESS)')
         psm_body.append('                add_to_map(pPacket->pMem, &local_mem);')