1 // Copyright 2001-2018 Crytek GmbH / Crytek Group. All rights reserved.
5 #include <CrySystem/ISystem.h>
6 #include <Cry3DEngine/I3DEngine.h>
7 #include <CryRenderer/IRenderer.h>
8 #include <CrySystem/IConsole.h>
9 #include <CryAnimation/ICryAnimation.h>
10 #include <CrySystem/Profilers/IPerfHud.h>
11 #include <CryString/CryPath.h>
12 #include <CryMemory/CrySizer.h>
13 #include "CrySizerImpl.h"
14 #include "CrySizerStats.h"
16 #include <CryMemory/CryMemoryManager.h>
17 #include <CryScriptSystem/IScriptSystem.h>
18 #include <CryCore/ToolsHelpers/ResourceCompilerHelper.h>
19 #include "PhysRenderer.h"
20 #include <CrySystem/File/IResourceManager.h>
21 #include <CrySystem/Scaleform/IFlashPlayer.h>
22 #include <CrySystem/IStreamEngine.h>
23 #include <CryAction/ITimeDemoRecorder.h>
24 #include <CrySystem/Profilers/ILegacyProfiler.h>
26 // Access to some game info.
27 #include <CryGame/IGameFramework.h>
28 #include <../CryAction/ILevelSystem.h>
29 #include <CryEntitySystem/IEntitySystem.h>
31 const std::vector
<string
>& GetModuleNames()
33 static std::vector
<string
> moduleNames
;
35 if (moduleNames
.empty())
37 static_cast<CSystem
*>(gEnv
->pSystem
)->GetLoadedDynamicLibraries(moduleNames
);
43 #if (!defined (_RELEASE) || defined(ENABLE_PROFILING_CODE))
44 #if CRY_PLATFORM_WINDOWS
46 const struct PEHeader_DLL
49 IMAGE_FILE_HEADER _head
;
50 IMAGE_OPTIONAL_HEADER opt_head
;
51 IMAGE_SECTION_HEADER
* section_header
; // actual number in NumberOfSections
56 extern int CryMemoryGetAllocatedSize();
57 static void SaveLevelStats(IConsoleCmdArgs
* pArgs
);
59 #define g_szTestResults "%USER%/TestResults"
61 class CResourceCollector
: public IResourceCollector
66 uint32 m_dwFileNameId
; // use with m_FilenameToId, m_IdToFilename
71 SAssetEntry() : m_dwInstanceCnt(0), m_dwDependencyCnt(0), m_dwMemSize(0xffffffff), m_dwFileSize(0xffffffff)
76 uint32 m_dwInstanceCnt
; // 1=this asset is used only once in the level, 2, 3, ...
77 uint32 m_dwDependencyCnt
; // 1=this asset is only used by one asset, 2, 3, ...
78 uint32 m_dwMemSize
; // 0xffffffff if unknown (only needed to verify disk file size)
79 uint32 m_dwFileSize
; // 0xffffffff if unknown
82 public: // -----------------------------------------------------------------------------
88 void Enable(bool bEnabled
) { m_bEnabled
= bEnabled
; }
90 // compute m_dwDependencyCnt
91 void ComputeDependencyCnt()
93 std::set
<SDependencyPair
>::const_iterator it
, end
= m_Dependencies
.end();
95 for (it
= m_Dependencies
.begin(); it
!= end
; ++it
)
97 const SDependencyPair
& rRef
= *it
;
99 ++m_Assets
[rRef
.m_idDependsOnAsset
].m_dwDependencyCnt
;
103 // watch out: this function modifies internal data
104 void LogData(ILog
& rLog
)
114 std::vector
<SAssetEntry
>::const_iterator it
, end
= m_Assets
.end();
115 uint32 dwAssetID
= 0;
117 for (it
= m_Assets
.begin(); it
!= end
; ++it
, ++dwAssetID
)
119 const SAssetEntry
& rRef
= *it
;
121 rLog
.Log(" A%u: inst:%5u dep:%u mem:%9u file:%9u name:%s", dwAssetID
, rRef
.m_dwInstanceCnt
, rRef
.m_dwDependencyCnt
, rRef
.m_dwMemSize
, rRef
.m_dwFileSize
, rRef
.m_sFileName
.c_str());
128 rLog
.Log("Dependencies:");
130 std::set
<SDependencyPair
>::const_iterator it
, end
= m_Dependencies
.end();
132 uint32 dwCurrentAssetID
= 0xffffffff;
133 uint32 dwSumFile
= 0;
135 for (it
= m_Dependencies
.begin(); it
!= end
; ++it
)
137 const SDependencyPair
& rRef
= *it
;
139 if (rRef
.m_idAsset
!= dwCurrentAssetID
)
141 if (dwSumFile
!= 0 && dwSumFile
!= 0xffffffff)
142 rLog
.Log(" ---> sum file: %u KB", (dwSumFile
+ 1023) / 1024);
147 rLog
.Log(" A%u '%s' depends on", rRef
.m_idAsset
, m_Assets
[rRef
.m_idAsset
].m_sFileName
.c_str());
150 uint32 dwFileSize
= m_Assets
[rRef
.m_idDependsOnAsset
].m_dwFileSize
;
152 rLog
.Log(" A%u file:%9u dep:%u '%s'", rRef
.m_idDependsOnAsset
, dwFileSize
, m_Assets
[rRef
.m_idDependsOnAsset
].m_dwDependencyCnt
, m_Assets
[rRef
.m_idDependsOnAsset
].m_sFileName
.c_str());
154 if (dwFileSize
!= 0xffffffff)
155 dwSumFile
+= dwFileSize
;
157 dwCurrentAssetID
= rRef
.m_idAsset
;
160 if (dwSumFile
!= 0 && dwSumFile
!= 0xffffffff)
161 rLog
.Log(" ---> sum file: %u KB", (dwSumFile
+ 1023) / 1024);
167 rLog
.Log("SourceAtoms:");
169 std::set
<SDependencyPair
>::const_iterator it
;
171 while (!m_Dependencies
.empty())
173 for (it
= m_Dependencies
.begin(); it
!= m_Dependencies
.end(); ++it
)
175 const SDependencyPair
& rRef1
= *it
;
178 std::set
<uint32
> localDependencies
;
180 localDependencies
.insert(rRef1
.m_idAsset
);
182 RecursiveMove(rRef1
.m_idAsset
, localDependencies
);
184 PrintDependencySet(rLog
, localDependencies
);
191 // interface IResourceCollector -------------------------------------------------
193 virtual bool AddResource(const char* szFileName
, const uint32 dwSize
= 0xffffffff)
198 uint32 dwNewAssetIdOrInvalid
= _AddResource(szFileName
, dwSize
);
200 return dwNewAssetIdOrInvalid
!= 0xffffffff;
203 virtual void AddInstance(const char* _szFileName
, void* pInstance
)
211 std::set
<void*>::const_iterator itInstance
= m_ReportedInstances
.find(pInstance
);
213 if (itInstance
!= m_ReportedInstances
.end())
217 string sOutputFileName
= UnifyFilename(_szFileName
);
219 std::map
<string
, uint32
>::const_iterator it
= m_FilenameToId
.find(sOutputFileName
);
221 if (it
== m_FilenameToId
.end())
223 OutputDebugString("ERROR: file wasn't registered with AddResource(): '");
224 OutputDebugString(sOutputFileName
.c_str());
225 OutputDebugString("'\n");
226 CRY_ASSERT_MESSAGE(0, "The asset wasn't registered yet. AddResource() missing - unpredictable result might happen.");
230 uint32 dwAssetId
= it
->second
;
234 cry_sprintf(str,"AddInstance: %p '",pInstance);
235 OutputDebugString(str);
236 OutputDebugString(sOutputFileName.c_str());
237 OutputDebugString("'\n");
239 ++m_Assets
[dwAssetId
].m_dwInstanceCnt
;
240 m_ReportedInstances
.insert(pInstance
);
243 virtual void OpenDependencies(const char* _szFileName
)
248 string sOutputFileName
= UnifyFilename(_szFileName
);
250 std::map
<string
, uint32
>::const_iterator it
= m_FilenameToId
.find(sOutputFileName
);
252 if (it
== m_FilenameToId
.end())
254 m_OpenedAssetId
.push_back(0xffffffff); // CloseDependencies() relies on that
256 OutputDebugString("ERROR: file wasn't registered with AddResource(): '");
257 OutputDebugString(sOutputFileName
.c_str());
258 OutputDebugString("'\n");
259 CRY_ASSERT_MESSAGE(0, "The asset wasn't registered yet. AddResource() missing - unpredictable result might happen.");
263 uint32 dwAssetId
= it
->second
;
265 m_OpenedAssetId
.push_back(dwAssetId
);
271 m_Dependencies
.clear();
272 m_FilenameToId
.clear();
273 m_OpenedAssetId
.resize(0);
274 m_ReportedInstances
.clear();
275 m_ResourceEntries
.resize(0);
278 virtual void CloseDependencies()
283 assert(!m_OpenedAssetId
.empty()); // internal error - OpenDependencies() should match CloseDependencies()
285 m_OpenedAssetId
.pop_back();
288 private: // -----------------------------------------------------------------------
290 struct SDependencyPair
292 SDependencyPair(const uint32 idAsset
, const uint32 idDependsOnAsset
) : m_idAsset(idAsset
), m_idDependsOnAsset(idDependsOnAsset
)
296 uint32 m_idAsset
; // AssetID
297 uint32 m_idDependsOnAsset
; // AssetID
299 bool operator<(const SDependencyPair
& rhs
) const
301 if (m_idAsset
< rhs
.m_idAsset
) return true;
302 if (m_idAsset
> rhs
.m_idAsset
) return false;
304 return m_idDependsOnAsset
< rhs
.m_idDependsOnAsset
;
308 std::vector
<uint32
> m_OpenedAssetId
; // to track for dependencies
309 std::map
<string
, uint32
> m_FilenameToId
; // could be done more efficiently
310 std::vector
<SAssetEntry
> m_Assets
; // could be done more efficiently
311 std::vector
<SInstanceEntry
> m_ResourceEntries
; //
312 std::set
<SDependencyPair
> m_Dependencies
; //
313 std::set
<void*> m_ReportedInstances
; // to avoid counting them twice
316 // ---------------------------------------------------------------------
318 string
UnifyFilename(const char* _szFileName
) const
320 char* szFileName
= (char*)_szFileName
;
322 // as bump and normal maps become combined during loading e.g. blah.tif+blah_ddn.dds
323 // the filename needs to be adjusted
325 char* pSearchForPlus
= szFileName
;
327 while (*pSearchForPlus
!= 0 && *pSearchForPlus
!= '+')
330 if (*pSearchForPlus
== '+')
331 szFileName
= pSearchForPlus
+ 1;
334 string sOutputFileName
;
337 CResourceCompilerHelper::GetOutputFilename(szFileName
, buffer
, sizeof(buffer
));
338 sOutputFileName
= buffer
;
341 sOutputFileName
= PathUtil::ToUnixPath(sOutputFileName
);
342 sOutputFileName
.MakeLower();
344 return sOutputFileName
;
348 // 0xffffffff if asset was already known (m_dwInstanceCnt will be increased), AssetId otherwise
349 uint32
_AddResource(const char* _szFileName
, const uint32 dwSize
= 0xffffffff)
353 if (_szFileName
[0] == 0)
354 return 0xffffffff; // no name provided - ignore this case - this often means the feature is not used
356 uint32 dwNewAssetIdOrInvalid
= 0xffffffff;
358 string sOutputFileName
= UnifyFilename(_szFileName
);
360 std::map
<string
, uint32
>::const_iterator it
= m_FilenameToId
.find(sOutputFileName
);
363 if (it
!= m_FilenameToId
.end())
364 dwAssetId
= it
->second
;
367 dwAssetId
= m_FilenameToId
.size();
368 m_FilenameToId
[sOutputFileName
] = dwAssetId
;
370 SAssetEntry NewAsset
;
372 NewAsset
.m_sFileName
= sOutputFileName
;
374 // if(dwSize==0xffffffff)
378 if (file
.Open(sOutputFileName
.c_str(), "rb"))
379 NewAsset
.m_dwFileSize
= file
.GetLength();
382 dwNewAssetIdOrInvalid
= dwAssetId
;
383 m_Assets
.push_back(NewAsset
);
386 SAssetEntry
& rAsset
= m_Assets
[dwAssetId
];
388 if (dwSize
!= 0xffffffff) // if size was specified
390 if (rAsset
.m_dwMemSize
== 0xffffffff)
392 rAsset
.m_dwMemSize
= dwSize
; // store size
395 assert(rAsset
.m_dwMemSize
== dwSize
); // size should always be the same
398 // rAsset.m_dwInstanceCnt+=dwInstanceCount;
402 // cry_sprintf(str,"_AddResource %s(size=%d cnt=%d)\n",_szFileName,rAsset.m_dwInstanceCnt,rAsset.m_dwMemSize);
403 // OutputDebugString(str);
405 SInstanceEntry instance
;
407 instance
.m_dwFileNameId
= dwAssetId
;
409 AddDependencies(dwAssetId
);
411 m_ResourceEntries
.push_back(instance
);
412 return dwNewAssetIdOrInvalid
;
415 void AddDependencies(const uint32 dwPushedAssetId
)
417 std::vector
<uint32
>::const_iterator it
, end
= m_OpenedAssetId
.end();
419 for (it
= m_OpenedAssetId
.begin(); it
!= end
; ++it
)
421 uint32 dwOpendedAssetId
= *it
;
423 if (dwOpendedAssetId
== 0xffffffff)
424 continue; // asset wasn't registered yet AddResource() missing
426 m_Dependencies
.insert(SDependencyPair(dwOpendedAssetId
, dwPushedAssetId
));
430 void PrintDependencySet(ILog
& rLog
, const std::set
<uint32
>& Dep
)
433 std::set
<uint32
>::const_iterator it
, end
= Dep
.end();
434 uint32 dwSumFile
= 0;
436 // iteration could be optimized
437 for (it
= Dep
.begin(); it
!= end
; ++it
)
439 uint32 idAsset
= *it
;
441 uint32 dwFileSize
= m_Assets
[idAsset
].m_dwFileSize
;
443 if (dwFileSize
!= 0xffffffff)
444 dwSumFile
+= dwFileSize
;
446 rLog
.Log(" A%u file:%9u dep:%u '%s'", idAsset
, m_Assets
[idAsset
].m_dwFileSize
, m_Assets
[idAsset
].m_dwDependencyCnt
, m_Assets
[idAsset
].m_sFileName
.c_str());
448 rLog
.Log(" } ---> sum file: %u KB", (dwSumFile
+ 1023) / 1024);
451 // find all dependencies to it and move to localDependencies
452 void RecursiveMove(const uint32 dwCurrentAssetID
, std::set
<uint32
>& localDependencies
)
454 bool bProcess
= true;
456 // iteration could be optimized
461 std::set
<SDependencyPair
>::iterator it
;
463 for (it
= m_Dependencies
.begin(); it
!= m_Dependencies
.end(); ++it
)
465 SDependencyPair Pair
= *it
;
467 if (Pair
.m_idAsset
== dwCurrentAssetID
|| Pair
.m_idDependsOnAsset
== dwCurrentAssetID
)
469 uint32 idAsset
= (Pair
.m_idAsset
== dwCurrentAssetID
) ? Pair
.m_idDependsOnAsset
: Pair
.m_idAsset
;
471 localDependencies
.insert(idAsset
);
473 m_Dependencies
.erase(it
);
475 RecursiveMove(idAsset
, localDependencies
);
483 friend class CStatsToExcelExporter
;
488 //////////////////////////////////////////////////////////////////////////
489 // Statistics about currently loaded level.
490 //////////////////////////////////////////////////////////////////////////
491 struct SCryEngineStats
497 int nIndicesPerLod
[MAX_LODS
];
502 int nPhysProxySizeMax
;
521 , pIDefaultSkeleton(nullptr)
523 ZeroArray(nVerticesPerLod
);
524 ZeroArray(nIndicesPerLod
);
529 int nVerticesPerLod
[MAX_LODS
];
530 int nIndicesPerLod
[MAX_LODS
];
536 IDefaultSkeleton
* pIDefaultSkeleton
;
548 struct MemInfo
: public SCryEngineStatsGlobalMemInfo
550 MemInfo() : m_pSizer(0), m_pStats(0) {}
551 ~MemInfo() { SAFE_DELETE(m_pSizer
); SAFE_DELETE(m_pStats
); }
553 //int totalUsedInModules;
554 //int totalCodeAndStatic;
555 //int countedMemoryModules;
556 //uint64 totalAllocatedInModules;
557 //int totalNumAllocsInModules;
558 CrySizerImpl
* m_pSizer
;
559 CrySizerStats
* m_pStats
;
561 //std::vector<SCryEngineStatsModuleInfo> modules;
567 int usedTextureMemory
;
576 //! Total time spent in this counter including time of child profilers in current frame.
578 //! How many times this profiler counter was executed.
580 //! Displayed quantity (interpolated or average).
581 float m_displayedValue
;
582 //! How variant this value.
595 struct SPeakProfilerInfo
597 ProfilerInfo profiler
;
601 int pageFaults
; // Number of page faults at this frame.
602 int count
; // Number of times called for peak.
603 float when
; // when it added.
606 struct SModuleProfilerInfo
609 float overBugetRatio
;
615 bool bInvisible
, bHidden
;
619 : nSummary_CodeAndStaticSize(0)
621 , nSummaryCharactersSize(0)
623 , nSummary_TextureSize(0)
624 , nSummary_UserTextureSize(0)
625 , nSummary_EngineTextureSize(0)
626 , nSummary_TexturesStreamingThroughput(0.0f
)
627 , nSummaryEntityCount(0)
629 , nStatObj_SummaryTextureSize(0)
630 , nStatObj_SummaryMeshSize(0)
631 , nStatObj_TotalCount(0)
633 , nChar_SummaryMeshSize(0)
634 , nChar_SummaryTextureSize(0)
635 , nChar_NumInstances(0)
637 , fLevelLoadTime(0.0f
)
638 , nSummary_TexturesPoolSize(0)
640 ISystem
* pSystem
= GetISystem();
641 I3DEngine
* p3DEngine
= pSystem
->GetI3DEngine();
642 IRenderer
* pRenderer
= pSystem
->GetIRenderer();
644 nTotalAllocatedMemory
= CryMemoryGetAllocatedSize();
645 nSummaryMeshSize
= 0;
646 nSummaryMeshCount
= 0;
651 pRenderer
->EF_Query(EFQ_Alloc_Mesh_SysMem
, nSummaryMeshSize
);
652 pRenderer
->EF_Query(EFQ_Mesh_Count
, nSummaryMeshCount
);
653 pRenderer
->EF_Query(EFQ_Alloc_APIMesh
, nAPI_MeshSize
);
656 nSummaryScriptSize
= pSystem
->GetIScriptSystem()->GetScriptAllocSize();
658 IMemoryManager::SProcessMemInfo procMeminfo
;
659 GetISystem()->GetIMemoryManager()->GetProcessMemInfo(procMeminfo
);
661 nWin32_WorkingSet
= procMeminfo
.WorkingSetSize
;
662 nWin32_PeakWorkingSet
= procMeminfo
.PeakWorkingSetSize
;
663 nWin32_PagefileUsage
= procMeminfo
.PagefileUsage
;
664 nWin32_PeakPagefileUsage
= procMeminfo
.PeakPagefileUsage
;
665 nWin32_PageFaultCount
= procMeminfo
.PageFaultCount
;
667 fLevelLoadTime
= gEnv
->pSystem
->GetIResourceManager()->GetLastLevelLoadTime().GetSeconds();
671 p3DEngine
->FillDebugFPSInfo(infoFPS
);
675 uint64 nWin32_WorkingSet
;
676 uint64 nWin32_PeakWorkingSet
;
677 uint64 nWin32_PagefileUsage
;
678 uint64 nWin32_PeakPagefileUsage
;
679 uint64 nWin32_PageFaultCount
;
681 uint32 nTotalAllocatedMemory
;
682 uint32 nSummary_CodeAndStaticSize
; // Total size of all code plus static data
684 uint32 nSummaryScriptSize
;
685 uint32 nSummaryCharactersSize
;
686 uint32 nSummaryMeshCount
;
687 uint32 nSummaryMeshSize
;
688 uint32 nSummaryEntityCount
;
690 uint32 nAPI_MeshSize
; // Allocated by DirectX
692 size_t nSummary_TextureSize
; // Total size of all textures
693 size_t nSummary_UserTextureSize
; // Size of user textures, (from files...)
694 size_t nSummary_EngineTextureSize
; // Dynamic Textures
695 size_t nSummary_TexturesPoolSize
; // Dynamic Textures
696 float nSummary_TexturesStreamingThroughput
; // in KB/sec
698 uint32 nStatObj_SummaryTextureSize
;
699 uint32 nStatObj_SummaryMeshSize
;
700 uint32 nStatObj_TotalCount
; // Including sub-objects.
702 uint32 nChar_SummaryMeshSize
;
703 uint32 nChar_SummaryTextureSize
;
704 uint32 nChar_NumInstances
;
705 SAnimMemoryTracker m_AnimMemoryTracking
;
707 float fLevelLoadTime
;
708 SDebugFPSInfo infoFPS
;
710 std::vector
<StatObjInfo
> objects
;
711 std::vector
<CharacterInfo
> characters
;
712 std::vector
<ITexture
*> textures
;
713 std::vector
<MeshInfo
> meshes
;
714 std::vector
<SBrushMemInfo
> brushes
;
715 std::vector
<IMaterial
*> materials
;
716 std::vector
<ProfilerInfo
> profilers
;
717 std::vector
<SPeakProfilerInfo
> peaks
;
718 std::vector
<SAnimationStatistics
> animations
;
719 std::vector
<SEntityInfo
> entities
;
724 inline bool CompareFrameProfilersValueStats(const SCryEngineStats::ProfilerInfo
& p1
, const SCryEngineStats::ProfilerInfo
& p2
)
726 return p1
.m_displayedValue
> p2
.m_displayedValue
;
731 CEngineStats(bool bDepends
)
733 m_ResourceCollector
.Enable(bDepends
);
737 private: // ----------------------------------------------------------------------------
739 // Collect all stats.
742 void CollectGeometry();
743 void CollectCharacters();
744 void CollectMaterialDependencies();
745 void CollectTextures();
746 void CollectMaterials();
747 void CollectVoxels();
748 void CollectRenderMeshes();
749 void CollectBrushes();
750 void CollectEntityDependencies();
751 void CollectEntities();
752 void CollectMemInfo();
753 void CollectProfileStatistics();
754 void CollectAnimations();
757 // pObj - 0 is ignored
758 // pMat - 0 if IStatObjet Material should be used
759 void AddResource_StatObjWithLODs(IStatObj
* pObj
, CrySizerImpl
& statObjTextureSizer
, IMaterial
* pMat
= 0);
760 // If the object was not previously registered, returns true. If the object was already registered, returns false.
761 bool AddResource_SingleStatObj(IStatObj
& rData
);
763 void AddResource_CharInstance(ICharacterInstance
& rData
);
765 void AddResource_Material(IMaterial
& rData
, const bool bSubMaterial
= false);
767 CResourceCollector m_ResourceCollector
; // dependencies between assets
768 SCryEngineStats m_stats
; //
770 friend void SaveLevelStats(IConsoleCmdArgs
* pArgs
);
773 //////////////////////////////////////////////////////////////////////////
774 void CEngineStats::Collect()
776 //////////////////////////////////////////////////////////////////////////
778 //////////////////////////////////////////////////////////////////////////
779 CollectMemInfo(); // First of all collect memory info for modules (must be first).
784 CollectRenderMeshes();
786 CollectMaterialDependencies();
787 CollectEntityDependencies();
789 CollectProfileStatistics();
793 inline bool CompareMaterialsByName(IMaterial
* pMat1
, IMaterial
* pMat2
)
795 return pMat1
->GetName() > pMat2
->GetName();
798 inline bool CompareTexturesBySizeFunc(ITexture
* pTex1
, ITexture
* pTex2
)
800 return pTex1
->GetDataSize() > pTex2
->GetDataSize();
802 inline bool CompareStatObjBySizeFunc(const SCryEngineStats::StatObjInfo
& s1
, const SCryEngineStats::StatObjInfo
& s2
)
804 return (s1
.nMeshSize
+ s1
.nTextureSize
) > (s2
.nMeshSize
+ s2
.nTextureSize
);
806 inline bool CompareCharactersBySizeFunc(const SCryEngineStats::CharacterInfo
& s1
, const SCryEngineStats::CharacterInfo
& s2
)
808 return (s1
.nMeshSize
+ s1
.nTextureSize
) > (s2
.nMeshSize
+ s2
.nTextureSize
);
810 inline bool CompareRenderMeshByTypeName(IRenderMesh
* pRM1
, IRenderMesh
* pRM2
)
812 return strcmp(pRM1
->GetTypeName(), pRM2
->GetTypeName()) < 0;
815 bool CEngineStats::AddResource_SingleStatObj(IStatObj
& rData
)
817 if (!m_ResourceCollector
.AddResource(rData
.GetFilePath()))
818 return false; // was already registered
822 if (rData
.GetMaterial())
824 m_ResourceCollector
.OpenDependencies(rData
.GetFilePath());
826 AddResource_Material(*rData
.GetMaterial());
828 m_ResourceCollector
.CloseDependencies();
833 void CEngineStats::AddResource_CharInstance(ICharacterInstance
& rData
)
835 if (!m_ResourceCollector
.AddResource(rData
.GetFilePath()))
836 return; // was already registered
840 if (rData
.GetIMaterial())
842 m_ResourceCollector
.OpenDependencies(rData
.GetFilePath());
844 AddResource_Material(*rData
.GetIMaterial());
846 m_ResourceCollector
.CloseDependencies();
850 void CEngineStats::AddResource_Material(IMaterial
& rData
, const bool bSubMaterial
)
854 string sName
= string(rData
.GetName()) + ".mtl";
856 if (!m_ResourceCollector
.AddResource(sName
))
857 return; // was already registered
861 m_ResourceCollector
.OpenDependencies(sName
);
865 SShaderItem
& rItem
= rData
.GetShaderItem();
867 uint32 dwSubMatCount
= rData
.GetSubMtlCount();
869 for (uint32 dwSubMat
= 0; dwSubMat
< dwSubMatCount
; ++dwSubMat
)
871 IMaterial
* pSub
= rData
.GetSubMtl(dwSubMat
);
874 AddResource_Material(*pSub
, true);
878 if (rItem
.m_pShaderResources
)
879 for (uint32 dwI
= 0; dwI
< EFTT_MAX
; ++dwI
)
881 SEfResTexture
* pTex
= rItem
.m_pShaderResources
->GetTexture(dwI
);
886 uint32 dwSize
= 0xffffffff;
888 if(pTex->m_Sampler.m_pITex)
890 dwSize = pTex->m_Sampler.m_pITex->GetDataSize();
892 assert(pTex->m_Name);
893 assert(pTex->m_Sampler.m_pITex->GetName());
895 string sTex = PathUtil::ToUnixPath(PathUtil::ReplaceExtension(pTex->m_Name,""));
896 string sSampler = PathUtil::ToUnixPath(PathUtil::ReplaceExtension(pTex->m_Sampler.m_pITex->GetName(),""));
898 if(stricmp(sTex.c_str(),sSampler.c_str())!=0)
902 cry_sprintf(str,"IGNORE '%s' '%s'\n",sTex.c_str(),sSampler.c_str());
903 OutputDebugString(str);
905 // IGNORE 'Textures/gradf' 'Editor/Objects/gradf'
906 // IGNORE 'textures/cubemaps/auto_cubemap' '$RT_CM'
907 // IGNORE '' 'Textures/Defaults/White_ddn'
908 // IGNORE '' 'textures/defaults/oceanwaves_ddn'
909 // IGNORE '' 'textures/sprites/fire_blur1_ddn'
910 // IGNORE '' 'textures/sprites/fire_blur1_ddn'
911 // IGNORE '' 'Game/Objects/Library/Barriers/Sandbags/sandbags_ddn'
912 // IGNORE '' 'objects/characters/human/us/nanosuit/nanosuit_ddn'
913 // IGNORE '' 'objects/characters/human/us/nanosuit/nanosuit_ddndif'
916 m_ResourceCollector.AddResource(pTex->m_Sampler.m_pITex->GetName(),dwSize); // used texture
920 // CryLog("AddResource ITex (%d): '%s' '%s'",dwI,pTex->m_Name.c_str(),pTex->m_Sampler.m_pITex->GetName());
922 if (pTex
->m_Sampler
.m_pITex
)
923 m_ResourceCollector
.AddResource(pTex
->m_Sampler
.m_pITex
->GetName(), dwSize
);
924 // m_ResourceCollector.AddResource(pTex->m_Name,dwSize);
926 IDynTextureSource
* pDynTextureSrc
= pTex
->m_Sampler
.m_pDynTexSource
;
929 const char* pStr
= pDynTextureSrc
->GetSourceFilePath();
931 m_ResourceCollector
.AddResource(pStr
);
937 m_ResourceCollector
.CloseDependencies();
940 PREFAST_SUPPRESS_WARNING(6262)
941 void CEngineStats::AddResource_StatObjWithLODs(IStatObj
* pObj
, CrySizerImpl
& statObjTextureSizer
, IMaterial
* pMat
)
946 // Make sure we have not already registered this object
947 if (!AddResource_SingleStatObj(*pObj
))
950 SCryEngineStats::StatObjInfo si
;
954 memset(si
.nIndicesPerLod
, 0, sizeof(si
.nIndicesPerLod
));
956 CrySizerImpl localTextureSizer
;
960 si
.nSubMeshCount
= 0;
962 si
.bSplitLods
= false;
963 // Analyze geom object.
969 si
.nPhysProxySize
= 0;
970 si
.nPhysProxySizeMax
= 0;
971 si
.nPhysPrimitives
= 0;
973 m_stats
.nStatObj_TotalCount
++;
975 IStatObj::SStatistics stats
;
976 stats
.pTextureSizer
= &statObjTextureSizer
;
977 stats
.pTextureSizer2
= &localTextureSizer
;
979 si
.pStatObj
->GetStatistics(stats
);
981 si
.nVertices
= stats
.nVertices
;
982 si
.nIndices
= stats
.nIndices
;
983 for (int i
= 0; i
< MAX_STATOBJ_LODS_NUM
; i
++)
984 si
.nIndicesPerLod
[i
] = stats
.nIndicesPerLod
[i
];
985 si
.nMeshSize
= stats
.nMeshSize
;
986 si
.nMeshSizeLoaded
= stats
.nMeshSizeLoaded
;
987 si
.nPhysProxySize
= stats
.nPhysProxySize
;
988 si
.nPhysProxySizeMax
= stats
.nPhysProxySizeMax
;
989 si
.nPhysPrimitives
= stats
.nPhysPrimitives
;
990 si
.nLods
= stats
.nLods
;
991 si
.nDrawCalls
= stats
.nDrawCalls
;
992 si
.nSubMeshCount
= stats
.nSubMeshCount
;
993 si
.nNumRefs
= stats
.nNumRefs
;
994 si
.bSplitLods
= stats
.bSplitLods
;
996 si
.nTextureSize
= localTextureSizer
.GetTotalSize();
998 m_stats
.nStatObj_SummaryMeshSize
+= si
.nMeshSize
;
999 m_stats
.objects
.push_back(si
);
1002 inline bool CompareAnimations(const SAnimationStatistics
& p1
, const SAnimationStatistics
& p2
)
1004 return p1
.count
> p2
.count
;
1007 //////////////////////////////////////////////////////////////////////////
1008 void CEngineStats::CollectAnimations()
1010 // ISystem* pSystem = GetISystem();
1012 m_stats
.animations
.clear();
1014 size_t count = pSystem->GetIAnimationSystem()->GetIAnimEvents()->GetGlobalAnimCount();
1016 //m_stats.animations.reserve(count);
1017 for (size_t i = 0; i < count; ++i) {
1018 SAnimationStatistics stat;
1019 pSystem->GetIAnimationSystem()->GetIAnimEvents()->GetGlobalAnimStatistics(i, stat);
1021 m_stats.animations.push_back(stat);
1023 std::sort( m_stats.animations.begin(),m_stats.animations.end(),CompareAnimations );
1028 void GetObjectsByType(EERType objectType
, std::vector
<IRenderNode
*>& lstInstances
)
1030 I3DEngine
* p3DEngine
= GetISystem()->GetI3DEngine();
1032 const uint32 dwCount
= p3DEngine
->GetObjectsByType(objectType
);
1035 const uint32 numObjects
= lstInstances
.size();
1036 lstInstances
.resize(numObjects
+ dwCount
);
1037 p3DEngine
->GetObjectsByType(objectType
, &lstInstances
[numObjects
]);
1041 //////////////////////////////////////////////////////////////////////////
1042 PREFAST_SUPPRESS_WARNING(6262)
1043 void CEngineStats::CollectGeometry()
1045 ISystem
* pSystem
= GetISystem();
1046 I3DEngine
* p3DEngine
= pSystem
->GetI3DEngine();
1048 m_stats
.nStatObj_SummaryTextureSize
= 0;
1049 m_stats
.nStatObj_SummaryMeshSize
= 0;
1050 m_stats
.nStatObj_TotalCount
= 0;
1052 CrySizerImpl statObjTextureSizer
;
1055 SCryEngineStats::StatObjInfo si;
1057 si.nSubMeshCount = 0;
1058 // Analyze geom object.
1060 si.nTextureSize = 0;
1063 si.nPhysProxySize = 0;
1064 si.nPhysPrimitives = 0;
1067 // iterate through all IStatObj
1071 p3DEngine
->GetLoadedStatObjArray(0, nObjCount
);
1075 const int numStatObjs
= nObjCount
;
1078 m_stats
.objects
.reserve(nObjCount
);
1079 IStatObj
** pObjects
= new IStatObj
*[nObjCount
];
1080 p3DEngine
->GetLoadedStatObjArray(pObjects
, nObjCount
);
1082 PREFAST_ASSUME(numStatObjs
== nObjCount
);
1083 for (int nCurObj
= 0; nCurObj
< nObjCount
; nCurObj
++)
1084 AddResource_StatObjWithLODs(pObjects
[nCurObj
], statObjTextureSizer
, 0);
1090 // iterate through all instances
1092 std::vector
<IRenderNode
*> lstInstances
;
1094 GetObjectsByType(eERType_Brush
, lstInstances
);
1095 GetObjectsByType(eERType_Vegetation
, lstInstances
);
1096 GetObjectsByType(eERType_Light
, lstInstances
);
1097 GetObjectsByType(eERType_Decal
, lstInstances
);
1098 GetObjectsByType(eERType_Character
, lstInstances
);
1099 GetObjectsByType(eERType_MovableBrush
, lstInstances
);
1101 std::vector
<IRenderNode
*>::const_iterator itEnd
= lstInstances
.end();
1102 for (std::vector
<IRenderNode
*>::iterator it
= lstInstances
.begin(); it
!= itEnd
; ++it
)
1104 IRenderNode
* pRenderNode
= *it
;
1106 if (IStatObj
* pEntObject
= pRenderNode
->GetEntityStatObj())
1108 // if the object is not backed by a file, ignore it
1109 if(pEntObject
->GetFilePath()[0] == 0)
1112 AddResource_StatObjWithLODs(pEntObject
, statObjTextureSizer
, 0); // Ensure object is registered
1113 m_ResourceCollector
.AddInstance(pEntObject
->GetFilePath(), pRenderNode
);
1115 if (IMaterial
* pMat
= pRenderNode
->GetMaterial()) // if this rendernode overwrites the IStatObj material
1117 m_ResourceCollector
.OpenDependencies(pEntObject
->GetFilePath());
1118 AddResource_Material(*pMat
); // to report the dependencies of this instance to the IStatObj
1119 m_ResourceCollector
.CloseDependencies();
1123 if (ICharacterInstance
* pCharInst
= pRenderNode
->GetEntityCharacter(0))
1125 AddResource_CharInstance(*pCharInst
);
1126 m_ResourceCollector
.AddInstance(pCharInst
->GetFilePath(), pRenderNode
);
1131 m_stats
.nStatObj_SummaryTextureSize
+= statObjTextureSizer
.GetTotalSize();
1132 std::sort(m_stats
.objects
.begin(), m_stats
.objects
.end(), CompareStatObjBySizeFunc
);
1135 //////////////////////////////////////////////////////////////////////////
1136 void CEngineStats::CollectCharacters() PREFAST_SUPPRESS_WARNING(6262)
1138 ISystem
* pSystem
= GetISystem();
1140 m_stats
.nChar_SummaryTextureSize
= 0;
1141 m_stats
.nChar_SummaryMeshSize
= 0;
1142 m_stats
.nChar_NumInstances
= 0;
1144 CrySizerImpl totalCharactersTextureSizer
;
1146 uint32 nObjCount
= 0;
1147 ICharacterManager
* pICharacterManager
= pSystem
->GetIAnimationSystem();
1149 if (!pICharacterManager
)
1152 m_stats
.m_AnimMemoryTracking
= pICharacterManager
->GetAnimMemoryTracker();
1154 pICharacterManager
->GetLoadedModels(0, nObjCount
);
1158 const int numLoadedModels
= nObjCount
;
1161 m_stats
.characters
.reserve(nObjCount
);
1162 IDefaultSkeleton
** pObjects
= new IDefaultSkeleton
*[nObjCount
];
1163 pICharacterManager
->GetLoadedModels(pObjects
, nObjCount
);
1164 PREFAST_ASSUME(numLoadedModels
== nObjCount
);
1165 for (uint32 nCurObj
= 0; nCurObj
< nObjCount
; nCurObj
++)
1167 if (!pObjects
[nCurObj
])
1170 // Do not consider cga files characters (they are already considered to be static geometries)
1171 //if (stricmp(PathUtil::GetExt(pObjects[nCurObj]->GetModelFilePath()),"cga") == 0)
1174 SCryEngineStats::CharacterInfo si
;
1175 si
.pIDefaultSkeleton
= pObjects
[nCurObj
];
1176 if (!si
.pIDefaultSkeleton
)
1180 // AddResource(*si.pModel);
1182 CrySizerImpl textureSizer
;
1184 si
.nInstances
= gEnv
->pCharacterManager
->GetNumInstancesPerModel(*si
.pIDefaultSkeleton
);
1185 si
.nLods
= 1; //the base-model can have only 1 LOD
1188 memset(si
.nVerticesPerLod
, 0, sizeof(si
.nVerticesPerLod
));
1189 memset(si
.nIndicesPerLod
, 0, sizeof(si
.nIndicesPerLod
));
1191 CrySizerImpl meshSizer
;
1193 si
.nMeshSize
= si
.pIDefaultSkeleton
->GetMeshMemoryUsage(&meshSizer
);
1194 si
.pIDefaultSkeleton
->GetTextureMemoryUsage2(&textureSizer
);
1195 si
.pIDefaultSkeleton
->GetTextureMemoryUsage2(&totalCharactersTextureSizer
);
1196 si
.nPhysProxySize
= 0;
1197 bool bLod0_Found
= false;
1198 IRenderMesh
* pRenderMesh
= si
.pIDefaultSkeleton
->GetIRenderMesh();
1204 si
.nVertices
= pRenderMesh
->GetVerticesCount();
1205 si
.nIndices
= pRenderMesh
->GetIndicesCount();
1207 si
.nVerticesPerLod
[0] = pRenderMesh
->GetVerticesCount();
1208 si
.nIndicesPerLod
[0] = pRenderMesh
->GetIndicesCount();
1210 const phys_geometry
* pgeom
;
1212 for (int i
= si
.pIDefaultSkeleton
->GetJointCount() - 1; i
>= 0; i
--)
1213 if (pgeom
= si
.pIDefaultSkeleton
->GetJointPhysGeom((uint32
)i
))
1215 CrySizerImpl physMeshSizer
;
1216 pgeom
->pGeom
->GetMemoryStatistics(&physMeshSizer
);
1217 si
.nPhysProxySize
+= physMeshSizer
.GetTotalSize();
1220 si
.nTextureSize
= textureSizer
.GetTotalSize();
1222 m_stats
.nChar_SummaryMeshSize
+= si
.nMeshSize
;
1223 m_stats
.characters
.push_back(si
);
1225 m_stats
.nChar_NumInstances
+= si
.nInstances
;
1229 m_stats
.nChar_SummaryTextureSize
= totalCharactersTextureSizer
.GetTotalSize();
1230 std::sort(m_stats
.characters
.begin(), m_stats
.characters
.end(), CompareCharactersBySizeFunc
);
1233 //////////////////////////////////////////////////////////////////////////
1234 void CEngineStats::CollectEntityDependencies()
1236 ISystem
* pSystem
= GetISystem();
1238 IEntitySystem
* pEntitySystem
= pSystem
->GetIEntitySystem();
1240 IEntityItPtr it
= pEntitySystem
->GetEntityIterator();
1241 while (!it
->IsEnd())
1243 IEntity
* pEntity
= it
->Next();
1245 IMaterial
* pMat
= pEntity
->GetMaterial();
1248 AddResource_Material(*pMat
);
1250 uint32 dwSlotCount
= pEntity
->GetSlotCount();
1252 for (uint32 dwI
= 0; dwI
< dwSlotCount
; ++dwI
)
1254 SEntitySlotInfo slotInfo
;
1256 if (pEntity
->GetSlotInfo(dwI
, slotInfo
))
1258 if (slotInfo
.pMaterial
)
1259 AddResource_Material(*slotInfo
.pMaterial
);
1261 if (slotInfo
.pCharacter
)
1262 AddResource_CharInstance(*slotInfo
.pCharacter
);
1268 //////////////////////////////////////////////////////////////////////////
1269 void CEngineStats::CollectEntities()
1271 ISystem
* pSystem
= GetISystem();
1272 IEntitySystem
* pEntitySystem
= pSystem
->GetIEntitySystem();
1273 IEntityItPtr it
= pEntitySystem
->GetEntityIterator();
1275 m_stats
.entities
.clear();
1277 while (!it
->IsEnd())
1279 IEntity
* pEntity
= it
->Next();
1280 SCryEngineStats::SEntityInfo entityInfo
;
1282 entityInfo
.name
= pEntity
->GetName();
1283 entityInfo
.bInvisible
= !pEntity
->IsInvisible();
1284 entityInfo
.bHidden
= pEntity
->IsHidden();
1286 for (size_t j
= 0, jCount
= pEntity
->GetSlotCount(); j
< jCount
; ++j
)
1288 if (pEntity
->GetStatObj(j
))
1290 entityInfo
.models
+= string(pEntity
->GetStatObj(j
)->GetFilePath()) + string(";");
1294 m_stats
.entities
.push_back(entityInfo
);
1297 m_stats
.nSummaryEntityCount
= m_stats
.entities
.size();
1299 //////////////////////////////////////////////////////////////////////////
1300 void CEngineStats::CollectBrushes()
1302 std::vector
<IRenderNode
*> lstInstances
;
1303 GetObjectsByType(eERType_Brush
, lstInstances
);
1305 std::vector
<IRenderNode
*>::const_iterator itEnd
= lstInstances
.end();
1306 for (std::vector
<IRenderNode
*>::iterator it
= lstInstances
.begin(); it
!= itEnd
; ++it
)
1308 IRenderNode
* pRenderNode
= *it
;
1310 if (IStatObj
* pEntObject
= pRenderNode
->GetEntityStatObj())
1312 IMaterial
* pMat
= NULL
;
1313 pMat
= pRenderNode
->GetMaterial();
1316 pMat
= pEntObject
->GetMaterial();
1321 for (int idx
= 0; idx
< 8; idx
++)
1323 if (IRenderMesh
* pMesh
= pRenderNode
->GetRenderMesh(idx
))
1325 SCryEngineStats::SBrushMemInfo brushInfo
;
1326 brushInfo
.brushName
= string(pRenderNode
->GetName());
1327 brushInfo
.usedTextureMemory
= pMesh
->GetTextureMemoryUsage(pMat
);
1328 brushInfo
.lodNum
= idx
;
1329 m_stats
.brushes
.push_back(brushInfo
);
1337 //////////////////////////////////////////////////////////////////////////
1338 void CEngineStats::CollectMaterialDependencies()
1340 ISystem
* pSystem
= GetISystem();
1341 I3DEngine
* p3DEngine
= pSystem
->GetI3DEngine();
1343 IMaterialManager
* pManager
= p3DEngine
->GetMaterialManager();
1345 uint32 nObjCount
= 0;
1346 pManager
->GetLoadedMaterials(0, nObjCount
);
1350 std::vector
<IMaterial
*> Materials
;
1352 Materials
.resize(nObjCount
);
1354 pManager
->GetLoadedMaterials(&Materials
[0], nObjCount
);
1356 std::vector
<IMaterial
*>::const_iterator it
, end
= Materials
.end();
1358 for (it
= Materials
.begin(); it
!= end
; ++it
)
1360 IMaterial
* pMat
= *it
;
1362 AddResource_Material(*pMat
);
1367 //////////////////////////////////////////////////////////////////////////
1368 void CEngineStats::CollectTextures()
1370 ISystem
* pSystem
= GetISystem();
1371 IRenderer
* pRenderer
= pSystem
->GetIRenderer();
1377 m_stats
.nSummary_TextureSize
= 0;
1378 m_stats
.nSummary_UserTextureSize
= 0;
1379 m_stats
.nSummary_EngineTextureSize
= 0;
1380 m_stats
.nSummary_TexturesStreamingThroughput
= 0;
1382 pRenderer
->EF_Query(EFQ_TexturesPoolSize
, m_stats
.nSummary_TexturesPoolSize
);
1384 m_stats
.textures
.clear();
1385 SRendererQueryGetAllTexturesParam query
;
1386 pRenderer
->EF_Query(EFQ_GetAllTextures
, query
);
1387 if (query
.pTextures
)
1389 m_stats
.textures
.reserve(query
.numTextures
);
1391 for (uint32 i
= 0; i
< query
.numTextures
; i
++)
1393 ITexture
* pTexture
= query
.pTextures
[i
];
1394 uint32 nTexSize
= pTexture
->GetDataSize();
1397 m_stats
.textures
.push_back(pTexture
);
1398 m_stats
.nSummary_TextureSize
+= nTexSize
;
1400 if (pTexture
->GetFlags() & (FT_USAGE_RENDERTARGET
| FT_USAGE_DEPTHSTENCIL
| FT_USAGE_UNORDERED_ACCESS
))
1404 numCopies
+= (pTexture
->GetFlags() & FT_STAGE_UPLOAD
) ? 1 : 0;
1405 numCopies
+= (pTexture
->GetFlags() & FT_STAGE_READBACK
) ? 1 : 0;
1407 m_stats
.nSummary_EngineTextureSize
+= size_t(nTexSize
) * numCopies
;
1411 m_stats
.nSummary_UserTextureSize
+= nTexSize
;
1416 std::sort(m_stats
.textures
.begin(), m_stats
.textures
.end(), CompareTexturesBySizeFunc
);
1419 pRenderer
->EF_Query(EFQ_GetAllTexturesRelease
, query
);
1421 STextureStreamingStats
stats(false);
1422 m_stats
.nSummary_TexturesStreamingThroughput
= 0;
1423 pRenderer
->EF_Query(EFQ_GetTexStreamingInfo
, stats
);
1424 m_stats
.nSummary_TexturesStreamingThroughput
= (float)stats
.nThroughput
;
1427 //////////////////////////////////////////////////////////////////////////
1428 void CEngineStats::CollectMaterials()
1430 ISystem
* pSystem
= GetISystem();
1431 I3DEngine
* p3DEngine
= pSystem
->GetI3DEngine();
1433 IMaterialManager
* pManager
= p3DEngine
->GetMaterialManager();
1435 uint32 nObjCount
= 0;
1436 pManager
->GetLoadedMaterials(0, nObjCount
);
1438 m_stats
.materials
.resize(nObjCount
);
1442 pManager
->GetLoadedMaterials(&m_stats
.materials
[0], nObjCount
);
1444 std::sort(m_stats
.materials
.begin(), m_stats
.materials
.end(), CompareMaterialsByName
);
1448 //////////////////////////////////////////////////////////////////////////
1449 void CEngineStats::CollectRenderMeshes()
1451 ISystem
* pSystem
= GetISystem();
1452 IRenderer
* pRenderer
= pSystem
->GetIRenderer();
1458 m_stats
.meshes
.clear();
1459 m_stats
.meshes
.reserve(100);
1464 IRenderMesh
** pMeshes
= NULL
;
1466 pRenderer
->EF_Query(EFQ_GetAllMeshes
, pMeshes
, nCount
);
1467 if (nCount
> 0 && pMeshes
)
1469 // Sort meshes by name.
1470 std::sort(pMeshes
, pMeshes
+ nCount
, CompareRenderMeshByTypeName
);
1472 CrySizerImpl
* pTextureSizer
= new CrySizerImpl();
1475 int nMeshSizeSys
= 0;
1476 int nMeshSizeDev
= 0;
1477 const char* sMeshName
= 0;
1478 const char* sLastMeshName
= "";
1479 for (size_t i
= 0; i
< nCount
; i
++)
1481 IRenderMesh
* pMesh
= pMeshes
[i
];
1482 sMeshName
= pMesh
->GetTypeName();
1484 if ((strcmp(sMeshName
, sLastMeshName
) != 0 && i
!= 0))
1486 SCryEngineStats::MeshInfo mi
;
1487 mi
.nCount
= nInstances
;
1488 mi
.nVerticesSum
= nVertices
;
1489 mi
.nIndicesSum
= nIndices
;
1490 mi
.nMeshSizeDev
= nMeshSizeDev
;
1491 mi
.nMeshSizeSys
= nMeshSizeSys
;
1492 mi
.nTextureSize
= (int)pTextureSizer
->GetTotalSize();
1493 mi
.name
= sLastMeshName
;
1494 m_stats
.meshes
.push_back(mi
);
1496 delete pTextureSizer
;
1497 pTextureSizer
= new CrySizerImpl();
1504 sLastMeshName
= sMeshName
;
1505 nMeshSizeSys
+= pMesh
->GetMemoryUsage(0, IRenderMesh::MEM_USAGE_ONLY_SYSTEM
); // Collect System+Video memory usage.
1506 nMeshSizeDev
+= pMesh
->GetMemoryUsage(0, IRenderMesh::MEM_USAGE_ONLY_VIDEO
); // Collect System+Video memory usage.
1508 // Vlad: checking default material in render mesh makes little sense, meshes can be used with any material
1509 //pMesh->GetTextureMemoryUsage(pMesh->GetMaterial(), pTextureSizer);
1511 nVertices
+= pMesh
->GetVerticesCount();
1512 nIndices
+= pMesh
->GetIndicesCount();
1516 if (nCount
> 0 && sMeshName
)
1518 SCryEngineStats::MeshInfo mi
;
1519 mi
.nCount
= nInstances
;
1520 mi
.nVerticesSum
= nVertices
;
1521 mi
.nIndicesSum
= nIndices
;
1522 mi
.nMeshSizeSys
= nMeshSizeSys
;
1523 mi
.nMeshSizeDev
= nMeshSizeDev
;
1524 mi
.nTextureSize
= (int)pTextureSizer
->GetTotalSize();
1525 mi
.name
= sMeshName
;
1526 m_stats
.meshes
.push_back(mi
);
1529 delete pTextureSizer
;
1535 //////////////////////////////////////////////////////////////////////////
1536 void CEngineStats::CollectVoxels()
1540 //////////////////////////////////////////////////////////////////////////
1541 void CEngineStats::CollectProfileStatistics()
1543 ISystem
* pSystem
= GetISystem();
1544 auto pProfiler
= pSystem
->GetLegacyProfilerInterface();
1545 if (pProfiler
== nullptr)
1548 pProfiler
->AcquireReadAccess();
1550 m_stats
.profilers
.clear();
1553 for (auto pTracker
: *pProfiler
->GetActiveTrackers())
1555 if (pTracker
->count
.Average() > 0 && pTracker
->totalValue
.Average() > 0.0f
)
1559 m_stats
.profilers
.resize(need
);
1561 for (auto pTracker
: *pProfiler
->GetActiveTrackers())
1563 if (pTracker
->count
.Average() > 0 && pTracker
->totalValue
.Average() > 0.0f
)
1565 m_stats
.profilers
[i
].m_count
= pos_round(pTracker
->count
.Average());
1566 m_stats
.profilers
[i
].m_displayedValue
= pTracker
->selfValue
.Average();
1567 m_stats
.profilers
[i
].m_name
= pTracker
->pDescription
->szEventname
;
1568 m_stats
.profilers
[i
].m_module
= pProfiler
->GetModuleName(pTracker
);
1569 m_stats
.profilers
[i
].m_totalTime
= pTracker
->totalValue
.Average();
1570 m_stats
.profilers
[i
].m_variance
= pTracker
->selfValue
.Variance();
1571 m_stats
.profilers
[i
].m_min
= pTracker
->selfValue
.Min();
1572 m_stats
.profilers
[i
].m_max
= pTracker
->selfValue
.Max();
1573 m_stats
.profilers
[i
].m_mincount
= pos_round(pTracker
->count
.Min());
1574 m_stats
.profilers
[i
].m_maxcount
= pos_round(pTracker
->count
.Max());
1579 std::sort(m_stats
.profilers
.begin(), m_stats
.profilers
.end(), CompareFrameProfilersValueStats
);
1582 auto& peaks
= *pProfiler
->GetPeakRecords();
1583 const uint32 peakCount
= peaks
.size();
1584 m_stats
.peaks
.resize(peakCount
);
1585 for (uint32 i
= 0; i
< peakCount
; ++i
)
1587 const SPeakRecord
* pPeak
= &peaks
[i
];
1588 SProfilingSectionTracker
* pTracker
= pPeak
->pTracker
;
1590 m_stats
.peaks
[i
].peakValue
= pPeak
->peakValue
;
1591 m_stats
.peaks
[i
].averageValue
= pPeak
->averageValue
;
1592 m_stats
.peaks
[i
].variance
= pPeak
->variance
;
1593 m_stats
.peaks
[i
].pageFaults
= pPeak
->pageFaults
; // Number of page faults at this frame.
1594 m_stats
.peaks
[i
].count
= pPeak
->count
; // Number of times called for peak.
1595 m_stats
.peaks
[i
].when
= pPeak
->timeSeconds
; // when it added.
1597 m_stats
.peaks
[i
].profiler
.m_count
= pos_round(pTracker
->count
.Average());
1598 m_stats
.peaks
[i
].profiler
.m_displayedValue
= pTracker
->selfValue
.Average();
1599 m_stats
.peaks
[i
].profiler
.m_name
= pTracker
->pDescription
->szEventname
;
1600 m_stats
.peaks
[i
].profiler
.m_module
= pProfiler
->GetModuleName(pTracker
);
1601 m_stats
.peaks
[i
].profiler
.m_totalTime
= pTracker
->totalValue
.Average();
1602 m_stats
.peaks
[i
].profiler
.m_variance
= pTracker
->selfValue
.Variance();
1603 m_stats
.peaks
[i
].profiler
.m_min
= pTracker
->selfValue
.Min();
1604 m_stats
.peaks
[i
].profiler
.m_max
= pTracker
->selfValue
.Max();
1605 m_stats
.peaks
[i
].profiler
.m_mincount
= pos_round(pTracker
->count
.Min());
1606 m_stats
.peaks
[i
].profiler
.m_maxcount
= pos_round(pTracker
->count
.Max());
1609 pProfiler
->ReleaseReadAccess();
1612 //////////////////////////////////////////////////////////////////////////
1613 #if CRY_PLATFORM_WINDOWS
1615 /*static*/ bool QueryModuleMemoryInfo(SCryEngineStatsModuleInfo
& moduleInfo
, int index
)
1617 HMODULE hModule
= GetModuleHandle(moduleInfo
.name
);
1621 typedef void (* PFN_MODULEMEMORY
)(CryModuleMemoryInfo
*);
1622 PFN_MODULEMEMORY fpCryModuleGetAllocatedMemory
= (PFN_MODULEMEMORY
)::GetProcAddress(hModule
, "CryModuleGetMemoryInfo");
1623 if (!fpCryModuleGetAllocatedMemory
)
1626 PEHeader_DLL pe_header
;
1627 PEHeader_DLL
* header
= &pe_header
;
1629 const IMAGE_DOS_HEADER
* dos_head
= (IMAGE_DOS_HEADER
*)hModule
;
1630 if (dos_head
->e_magic
!= IMAGE_DOS_SIGNATURE
)
1632 // Wrong pointer, not to PE header.
1635 header
= (PEHeader_DLL
*)(const void*)((char*)dos_head
+ dos_head
->e_lfanew
);
1636 moduleInfo
.moduleStaticSize
= header
->opt_head
.SizeOfInitializedData
+ header
->opt_head
.SizeOfUninitializedData
+ header
->opt_head
.SizeOfCode
+ header
->opt_head
.SizeOfHeaders
;
1637 moduleInfo
.SizeOfCode
= header
->opt_head
.SizeOfCode
;
1638 moduleInfo
.SizeOfInitializedData
= header
->opt_head
.SizeOfInitializedData
;
1639 moduleInfo
.SizeOfUninitializedData
= header
->opt_head
.SizeOfUninitializedData
;
1641 fpCryModuleGetAllocatedMemory(&moduleInfo
.memInfo
);
1643 moduleInfo
.usedInModule
= (int)(moduleInfo
.memInfo
.allocated
- moduleInfo
.memInfo
.freed
);
1647 #else //Another platform
1649 /*static */ bool QueryModuleMemoryInfo(SCryEngineStatsModuleInfo
& moduleInfo
, int index
)
1651 //CryModuleGetMemoryInfo( &moduleInfo.memInfo, (ECryModule)index );
1652 CryModuleGetMemoryInfo(&moduleInfo
.memInfo
);
1653 moduleInfo
.usedInModule
= (int)(moduleInfo
.memInfo
.allocated
- moduleInfo
.memInfo
.freed
);
1659 //////////////////////////////////////////////////////////////////////////
1660 void CEngineStats::CollectMemInfo()
1662 m_stats
.memInfo
.totalUsedInModules
= 0;
1663 m_stats
.memInfo
.totalCodeAndStatic
= 0;
1664 m_stats
.memInfo
.countedMemoryModules
= 0;
1665 m_stats
.memInfo
.totalAllocatedInModules
= 0;
1666 m_stats
.memInfo
.totalNumAllocsInModules
= 0;
1668 const std::vector
<string
>& moduleNames
= GetModuleNames();
1669 const int numModules
= moduleNames
.size();
1671 //////////////////////////////////////////////////////////////////////////
1672 // Hardcoded value for the OS memory allocation.
1673 //////////////////////////////////////////////////////////////////////////
1674 for (int i
= 0; i
< numModules
; i
++)
1676 const char* szModule
= moduleNames
[i
].c_str();
1678 SCryEngineStatsModuleInfo moduleInfo
;
1679 ZeroStruct(moduleInfo
.memInfo
);
1680 moduleInfo
.moduleStaticSize
= moduleInfo
.SizeOfCode
= moduleInfo
.SizeOfInitializedData
= moduleInfo
.SizeOfUninitializedData
= moduleInfo
.usedInModule
= 0;
1681 moduleInfo
.name
= szModule
;
1683 if (!QueryModuleMemoryInfo(moduleInfo
, i
))
1686 m_stats
.memInfo
.totalNumAllocsInModules
+= moduleInfo
.memInfo
.num_allocations
;
1687 m_stats
.memInfo
.totalAllocatedInModules
+= moduleInfo
.memInfo
.allocated
;
1688 m_stats
.memInfo
.totalUsedInModules
+= moduleInfo
.usedInModule
;
1689 m_stats
.memInfo
.countedMemoryModules
++;
1690 m_stats
.memInfo
.totalCodeAndStatic
+= moduleInfo
.moduleStaticSize
;
1692 m_stats
.memInfo
.modules
.push_back(moduleInfo
);
1695 m_stats
.memInfo
.m_pSizer
= new CrySizerImpl();
1696 ((CSystem
*)GetISystem())->CollectMemStats(m_stats
.memInfo
.m_pSizer
, CSystem::nMSP_ForDump
);
1697 m_stats
.memInfo
.m_pStats
= new CrySizerStats(m_stats
.memInfo
.m_pSizer
);
1701 // Exports engine stats to the Excel.
1702 class CStatsToExcelExporter
1708 CELL_CENTERED
= 0x0002,
1710 void ExportToFile(SCryEngineStats
& stats
, const char* filename
);
1711 void ExportDependenciesToFile(CResourceCollector
& stats
, const char* filename
);
1712 void Export(XmlNodeRef Workbook
, SCryEngineStats
& stats
);
1715 void ExportSummary(SCryEngineStats
& stats
);
1716 void ExportStatObjects(SCryEngineStats
& stats
);
1717 void ExportCharacters(SCryEngineStats
& stats
);
1718 void ExportRenderMeshes(SCryEngineStats
& stats
);
1719 void ExportBrushes(SCryEngineStats
& stats
);
1720 void ExportTextures(SCryEngineStats
& stats
);
1721 void ExportMaterials(SCryEngineStats
& stats
);
1722 void ExportMemStats(SCryEngineStats
& stats
);
1723 void ExportMemInfo(SCryEngineStats
& stats
);
1724 void ExportTimeDemoInfo();
1725 void ExportStreamingInfo(SStreamEngineStatistics
& stats
);
1726 void ExportAnimationInfo(SCryEngineStats
& stats
);
1727 void ExportDependencies(CResourceCollector
& stats
);
1728 void ExportProfilerStatistics(SCryEngineStats
& stats
);
1729 void ExportAnimationStatistics(SCryEngineStats
& stats
);
1730 void ExportFPSBuckets();
1731 void ExportPhysEntStatistics(SCryEngineStats
& stats
);
1732 void ExportEntitiesStatistics(SCryEngineStats
& stats
);
1734 void InitExcelWorkbook(XmlNodeRef Workbook
);
1736 XmlNodeRef
NewWorksheet(const char* name
);
1737 void FreezeFirstRow();
1738 void AutoFilter(int nRow
, int nNumColumns
);
1739 void AddCell(float number
);
1740 void AddCell(int number
);
1741 void AddCell(uint32 number
);
1742 void AddCell(uint64 number
) { AddCell((uint32
)number
); };
1743 void AddCell(int64 number
) { AddCell((int)number
); };
1744 void AddCell(const char* str
, int flags
= 0);
1745 void AddCellAtIndex(int nIndex
, const char* str
, int flags
= 0);
1746 void SetCellFlags(XmlNodeRef cell
, int flags
);
1748 void AddCell_SumOfRows(int nRows
);
1749 string
GetXmlHeader();
1752 XmlNodeRef m_Workbook
;
1753 XmlNodeRef m_CurrTable
;
1754 XmlNodeRef m_CurrWorksheet
;
1755 XmlNodeRef m_CurrRow
;
1756 XmlNodeRef m_CurrCell
;
1759 //////////////////////////////////////////////////////////////////////////
1760 string
CStatsToExcelExporter::GetXmlHeader()
1762 return "<?xml version=\"1.0\"?>\n<?mso-application progid=\"Excel.Sheet\"?>\n";
1765 //////////////////////////////////////////////////////////////////////////
1766 void CStatsToExcelExporter::InitExcelWorkbook(XmlNodeRef Workbook
)
1768 m_Workbook
= Workbook
;
1769 m_Workbook
->setTag("Workbook");
1770 m_Workbook
->setAttr("xmlns", "urn:schemas-microsoft-com:office:spreadsheet");
1771 XmlNodeRef ExcelWorkbook
= Workbook
->newChild("ExcelWorkbook");
1772 ExcelWorkbook
->setAttr("xmlns", "urn:schemas-microsoft-com:office:excel");
1774 XmlNodeRef Styles
= m_Workbook
->newChild("Styles");
1777 // Bold header, With Background Color.
1778 XmlNodeRef Style
= Styles
->newChild("Style");
1779 Style
->setAttr("ss:ID", "s25");
1780 XmlNodeRef StyleFont
= Style
->newChild("Font");
1781 StyleFont
->setAttr("x:CharSet", "204");
1782 StyleFont
->setAttr("x:Family", "Swiss");
1783 StyleFont
->setAttr("ss:Bold", "1");
1784 XmlNodeRef StyleInterior
= Style
->newChild("Interior");
1785 StyleInterior
->setAttr("ss:Color", "#00FF00");
1786 StyleInterior
->setAttr("ss:Pattern", "Solid");
1787 XmlNodeRef NumberFormat
= Style
->newChild("NumberFormat");
1788 NumberFormat
->setAttr("ss:Format", "#,##0");
1792 // Bold/Centered header.
1793 XmlNodeRef Style
= Styles
->newChild("Style");
1794 Style
->setAttr("ss:ID", "s26");
1795 XmlNodeRef StyleFont
= Style
->newChild("Font");
1796 StyleFont
->setAttr("x:CharSet", "204");
1797 StyleFont
->setAttr("x:Family", "Swiss");
1798 StyleFont
->setAttr("ss:Bold", "1");
1799 XmlNodeRef StyleInterior
= Style
->newChild("Interior");
1800 StyleInterior
->setAttr("ss:Color", "#FFFF99");
1801 StyleInterior
->setAttr("ss:Pattern", "Solid");
1802 XmlNodeRef Alignment
= Style
->newChild("Alignment");
1803 Alignment
->setAttr("ss:Horizontal", "Center");
1804 Alignment
->setAttr("ss:Vertical", "Bottom");
1809 XmlNodeRef Style
= Styles
->newChild("Style");
1810 Style
->setAttr("ss:ID", "s20");
1811 XmlNodeRef Alignment
= Style
->newChild("Alignment");
1812 Alignment
->setAttr("ss:Horizontal", "Center");
1813 Alignment
->setAttr("ss:Vertical", "Bottom");
1818 XmlNodeRef Style
= Styles
->newChild("Style");
1819 Style
->setAttr("ss:ID", "s21");
1820 XmlNodeRef StyleFont
= Style
->newChild("Font");
1821 StyleFont
->setAttr("x:CharSet", "204");
1822 StyleFont
->setAttr("x:Family", "Swiss");
1823 StyleFont
->setAttr("ss:Bold", "1");
1827 // Centered, Integer Number format
1828 XmlNodeRef Style
= Styles
->newChild("Style");
1829 Style
->setAttr("ss:ID", "s22");
1830 XmlNodeRef Alignment
= Style
->newChild("Alignment");
1831 Alignment
->setAttr("ss:Horizontal", "Center");
1832 Alignment
->setAttr("ss:Vertical", "Bottom");
1833 XmlNodeRef NumberFormat
= Style
->newChild("NumberFormat");
1834 NumberFormat
->setAttr("ss:Format", "#,##0");
1838 // Centered, Float Number format
1839 XmlNodeRef Style
= Styles
->newChild("Style");
1840 Style
->setAttr("ss:ID", "s23");
1841 XmlNodeRef Alignment
= Style
->newChild("Alignment");
1842 Alignment
->setAttr("ss:Horizontal", "Center");
1843 Alignment
->setAttr("ss:Vertical", "Bottom");
1844 //XmlNodeRef NumberFormat = Style->newChild( "NumberFormat" );
1845 //NumberFormat->setAttr( "ss:Format","#,##0" );
1850 <Font x:CharSet="204" x:Family="Swiss" ss:Bold="1"/>
1851 <Interior ss:Color="#FFFF99" ss:Pattern="Solid"/>
1856 //////////////////////////////////////////////////////////////////////////
1857 XmlNodeRef
CStatsToExcelExporter::NewWorksheet(const char* name
)
1859 m_CurrWorksheet
= m_Workbook
->newChild("Worksheet");
1860 m_CurrWorksheet
->setAttr("ss:Name", name
);
1861 m_CurrTable
= m_CurrWorksheet
->newChild("Table");
1862 return m_CurrWorksheet
;
1865 //////////////////////////////////////////////////////////////////////////
1866 void CStatsToExcelExporter::FreezeFirstRow()
1868 XmlNodeRef options
= m_CurrWorksheet
->newChild("WorksheetOptions");
1869 options
->setAttr("xmlns", "urn:schemas-microsoft-com:office:excel");
1870 options
->newChild("FreezePanes");
1871 options
->newChild("FrozenNoSplit");
1872 options
->newChild("SplitHorizontal")->setContent("1");
1873 options
->newChild("TopRowBottomPane")->setContent("1");
1874 options
->newChild("ActivePane")->setContent("2");
1877 //////////////////////////////////////////////////////////////////////////
1878 void CStatsToExcelExporter::AutoFilter(int nRow
, int nNumColumns
)
1880 XmlNodeRef options
= m_CurrWorksheet
->newChild("AutoFilter");
1881 options
->setAttr("xmlns", "urn:schemas-microsoft-com:office:excel");
1883 range
.Format("R%dC1:R%dC%d", nRow
, nRow
, nNumColumns
);
1884 options
->setAttr("x:Range", range
); // x:Range="R1C1:R1C8"
1887 //////////////////////////////////////////////////////////////////////////
1888 void CStatsToExcelExporter::AddRow()
1890 m_CurrRow
= m_CurrTable
->newChild("Row");
1893 //////////////////////////////////////////////////////////////////////////
1894 void CStatsToExcelExporter::AddCell_SumOfRows(int nRows
)
1896 XmlNodeRef cell
= m_CurrRow
->newChild("Cell");
1897 XmlNodeRef data
= cell
->newChild("Data");
1898 data
->setAttr("ss:Type", "Number");
1899 data
->setContent("0");
1905 cry_sprintf(buf
, "=SUM(R[-%d]C:R[-1]C)", nRows
);
1906 m_CurrCell
->setAttr("ss:Formula", buf
);
1910 //////////////////////////////////////////////////////////////////////////
1911 void CStatsToExcelExporter::AddCell(float number
)
1913 XmlNodeRef cell
= m_CurrRow
->newChild("Cell");
1914 cell
->setAttr("ss:StyleID", "s23"); // Centered
1915 XmlNodeRef data
= cell
->newChild("Data");
1916 data
->setAttr("ss:Type", "Number");
1918 cry_sprintf(str
, "%.3f", number
);
1919 data
->setContent(str
);
1923 //////////////////////////////////////////////////////////////////////////
1924 void CStatsToExcelExporter::AddCell(int number
)
1926 XmlNodeRef cell
= m_CurrRow
->newChild("Cell");
1927 cell
->setAttr("ss:StyleID", "s22"); // Centered
1928 XmlNodeRef data
= cell
->newChild("Data");
1929 data
->setAttr("ss:Type", "Number");
1931 cry_sprintf(str
, "%d", number
);
1932 data
->setContent(str
);
1936 //////////////////////////////////////////////////////////////////////////
1937 void CStatsToExcelExporter::AddCell(uint32 number
)
1939 XmlNodeRef cell
= m_CurrRow
->newChild("Cell");
1940 cell
->setAttr("ss:StyleID", "s22"); // Centered
1941 XmlNodeRef data
= cell
->newChild("Data");
1942 data
->setAttr("ss:Type", "Number");
1944 cry_sprintf(str
, "%u", number
);
1945 data
->setContent(str
);
1949 //////////////////////////////////////////////////////////////////////////
1950 void CStatsToExcelExporter::AddCell(const char* str
, int nFlags
)
1952 XmlNodeRef cell
= m_CurrRow
->newChild("Cell");
1953 XmlNodeRef data
= cell
->newChild("Data");
1954 data
->setAttr("ss:Type", "String");
1955 data
->setContent(str
);
1956 SetCellFlags(cell
, nFlags
);
1960 //////////////////////////////////////////////////////////////////////////
1961 void CStatsToExcelExporter::AddCellAtIndex(int nIndex
, const char* str
, int nFlags
)
1963 XmlNodeRef cell
= m_CurrRow
->newChild("Cell");
1964 cell
->setAttr("ss:Index", nIndex
);
1965 XmlNodeRef data
= cell
->newChild("Data");
1966 data
->setAttr("ss:Type", "String");
1967 data
->setContent(str
);
1968 SetCellFlags(cell
, nFlags
);
1972 //////////////////////////////////////////////////////////////////////////
1973 void CStatsToExcelExporter::SetCellFlags(XmlNodeRef cell
, int flags
)
1975 if (flags
& CELL_BOLD
)
1977 if (flags
& CELL_CENTERED
)
1978 cell
->setAttr("ss:StyleID", "s26");
1980 cell
->setAttr("ss:StyleID", "s21");
1984 if (flags
& CELL_CENTERED
)
1985 cell
->setAttr("ss:StyleID", "s20");
1989 static FILE* HandleFileExport(const char* filename
)
1991 CryPathString directory
;
1992 gEnv
->pCryPak
->AdjustFileName(g_szTestResults
, directory
, ICryPak::FLAGS_PATH_REAL
| ICryPak::FLAGS_FOR_WRITING
| ICryPak::FLAGS_ADD_TRAILING_SLASH
);
1993 gEnv
->pCryPak
->MakeDir(directory
);
1995 gEnv
->pCryPak
->AdjustFileName(directory
+ filename
, path
, ICryPak::FLAGS_PATH_REAL
| ICryPak::FLAGS_FOR_WRITING
);
1997 return fopen(path
, "wb");
2000 //////////////////////////////////////////////////////////////////////////
2001 void CStatsToExcelExporter::ExportToFile(SCryEngineStats
& stats
, const char* filename
)
2003 XmlNodeRef Workbook
= GetISystem()->CreateXmlNode("Workbook");
2004 Export(Workbook
, stats
);
2005 string xml
= GetXmlHeader();
2006 // xml = xml + Workbook->getXML();
2007 FILE* file
= HandleFileExport(filename
);
2010 fprintf(file
, "%s", xml
.c_str());
2011 Workbook
->saveToFile(filename
, 8 * 1024 /*chunksize*/, file
);
2016 //////////////////////////////////////////////////////////////////////////
2017 void CStatsToExcelExporter::ExportDependenciesToFile(CResourceCollector
& stats
, const char* filename
)
2019 XmlNodeRef Workbook
= GetISystem()->CreateXmlNode("Workbook");
2022 InitExcelWorkbook(Workbook
);
2023 ExportDependencies(stats
);
2026 string xml
= GetXmlHeader();
2027 // xml = xml + Workbook->getXML();
2029 FILE* file
= HandleFileExport(filename
);
2032 fprintf(file
, "%s", xml
.c_str());
2033 Workbook
->saveToFile(filename
, 8 * 1024 /*chunksize*/, file
);
2038 //////////////////////////////////////////////////////////////////////////
2039 void CStatsToExcelExporter::Export(XmlNodeRef Workbook
, SCryEngineStats
& stats
)
2041 bool bPhysWasActive
= gEnv
->pSystem
->SetThreadState(ESubsys_Physics
, false) != 0;
2042 InitExcelWorkbook(Workbook
);
2043 ExportSummary(stats
);
2044 ExportMemInfo(stats
);
2045 ExportMemStats(stats
);
2046 ExportStatObjects(stats
);
2047 ExportCharacters(stats
);
2048 ExportRenderMeshes(stats
);
2049 ExportBrushes(stats
);
2050 ExportTextures(stats
);
2051 ExportMaterials(stats
);
2052 ExportTimeDemoInfo();
2053 ExportProfilerStatistics(stats
);
2054 ExportAnimationStatistics(stats
);
2055 ExportPhysEntStatistics(stats
);
2056 ExportEntitiesStatistics(stats
);
2057 ExportAnimationInfo(stats
);
2059 SStreamEngineStatistics
& streamingStats
= gEnv
->pSystem
->GetStreamEngine()->GetStreamingStatistics();
2060 ExportStreamingInfo(streamingStats
);
2061 gEnv
->pSystem
->SetThreadState(ESubsys_Physics
, bPhysWasActive
);
2064 //////////////////////////////////////////////////////////////////////////
2065 void CStatsToExcelExporter::ExportSummary(SCryEngineStats
& stats
)
2067 // Make summary sheet.en
2068 NewWorksheet("Summary");
2071 Column
= m_CurrTable
->newChild("Column");
2072 Column
->setAttr("ss:Width", 200);
2073 Column
= m_CurrTable
->newChild("Column");
2074 Column
->setAttr("ss:Width", 100);
2075 Column
= m_CurrTable
->newChild("Column");
2076 Column
->setAttr("ss:Width", 100);
2077 Column
= m_CurrTable
->newChild("Column");
2078 Column
->setAttr("ss:Width", 100);
2079 Column
= m_CurrTable
->newChild("Column");
2080 Column
->setAttr("ss:Width", 100);
2081 Column
= m_CurrTable
->newChild("Column");
2082 Column
->setAttr("ss:Width", 100);
2083 Column
= m_CurrTable
->newChild("Column");
2084 Column
->setAttr("ss:Width", 100);
2087 const SFileVersion
& ver
= GetISystem()->GetFileVersion();
2089 ver
.ToString(sVersion
);
2090 string levelName
= "no_level";
2091 ICVar
* sv_map
= gEnv
->pConsole
->GetCVar("sv_map");
2093 levelName
= sv_map
->GetString();
2096 AddCell(string("CryEngine Version ") + sVersion
);
2098 AddCell(string("Level ") + levelName
);
2100 #if CRY_PLATFORM_WINDOWS
2101 AddCell("Running in 64bit version");
2104 AddCell("Level Load Time (sec):");
2105 AddCell((int)stats
.fLevelLoadTime
);
2108 AddCell("Average\\Min\\Max (fps):");
2109 AddCell((int)stats
.infoFPS
.fAverageFPS
);
2110 AddCell((int)stats
.infoFPS
.fMinFPS
);
2111 AddCell((int)stats
.infoFPS
.fMaxFPS
);
2115 m_CurrRow
->setAttr("ss:StyleID", "s25");
2116 AddCell("Resource Type (MB)");
2118 AddCell("Memory Size");
2119 AddCell("Only Mesh Size");
2120 AddCell("Only Texture Size");
2123 AddCell("CGF Objects", CELL_BOLD
);
2124 AddCell((uint32
)stats
.objects
.size());
2125 AddCell((stats
.nStatObj_SummaryTextureSize
+ stats
.nStatObj_SummaryMeshSize
) / (1024 * 1024));
2126 AddCell((stats
.nStatObj_SummaryMeshSize
) / (1024 * 1024));
2127 AddCell((stats
.nStatObj_SummaryTextureSize
) / (1024 * 1024));
2129 AddCell("Character Models", CELL_BOLD
);
2130 AddCell((uint32
)stats
.characters
.size());
2131 AddCell((stats
.nChar_SummaryTextureSize
+ stats
.nChar_SummaryMeshSize
) / (1024 * 1024));
2132 AddCell((stats
.nChar_SummaryMeshSize
) / (1024 * 1024));
2133 AddCell((stats
.nChar_SummaryTextureSize
) / (1024 * 1024));
2136 AddCell("Character Instances", CELL_BOLD
);
2137 AddCell(stats
.nChar_NumInstances
);
2140 AddCell("Entities", CELL_BOLD
);
2141 AddCell(stats
.nSummaryEntityCount
);
2143 //AddCell( stats.nMemCharactersTotalSize );
2147 m_CurrRow
->setAttr("ss:StyleID", "s25");
2148 AddCell("Textures");
2150 AddCell("Count", CELL_BOLD
);
2151 AddCell((uint32
)stats
.textures
.size());
2152 AddCell("Total count of textures");
2155 AddCell("Textures Overall Size", CELL_BOLD
);
2156 AddCell((uint32
)(stats
.nSummary_TextureSize
/ (1024 * 1024)));
2157 AddCell("Total amount of textures memory usage");
2160 AddCell("Pool Size", CELL_BOLD
);
2161 AddCell((uint32
)(stats
.nSummary_TexturesPoolSize
/ 1024 / 1024));
2162 AddCell("Size of textures pool");
2165 AddCell("Textures Memory Usage", CELL_BOLD
);
2166 AddCell(((uint32
)(stats
.nSummary_TexturesPoolSize
+ stats
.nSummary_UserTextureSize
+ stats
.nSummary_EngineTextureSize
) / (1024 * 1024)));
2167 AddCell("Total memory of textures in RAM");
2170 AddCell("Textures Engine Only", CELL_BOLD
);
2171 AddCell(((uint32
)(stats
.nSummary_EngineTextureSize
) / (1024 * 1024)));
2172 AddCell("Textures for internal Engine usage ");
2175 AddCell("User Textures", CELL_BOLD
);
2176 AddCell(((uint32
)(stats
.nSummary_UserTextureSize
) / (1024 * 1024)));
2177 AddCell("User textures not stored in the textures pool");
2180 AddCell("Textures streaming throughput(KB/s)", CELL_BOLD
);
2181 AddCell((uint32
)((stats
.nSummary_TexturesStreamingThroughput
) / 1024));
2185 //m_CurrRow->setAttr( "ss:StyleID","s25" );
2186 //AddCell( "Resource Type (MB)" );
2187 //AddCell( "Count" );
2188 //AddCell( "Total Size" );
2189 //AddCell( "System Memory" );
2190 //AddCell( "Video Memory" );
2191 //AddCell( "Engine Textures" );
2192 //AddCell( "User Textures" );
2193 //if(stats.nSummary_TexturesStreamingThroughput > 0)
2194 // AddCell( "Textures streaming throughput(KB/s)" );
2197 //AddCell( "Textures",CELL_BOLD );
2198 //AddCell( stats.textures.size() );
2199 //AddCell( (stats.nSummary_TextureSize)/(1024*1024) );
2200 //AddCell( (stats.nSummary_TextureSize)/(1024*1024) );
2201 //AddCell( (stats.nSummary_TextureSize)/(1024*1024) );
2202 //AddCell( (stats.nSummary_EngineTextureSize)/(1024*1024) );
2203 //AddCell( (stats.nSummary_UserTextureSize)/(1024*1024) );
2204 //if(stats.nSummary_TexturesStreamingThroughput > 0)
2205 // AddCell( (stats.nSummary_TexturesStreamingThroughput) / 1024 );
2208 m_CurrRow
->setAttr("ss:StyleID", "s25");
2211 AddCell("Count", CELL_BOLD
);
2212 AddCell(stats
.nSummaryMeshCount
);
2214 AddCell("Total Size", CELL_BOLD
);
2215 AddCell((stats
.nAPI_MeshSize
+ stats
.nSummaryMeshSize
) / (1024 * 1024));
2217 AddCell("System Memory", CELL_BOLD
);
2218 AddCell((stats
.nSummaryMeshSize
) / (1024 * 1024));
2220 AddCell("Video Memory", CELL_BOLD
);
2221 AddCell((stats
.nAPI_MeshSize
) / (1024 * 1024));
2224 m_CurrRow
->setAttr("ss:StyleID", "s25");
2228 AddCell("Lua Memory Usage (MB)");
2229 AddCell(stats
.nSummaryScriptSize
/ (1024 * 1024));
2232 AddCell("Game Memory Usage (MB)");
2233 AddCell(stats
.nTotalAllocatedMemory
/ (1024 * 1024));
2234 uint64 totalAll
= stats
.memInfo
.totalUsedInModules
;
2235 totalAll
+= stats
.nAPI_MeshSize
;
2236 totalAll
+= stats
.nSummary_UserTextureSize
;
2237 totalAll
+= stats
.nSummary_EngineTextureSize
;
2238 totalAll
+= stats
.memInfo
.totalCodeAndStatic
;
2240 AddCell("Total Allocated (With Code/Textures/Mesh) (MB)");
2241 AddCell(totalAll
/ (1024 * 1024));
2244 AddCell("Virtual Memory Usage (MB)");
2245 AddCell(stats
.nWin32_PagefileUsage
/ (1024 * 1024));
2248 AddCell("Peak Virtual Memory Usage (MB)");
2249 AddCell(stats
.nWin32_PeakPagefileUsage
/ (1024 * 1024));
2255 //////////////////////////////////////////////////////////////////////////
2256 void CStatsToExcelExporter::ExportStatObjects(SCryEngineStats
& stats
)
2258 NewWorksheet("Static Geometry");
2263 Column
= m_CurrTable
->newChild("Column");
2264 Column
->setAttr("ss:Width", 350);
2265 Column
= m_CurrTable
->newChild("Column");
2266 Column
->setAttr("ss:Width", 50);
2267 Column
= m_CurrTable
->newChild("Column");
2268 Column
->setAttr("ss:Width", 90);
2269 Column
= m_CurrTable
->newChild("Column");
2270 Column
->setAttr("ss:Width", 100);
2271 Column
= m_CurrTable
->newChild("Column");
2272 Column
->setAttr("ss:Width", 50);
2273 Column
= m_CurrTable
->newChild("Column");
2274 Column
->setAttr("ss:Width", 50);
2275 Column
= m_CurrTable
->newChild("Column");
2276 Column
->setAttr("ss:Width", 80);
2277 Column
= m_CurrTable
->newChild("Column");
2278 Column
->setAttr("ss:Width", 60);
2279 Column
= m_CurrTable
->newChild("Column");
2280 Column
->setAttr("ss:Width", 60);
2281 Column
= m_CurrTable
->newChild("Column");
2282 Column
->setAttr("ss:Width", 100);
2283 Column
= m_CurrTable
->newChild("Column");
2284 Column
->setAttr("ss:Width", 100);
2285 Column
= m_CurrTable
->newChild("Column");
2286 Column
->setAttr("ss:Width", 120);
2287 Column
= m_CurrTable
->newChild("Column");
2288 Column
->setAttr("ss:Width", 90);
2289 Column
= m_CurrTable
->newChild("Column");
2290 Column
->setAttr("ss:Width", 80);
2293 m_CurrRow
->setAttr("ss:StyleID", "s25");
2294 AddCell("Filename");
2296 AddCell("Mesh Size (KB)");
2297 AddCell("Texture Size (KB)");
2298 AddCell("DrawCalls");
2300 AddCell("Sub Meshes");
2301 AddCell("Vertices");
2303 AddCell("Physics Tris");
2304 AddCell("Physics Size (KB)");
2305 AddCell("LODs Tris");
2306 AddCell("Mesh Size Loaded (KB)");
2307 AddCell("Split LODs");
2309 int nRows
= (int)stats
.objects
.size();
2310 for (int i
= 0; i
< nRows
; i
++)
2312 SCryEngineStats::StatObjInfo
& si
= stats
.objects
[i
];
2315 AddCell((si
.pStatObj
) ? si
.pStatObj
->GetFilePath() : "");
2316 AddCell(si
.nNumRefs
);
2317 AddCell(si
.nMeshSize
/ 1024);
2318 AddCell(si
.nTextureSize
/ 1024);
2319 AddCell(si
.nDrawCalls
);
2321 AddCell(si
.nSubMeshCount
);
2322 AddCell(si
.nVertices
);
2323 AddCell(si
.nIndices
/ 3);
2324 AddCell(si
.nPhysPrimitives
);
2325 AddCell((si
.nPhysProxySize
+ 512) / 1024);
2329 // Print lod1/lod2/lod3 ...
2334 for (int lod
= 0; lod
< MAX_LODS
; lod
++)
2336 if (si
.nIndicesPerLod
[lod
] != 0)
2338 cry_sprintf(numstr
, "%d", (si
.nIndicesPerLod
[lod
] / 3));
2340 cry_strcat(tempstr
, " / ");
2341 cry_strcat(tempstr
, numstr
);
2353 AddCell(si
.nMeshSizeLoaded
/ 1024);
2366 AddRow(); m_CurrRow->setAttr( "ss:StyleID","s25" );
2368 AddCell_SumOfRows( nRows ); // Mesh size
2369 AddCell_SumOfRows( nRows ); // Texture size
2370 AddCell( "" ); // LODs
2371 AddCell( "" ); // Sub Meshes
2372 AddCell_SumOfRows( nRows ); // Vertices
2373 AddCell_SumOfRows( nRows ); // Tris
2374 AddCell_SumOfRows( nRows ); // Physics Tris
2375 AddCell_SumOfRows( nRows ); // Physics Size
2376 AddCell( "" ); // LODs Tris
2377 AddCell_SumOfRows( nRows ); // Mesh Size Loaded
2381 //////////////////////////////////////////////////////////////////////////
2382 struct CrySizerNaive
: ICrySizer
2384 CrySizerNaive() : m_count(0), m_size(0) {}
2385 virtual void Release() {}
2386 virtual void End() {}
2387 virtual size_t GetTotalSize() { return m_size
; }
2388 virtual size_t GetObjectCount() { return m_count
; }
2389 virtual IResourceCollector
* GetResourceCollector()
2392 return (IResourceCollector
*)0;
2394 virtual void Push(const char*) {}
2395 virtual void PushSubcomponent(const char*) {}
2396 virtual void Pop() {}
2397 virtual bool AddObject(const void* id
, size_t size
, int count
= 1) { m_size
+= size
* count
; m_count
++; return true; }
2398 virtual void Reset() { m_size
= 0; m_count
= 0; }
2399 virtual void SetResourceCollector(IResourceCollector
* pColl
) {};
2400 size_t m_count
, m_size
;
2403 //////////////////////////////////////////////////////////////////////////
2404 void CStatsToExcelExporter::ExportPhysEntStatistics(SCryEngineStats
& stats
)
2406 NewWorksheet("Physical Entities");
2412 Column
= m_CurrTable
->newChild("Column");
2413 Column
->setAttr("ss:Width", 300);
2414 Column
= m_CurrTable
->newChild("Column");
2415 Column
->setAttr("ss:Width", 50);
2416 Column
= m_CurrTable
->newChild("Column");
2417 Column
->setAttr("ss:Width", 50);
2418 Column
= m_CurrTable
->newChild("Column");
2419 Column
->setAttr("ss:Width", 50);
2420 Column
= m_CurrTable
->newChild("Column");
2421 Column
->setAttr("ss:Width", 50);
2422 Column
= m_CurrTable
->newChild("Column");
2423 Column
->setAttr("ss:Width", 50);
2424 Column
= m_CurrTable
->newChild("Column");
2425 Column
->setAttr("ss:Width", 150);
2426 Column
= m_CurrTable
->newChild("Column");
2427 Column
->setAttr("ss:Width", 150);
2428 Column
= m_CurrTable
->newChild("Column");
2429 Column
->setAttr("ss:Width", 150);
2430 Column
= m_CurrTable
->newChild("Column");
2431 Column
->setAttr("ss:Width", 150);
2434 m_CurrRow
->setAttr("ss:StyleID", "s25");
2437 AddCell("SimClass");
2438 AddCell("Total Size");
2439 AddCell("Instanced Geom Size");
2440 AddCell("Grid Footprint");
2441 AddCell("RB_Intersect Unfriendly");
2442 AddCell("Cloth Unfriendly");
2443 AddCell("Rope Unfriendly");
2444 AddCell("Featherstone Unfriendly");
2446 IPhysicalEntityIt
* iter
= gEnv
->pPhysicalWorld
->GetEntitiesIterator();
2447 IPhysicalEntity
* pent
;
2448 PhysicsVars
* pVars
= gEnv
->pPhysicalWorld
->GetPhysVars();
2450 for (iter
->MoveFirst(); pent
= iter
->Next(); )
2453 pe_params_foreign_data pfd
;
2454 pent
->GetParams(&pfd
);
2455 AddCell(CPhysRenderer::GetPhysForeignName(pfd
.pForeignData
, pfd
.iForeignData
, pfd
.iForeignFlags
));
2458 pent
->GetStatus(&sp
);
2459 const char* entypes
[] = { "none", "static", "rigidbody", "vehicle", "living", "particle", "character", "rope", "cloth", "area" };
2460 AddCell(entypes
[pent
->GetType()]);
2461 const char* simclass
[] = { "hidden", "0-static", "1-sleeping", "2-active", "3-actor", "4-independent", "5-area", "6-trigger", "7-deleted" };
2462 AddCell(simclass
[sp
.iSimClass
+ 1]);
2464 CrySizerNaive sizer
;
2465 pVars
->iDrawHelpers
|= 1 << 31;
2466 pent
->GetMemoryStatistics(&sizer
);
2467 int sizeTot
= sizer
.m_size
;
2468 pVars
->iDrawHelpers
&= ~(1 << 31);
2470 pent
->GetMemoryStatistics(&sizer
);
2471 int sizeGrid
= sizeTot
- sizer
.m_size
;
2476 char szFallbackReason
[2048];
2477 size_t len
= sizeof(szFallbackReason
);
2478 memset(szFallbackReason
, 0, sizeof(szFallbackReason
));
2479 for (pp
.ipart
= 0; pent
->GetParams(&pp
); pp
.ipart
++)
2481 size_t old_len
= len
;
2485 cry_sprintf(token
, "[part %d]", pp
.ipart
);
2486 cry_strcat(szFallbackReason
, token
);
2487 len
-= strlen(token
);
2490 if (pp
.flagsAND
& geom_can_modify
)
2492 pp
.pPhysGeom
->pGeom
->GetMemoryStatistics(&sizer
);
2493 if (pp
.pPhysGeomProxy
!= pp
.pPhysGeom
)
2495 pp
.pPhysGeomProxy
->pGeom
->GetMemoryStatistics(&sizer
);
2498 MARK_UNUSED pp
.partid
;
2500 AddCell(sizeTot
+ (int)sizer
.m_size
);
2501 AddCell((uint32
)sizer
.m_size
);
2504 szFallbackReason
[sizeof(szFallbackReason
) - 1] = 0;
2505 AddCell(strlen(szFallbackReason
) ? szFallbackReason
: " ");
2506 AddCell(pent
->GetType() == PE_SOFT
&& sizeTot
+ sizer
.m_size
- sizeGrid
> 90 << 10 ? "too big" : " ");
2507 AddCell(pent
->GetType() == PE_ROPE
&& sizeTot
+ sizer
.m_size
- sizeGrid
> 70 << 10 ? "too big" : " ");
2508 AddCell(pent
->GetType() == PE_ARTICULATED
&& sizeTot
+ sizer
.m_size
- sizeGrid
> 60 << 10 ? "too big" : " ");
2512 //////////////////////////////////////////////////////////////////////////
2513 void CStatsToExcelExporter::ExportEntitiesStatistics(SCryEngineStats
& stats
)
2515 NewWorksheet("Entities");
2521 Column
= m_CurrTable
->newChild("Column");
2522 Column
->setAttr("ss:Width", 300);
2523 Column
= m_CurrTable
->newChild("Column");
2524 Column
->setAttr("ss:Width", 300);
2525 Column
= m_CurrTable
->newChild("Column");
2526 Column
->setAttr("ss:Width", 100);
2527 Column
= m_CurrTable
->newChild("Column");
2528 Column
->setAttr("ss:Width", 100);
2529 Column
= m_CurrTable
->newChild("Column");
2530 Column
->setAttr("ss:Width", 100);
2531 Column
= m_CurrTable
->newChild("Column");
2532 Column
->setAttr("ss:Width", 300);
2535 m_CurrRow
->setAttr("ss:StyleID", "s25");
2538 AddCell("IsInvisible(but updated)");
2539 AddCell("IsHidden(and disabled)");
2541 for (size_t i
= 0, iCount
= stats
.entities
.size(); i
< iCount
; ++i
)
2544 AddCell(stats
.entities
[i
].name
.c_str());
2545 AddCell(stats
.entities
[i
].models
.c_str());
2546 AddCell(stats
.entities
[i
].bInvisible
? "Yes" : "No");
2547 AddCell(stats
.entities
[i
].bHidden
? "Yes" : "No");
2551 //////////////////////////////////////////////////////////////////////////
2552 void CStatsToExcelExporter::ExportAnimationStatistics(SCryEngineStats
& stats
)
2554 if (stats
.animations
.empty())
2557 NewWorksheet("Animations");
2562 Column
= m_CurrTable
->newChild("Column");
2563 Column
->setAttr("ss:Width", 300);
2564 Column
= m_CurrTable
->newChild("Column");
2565 Column
->setAttr("ss:Width", 50);
2568 m_CurrRow
->setAttr("ss:StyleID", "s25");
2572 int nRows
= (int)stats
.animations
.size();
2573 for (int i
= 0; i
< nRows
; i
++)
2575 SAnimationStatistics
& an
= stats
.animations
[i
];
2578 AddCell((uint32
)an
.count
);
2582 //////////////////////////////////////////////////////////////////////////
2583 void CStatsToExcelExporter::ExportProfilerStatistics(SCryEngineStats
& stats
)
2585 if (stats
.profilers
.empty())
2590 NewWorksheet("Profiler");
2595 Column
= m_CurrTable
->newChild("Column");
2596 Column
->setAttr("ss:Width", 100);
2597 Column
= m_CurrTable
->newChild("Column");
2598 Column
->setAttr("ss:Width", 300);
2599 Column
= m_CurrTable
->newChild("Column");
2600 Column
->setAttr("ss:Width", 50);
2601 Column
= m_CurrTable
->newChild("Column");
2602 Column
->setAttr("ss:Width", 50);
2603 Column
= m_CurrTable
->newChild("Column");
2604 Column
->setAttr("ss:Width", 50);
2605 Column
= m_CurrTable
->newChild("Column");
2606 Column
->setAttr("ss:Width", 50);
2607 Column
= m_CurrTable
->newChild("Column");
2608 Column
->setAttr("ss:Width", 50);
2609 Column
= m_CurrTable
->newChild("Column");
2610 Column
->setAttr("ss:Width", 50);
2611 Column
= m_CurrTable
->newChild("Column");
2612 Column
->setAttr("ss:Width", 50);
2613 Column
= m_CurrTable
->newChild("Column");
2614 Column
->setAttr("ss:Width", 50);
2616 // Column = m_CurrTable->newChild("Column"); Column->setAttr( "ss:Width",40 );
2619 m_CurrRow
->setAttr("ss:StyleID", "s25");
2622 AddCell("Self time, ms");
2623 AddCell("Total time, ms");
2626 AddCell("Min time, ms");
2627 AddCell("Max time, ms");
2628 AddCell("Min count");
2629 AddCell("Max count");
2631 int nRows
= (int)stats
.profilers
.size();
2632 for (int i
= 0; i
< nRows
; i
++)
2634 SCryEngineStats::ProfilerInfo
& pi
= stats
.profilers
[i
];
2636 AddCell(pi
.m_module
);
2638 AddCell(pi
.m_displayedValue
);
2639 AddCell(pi
.m_totalTime
);
2640 AddCell(pi
.m_count
);
2644 AddCell(pi
.m_mincount
);
2645 AddCell(pi
.m_maxcount
);
2650 m_CurrRow
->setAttr("ss:StyleID", "s25");
2653 AddCell_SumOfRows(nRows
);
2654 AddCell_SumOfRows(nRows
);
2655 AddCell_SumOfRows(nRows
);
2663 NewWorksheet("Peaks");
2666 Column
= m_CurrTable
->newChild("Column");
2667 Column
->setAttr("ss:Width", 100);
2668 Column
= m_CurrTable
->newChild("Column");
2669 Column
->setAttr("ss:Width", 300);
2670 Column
= m_CurrTable
->newChild("Column");
2671 Column
->setAttr("ss:Width", 50);
2672 Column
= m_CurrTable
->newChild("Column");
2673 Column
->setAttr("ss:Width", 50);
2674 //Column = m_CurrTable->newChild("Column"); Column->setAttr( "ss:Width",50 );
2675 //Column = m_CurrTable->newChild("Column"); Column->setAttr( "ss:Width",50 );
2676 //Column = m_CurrTable->newChild("Column"); Column->setAttr( "ss:Width",50 );
2677 //Column = m_CurrTable->newChild("Column"); Column->setAttr( "ss:Width",50 );
2678 //Column = m_CurrTable->newChild("Column"); Column->setAttr( "ss:Width",50 );
2679 //Column = m_CurrTable->newChild("Column"); Column->setAttr( "ss:Width",50 );
2680 //Column = m_CurrTable->newChild("Column"); Column->setAttr( "ss:Width",50 );
2682 // Column = m_CurrTable->newChild("Column"); Column->setAttr( "ss:Width",40 );
2685 m_CurrRow
->setAttr("ss:StyleID", "s25");
2688 AddCell("Peak, ms");
2689 //AddCell( "Self time, ms" );
2690 //AddCell( "Total time, ms" );
2693 //AddCell( "Min time, ms" );
2694 //AddCell( "Max time, ms" );
2695 //AddCell( "Min count" );
2696 //AddCell( "Max count" );
2698 int nRows
= (int)stats
.peaks
.size();
2699 for (int i
= 0; i
< nRows
; i
++)
2701 SCryEngineStats::SPeakProfilerInfo
& peak
= stats
.peaks
[i
];
2702 SCryEngineStats::ProfilerInfo
& pi
= stats
.peaks
[i
].profiler
;
2704 AddCell(pi
.m_module
);
2706 AddCell(peak
.peakValue
);
2707 //AddCell( pi.m_displayedValue );
2708 //AddCell( pi.m_totalTime );
2709 AddCell(peak
.count
);
2711 //AddCell( pi.m_min );
2712 //AddCell( pi.m_max );
2713 //AddCell( pi.m_mincount );
2714 //AddCell( pi.m_maxcount );
2717 //AddRow(); m_CurrRow->setAttr( "ss:StyleID","s25" );
2721 //AddCell_SumOfRows( nRows );
2722 //AddCell_SumOfRows( nRows );
2723 //AddCell_SumOfRows( nRows );
2728 NewWorksheet("Budget");
2730 Column
= m_CurrTable
->newChild("Column");
2731 Column
->setAttr("ss:Width", 100);
2732 Column
= m_CurrTable
->newChild("Column");
2733 Column
->setAttr("ss:Width", 300);
2734 Column
= m_CurrTable
->newChild("Column");
2735 Column
->setAttr("ss:Width", 50);
2736 Column
= m_CurrTable
->newChild("Column");
2737 Column
->setAttr("ss:Width", 50);
2742 //////////////////////////////////////////////////////////////////////////
2743 void CStatsToExcelExporter::ExportCharacters(SCryEngineStats
& stats
)
2745 NewWorksheet("Characters");
2750 Column
= m_CurrTable
->newChild("Column");
2751 Column
->setAttr("ss:Width", 300);
2752 Column
= m_CurrTable
->newChild("Column");
2753 Column
->setAttr("ss:Width", 40);
2754 Column
= m_CurrTable
->newChild("Column");
2755 Column
->setAttr("ss:Width", 90);
2756 Column
= m_CurrTable
->newChild("Column");
2757 Column
->setAttr("ss:Width", 90);
2758 Column
= m_CurrTable
->newChild("Column");
2759 Column
->setAttr("ss:Width", 90);
2760 Column
= m_CurrTable
->newChild("Column");
2761 Column
->setAttr("ss:Width", 40);
2762 Column
= m_CurrTable
->newChild("Column");
2763 Column
->setAttr("ss:Width", 90);
2764 Column
= m_CurrTable
->newChild("Column");
2765 Column
->setAttr("ss:Width", 90);
2766 Column
= m_CurrTable
->newChild("Column");
2767 Column
->setAttr("ss:Width", 90);
2768 Column
= m_CurrTable
->newChild("Column");
2769 Column
->setAttr("ss:Width", 90);
2770 Column
= m_CurrTable
->newChild("Column");
2771 Column
->setAttr("ss:Width", 150);
2774 m_CurrRow
->setAttr("ss:StyleID", "s25");
2775 AddCell("Filename");
2776 AddCell("Num Instances");
2777 AddCell("Mesh Size (KB)");
2778 AddCell("Texture Size (KB)");
2779 AddCell("PhysProxy Size (KB)");
2781 AddCell("Vertices Lod0");
2782 AddCell("Tris Lod0");
2783 AddCell("All Vertices");
2784 AddCell("All Tris");
2785 AddCell("LOD Tris");
2787 int nRows
= (int)stats
.characters
.size();
2788 for (int i
= 0; i
< nRows
; i
++)
2790 SCryEngineStats::CharacterInfo
& si
= stats
.characters
[i
];
2792 AddCell(si
.pIDefaultSkeleton
->GetModelFilePath());
2793 AddCell(si
.nInstances
);
2794 AddCell(si
.nMeshSize
/ 1024);
2795 AddCell(si
.nTextureSize
/ 1024);
2796 AddCell((si
.nPhysProxySize
+ 512) >> 10);
2798 AddCell(si
.nVertices
);
2799 AddCell(si
.nIndices
/ 3);
2802 for (int k
= 0; k
< MAX_LODS
; k
++)
2803 nAllVerts
+= si
.nVerticesPerLod
[k
];
2806 int nAllIndices
= 0;
2807 for (int k
= 0; k
< MAX_LODS
; k
++)
2808 nAllIndices
+= si
.nIndicesPerLod
[k
];
2809 AddCell(nAllIndices
/ 3);
2813 // Print lod1/lod2/lod3 ...
2818 for (int lod
= 0; lod
< MAX_LODS
; lod
++)
2820 if (si
.nIndicesPerLod
[lod
] != 0)
2822 cry_sprintf(numstr
, "%d", (si
.nIndicesPerLod
[lod
] / 3));
2824 cry_strcat(tempstr
, " / ");
2825 cry_strcat(tempstr
, numstr
);
2834 m_CurrRow
->setAttr("ss:StyleID", "s25");
2836 AddCell_SumOfRows(nRows
);
2837 AddCell_SumOfRows(nRows
);
2838 AddCell_SumOfRows(nRows
);
2840 AddCell_SumOfRows(nRows
);
2841 AddCell_SumOfRows(nRows
);
2844 //////////////////////////////////////////////////////////////////////////
2845 void CStatsToExcelExporter::ExportDependencies(CResourceCollector
& stats
)
2848 NewWorksheet("Assets");
2852 Column
= m_CurrTable
->newChild("Column");
2853 Column
->setAttr("ss:Width", 72);
2854 Column
= m_CurrTable
->newChild("Column");
2855 Column
->setAttr("ss:Width", 108);
2856 Column
= m_CurrTable
->newChild("Column");
2857 Column
->setAttr("ss:Width", 73);
2858 Column
= m_CurrTable
->newChild("Column");
2859 Column
->setAttr("ss:Width", 60);
2860 Column
= m_CurrTable
->newChild("Column");
2861 Column
->setAttr("ss:Width", 1000);
2864 m_CurrRow
->setAttr("ss:StyleID", "s25");
2865 AddCell("Instances");
2866 AddCell("Dependencies");
2867 AddCell("FileMem (KB)");
2868 AddCell("Extension");
2869 AddCell("FileName");
2871 std::vector
<CResourceCollector::SAssetEntry
>::const_iterator it
, end
= stats
.m_Assets
.end();
2872 uint32 dwAssetID
= 0;
2874 for (it
= stats
.m_Assets
.begin(); it
!= end
; ++it
, ++dwAssetID
)
2876 const CResourceCollector::SAssetEntry
& rRef
= *it
;
2880 char szAName1
[1024];
2881 cry_sprintf(szAName1
, "A%u %s", dwAssetID
, rRef
.m_sFileName
.c_str());
2883 AddCell(rRef
.m_dwInstanceCnt
);
2884 AddCell(rRef
.m_dwDependencyCnt
);
2885 AddCell(rRef
.m_dwFileSize
!= 0xffffffff ? rRef
.m_dwFileSize
/ 1024 : 0);
2886 AddCell(PathUtil::GetExt(rRef
.m_sFileName
));
2891 m_CurrRow
->setAttr("ss:StyleID", "s25");
2892 AddCell_SumOfRows(dwAssetID
);
2894 AddCell_SumOfRows(dwAssetID
);
2898 NewWorksheet("Dependencies");
2902 Column
= m_CurrTable
->newChild("Column");
2903 Column
->setAttr("ss:Width", 600);
2904 Column
= m_CurrTable
->newChild("Column");
2905 Column
->setAttr("ss:Width", 90);
2906 Column
= m_CurrTable
->newChild("Column");
2907 Column
->setAttr("ss:Width", 60);
2910 m_CurrRow
->setAttr("ss:StyleID", "s25");
2911 AddCell("Asset Filename");
2912 AddCell("Requires Sum (KB)");
2913 AddCell("Requires Count");
2915 std::set
<CResourceCollector::SDependencyPair
>::const_iterator it
, end
= stats
.m_Dependencies
.end();
2917 uint32 dwCurrentAssetID
= 0xffffffff;
2918 uint32 dwSumFile
= 0, dwSum
= 0;
2920 for (it
= stats
.m_Dependencies
.begin();; ++it
)
2922 uint32 dwAssetsSize
= stats
.m_Assets
.size();
2924 if (it
== end
|| (*it
).m_idAsset
!= dwCurrentAssetID
)
2926 if (dwSum
!= 0 && dwSumFile
!= 0xffffffff)
2928 assert(dwCurrentAssetID
< dwAssetsSize
);
2930 char szAName0
[1024];
2931 cry_sprintf(szAName0
, "A%u %s", dwCurrentAssetID
, stats
.m_Assets
[dwCurrentAssetID
].m_sFileName
.c_str());
2935 AddCell(dwSumFile
/ 1024);
2946 const CResourceCollector::SDependencyPair
& rRef
= *it
;
2948 assert(rRef
.m_idDependsOnAsset
< dwAssetsSize
);
2950 CResourceCollector::SAssetEntry
& rDepAsset
= stats
.m_Assets
[rRef
.m_idDependsOnAsset
];
2952 if (rDepAsset
.m_dwFileSize
!= 0xffffffff)
2953 dwSumFile
+= rDepAsset
.m_dwFileSize
;
2957 dwCurrentAssetID
= rRef
.m_idAsset
;
2962 NewWorksheet("Detailed Dependencies");
2966 Column
= m_CurrTable
->newChild("Column");
2967 Column
->setAttr("ss:Width", 600);
2968 Column
= m_CurrTable
->newChild("Column");
2969 Column
->setAttr("ss:Width", 1000);
2970 Column
= m_CurrTable
->newChild("Column");
2971 Column
->setAttr("ss:Width", 70);
2974 m_CurrRow
->setAttr("ss:StyleID", "s25");
2975 AddCell("Asset Filename");
2976 AddCell("Requires Filename");
2977 AddCell("Requires (KB)");
2979 std::set
<CResourceCollector::SDependencyPair
>::const_iterator it
, end
= stats
.m_Dependencies
.end();
2981 uint32 dwCurrentAssetID
= 0xffffffff;
2982 uint32 dwSumFile
= 0, dwSum
= 0;
2984 for (it
= stats
.m_Dependencies
.begin();; ++it
)
2986 if (it
== end
|| (*it
).m_idAsset
!= dwCurrentAssetID
)
2988 if (dwSum
!= 0 && dwSumFile
!= 0xffffffff)
2990 // AddRow(); m_CurrRow->setAttr( "ss:StyleID","s21" );
2992 // AddCell_SumOfRows( dwSum );
3003 const CResourceCollector::SDependencyPair &rRef = *it;
3006 cry_sprintf(szAName0,"A%d",rRef.m_idAsset);
3008 AddRow(); m_CurrRow->setAttr( "ss:StyleID","s21" );
3009 AddCell( szAName0 );
3010 AddCell( stats.m_Assets[rRef.m_idAsset].m_sFileName.c_str() );
3014 const CResourceCollector::SDependencyPair
& rRef
= *it
;
3016 CResourceCollector::SAssetEntry
& rDepAsset
= stats
.m_Assets
[rRef
.m_idDependsOnAsset
];
3020 char szAName0
[1024];
3021 cry_sprintf(szAName0
, "A%u %s", rRef
.m_idAsset
, stats
.m_Assets
[rRef
.m_idAsset
].m_sFileName
.c_str());
3022 char szAName1
[1024];
3023 cry_sprintf(szAName1
, "A%u %s", rRef
.m_idDependsOnAsset
, rDepAsset
.m_sFileName
.c_str());
3027 AddCell(rDepAsset
.m_dwFileSize
!= 0xffffffff ? rDepAsset
.m_dwFileSize
/ 1024 : 0);
3029 if (rDepAsset
.m_dwFileSize
!= 0xffffffff)
3030 dwSumFile
+= rDepAsset
.m_dwFileSize
;
3034 dwCurrentAssetID
= rRef
.m_idAsset
;
3039 //////////////////////////////////////////////////////////////////////////
3040 void CStatsToExcelExporter::ExportRenderMeshes(SCryEngineStats
& stats
)
3042 NewWorksheet("Meshes");
3047 Column
= m_CurrTable
->newChild("Column");
3048 Column
->setAttr("ss:Width", 300);
3049 Column
= m_CurrTable
->newChild("Column");
3050 Column
->setAttr("ss:Width", 40);
3051 Column
= m_CurrTable
->newChild("Column");
3052 Column
->setAttr("ss:Width", 90);
3053 Column
= m_CurrTable
->newChild("Column");
3054 Column
->setAttr("ss:Width", 100);
3055 Column
= m_CurrTable
->newChild("Column");
3056 Column
->setAttr("ss:Width", 100);
3057 Column
= m_CurrTable
->newChild("Column");
3058 Column
->setAttr("ss:Width", 90);
3059 Column
= m_CurrTable
->newChild("Column");
3060 Column
->setAttr("ss:Width", 90);
3063 m_CurrRow
->setAttr("ss:StyleID", "s25");
3064 AddCell("Mesh Type");
3065 AddCell("Num Instances");
3066 AddCell("Mesh Size Sys (KB)");
3067 AddCell("Mesh Size Dev (KB)");
3068 AddCell("Texture Size (KB)");
3069 AddCell("Total Vertices");
3070 AddCell("Total Tris");
3071 int nRows
= (int)stats
.meshes
.size();
3072 for (int i
= 0; i
< nRows
; i
++)
3074 SCryEngineStats::MeshInfo
& mi
= stats
.meshes
[i
];
3078 AddCell(mi
.nMeshSizeSys
/ 1024);
3079 AddCell(mi
.nMeshSizeDev
/ 1024);
3080 AddCell(mi
.nTextureSize
/ 1024);
3081 AddCell(mi
.nVerticesSum
);
3082 AddCell(mi
.nIndicesSum
/ 3);
3085 m_CurrRow
->setAttr("ss:StyleID", "s25");
3087 AddCell_SumOfRows(nRows
);
3088 AddCell_SumOfRows(nRows
);
3089 AddCell_SumOfRows(nRows
);
3090 AddCell_SumOfRows(nRows
);
3091 AddCell_SumOfRows(nRows
);
3094 //////////////////////////////////////////////////////////////////////////
3095 bool SortBrushes(SCryEngineStats::SBrushMemInfo a
, SCryEngineStats::SBrushMemInfo b
)
3097 return a
.usedTextureMemory
> b
.usedTextureMemory
;
3100 void CStatsToExcelExporter::ExportBrushes(SCryEngineStats
& stats
)
3102 NewWorksheet("Brushes");
3107 Column
= m_CurrTable
->newChild("Column");
3108 Column
->setAttr("ss:Width", 700);
3109 Column
= m_CurrTable
->newChild("Column");
3110 Column
->setAttr("ss:Width", 100);
3111 Column
= m_CurrTable
->newChild("Column");
3112 Column
->setAttr("ss:Width", 100);
3115 m_CurrRow
->setAttr("ss:StyleID", "s25");
3116 AddCell("Brush Name");
3118 AddCell("Used Texture Mem(KB)");
3120 std::sort(stats
.brushes
.begin(), stats
.brushes
.end(), SortBrushes
);
3122 int nRows
= (int)stats
.brushes
.size();
3123 for (int i
= 0; i
< nRows
; i
++)
3125 SCryEngineStats::SBrushMemInfo
& mi
= stats
.brushes
[i
];
3127 AddCell(mi
.brushName
);
3129 AddCell(mi
.usedTextureMemory
/ 1024);
3132 m_CurrRow
->setAttr("ss:StyleID", "s25");
3135 AddCell_SumOfRows(nRows
);
3138 //////////////////////////////////////////////////////////////////////////
3139 void CStatsToExcelExporter::ExportMaterials(SCryEngineStats
& stats
)
3142 NewWorksheet("Materials");
3147 Column
= m_CurrTable
->newChild("Column");
3148 Column
->setAttr("ss:Width", 400);
3151 m_CurrRow
->setAttr("ss:StyleID", "s25");
3154 AddCell("IsSystem");
3155 AddCell("IsConsoleMtl");
3156 AddCell("RefCount");
3157 AddCell("NumSubMtls");
3159 int nRows
= (int)stats
.materials
.size();
3160 for (int i
= 0; i
< nRows
; i
++)
3162 IMaterial
* pMat
= stats
.materials
[i
];
3164 AddCell(pMat
->GetName());
3166 const bool isSysMtl
= pMat
->GetShaderItem().m_pShader
&& (pMat
->GetShaderItem().m_pShader
->GetFlags() & EF_SYSTEM
) != 0;
3167 AddCell(isSysMtl
? "Yes" : "No");
3169 const bool isConsoleMtl
= (pMat
->GetFlags() & MTL_FLAG_CONSOLE_MAT
) != 0;
3170 AddCell(isConsoleMtl
? "Yes" : "No");
3172 AddCell(pMat
->GetNumRefs());
3174 AddCell(pMat
->GetSubMtlCount());
3179 NewWorksheet("Materials Unused Textures");
3183 Column
= m_CurrTable
->newChild("Column");
3184 Column
->setAttr("ss:Width", 60);
3187 AddCell("This is an estimate of which materials have slots filled with textures that are unused but will still stream.");
3189 AddCell("Please use caution when removing these textures, and double check that it's valid.");
3193 int nRows
= (int)stats
.materials
.size();
3194 for (int i
= 0; i
< nRows
; i
++)
3196 IMaterial
* pMat
= stats
.materials
[i
];
3198 for (int sub
= 0; pMat
&& sub
< pMat
->GetSubMtlCount(); sub
++)
3200 IMaterial
* pSubMat
= pMat
->GetSubMtl(sub
);
3205 bool isMaterialRowAdded
= false;
3207 IShader
* pShader
= pSubMat
->GetShaderItem().m_pShader
;
3208 int nTech
= max(0, pSubMat
->GetShaderItem().m_nTechnique
);
3213 IRenderShaderResources
* pShaderResources
= pSubMat
->GetShaderItem().m_pShaderResources
;
3215 if (!pShaderResources
)
3218 SShaderTexSlots
* pShaderSlots
= pShader
->GetUsedTextureSlots(nTech
);
3223 for (int t
= 0; t
< EFTT_MAX
; ++t
)
3225 SShaderTextureSlot
* pSlot
= pShaderSlots
->m_UsedSlots
[t
];
3227 const string textureName
= (pShaderResources
->GetTexture(t
) != nullptr) ? pShaderResources
->GetTexture(t
)->m_Name
.c_str() : "";
3229 if (!pSlot
&& !textureName
.empty())
3231 // found unused texture.
3233 if (!isMaterialRowAdded
)
3235 // first texture in this material, add material name row
3238 m_CurrRow
->setAttr("ss:StyleID", "s25");
3240 AddCell(string(pMat
->GetName()) + "/" + pSubMat
->GetName());
3242 isMaterialRowAdded
= true;
3246 AddCell(pMat
->GetMaterialHelpers().LookupTexName((EEfResTextures
)t
));
3247 AddCell(textureName
);
3255 //////////////////////////////////////////////////////////////////////////
3256 void CStatsToExcelExporter::ExportTextures(SCryEngineStats
& stats
)
3258 NewWorksheet("Textures");
3263 Column
= m_CurrTable
->newChild("Column");
3264 Column
->setAttr("ss:Width", 400);
3265 Column
= m_CurrTable
->newChild("Column");
3266 Column
->setAttr("ss:Width", 40);
3267 Column
= m_CurrTable
->newChild("Column");
3268 Column
->setAttr("ss:Width", 80);
3269 Column
= m_CurrTable
->newChild("Column");
3270 Column
->setAttr("ss:Width", 80);
3271 Column
= m_CurrTable
->newChild("Column");
3272 Column
->setAttr("ss:Width", 40);
3273 Column
= m_CurrTable
->newChild("Column");
3274 Column
->setAttr("ss:Width", 40);
3275 Column
= m_CurrTable
->newChild("Column");
3276 Column
->setAttr("ss:Width", 80);
3277 Column
= m_CurrTable
->newChild("Column");
3278 Column
->setAttr("ss:Width", 80);
3279 Column
= m_CurrTable
->newChild("Column");
3280 Column
->setAttr("ss:Width", 80);
3281 Column
= m_CurrTable
->newChild("Column");
3282 Column
->setAttr("ss:Width", 80);
3285 m_CurrRow
->setAttr("ss:StyleID", "s25");
3287 AddCell("Filename");
3289 AddCell("Texture Size (KB)");
3290 AddCell("Resolution");
3291 AddCell("Mip Levels");
3295 AddCell("Actual current size (KB)");
3296 AddCell("Last frame used");
3298 int nRows
= (int)stats
.textures
.size();
3299 for (int i
= 0; i
< nRows
; i
++)
3301 ITexture
* pTexture
= stats
.textures
[i
];
3304 AddCell(pTexture
->GetName());
3306 AddCell(pTexture
->AddRef() - 1);
3307 pTexture
->Release();
3309 AddCell(pTexture
->GetDataSize() / 1024);
3312 cry_sprintf(texres
, "%d x %d", pTexture
->GetWidth(), pTexture
->GetHeight());
3313 AddCell(texres
, CELL_CENTERED
);
3315 AddCell(pTexture
->GetNumMips());
3316 AddCell(pTexture
->GetTypeName(), CELL_CENTERED
);
3317 AddCell(pTexture
->GetFormatName(), CELL_CENTERED
);
3319 if (pTexture
->IsStreamedVirtual())
3320 AddCell("Streamed", CELL_CENTERED
);
3323 const char* pTexDesc
= "Static";
3324 uint32 texFlags
= pTexture
->GetFlags();
3325 if (texFlags
& (FT_USAGE_RENDERTARGET
| FT_USAGE_DEPTHSTENCIL
| FT_USAGE_UNORDERED_ACCESS
))
3326 pTexDesc
= "Render Target";
3327 else if (texFlags
& (FT_STAGE_UPLOAD
| FT_STAGE_READBACK
))
3329 pTexDesc
= "Dynamic";
3330 numCopies
+= (texFlags
& FT_STAGE_UPLOAD
) ? 1 : 0;
3331 numCopies
+= (texFlags
& FT_STAGE_READBACK
) ? 1 : 0;
3333 else if (texFlags
& FT_USAGE_ATLAS
)
3335 AddCell(pTexDesc
, CELL_CENTERED
);
3337 AddCell(numCopies
* pTexture
->GetDeviceDataSize() / 1024);
3340 const uint32 nFrameId
= pTexture
->GetAccessFrameId();
3343 cry_sprintf(pTexDesc
, "Not used");
3347 cry_sprintf(pTexDesc
, "%u", nFrameId
);
3349 AddCell(pTexDesc
, CELL_CENTERED
);
3354 m_CurrRow
->setAttr("ss:StyleID", "s25");
3358 //////////////////////////////////////////////////////////////////////////
3359 void CStatsToExcelExporter::ExportMemStats(SCryEngineStats
& stats
)
3361 if (!stats
.memInfo
.m_pStats
)
3364 NewWorksheet("Memory Stats");
3368 Column
= m_CurrTable
->newChild("Column");
3369 Column
->setAttr("ss:Width", 300);
3370 Column
= m_CurrTable
->newChild("Column");
3371 Column
->setAttr("ss:Width", 90);
3372 Column
= m_CurrTable
->newChild("Column");
3373 Column
->setAttr("ss:Width", 90);
3374 Column
= m_CurrTable
->newChild("Column");
3375 Column
->setAttr("ss:Width", 90);
3376 Column
= m_CurrTable
->newChild("Column");
3377 Column
->setAttr("ss:Width", 90);
3380 m_CurrRow
->setAttr("ss:StyleID", "s25");
3383 AddCell("Size (KB)");
3384 AddCell("Total Size (KB)");
3385 AddCell("Object Count");
3389 for (unsigned i
= 0; i
< stats
.memInfo
.m_pStats
->size(); ++i
)
3392 const CrySizerStats::Component
& rComp
= (*stats
.memInfo
.m_pStats
)[i
];
3394 if (rComp
.nDepth
< 2)
3396 AddRow(); // Skip one row if primary component.
3397 m_CurrRow
->setAttr("ss:StyleID", "s25");
3400 char szDepth
[64] = " ";
3401 if (rComp
.nDepth
< sizeof(szDepth
))
3402 szDepth
[rComp
.nDepth
* 2] = '\0';
3404 string sCompDisplayName
= szDepth
;
3405 sCompDisplayName
+= rComp
.strName
;
3407 AddCell(sCompDisplayName
.c_str());
3409 //cry_sprintf(szSize, "%s%7.3f", szDepth,rComp.getSizeMBytes() );
3410 //AddCell( szSize );
3411 //cry_sprintf(szSize, "%s%7.3f", szDepth,rComp.getTotalSizeMBytes() );
3412 //AddCell( szSize );
3414 if (rComp
.sizeBytes
> 0)
3415 AddCell((unsigned int)(rComp
.sizeBytes
/ 1024));
3418 AddCell((unsigned int)(rComp
.sizeBytesTotal
/ 1024));
3420 if (rComp
.numObjects
> 0)
3422 AddCell((unsigned int)(rComp
.numObjects
));
3425 //if (rComp.sizeBytesTotal <= m_nMinSubcomponentBytes || rComp.nDepth > m_nMaxSubcomponentDepth)
3429 char szDepth[32] = " ..............................";
3430 if (rComp.nDepth < sizeof(szDepth))
3431 szDepth[rComp.nDepth] = '\0';
3434 if (rComp.sizeBytes > 0)
3436 if (rComp.sizeBytesTotal > rComp.sizeBytes)
3437 cry_sprintf (szSize, "%7.3f %7.3f", rComp.getTotalSizeMBytes(), rComp.getSizeMBytes());
3439 cry_sprintf (szSize, " %7.3f", rComp.getSizeMBytes());
3443 assert (rComp.sizeBytesTotal > 0);
3444 cry_sprintf (szSize, "%7.3f ", rComp.getTotalSizeMBytes());
3448 if (rComp.numObjects)
3449 cry_sprintf (szCount, "%8u", rComp.numObjects);
3453 m_pLog->LogToFile ("%s%-*s:%s%s",szDepth, nNameWidth-rComp.nDepth,rComp.strName.c_str(), szSize, szCount);
3461 //////////////////////////////////////////////////////////////////////////
3463 void CStatsToExcelExporter::ExportStreamingInfo(
3464 SStreamEngineStatistics
& stats
)
3466 NewWorksheet("Streaming Info");
3469 Column
= m_CurrTable
->newChild("Column");
3470 Column
->setAttr("ss:Width", 400);
3471 Column
= m_CurrTable
->newChild("Column");
3472 Column
->setAttr("ss:Width", 80);
3473 Column
= m_CurrTable
->newChild("Column");
3474 Column
->setAttr("ss:Width", 80);
3478 AddCell("Average Completion Time (ms):", CELL_BOLD
);
3479 AddCell(stats
.fAverageCompletionTime
);
3481 AddCell("Session Read Bandwidth (KB):", CELL_BOLD
);
3482 AddCell(stats
.nTotalSessionReadBandwidth
/ (1024.f
));
3484 AddCell("Average Decompression Bandwidth (MB):", CELL_BOLD
);
3485 AddCell(stats
.nDecompressBandwidthAverage
/ (1024.f
* 1024.f
));
3487 AddCell("Average Decryption Bandwidth (MB):", CELL_BOLD
);
3488 AddCell(stats
.nDecryptBandwidthAverage
/ (1024.f
* 1024.f
));
3490 AddCell("Average Verification Bandwidth (MB):", CELL_BOLD
);
3491 AddCell(stats
.nVerifyBandwidthAverage
/ (1024.f
* 1024.f
));
3493 AddCell("Bytes Read (MB):", CELL_BOLD
);
3494 AddCell(stats
.nTotalBytesRead
/ (1024.f
* 1024.f
));
3496 AddCell("Request Count:", CELL_BOLD
);
3497 AddCell(stats
.nTotalRequestCount
);
3503 AddCell("HDD - Average Active Time (%):", CELL_BOLD
);
3504 AddCell(stats
.hddInfo
.fAverageActiveTime
);
3506 AddCell("HDD - Session Read Bandwidth (KB):", CELL_BOLD
);
3507 AddCell(stats
.hddInfo
.nSessionReadBandwidth
/ (1024.f
));
3509 AddCell("HDD - Effective Read Bandwidth (KB):", CELL_BOLD
);
3510 AddCell(stats
.hddInfo
.nAverageActualReadBandwidth
/ (1024.f
));
3512 AddCell("HDD - Average Seek Offset (MB):", CELL_BOLD
);
3513 AddCell(stats
.hddInfo
.nAverageSeekOffset
/ (1024.f
* 1024.f
));
3515 AddCell("HDD - Bytes Read (MB):", CELL_BOLD
);
3516 AddCell(stats
.hddInfo
.nTotalBytesRead
/ (1024.f
* 1024.f
));
3522 AddCell("Texture - Average Completion Time (ms):", CELL_BOLD
);
3523 AddCell(stats
.typeInfo
[eStreamTaskTypeTexture
].fAverageCompletionTime
);
3525 AddCell("Texture - Session Read Bandwidth (KB):", CELL_BOLD
);
3526 AddCell(stats
.typeInfo
[eStreamTaskTypeTexture
].nSessionReadBandwidth
/ (1024.f
));
3528 AddCell("Texture - Request Count:", CELL_BOLD
);
3529 AddCell(stats
.typeInfo
[eStreamTaskTypeTexture
].nTotalRequestCount
);
3531 AddCell("Texture - Streaming Requests:", CELL_BOLD
);
3532 AddCell(stats
.typeInfo
[eStreamTaskTypeTexture
].nTotalStreamingRequestCount
);
3534 AddCell("Texture - Total Read Bytes (MB):", CELL_BOLD
);
3535 AddCell(stats
.typeInfo
[eStreamTaskTypeTexture
].nTotalReadBytes
/ (1024.f
* 1024.f
));
3537 AddCell("Texture - Average Read Size (KB):", CELL_BOLD
);
3538 AddCell((uint32
)(stats
.typeInfo
[eStreamTaskTypeTexture
].nTotalReadBytes
/
3539 max((uint32
)1, stats
.typeInfo
[eStreamTaskTypeTexture
].nTotalStreamingRequestCount
) / 1024));
3541 AddCell("Texture - Average Request Size (KB):", CELL_BOLD
);
3542 AddCell((uint32
)(stats
.typeInfo
[eStreamTaskTypeTexture
].nTotalRequestDataSize
/
3543 max((uint32
)1, stats
.typeInfo
[eStreamTaskTypeTexture
].nTotalStreamingRequestCount
) / 1024));
3549 AddCell("Geometry - Average Completion Time (ms):", CELL_BOLD
);
3550 AddCell(stats
.typeInfo
[eStreamTaskTypeGeometry
].fAverageCompletionTime
);
3552 AddCell("Geometry - Session Read Bandwidth (KB):", CELL_BOLD
);
3553 AddCell(stats
.typeInfo
[eStreamTaskTypeGeometry
].nSessionReadBandwidth
/ (1024.f
));
3555 AddCell("Geometry - Request Count:", CELL_BOLD
);
3556 AddCell(stats
.typeInfo
[eStreamTaskTypeGeometry
].nTotalRequestCount
);
3558 AddCell("Geometry - Streaming Requests:", CELL_BOLD
);
3559 AddCell(stats
.typeInfo
[eStreamTaskTypeGeometry
].nTotalStreamingRequestCount
);
3561 AddCell("Geometry - Total Read Bytes (MB):", CELL_BOLD
);
3562 AddCell(stats
.typeInfo
[eStreamTaskTypeGeometry
].nTotalReadBytes
/ (1024.f
* 1024.f
));
3564 AddCell("Geometry - Average Read Size (KB):", CELL_BOLD
);
3565 AddCell((uint32
)(stats
.typeInfo
[eStreamTaskTypeGeometry
].nTotalReadBytes
/
3566 max((uint32
)1, stats
.typeInfo
[eStreamTaskTypeGeometry
].nTotalStreamingRequestCount
) / 1024));
3568 AddCell("Geometry - Average Request Size (KB):", CELL_BOLD
);
3569 AddCell((uint32
)(stats
.typeInfo
[eStreamTaskTypeGeometry
].nTotalRequestDataSize
/
3570 max((uint32
)1, stats
.typeInfo
[eStreamTaskTypeGeometry
].nTotalStreamingRequestCount
) / 1024));
3576 AddCell("Terrain - Average Completion Time (ms):", CELL_BOLD
);
3577 AddCell(stats
.typeInfo
[eStreamTaskTypeTerrain
].fAverageCompletionTime
);
3579 AddCell("Terrain - Session Read Bandwidth (KB):", CELL_BOLD
);
3580 AddCell(stats
.typeInfo
[eStreamTaskTypeTerrain
].nSessionReadBandwidth
/ (1024.f
));
3582 AddCell("Terrain - Request Count:", CELL_BOLD
);
3583 AddCell(stats
.typeInfo
[eStreamTaskTypeTerrain
].nTotalRequestCount
);
3585 AddCell("Terrain - Streaming Requests:", CELL_BOLD
);
3586 AddCell(stats
.typeInfo
[eStreamTaskTypeTerrain
].nTotalStreamingRequestCount
);
3588 AddCell("Terrain - Total Read Bytes (MB):", CELL_BOLD
);
3589 AddCell(stats
.typeInfo
[eStreamTaskTypeTerrain
].nTotalReadBytes
/ (1024.f
* 1024.f
));
3591 AddCell("Terrain - Average Read Size (KB):", CELL_BOLD
);
3592 AddCell((uint32
)(stats
.typeInfo
[eStreamTaskTypeTerrain
].nTotalReadBytes
/
3593 max((uint32
)1, stats
.typeInfo
[eStreamTaskTypeTerrain
].nTotalStreamingRequestCount
) / 1024));
3595 AddCell("Terrain - Average Request Size (KB):", CELL_BOLD
);
3596 AddCell((uint32
)(stats
.typeInfo
[eStreamTaskTypeTerrain
].nTotalRequestDataSize
/
3597 max((uint32
)1, stats
.typeInfo
[eStreamTaskTypeTerrain
].nTotalStreamingRequestCount
) / 1024));
3603 AddCell("Animation - Average Completion Time (ms):", CELL_BOLD
);
3604 AddCell(stats
.typeInfo
[eStreamTaskTypeAnimation
].fAverageCompletionTime
);
3606 AddCell("Animation - Session Read Bandwidth (KB):", CELL_BOLD
);
3607 AddCell(stats
.typeInfo
[eStreamTaskTypeAnimation
].nSessionReadBandwidth
/ (1024.f
));
3609 AddCell("Animation - Request Count:", CELL_BOLD
);
3610 AddCell(stats
.typeInfo
[eStreamTaskTypeAnimation
].nTotalRequestCount
);
3612 AddCell("Animation - Streaming Requests:", CELL_BOLD
);
3613 AddCell(stats
.typeInfo
[eStreamTaskTypeAnimation
].nTotalStreamingRequestCount
);
3615 AddCell("Animation - Total Read Bytes (MB):", CELL_BOLD
);
3616 AddCell(stats
.typeInfo
[eStreamTaskTypeAnimation
].nTotalReadBytes
/ (1024.f
* 1024.f
));
3618 AddCell("Animation - Average Read Size (KB):", CELL_BOLD
);
3619 AddCell((uint32
)(stats
.typeInfo
[eStreamTaskTypeAnimation
].nTotalReadBytes
/
3620 max((uint32
)1, stats
.typeInfo
[eStreamTaskTypeAnimation
].nTotalStreamingRequestCount
) / 1024));
3622 AddCell("Animation - Average Request Size (KB):", CELL_BOLD
);
3623 AddCell((uint32
)(stats
.typeInfo
[eStreamTaskTypeAnimation
].nTotalRequestDataSize
/
3624 max((uint32
)1, stats
.typeInfo
[eStreamTaskTypeAnimation
].nTotalStreamingRequestCount
) / 1024));
3630 AddCell("Sound - Average Completion Time (ms):", CELL_BOLD
);
3631 AddCell(stats
.typeInfo
[eStreamTaskTypeSound
].fAverageCompletionTime
);
3633 AddCell("Sound - Session Read Bandwidth (KB):", CELL_BOLD
);
3634 AddCell(stats
.typeInfo
[eStreamTaskTypeSound
].nSessionReadBandwidth
/ (1024.f
));
3636 AddCell("Sound - Request Count:", CELL_BOLD
);
3637 AddCell(stats
.typeInfo
[eStreamTaskTypeSound
].nTotalRequestCount
);
3639 AddCell("Sound - Streaming Requests:", CELL_BOLD
);
3640 AddCell(stats
.typeInfo
[eStreamTaskTypeSound
].nTotalStreamingRequestCount
);
3642 AddCell("Sound - Total Read Bytes (MB):", CELL_BOLD
);
3643 AddCell(stats
.typeInfo
[eStreamTaskTypeSound
].nTotalReadBytes
/ (1024.f
* 1024.f
));
3645 AddCell("Sound - Average Read Size (KB):", CELL_BOLD
);
3646 AddCell((uint32
)(stats
.typeInfo
[eStreamTaskTypeSound
].nTotalReadBytes
/
3647 max((uint32
)1, stats
.typeInfo
[eStreamTaskTypeSound
].nTotalStreamingRequestCount
) / 1024));
3649 AddCell("Sound - Average Request Size (KB):", CELL_BOLD
);
3650 AddCell((uint32
)(stats
.typeInfo
[eStreamTaskTypeSound
].nTotalRequestDataSize
/
3651 max((uint32
)1, stats
.typeInfo
[eStreamTaskTypeSound
].nTotalStreamingRequestCount
) / 1024));
3657 AddCell("Shader - Average Completion Time (ms):", CELL_BOLD
);
3658 AddCell(stats
.typeInfo
[eStreamTaskTypeShader
].fAverageCompletionTime
);
3660 AddCell("Shader - Session Read Bandwidth (KB):", CELL_BOLD
);
3661 AddCell(stats
.typeInfo
[eStreamTaskTypeShader
].nSessionReadBandwidth
/ (1024.f
));
3663 AddCell("Shader - Request Count:", CELL_BOLD
);
3664 AddCell(stats
.typeInfo
[eStreamTaskTypeShader
].nTotalRequestCount
);
3666 AddCell("Shader - Streaming Requests:", CELL_BOLD
);
3667 AddCell(stats
.typeInfo
[eStreamTaskTypeShader
].nTotalStreamingRequestCount
);
3669 AddCell("Shader - Total Read Bytes (MB):", CELL_BOLD
);
3670 AddCell(stats
.typeInfo
[eStreamTaskTypeShader
].nTotalReadBytes
/ (1024.f
* 1024.f
));
3672 AddCell("Shader - Average Read Size (KB):", CELL_BOLD
);
3673 AddCell((uint32
)(stats
.typeInfo
[eStreamTaskTypeShader
].nTotalReadBytes
/
3674 max((uint32
)1, stats
.typeInfo
[eStreamTaskTypeShader
].nTotalStreamingRequestCount
) / 1024));
3676 AddCell("Shader - Average Request Size (KB):", CELL_BOLD
);
3677 AddCell((uint32
)(stats
.typeInfo
[eStreamTaskTypeShader
].nTotalRequestDataSize
/
3678 max((uint32
)1, stats
.typeInfo
[eStreamTaskTypeShader
].nTotalStreamingRequestCount
) / 1024));
3681 void CStatsToExcelExporter::ExportAnimationInfo(SCryEngineStats
& stats
)
3683 NewWorksheet("AnimationKeys Info");
3686 Column
= m_CurrTable
->newChild("Column");
3687 Column
->setAttr("ss:Width", 400);
3688 Column
= m_CurrTable
->newChild("Column");
3689 Column
->setAttr("ss:Width", 80);
3690 Column
= m_CurrTable
->newChild("Column");
3691 Column
->setAttr("ss:Width", 80);
3695 AddCell("Animation Keys Current KB:", CELL_BOLD
);
3696 AddCell(stats
.m_AnimMemoryTracking
.m_nAnimsCurrent
/ 1024);
3698 AddCell("Animation Keys Maximum KB::", CELL_BOLD
);
3699 AddCell(stats
.m_AnimMemoryTracking
.m_nAnimsMax
/ 1024);
3702 if (stats
.m_AnimMemoryTracking
.m_nAnimsCounter
)
3703 average
= stats
.m_AnimMemoryTracking
.m_nAnimsAdd
/ stats
.m_AnimMemoryTracking
.m_nAnimsCounter
;
3705 AddCell("Animation Keys Average KB::", CELL_BOLD
);
3706 AddCell(average
/ 1024);
3708 AddCell("Animation Global Counter::", CELL_BOLD
);
3709 AddCell(stats
.m_AnimMemoryTracking
.m_nGlobalCAFs
);
3711 AddCell("Animation Used Global Headers::", CELL_BOLD
);
3712 AddCell(stats
.m_AnimMemoryTracking
.m_nUsedGlobalCAFs
);
3715 AddCell("Animation Char Instances Counter::", CELL_BOLD
);
3716 AddCell(stats
.m_AnimMemoryTracking
.m_numTCharInstances
);
3718 AddCell("Animation Char Instances Memory::", CELL_BOLD
);
3719 AddCell(stats
.m_AnimMemoryTracking
.m_nTotalCharMemory
);
3721 AddCell("Animation Skin Instances Counter::", CELL_BOLD
);
3722 AddCell(stats
.m_AnimMemoryTracking
.m_numTSkinInstances
);
3724 AddCell("Animation Skin Instances Memory::", CELL_BOLD
);
3725 AddCell(stats
.m_AnimMemoryTracking
.m_nTotalSkinMemory
);
3727 AddCell("Animation Model Counter::", CELL_BOLD
);
3728 AddCell(stats
.m_AnimMemoryTracking
.m_numModels
);
3730 AddCell("Animation Model Memory::", CELL_BOLD
);
3731 AddCell(stats
.m_AnimMemoryTracking
.m_nTotalMMemory
);
3735 //////////////////////////////////////////////////////////////////////////
3736 void CStatsToExcelExporter::ExportMemInfo(SCryEngineStats
& stats
)
3738 NewWorksheet("Modules Memory Info");
3742 Column
= m_CurrTable
->newChild("Column");
3743 Column
->setAttr("ss:Width", 300);
3744 Column
= m_CurrTable
->newChild("Column");
3745 Column
->setAttr("ss:Width", 90);
3746 Column
= m_CurrTable
->newChild("Column");
3747 Column
->setAttr("ss:Width", 90);
3748 Column
= m_CurrTable
->newChild("Column");
3749 Column
->setAttr("ss:Width", 90);
3750 Column
= m_CurrTable
->newChild("Column");
3751 Column
->setAttr("ss:Width", 20);
3752 Column
= m_CurrTable
->newChild("Column");
3753 Column
->setAttr("ss:Width", 90);
3754 Column
= m_CurrTable
->newChild("Column");
3755 Column
->setAttr("ss:Width", 90);
3756 Column
= m_CurrTable
->newChild("Column");
3757 Column
->setAttr("ss:Width", 90);
3758 Column
= m_CurrTable
->newChild("Column");
3759 Column
->setAttr("ss:Width", 90);
3760 Column
= m_CurrTable
->newChild("Column");
3761 Column
->setAttr("ss:Width", 90);
3762 Column
= m_CurrTable
->newChild("Column");
3763 Column
->setAttr("ss:Width", 90);
3764 Column
= m_CurrTable
->newChild("Column");
3765 Column
->setAttr("ss:Width", 90);
3767 m_CurrRow
->setAttr("ss:StyleID", "s25");
3769 AddCell("Dynamic(KB)");
3770 AddCell("Num Allocs");
3771 AddCell("Sum Of Allocs (KB)");
3773 AddCell("Static Total (KB)");
3774 AddCell("Static Code (KB)");
3775 AddCell("Static Init. Data (KB)");
3776 AddCell("Static Uninit. Data (KB)");
3777 AddCell("Strings (KB)");
3778 AddCell("STL (KB)");
3779 AddCell("STL Wasted (KB)");
3780 AddCell("Dynamic - Wasted (KB)");
3784 //////////////////////////////////////////////////////////////////////////
3787 for (uint32 i
= 0; i
< stats
.memInfo
.modules
.size(); i
++)
3789 SCryEngineStatsModuleInfo
& moduleInfo
= stats
.memInfo
.modules
[i
];
3790 const char* szModule
= moduleInfo
.name
;
3794 AddCell(szModule
, CELL_BOLD
);
3795 AddCell(moduleInfo
.usedInModule
/ 1024);
3796 AddCell(moduleInfo
.memInfo
.num_allocations
);
3797 AddCell(moduleInfo
.memInfo
.allocated
/ 1024);
3799 AddCell(moduleInfo
.moduleStaticSize
/ 1024);
3800 AddCell((uint32
)moduleInfo
.SizeOfCode
/ 1024);
3801 AddCell((uint32
)moduleInfo
.SizeOfInitializedData
/ 1024);
3802 AddCell((uint32
)moduleInfo
.SizeOfUninitializedData
/ 1024);
3803 AddCell((uint32
)(moduleInfo
.memInfo
.CryString_allocated
/ 1024));
3804 AddCell((uint32
)(moduleInfo
.memInfo
.STL_allocated
/ 1024));
3805 AddCell((uint32
)(moduleInfo
.memInfo
.STL_wasted
/ 1024));
3806 AddCell((uint32
)((moduleInfo
.memInfo
.allocated
- moduleInfo
.memInfo
.requested
) / 1024));
3811 m_CurrRow
->setAttr("ss:StyleID", "s25");
3812 AddCell_SumOfRows(nRows
);
3813 AddCell_SumOfRows(nRows
);
3814 AddCell_SumOfRows(nRows
);
3816 AddCell_SumOfRows(nRows
);
3817 AddCell_SumOfRows(nRows
);
3818 AddCell_SumOfRows(nRows
);
3823 AddCell("Lua Memory Usage (KB)", CELL_BOLD
);
3824 AddCell(stats
.nSummaryScriptSize
/ (1024));
3826 AddCell("Total Num Allocs", CELL_BOLD
);
3827 AddCell(stats
.memInfo
.totalNumAllocsInModules
);
3829 AddCell("Total Allocated (KB)", CELL_BOLD
);
3830 AddCell(stats
.memInfo
.totalUsedInModules
/ 1024);
3832 AddCell("Total Code and Static (KB)", CELL_BOLD
);
3833 AddCell(stats
.memInfo
.totalCodeAndStatic
/ 1024);
3837 AddCell("API Textures (KB)", CELL_BOLD
);
3838 AddCell((uint32
)((stats
.nSummary_TexturesPoolSize
+ stats
.nSummary_UserTextureSize
+ stats
.nSummary_EngineTextureSize
) / (1024 * 1024)));
3840 AddCell("API Meshes (KB)", CELL_BOLD
);
3841 AddCell(stats
.nAPI_MeshSize
/ 1024);
3844 //////////////////////////////////////////////////////////////////////////
3845 void CStatsToExcelExporter::ExportTimeDemoInfo()
3847 STimeDemoInfo
* pTD
= gEnv
->pGameFramework
->GetITimeDemoRecorder()->GetLastPlayedTimeDemo();
3851 NewWorksheet("TimeDemo");
3855 Column
= m_CurrTable
->newChild("Column");
3856 Column
->setAttr("ss:Width", 400);
3857 Column
= m_CurrTable
->newChild("Column");
3858 Column
->setAttr("ss:Width", 80);
3859 Column
= m_CurrTable
->newChild("Column");
3860 Column
->setAttr("ss:Width", 80);
3863 AddCell("Play Time:", CELL_BOLD
);
3864 AddCell(pTD
->lastPlayedTotalTime
);
3866 AddCell("Num Frames:", CELL_BOLD
);
3867 AddCell((int)pTD
->frames
.size());
3869 AddCell("Average FPS:", CELL_BOLD
);
3870 AddCell(pTD
->lastAveFrameRate
);
3872 AddCell("Min FPS:", CELL_BOLD
);
3873 AddCell(pTD
->minFPS
);
3874 AddCell("At Frame:");
3875 AddCell(pTD
->minFPS_Frame
);
3877 AddCell("Max FPS:", CELL_BOLD
);
3878 AddCell(pTD
->maxFPS
);
3879 AddCell("At Frame:");
3880 AddCell(pTD
->maxFPS_Frame
);
3882 AddCell("Average Tri/Sec:", CELL_BOLD
);
3883 AddCell((uint32
)((float)pTD
->nTotalPolysPlayed
/ pTD
->lastPlayedTotalTime
));
3885 AddCell("Average Tri/Frame:", CELL_BOLD
);
3886 AddCell((uint32
)((float)pTD
->nTotalPolysPlayed
/ pTD
->frames
.size()));
3888 AddCell("Played/Recorded Tris ratio:", CELL_BOLD
);
3889 AddCell(pTD
->nTotalPolysRecorded
? (float)pTD
->nTotalPolysPlayed
/ pTD
->nTotalPolysRecorded
: 0.f
);
3891 //////////////////////////////////////////////////////////////////////////
3892 NewWorksheet("TimeDemoFrames");
3895 Column
= m_CurrTable
->newChild("Column");
3896 Column
->setAttr("ss:Width", 80);
3897 Column
= m_CurrTable
->newChild("Column");
3898 Column
->setAttr("ss:Width", 80);
3899 Column
= m_CurrTable
->newChild("Column");
3900 Column
->setAttr("ss:Width", 80);
3902 m_CurrRow
->setAttr("ss:StyleID", "s25");
3903 AddCell("Frame Number");
3904 AddCell("Frame Rate");
3905 AddCell("Rendered Polygons");
3906 AddCell("Draw Calls");
3910 for (int i
= 0; i
< pTD
->frames
.size(); i
++)
3914 AddCell(pTD
->frames
[i
].fFrameRate
);
3915 AddCell(pTD
->frames
[i
].nPolysRendered
);
3916 AddCell(pTD
->frames
[i
].nDrawCalls
);
3920 void CStatsToExcelExporter::ExportFPSBuckets()
3922 //get perfHUD Export stats
3923 ICryPerfHUD
* perfHUD
= GetISystem()->GetPerfHUD();
3927 float totalTime
= 0;
3928 const std::vector
<ICryPerfHUD::PerfBucket
>* fpsBuckets
= perfHUD
->GetFpsBuckets(totalTime
);
3930 if (fpsBuckets
&& totalTime
> 0.f
)
3932 int numBuckets
= fpsBuckets
->size();
3936 m_CurrRow
->setAttr("ss:StyleID", "s25");
3938 AddCell("Frame Rate Bucket");
3939 AddCell("Time Spent%");
3941 for (int i
= 0; i
< numBuckets
; i
++)
3946 cry_sprintf(buf
, ">=%.1f FPS", fpsBuckets
->at(i
).target
);
3949 float percentAtTarget
= 100.f
* (fpsBuckets
->at(i
).timeAtTarget
/ totalTime
);
3950 AddCell(percentAtTarget
);
3956 //////////////////////////////////////////////////////////////////////////
3957 static void SaveLevelStats(IConsoleCmdArgs
* pArgs
)
3959 #if !defined(_RELEASE)
3961 auto levelName
= gEnv
->pGameFramework
->GetLevelName();
3962 if (!levelName
|| !*levelName
)
3964 CryWarning(VALIDATOR_MODULE_GAME
, VALIDATOR_WARNING
, "Cannot save level statistics because level is not loaded.");
3968 CryLog("Execute SaveLevelStats");
3970 SCOPED_ALLOW_FILE_ACCESS_FROM_THIS_THREAD();
3973 string levelName
= "no_level";
3975 ICVar
* sv_map
= gEnv
->pConsole
->GetCVar("sv_map");
3977 levelName
= sv_map
->GetString();
3979 levelName
= PathUtil::GetFileName(levelName
);
3981 bool bDepends
= true;
3982 if (pArgs
->GetArgCount() > 1)
3985 CEngineStats
engineStats(bDepends
);
3989 CStatsToExcelExporter excelExporter
;
3991 string filename
= PathUtil::ReplaceExtension(levelName
, "xml");
3993 excelExporter
.ExportToFile(engineStats
.m_stats
, filename
);
3995 CryLog("SaveLevelStats exported '%s'", filename
.c_str());
3998 // level_dependencies.xml
4001 CStatsToExcelExporter excelExporter
;
4003 engineStats
.m_ResourceCollector
.ComputeDependencyCnt();
4005 string filename
= PathUtil::ReplaceExtension(string("depends_") + levelName
, "xml");
4007 excelExporter
.ExportDependenciesToFile(engineStats
.m_ResourceCollector
, filename
);
4009 // log to log file - modifies engineStats.m_ResourceCollector data
4010 // engineStats.m_ResourceCollector.LogData(*gEnv->pLog);
4011 CryLog("SaveLevelStats exported '%s'", filename
.c_str());
4018 #else // (!defined (_RELEASE) || defined(ENABLE_PROFILING_CODE))
4020 bool QueryModuleMemoryInfo(SCryEngineStatsModuleInfo
& moduleInfo
, int index
)
4025 #endif // (!defined (_RELEASE) || defined(ENABLE_PROFILING_CODE))
4027 void RegisterEngineStatistics()
4029 #if (!defined (_RELEASE) || defined(ENABLE_PROFILING_CODE))
4030 REGISTER_COMMAND("SaveLevelStats", SaveLevelStats
, 0,
4031 "Calling this command creates multiple XML files with level statistics.\n"
4032 "The data includes file usage, dependencies, size in more/disk.\n"
4033 "The files can be loaded in Excel.");