Add more memory profiler categories
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
#include "Engine/Serialization/Serialization.h"
|
||||
#include "Engine/Serialization/JsonWriter.h"
|
||||
#include "Engine/Profiler/ProfilerCPU.h"
|
||||
#include "Engine/Profiler/ProfilerMemory.h"
|
||||
#include "Engine/Utilities/StringConverter.h"
|
||||
#include "Engine/Threading/MainThreadTask.h"
|
||||
#include "Engine/Level/SceneObject.h"
|
||||
@@ -1340,6 +1341,8 @@ bool VisualScript::Save(const StringView& path)
|
||||
|
||||
Asset::LoadResult VisualScript::load()
|
||||
{
|
||||
PROFILE_MEM(ScriptingVisual);
|
||||
|
||||
// Build Visual Script typename that is based on asset id
|
||||
String typeName = _id.ToString();
|
||||
StringUtils::ConvertUTF162ANSI(typeName.Get(), _typenameChars, 32);
|
||||
@@ -1532,6 +1535,7 @@ Asset::LoadResult VisualScript::load()
|
||||
|
||||
void VisualScript::unload(bool isReloading)
|
||||
{
|
||||
PROFILE_MEM(ScriptingVisual);
|
||||
#if USE_EDITOR
|
||||
if (isReloading)
|
||||
{
|
||||
@@ -1588,6 +1592,7 @@ AssetChunksFlag VisualScript::getChunksToPreload() const
|
||||
|
||||
void VisualScript::CacheScriptingType()
|
||||
{
|
||||
PROFILE_MEM(ScriptingVisual);
|
||||
ScopeLock lock(VisualScriptingBinaryModule::Locker);
|
||||
auto& binaryModule = VisualScriptingModule;
|
||||
|
||||
@@ -1723,6 +1728,7 @@ ScriptingObject* VisualScriptingBinaryModule::VisualScriptObjectSpawn(const Scri
|
||||
VisualScript* visualScript = VisualScriptingModule.Scripts[params.Type.TypeIndex];
|
||||
|
||||
// Initialize instance data
|
||||
PROFILE_MEM(ScriptingVisual);
|
||||
ScopeLock lock(visualScript->Locker);
|
||||
auto& instanceParams = visualScript->_instances[object->GetID()].Params;
|
||||
instanceParams.Resize(visualScript->Graph.Parameters.Count());
|
||||
@@ -1747,6 +1753,8 @@ ScriptingObject* VisualScriptingBinaryModule::VisualScriptObjectSpawn(const Scri
|
||||
|
||||
void VisualScriptingBinaryModule::OnScriptsReloading()
|
||||
{
|
||||
PROFILE_MEM(ScriptingVisual);
|
||||
|
||||
// Clear any cached types from that module across all loaded Visual Scripts
|
||||
for (auto& script : Scripts)
|
||||
{
|
||||
@@ -1795,6 +1803,7 @@ void VisualScriptingBinaryModule::OnScriptsReloading()
|
||||
|
||||
void VisualScriptingBinaryModule::OnEvent(ScriptingObject* object, Span<Variant> parameters, ScriptingTypeHandle eventType, StringView eventName)
|
||||
{
|
||||
PROFILE_MEM(ScriptingVisual);
|
||||
if (object)
|
||||
{
|
||||
// Object event
|
||||
@@ -1956,6 +1965,7 @@ bool VisualScriptingBinaryModule::GetFieldValue(void* field, const Variant& inst
|
||||
|
||||
bool VisualScriptingBinaryModule::SetFieldValue(void* field, const Variant& instance, Variant& value)
|
||||
{
|
||||
PROFILE_MEM(ScriptingVisual);
|
||||
const auto vsFiled = (VisualScript::Field*)field;
|
||||
const auto instanceObject = (ScriptingObject*)instance;
|
||||
if (!instanceObject)
|
||||
@@ -2042,6 +2052,7 @@ void VisualScriptingBinaryModule::SerializeObject(JsonWriter& stream, ScriptingO
|
||||
|
||||
void VisualScriptingBinaryModule::DeserializeObject(ISerializable::DeserializeStream& stream, ScriptingObject* object, ISerializeModifier* modifier)
|
||||
{
|
||||
PROFILE_MEM(ScriptingVisual);
|
||||
ASSERT(stream.IsObject());
|
||||
Locker.Lock();
|
||||
const auto asset = Scripts[object->GetTypeHandle().TypeIndex].Get();
|
||||
@@ -2165,6 +2176,7 @@ const Variant& VisualScript::GetScriptInstanceParameterValue(const StringView& n
|
||||
|
||||
void VisualScript::SetScriptInstanceParameterValue(const StringView& name, ScriptingObject* instance, const Variant& value)
|
||||
{
|
||||
PROFILE_MEM(ScriptingVisual);
|
||||
CHECK(instance);
|
||||
for (int32 paramIndex = 0; paramIndex < Graph.Parameters.Count(); paramIndex++)
|
||||
{
|
||||
@@ -2186,6 +2198,7 @@ void VisualScript::SetScriptInstanceParameterValue(const StringView& name, Scrip
|
||||
|
||||
void VisualScript::SetScriptInstanceParameterValue(const StringView& name, ScriptingObject* instance, Variant&& value)
|
||||
{
|
||||
PROFILE_MEM(ScriptingVisual);
|
||||
CHECK(instance);
|
||||
for (int32 paramIndex = 0; paramIndex < Graph.Parameters.Count(); paramIndex++)
|
||||
{
|
||||
@@ -2383,6 +2396,7 @@ VisualScriptingBinaryModule* VisualScripting::GetBinaryModule()
|
||||
|
||||
Variant VisualScripting::Invoke(VisualScript::Method* method, ScriptingObject* instance, Span<Variant> parameters)
|
||||
{
|
||||
PROFILE_MEM(ScriptingVisual);
|
||||
CHECK_RETURN(method && method->Script->IsLoaded(), Variant::Zero);
|
||||
PROFILE_CPU_SRC_LOC(method->ProfilerData);
|
||||
|
||||
@@ -2423,6 +2437,7 @@ bool VisualScripting::Evaluate(VisualScript* script, ScriptingObject* instance,
|
||||
const auto box = node->GetBox(boxId);
|
||||
if (!box)
|
||||
return false;
|
||||
PROFILE_MEM(ScriptingVisual);
|
||||
|
||||
// Add to the calling stack
|
||||
ScopeContext scope;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "ArenaAllocation.h"
|
||||
#include "../Math/Math.h"
|
||||
#include "Engine/Profiler/ProfilerMemory.h"
|
||||
|
||||
void ArenaAllocator::Free()
|
||||
{
|
||||
@@ -9,6 +10,9 @@ void ArenaAllocator::Free()
|
||||
Page* page = _first;
|
||||
while (page)
|
||||
{
|
||||
#if COMPILE_WITH_PROFILER
|
||||
ProfilerMemory::OnGroupUpdate(ProfilerMemory::Groups::MallocArena, -page->Size, -1);
|
||||
#endif
|
||||
Allocator::Free(page->Memory);
|
||||
Page* next = page->Next;
|
||||
Allocator::Free(page);
|
||||
@@ -30,6 +34,9 @@ void* ArenaAllocator::Allocate(uint64 size, uint64 alignment)
|
||||
if (!page)
|
||||
{
|
||||
uint64 pageSize = Math::Max<uint64>(_pageSize, size);
|
||||
#if COMPILE_WITH_PROFILER
|
||||
ProfilerMemory::OnGroupUpdate(ProfilerMemory::Groups::MallocArena, pageSize, 1);
|
||||
#endif
|
||||
page = (Page*)Allocator::Allocate(sizeof(Page));
|
||||
page->Memory = Allocator::Allocate(pageSize);
|
||||
page->Next = _first;
|
||||
|
||||
@@ -244,7 +244,15 @@ bool GPUBuffer::Init(const GPUBufferDescription& desc)
|
||||
LOG(Warning, "Cannot initialize buffer. Description: {0}", desc.ToString());
|
||||
return true;
|
||||
}
|
||||
PROFILE_MEM_INC(GraphicsBuffers, GetMemoryUsage());
|
||||
|
||||
#if COMPILE_WITH_PROFILER
|
||||
auto group = ProfilerMemory::Groups::GraphicsBuffers;
|
||||
if (EnumHasAnyFlags(_desc.Flags, GPUBufferFlags::VertexBuffer))
|
||||
group = ProfilerMemory::Groups::GraphicsVertexBuffers;
|
||||
else if (EnumHasAnyFlags(_desc.Flags, GPUBufferFlags::IndexBuffer))
|
||||
group = ProfilerMemory::Groups::GraphicsIndexBuffers;
|
||||
ProfilerMemory::IncrementGroup(group, _memoryUsage);
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -480,7 +488,15 @@ GPUResourceType GPUBuffer::GetResourceType() const
|
||||
|
||||
void GPUBuffer::OnReleaseGPU()
|
||||
{
|
||||
PROFILE_MEM_DEC(GraphicsBuffers, GetMemoryUsage());
|
||||
#if COMPILE_WITH_PROFILER
|
||||
auto group = ProfilerMemory::Groups::GraphicsBuffers;
|
||||
if (EnumHasAnyFlags(_desc.Flags, GPUBufferFlags::VertexBuffer))
|
||||
group = ProfilerMemory::Groups::GraphicsVertexBuffers;
|
||||
else if (EnumHasAnyFlags(_desc.Flags, GPUBufferFlags::IndexBuffer))
|
||||
group = ProfilerMemory::Groups::GraphicsIndexBuffers;
|
||||
ProfilerMemory::IncrementGroup(group, _memoryUsage);
|
||||
#endif
|
||||
|
||||
_desc.Clear();
|
||||
_isLocked = false;
|
||||
}
|
||||
|
||||
@@ -503,7 +503,17 @@ bool GPUTexture::Init(const GPUTextureDescription& desc)
|
||||
LOG(Warning, "Cannot initialize texture. Description: {0}", desc.ToString());
|
||||
return true;
|
||||
}
|
||||
PROFILE_MEM_INC(GraphicsTextures, GetMemoryUsage());
|
||||
|
||||
#if COMPILE_WITH_PROFILER
|
||||
auto group = ProfilerMemory::Groups::GraphicsTextures;
|
||||
if (_desc.IsRenderTarget())
|
||||
group = ProfilerMemory::Groups::GraphicsRenderTargets;
|
||||
else if (_desc.IsCubeMap())
|
||||
group = ProfilerMemory::Groups::GraphicsCubeMaps;
|
||||
else if (_desc.IsVolume())
|
||||
group = ProfilerMemory::Groups::GraphicsVolumeTextures;
|
||||
ProfilerMemory::IncrementGroup(group, _memoryUsage);
|
||||
#endif
|
||||
|
||||
// Render targets and depth buffers doesn't support normal textures streaming and are considered to be always resident
|
||||
if (IsRegularTexture() == false)
|
||||
@@ -593,7 +603,17 @@ GPUResourceType GPUTexture::GetResourceType() const
|
||||
|
||||
void GPUTexture::OnReleaseGPU()
|
||||
{
|
||||
PROFILE_MEM_DEC(GraphicsTextures, GetMemoryUsage());
|
||||
#if COMPILE_WITH_PROFILER
|
||||
auto group = ProfilerMemory::Groups::GraphicsTextures;
|
||||
if (_desc.IsRenderTarget())
|
||||
group = ProfilerMemory::Groups::GraphicsRenderTargets;
|
||||
else if (_desc.IsCubeMap())
|
||||
group = ProfilerMemory::Groups::GraphicsCubeMaps;
|
||||
else if (_desc.IsVolume())
|
||||
group = ProfilerMemory::Groups::GraphicsVolumeTextures;
|
||||
ProfilerMemory::DecrementGroup(group, _memoryUsage);
|
||||
#endif
|
||||
|
||||
_desc.Clear();
|
||||
_residentMipLevels = 0;
|
||||
}
|
||||
|
||||
@@ -25,14 +25,14 @@ struct GroupNameBuffer
|
||||
Char Buffer[30];
|
||||
|
||||
template<typename T>
|
||||
void Set(const T* str)
|
||||
void Set(const T* str, bool autoFormat = false)
|
||||
{
|
||||
int32 max = StringUtils::Length(str), dst = 0;
|
||||
char prev = 0;
|
||||
for (int32 i = 0; i < max && dst < ARRAY_COUNT(Buffer) - 2; i++)
|
||||
{
|
||||
char cur = str[i];
|
||||
if (StringUtils::IsUpper(cur) && StringUtils::IsLower(prev))
|
||||
if (autoFormat && StringUtils::IsUpper(cur) && StringUtils::IsLower(prev))
|
||||
Buffer[dst++] = '/';
|
||||
Buffer[dst++] = cur;
|
||||
prev = cur;
|
||||
@@ -52,10 +52,6 @@ struct GroupStackData
|
||||
{
|
||||
if (Count < ARRAY_COUNT(Stack))
|
||||
Count++;
|
||||
else
|
||||
{
|
||||
int a= 10;
|
||||
}
|
||||
Stack[Count - 1] = (uint8)group;
|
||||
}
|
||||
|
||||
@@ -112,8 +108,15 @@ namespace
|
||||
for (int32 i = 0; i < GROUPS_COUNT; i++)
|
||||
{
|
||||
const char* name = ScriptingEnum::GetName((ProfilerMemory::Groups)i);
|
||||
GroupNames[i].Set(name);
|
||||
GroupNames[i].Set(name, true);
|
||||
}
|
||||
#define RENAME_GROUP(group, name) GroupNames[(int32)ProfilerMemory::Groups::group].Set(name)
|
||||
RENAME_GROUP(GraphicsRenderTargets, "Graphics/RenderTargets");
|
||||
RENAME_GROUP(GraphicsCubeMaps, "Graphics/CubeMaps");
|
||||
RENAME_GROUP(GraphicsVolumeTextures, "Graphics/VolumeTextures");
|
||||
RENAME_GROUP(GraphicsVertexBuffers, "Graphics/VertexBuffers");
|
||||
RENAME_GROUP(GraphicsIndexBuffers, "Graphics/IndexBuffers");
|
||||
#undef RENAME_GROUP
|
||||
|
||||
// Init constant memory
|
||||
PROFILE_MEM_INC(ProgramSize, Platform::GetMemoryStats().ProgramSizeMemory);
|
||||
@@ -162,31 +165,6 @@ namespace
|
||||
output.AppendLine();
|
||||
}
|
||||
|
||||
#if 0
|
||||
// Print count of memory allocs count per group
|
||||
for (int32 i = 0; i < GROUPS_COUNT; i++)
|
||||
{
|
||||
GroupInfo& group = groups[i];
|
||||
group.Group = (ProfilerMemory::Groups)i;
|
||||
group.Size = 0;
|
||||
}
|
||||
PointersLocker.Lock();
|
||||
for (auto& e : Pointers)
|
||||
groups[e.Value.Group].Size++;
|
||||
PointersLocker.Unlock();
|
||||
Sorting::QuickSort(groups, GROUPS_COUNT);
|
||||
output.Append(TEXT("Memory allocations count summary:")).AppendLine();
|
||||
for (int32 i = 0; i < maxCount; i++)
|
||||
{
|
||||
const GroupInfo& group = groups[i];
|
||||
if (group.Size == 0)
|
||||
break;
|
||||
const Char* name = GroupName[(int32)group.Group].Buffer;
|
||||
output.AppendFormat(TEXT("{:>30}: {:>11}"), name, group.Size);
|
||||
output.AppendLine();
|
||||
}
|
||||
#endif
|
||||
|
||||
// Warn that data might be missing due to inactive profiler
|
||||
if (!ProfilerMemory::Enabled)
|
||||
output.AppendLine(TEXT("Detailed memory profiling is disabled. Run with command line: -mem"));
|
||||
@@ -243,8 +221,14 @@ void InitProfilerMemory(const Char* cmdLine)
|
||||
|
||||
// Init hierarchy
|
||||
#define INIT_PARENT(parent, child) GroupParents[(int32)ProfilerMemory::Groups::child] = (uint8)ProfilerMemory::Groups::parent
|
||||
INIT_PARENT(Malloc, MallocArena);
|
||||
INIT_PARENT(Graphics, GraphicsTextures);
|
||||
INIT_PARENT(Graphics, GraphicsRenderTargets);
|
||||
INIT_PARENT(Graphics, GraphicsCubeMaps);
|
||||
INIT_PARENT(Graphics, GraphicsVolumeTextures);
|
||||
INIT_PARENT(Graphics, GraphicsBuffers);
|
||||
INIT_PARENT(Graphics, GraphicsVertexBuffers);
|
||||
INIT_PARENT(Graphics, GraphicsIndexBuffers);
|
||||
INIT_PARENT(Graphics, GraphicsMeshes);
|
||||
INIT_PARENT(Graphics, GraphicsShaders);
|
||||
INIT_PARENT(Graphics, GraphicsMaterials);
|
||||
@@ -414,4 +398,11 @@ void ProfilerMemory::OnMemoryFree(void* ptr)
|
||||
stack.SkipRecursion = false;
|
||||
}
|
||||
|
||||
void ProfilerMemory::OnGroupUpdate(Groups group, int64 sizeDelta, int64 countDetla)
|
||||
{
|
||||
Platform::InterlockedAdd(&GroupMemory[(int32)group], sizeDelta);
|
||||
Platform::InterlockedAdd(&GroupMemoryCount[(int32)group], countDetla);
|
||||
UPDATE_PEEK(group);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -30,19 +30,32 @@ public:
|
||||
TotalUntracked,
|
||||
// Initial memory used by program upon startup (eg. executable size, static variables).
|
||||
ProgramSize,
|
||||
// Total memory allocated via malloc.
|
||||
Malloc,
|
||||
// General purpose engine memory.
|
||||
Engine,
|
||||
// Profiling tool memory overhead.
|
||||
Profiler,
|
||||
|
||||
// Total memory allocated via dynamic memory allocations.
|
||||
Malloc,
|
||||
// Total memory allocated via arena allocators (all pages).
|
||||
MallocArena,
|
||||
|
||||
// Total graphics memory usage.
|
||||
Graphics,
|
||||
// Total textures memory usage.
|
||||
GraphicsTextures,
|
||||
// Total render targets memory usage (textures used as target image for rendering).
|
||||
GraphicsRenderTargets,
|
||||
// Total cubemap textures memory usage (each cubemap is 6 textures).
|
||||
GraphicsCubeMaps,
|
||||
// Total volume textures memory usage (3D textures).
|
||||
GraphicsVolumeTextures,
|
||||
// Total buffers memory usage.
|
||||
GraphicsBuffers,
|
||||
// Total vertex buffers memory usage.
|
||||
GraphicsVertexBuffers,
|
||||
// Total index buffers memory usage.
|
||||
GraphicsIndexBuffers,
|
||||
// Total meshes memory usage (vertex and idnex buffers allocated by models).
|
||||
GraphicsMeshes,
|
||||
// Totoal shaders memory usage (shaders bytecode, PSOs data).
|
||||
@@ -95,6 +108,8 @@ public:
|
||||
|
||||
// Total scripting memory allocated by game.
|
||||
Scripting,
|
||||
// Total Visual scripting memory allocated by game (visual script graphs, data and runtime allocations).
|
||||
ScriptingVisual,
|
||||
|
||||
// Total User Interface components memory.
|
||||
UI,
|
||||
@@ -144,6 +159,15 @@ public:
|
||||
// Custom plugin-specific memory tracking.
|
||||
CustomPlugin9,
|
||||
|
||||
// Custom platform-specific memory tracking.
|
||||
CustomPlatform0,
|
||||
// Custom platform-specific memory tracking.
|
||||
CustomPlatform1,
|
||||
// Custom platform-specific memory tracking.
|
||||
CustomPlatform2,
|
||||
// Custom platform-specific memory tracking.
|
||||
CustomPlatform3,
|
||||
|
||||
// Total editor-specific memory.
|
||||
Editor,
|
||||
|
||||
@@ -219,6 +243,7 @@ public:
|
||||
|
||||
static void OnMemoryAlloc(void* ptr, uint64 size);
|
||||
static void OnMemoryFree(void* ptr);
|
||||
static void OnGroupUpdate(Groups group, int64 sizeDelta, int64 countDetla);
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user