Add more improvements to usability of memory profiler
This commit is contained in:
@@ -232,7 +232,7 @@ namespace FlaxEditor.Windows.Profiler
|
||||
Array.Sort(_groupOrder, (x, y) =>
|
||||
{
|
||||
var tmp = _frames.Get(selectedFrame);
|
||||
return (int)(tmp.Usage.Values0[y] - tmp.Usage.Values0[x]);
|
||||
return tmp.Usage.Values0[y].CompareTo(tmp.Usage.Values0[x]);
|
||||
});
|
||||
|
||||
// Add rows
|
||||
|
||||
@@ -400,6 +400,7 @@ void Foliage::DrawClusterGlobalSA(GlobalSurfaceAtlasPass* globalSA, const Vector
|
||||
void Foliage::DrawFoliageJob(int32 i)
|
||||
{
|
||||
PROFILE_CPU();
|
||||
PROFILE_MEM(Graphics);
|
||||
const FoliageType& type = FoliageTypes[i];
|
||||
if (type.IsReady() && type.Model->CanBeRendered())
|
||||
{
|
||||
@@ -551,6 +552,7 @@ FoliageType* Foliage::GetFoliageType(int32 index)
|
||||
void Foliage::AddFoliageType(Model* model)
|
||||
{
|
||||
PROFILE_CPU();
|
||||
PROFILE_MEM(LevelFoliage);
|
||||
|
||||
// Ensure to have unique model
|
||||
CHECK(model);
|
||||
@@ -629,6 +631,7 @@ int32 Foliage::GetFoliageTypeInstancesCount(int32 index) const
|
||||
|
||||
void Foliage::AddInstance(const FoliageInstance& instance)
|
||||
{
|
||||
PROFILE_MEM(LevelFoliage);
|
||||
ASSERT(instance.Type >= 0 && instance.Type < FoliageTypes.Count());
|
||||
auto type = &FoliageTypes[instance.Type];
|
||||
|
||||
@@ -705,6 +708,7 @@ void Foliage::OnFoliageTypeModelLoaded(int32 index)
|
||||
if (_disableFoliageTypeEvents)
|
||||
return;
|
||||
PROFILE_CPU();
|
||||
PROFILE_MEM(LevelFoliage);
|
||||
auto& type = FoliageTypes[index];
|
||||
ASSERT(type.IsReady());
|
||||
|
||||
@@ -803,6 +807,7 @@ void Foliage::OnFoliageTypeModelLoaded(int32 index)
|
||||
void Foliage::RebuildClusters()
|
||||
{
|
||||
PROFILE_CPU();
|
||||
PROFILE_MEM(LevelFoliage);
|
||||
|
||||
// Faster path if foliage is empty or no types is ready
|
||||
bool anyTypeReady = false;
|
||||
@@ -1328,6 +1333,7 @@ void Foliage::Deserialize(DeserializeStream& stream, ISerializeModifier* modifie
|
||||
Actor::Deserialize(stream, modifier);
|
||||
|
||||
PROFILE_CPU();
|
||||
PROFILE_MEM(LevelFoliage);
|
||||
|
||||
// Clear
|
||||
#if FOLIAGE_USE_SINGLE_QUAD_TREE
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "Engine/Core/Collections/ArrayExtensions.h"
|
||||
#include "Engine/Core/Random.h"
|
||||
#include "Engine/Serialization/Serialization.h"
|
||||
#include "Engine/Profiler/ProfilerMemory.h"
|
||||
#include "Foliage.h"
|
||||
|
||||
FoliageType::FoliageType()
|
||||
@@ -62,6 +63,7 @@ Array<MaterialBase*> FoliageType::GetMaterials() const
|
||||
|
||||
void FoliageType::SetMaterials(const Array<MaterialBase*>& value)
|
||||
{
|
||||
PROFILE_MEM(LevelFoliage);
|
||||
CHECK(value.Count() == Entries.Count());
|
||||
for (int32 i = 0; i < value.Count(); i++)
|
||||
Entries[i].Material = value[i];
|
||||
@@ -114,6 +116,8 @@ void FoliageType::OnModelChanged()
|
||||
|
||||
void FoliageType::OnModelLoaded()
|
||||
{
|
||||
PROFILE_MEM(LevelFoliage);
|
||||
|
||||
// Now it's ready
|
||||
_isReady = 1;
|
||||
|
||||
@@ -169,6 +173,7 @@ void FoliageType::Serialize(SerializeStream& stream, const void* otherObj)
|
||||
|
||||
void FoliageType::Deserialize(DeserializeStream& stream, ISerializeModifier* modifier)
|
||||
{
|
||||
PROFILE_MEM(LevelFoliage);
|
||||
DESERIALIZE(Model);
|
||||
|
||||
const auto member = stream.FindMember("Materials");
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#define USE_TRACY_MEMORY_PLOTS (defined(TRACY_ENABLE))
|
||||
|
||||
static_assert(GROUPS_COUNT <= MAX_uint8, "Fix memory profiler groups to fit a single byte.");
|
||||
static_assert(sizeof(ProfilerMemory::Groups) == sizeof(uint8), "Fix memory profiler groups to fit a single byte.");
|
||||
|
||||
// Compact name storage.
|
||||
struct GroupNameBuffer
|
||||
@@ -32,17 +33,17 @@ struct GroupNameBuffer
|
||||
void Set(const T* str, bool autoFormat = false)
|
||||
{
|
||||
int32 max = StringUtils::Length(str), dst = 0;
|
||||
char prev = 0;
|
||||
T prev = 0;
|
||||
for (int32 i = 0; i < max && dst < ARRAY_COUNT(Buffer) - 2; i++)
|
||||
{
|
||||
char cur = (char)str[i];
|
||||
T cur = (T)str[i];
|
||||
if (autoFormat && StringUtils::IsUpper(cur) && StringUtils::IsLower(prev))
|
||||
{
|
||||
Ansi[dst] = '/';
|
||||
Buffer[dst++] = '/';
|
||||
}
|
||||
Ansi[dst] = cur;
|
||||
Buffer[dst++] = cur;
|
||||
Ansi[dst] = (char)cur;
|
||||
Buffer[dst++] = (Char)cur;
|
||||
prev = cur;
|
||||
}
|
||||
Buffer[dst] = 0;
|
||||
@@ -257,6 +258,8 @@ void InitProfilerMemory(const Char* cmdLine, int32 stage)
|
||||
INIT_PARENT(Animations, AnimationsData);
|
||||
INIT_PARENT(Content, ContentAssets);
|
||||
INIT_PARENT(Content, ContentFiles);
|
||||
INIT_PARENT(Level, LevelFoliage);
|
||||
INIT_PARENT(Level, LevelTerrain);
|
||||
INIT_PARENT(Scripting, ScriptingVisual);
|
||||
INIT_PARENT(Scripting, ScriptingCSharp);
|
||||
INIT_PARENT(ScriptingCSharp, ScriptingCSharpGCCommitted);
|
||||
@@ -403,10 +406,10 @@ ProfilerMemory::GroupsArray ProfilerMemory::GetGroups(int32 mode)
|
||||
void ProfilerMemory::Dump(const StringView& options)
|
||||
{
|
||||
#if LOG_ENABLE
|
||||
bool file = options.Contains(TEXT("file"));
|
||||
bool file = options.Contains(TEXT("file"), StringSearchCase::IgnoreCase);
|
||||
StringBuilder output;
|
||||
int32 maxCount = 20;
|
||||
if (file || options.Contains(TEXT("all")))
|
||||
if (file || options.Contains(TEXT("all"), StringSearchCase::IgnoreCase))
|
||||
maxCount = MAX_int32;
|
||||
::Dump(output, maxCount);
|
||||
if (file)
|
||||
@@ -476,10 +479,10 @@ void ProfilerMemory::OnMemoryFree(void* ptr)
|
||||
stack.SkipRecursion = false;
|
||||
}
|
||||
|
||||
void ProfilerMemory::OnGroupUpdate(Groups group, int64 sizeDelta, int64 countDetla)
|
||||
void ProfilerMemory::OnGroupUpdate(Groups group, int64 sizeDelta, int64 countDelta)
|
||||
{
|
||||
Platform::InterlockedAdd(&GroupMemory[(int32)group], sizeDelta);
|
||||
Platform::InterlockedAdd(&GroupMemoryCount[(int32)group], countDetla);
|
||||
Platform::InterlockedAdd(&GroupMemoryCount[(int32)group], countDelta);
|
||||
UPDATE_PEEK(group);
|
||||
}
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ public:
|
||||
GraphicsVertexBuffers,
|
||||
// Total index buffers memory usage.
|
||||
GraphicsIndexBuffers,
|
||||
// Total meshes memory usage (vertex and idnex buffers allocated by models).
|
||||
// Total meshes memory usage (vertex and index buffers allocated by models).
|
||||
GraphicsMeshes,
|
||||
// Totoal shaders memory usage (shaders bytecode, PSOs data).
|
||||
GraphicsShaders,
|
||||
@@ -78,7 +78,7 @@ public:
|
||||
// Total animation data memory usage (curves, events, keyframes, graphs, etc.).
|
||||
AnimationsData,
|
||||
|
||||
// Total autio system memory.
|
||||
// Total audio system memory.
|
||||
Audio,
|
||||
|
||||
// Total content system memory usage.
|
||||
@@ -90,11 +90,15 @@ public:
|
||||
// Total memory used by content streaming system (internals).
|
||||
ContentStreaming,
|
||||
|
||||
// Total memory allocated by input system.
|
||||
Input,
|
||||
|
||||
// Total memory allocated by scene objects.
|
||||
Level,
|
||||
// Total memory allocated by the foliage system (quad-tree, foliage instances data). Excluding foliage models data.
|
||||
LevelFoliage,
|
||||
// Total memory allocated by the terrain system (patches).
|
||||
LevelTerrain,
|
||||
|
||||
// Total memory allocated by input system.
|
||||
Input,
|
||||
|
||||
// Total localization system memory.
|
||||
Localization,
|
||||
@@ -148,7 +152,7 @@ public:
|
||||
CustomGame8,
|
||||
// Custom game-specific memory tracking.
|
||||
CustomGame9,
|
||||
|
||||
|
||||
// Custom plugin-specific memory tracking.
|
||||
CustomPlugin0,
|
||||
// Custom plugin-specific memory tracking.
|
||||
@@ -186,7 +190,7 @@ public:
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// The memory groups array wraper to avoid dynamic memory allocation.
|
||||
/// The memory groups array wrapper to avoid dynamic memory allocation.
|
||||
/// </summary>
|
||||
API_STRUCT(NoDefault) struct GroupsArray
|
||||
{
|
||||
@@ -254,7 +258,7 @@ public:
|
||||
|
||||
static void OnMemoryAlloc(void* ptr, uint64 size);
|
||||
static void OnMemoryFree(void* ptr);
|
||||
static void OnGroupUpdate(Groups group, int64 sizeDelta, int64 countDetla);
|
||||
static void OnGroupUpdate(Groups group, int64 sizeDelta, int64 countDelta);
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "Engine/Graphics/Textures/GPUTexture.h"
|
||||
#include "Engine/Level/Scene/Scene.h"
|
||||
#include "Engine/Profiler/ProfilerCPU.h"
|
||||
#include "Engine/Profiler/ProfilerMemory.h"
|
||||
#include "Engine/Renderer/GlobalSignDistanceFieldPass.h"
|
||||
#include "Engine/Renderer/GI/GlobalSurfaceAtlasPass.h"
|
||||
|
||||
@@ -290,6 +291,7 @@ void Terrain::SetCollisionLOD(int32 value)
|
||||
|
||||
void Terrain::SetPhysicalMaterials(const Array<JsonAssetReference<PhysicalMaterial>, FixedAllocation<8>>& value)
|
||||
{
|
||||
PROFILE_MEM(LevelTerrain);
|
||||
_physicalMaterials = value;
|
||||
_physicalMaterials.Resize(8);
|
||||
JsonAsset* materials[8];
|
||||
@@ -431,6 +433,7 @@ void Terrain::Setup(int32 lodCount, int32 chunkSize)
|
||||
|
||||
void Terrain::AddPatches(const Int2& numberOfPatches)
|
||||
{
|
||||
PROFILE_MEM(LevelTerrain);
|
||||
if (_chunkSize == 0)
|
||||
Setup();
|
||||
_patches.ClearDelete();
|
||||
@@ -470,6 +473,7 @@ void Terrain::AddPatch(const Int2& patchCoord)
|
||||
LOG(Warning, "Cannot add patch at {0}x{1}. The patch at the given location already exists.", patchCoord.X, patchCoord.Y);
|
||||
return;
|
||||
}
|
||||
PROFILE_MEM(LevelTerrain);
|
||||
if (_chunkSize == 0)
|
||||
Setup();
|
||||
|
||||
@@ -726,6 +730,8 @@ void Terrain::Serialize(SerializeStream& stream, const void* otherObj)
|
||||
|
||||
void Terrain::Deserialize(DeserializeStream& stream, ISerializeModifier* modifier)
|
||||
{
|
||||
PROFILE_MEM(LevelTerrain);
|
||||
|
||||
// Base
|
||||
Actor::Deserialize(stream, modifier);
|
||||
|
||||
|
||||
@@ -5,16 +5,17 @@
|
||||
#include "Engine/Threading/Threading.h"
|
||||
#include "Engine/Graphics/GPUDevice.h"
|
||||
#include "Engine/Graphics/GPUBuffer.h"
|
||||
#include "Engine/Graphics/Shaders/GPUVertexLayout.h"
|
||||
#include "Engine/Core/Log.h"
|
||||
#include "Engine/Core/Math/Color32.h"
|
||||
#include "Engine/Core/Collections/ChunkedArray.h"
|
||||
#include "Engine/Core/Collections/Dictionary.h"
|
||||
#include "Engine/Content/Content.h"
|
||||
#include "Engine/Engine/EngineService.h"
|
||||
#include "Engine/Content/Content.h"
|
||||
#include "Engine/Content/Assets/MaterialBase.h"
|
||||
#include "Engine/Content/AssetReference.h"
|
||||
#include "Engine/Core/Log.h"
|
||||
#include "Engine/Graphics/Shaders/GPUVertexLayout.h"
|
||||
#include "Engine/Renderer/DrawCall.h"
|
||||
#include "Engine/Profiler/ProfilerMemory.h"
|
||||
|
||||
// Must match structure defined in Terrain.shader
|
||||
struct TerrainVertex
|
||||
@@ -94,6 +95,7 @@ bool TerrainManager::GetChunkGeometry(DrawCall& drawCall, int32 chunkSize, int32
|
||||
data->GetChunkGeometry(drawCall);
|
||||
return false;
|
||||
}
|
||||
PROFILE_MEM(LevelTerrain);
|
||||
|
||||
// Prepare
|
||||
const int32 vertexCount = (chunkSize + 1) >> lodIndex;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "Engine/Core/Log.h"
|
||||
#include "Engine/Core/Math/Color32.h"
|
||||
#include "Engine/Profiler/ProfilerCPU.h"
|
||||
#include "Engine/Profiler/ProfilerMemory.h"
|
||||
#include "Engine/Physics/Physics.h"
|
||||
#include "Engine/Physics/PhysicsScene.h"
|
||||
#include "Engine/Physics/PhysicsBackend.h"
|
||||
@@ -66,6 +67,7 @@ TerrainPatch::TerrainPatch(const SpawnParams& params)
|
||||
|
||||
void TerrainPatch::Init(Terrain* terrain, int16 x, int16 z)
|
||||
{
|
||||
PROFILE_MEM(LevelTerrain);
|
||||
ScopeLock lock(_collisionLocker);
|
||||
|
||||
_terrain = terrain;
|
||||
@@ -823,6 +825,7 @@ bool ModifyCollision(TerrainDataUpdateInfo& info, TextureBase::InitData* initDat
|
||||
bool TerrainPatch::SetupHeightMap(int32 heightMapLength, const float* heightMap, const byte* holesMask, bool forceUseVirtualStorage)
|
||||
{
|
||||
PROFILE_CPU_NAMED("Terrain.Setup");
|
||||
PROFILE_MEM(LevelTerrain);
|
||||
if (heightMap == nullptr)
|
||||
{
|
||||
LOG(Warning, "Cannot create terrain without a heightmap specified.");
|
||||
@@ -1034,6 +1037,7 @@ bool TerrainPatch::SetupHeightMap(int32 heightMapLength, const float* heightMap,
|
||||
bool TerrainPatch::SetupSplatMap(int32 index, int32 splatMapLength, const Color32* splatMap, bool forceUseVirtualStorage)
|
||||
{
|
||||
PROFILE_CPU_NAMED("Terrain.SetupSplatMap");
|
||||
PROFILE_MEM(LevelTerrain);
|
||||
CHECK_RETURN(index >= 0 && index < TERRAIN_MAX_SPLATMAPS_COUNT, true);
|
||||
if (splatMap == nullptr)
|
||||
{
|
||||
@@ -1182,6 +1186,7 @@ bool TerrainPatch::SetupSplatMap(int32 index, int32 splatMapLength, const Color3
|
||||
bool TerrainPatch::InitializeHeightMap()
|
||||
{
|
||||
PROFILE_CPU_NAMED("Terrain.InitializeHeightMap");
|
||||
PROFILE_MEM(LevelTerrain);
|
||||
const auto heightmapSize = _terrain->GetChunkSize() * Terrain::ChunksCountEdge + 1;
|
||||
Array<float> heightmap;
|
||||
heightmap.Resize(heightmapSize * heightmapSize);
|
||||
@@ -1248,6 +1253,7 @@ void TerrainPatch::ClearCache()
|
||||
void TerrainPatch::CacheHeightData()
|
||||
{
|
||||
PROFILE_CPU_NAMED("Terrain.CacheHeightData");
|
||||
PROFILE_MEM(LevelTerrain);
|
||||
const TerrainDataUpdateInfo info(this);
|
||||
|
||||
// Ensure that heightmap data is all loaded
|
||||
@@ -1313,6 +1319,7 @@ void TerrainPatch::CacheHeightData()
|
||||
void TerrainPatch::CacheSplatData()
|
||||
{
|
||||
PROFILE_CPU_NAMED("Terrain.CacheSplatData");
|
||||
PROFILE_MEM(LevelTerrain);
|
||||
const TerrainDataUpdateInfo info(this);
|
||||
|
||||
// Cache all the splatmaps
|
||||
@@ -1396,6 +1403,7 @@ bool TerrainPatch::ModifyHeightMap(const float* samples, const Int2& modifiedOff
|
||||
return true;
|
||||
}
|
||||
PROFILE_CPU_NAMED("Terrain.ModifyHeightMap");
|
||||
PROFILE_MEM(LevelTerrain);
|
||||
|
||||
// Check if has no heightmap
|
||||
if (Heightmap == nullptr)
|
||||
@@ -1490,6 +1498,7 @@ bool TerrainPatch::ModifyHolesMask(const byte* samples, const Int2& modifiedOffs
|
||||
return true;
|
||||
}
|
||||
PROFILE_CPU_NAMED("Terrain.ModifyHolesMask");
|
||||
PROFILE_MEM(LevelTerrain);
|
||||
|
||||
// Check if has no heightmap
|
||||
if (Heightmap == nullptr)
|
||||
@@ -1567,6 +1576,7 @@ bool TerrainPatch::ModifySplatMap(int32 index, const Color32* samples, const Int
|
||||
return true;
|
||||
}
|
||||
PROFILE_CPU_NAMED("Terrain.ModifySplatMap");
|
||||
PROFILE_MEM(LevelTerrain);
|
||||
|
||||
// Get the current data to modify it
|
||||
Color32* splatMap = GetSplatMapData(index);
|
||||
@@ -1738,6 +1748,7 @@ bool TerrainPatch::ModifySplatMap(int32 index, const Color32* samples, const Int
|
||||
bool TerrainPatch::UpdateHeightData(TerrainDataUpdateInfo& info, const Int2& modifiedOffset, const Int2& modifiedSize, bool wasHeightRangeChanged, bool wasHeightChanged)
|
||||
{
|
||||
PROFILE_CPU();
|
||||
PROFILE_MEM(LevelTerrain);
|
||||
float* heightMap = GetHeightmapData();
|
||||
byte* holesMask = GetHolesMaskData();
|
||||
ASSERT(heightMap && holesMask);
|
||||
@@ -2126,6 +2137,7 @@ void TerrainPatch::UpdatePostManualDeserialization()
|
||||
void TerrainPatch::CreateCollision()
|
||||
{
|
||||
PROFILE_CPU();
|
||||
PROFILE_MEM(LevelTerrain);
|
||||
ASSERT(!HasCollision());
|
||||
if (CreateHeightField())
|
||||
return;
|
||||
@@ -2241,6 +2253,7 @@ void TerrainPatch::DestroyCollision()
|
||||
void TerrainPatch::CacheDebugLines()
|
||||
{
|
||||
PROFILE_CPU();
|
||||
PROFILE_MEM(LevelTerrain);
|
||||
ASSERT(_physicsHeightField);
|
||||
_debugLinesDirty = false;
|
||||
if (!_debugLines)
|
||||
@@ -2322,6 +2335,7 @@ void TerrainPatch::DrawPhysicsDebug(RenderView& view)
|
||||
const BoundingBox bounds(_bounds.Minimum - view.Origin, _bounds.Maximum - view.Origin);
|
||||
if (!_physicsShape || !view.CullingFrustum.Intersects(bounds))
|
||||
return;
|
||||
PROFILE_MEM(LevelTerrain);
|
||||
if (view.Mode == ViewMode::PhysicsColliders)
|
||||
{
|
||||
const auto& triangles = GetCollisionTriangles();
|
||||
@@ -2378,6 +2392,7 @@ const Array<Vector3>& TerrainPatch::GetCollisionTriangles()
|
||||
if (!_physicsShape || _collisionTriangles.HasItems())
|
||||
return _collisionTriangles;
|
||||
PROFILE_CPU();
|
||||
PROFILE_MEM(LevelTerrain);
|
||||
|
||||
int32 rows, cols;
|
||||
PhysicsBackend::GetHeightFieldSize(_physicsHeightField, rows, cols);
|
||||
@@ -2428,6 +2443,7 @@ const Array<Vector3>& TerrainPatch::GetCollisionTriangles()
|
||||
void TerrainPatch::GetCollisionTriangles(const BoundingSphere& bounds, Array<Vector3>& result)
|
||||
{
|
||||
PROFILE_CPU();
|
||||
PROFILE_MEM(LevelTerrain);
|
||||
result.Clear();
|
||||
|
||||
// Skip if no intersection with patch
|
||||
@@ -2525,6 +2541,7 @@ void TerrainPatch::GetCollisionTriangles(const BoundingSphere& bounds, Array<Vec
|
||||
void TerrainPatch::ExtractCollisionGeometry(Array<Float3>& vertexBuffer, Array<int32>& indexBuffer)
|
||||
{
|
||||
PROFILE_CPU();
|
||||
PROFILE_MEM(LevelTerrain);
|
||||
vertexBuffer.Clear();
|
||||
indexBuffer.Clear();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user