diff --git a/Source/Editor/Cooker/GameCooker.cpp b/Source/Editor/Cooker/GameCooker.cpp index ea64bbae6..db8ded610 100644 --- a/Source/Editor/Cooker/GameCooker.cpp +++ b/Source/Editor/Cooker/GameCooker.cpp @@ -30,6 +30,7 @@ #include "Engine/Scripting/ManagedCLR/MAssembly.h" #include "Engine/Content/JsonAsset.h" #include "Engine/Content/AssetReference.h" +#include "Engine/Profiler/ProfilerMemory.h" #if PLATFORM_TOOLS_WINDOWS #include "Platform/Windows/WindowsPlatformTools.h" #include "Engine/Platform/Windows/WindowsPlatformSettings.h" @@ -380,6 +381,7 @@ bool GameCooker::IsCancelRequested() PlatformTools* GameCooker::GetTools(BuildPlatform platform) { + PROFILE_MEM(Editor); PlatformTools* result = nullptr; if (!Tools.TryGet(platform, result)) { @@ -471,6 +473,7 @@ bool GameCooker::Build(BuildPlatform platform, BuildConfiguration configuration, LOG(Error, "Build platform {0} is not supported.", ::ToString(platform)); return true; } + PROFILE_MEM(Editor); // Setup CancelFlag = 0; @@ -624,6 +627,7 @@ void GameCookerImpl::ReportProgress(const String& info, float totalProgress) void GameCookerImpl::OnCollectAssets(HashSet& assets) { + PROFILE_MEM(Editor); if (Internal_OnCollectAssets == nullptr) { auto c = GameCooker::GetStaticClass(); @@ -651,6 +655,7 @@ void GameCookerImpl::OnCollectAssets(HashSet& assets) bool GameCookerImpl::Build() { + PROFILE_MEM(Editor); CookingData& data = *Data; LOG(Info, "Starting Game Cooker..."); LOG(Info, "Platform: {0}, Configuration: {2}, Options: {1}", ::ToString(data.Platform), (int32)data.Options, ::ToString(data.Configuration)); @@ -778,6 +783,8 @@ int32 GameCookerImpl::ThreadFunction() bool GameCookerService::Init() { + PROFILE_MEM(Editor); + auto editorAssembly = ((NativeBinaryModule*)GetBinaryModuleFlaxEngine())->Assembly; editorAssembly->Unloading.Bind(OnEditorAssemblyUnloading); GameCooker::OnCollectAssets.Bind(OnCollectAssets); @@ -789,6 +796,7 @@ void GameCookerService::Update() { if (IsRunning) { + PROFILE_MEM(Editor); ScopeLock lock(ProgressLocker); if (ProgressMsg.HasChars()) diff --git a/Source/Editor/CustomEditors/CustomEditorsUtil.cpp b/Source/Editor/CustomEditors/CustomEditorsUtil.cpp index e5f2da5e4..3549cb866 100644 --- a/Source/Editor/CustomEditors/CustomEditorsUtil.cpp +++ b/Source/Editor/CustomEditors/CustomEditorsUtil.cpp @@ -6,6 +6,8 @@ #include "Engine/Core/Types/TimeSpan.h" #include "Engine/Core/Types/Stopwatch.h" #include "Engine/Core/Collections/Dictionary.h" +#include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Engine/EngineService.h" #include "Engine/Scripting/Scripting.h" #include "Engine/Scripting/BinaryModule.h" @@ -69,6 +71,7 @@ MTypeObject* CustomEditorsUtil::GetCustomEditor(MTypeObject* refType) bool CustomEditorsUtilService::Init() { + PROFILE_MEM(Editor); TRACK_ASSEMBLY(((NativeBinaryModule*)GetBinaryModuleFlaxEngine())->Assembly); Scripting::BinaryModuleLoaded.Bind(&OnBinaryModuleLoaded); @@ -77,6 +80,8 @@ bool CustomEditorsUtilService::Init() void OnAssemblyLoaded(MAssembly* assembly) { + PROFILE_CPU_NAMED("CustomEditors.OnAssemblyLoaded"); + PROFILE_MEM(Editor); Stopwatch stopwatch; // Prepare FlaxEngine diff --git a/Source/Editor/Editor.cpp b/Source/Editor/Editor.cpp index 04c6eee71..99b7f1522 100644 --- a/Source/Editor/Editor.cpp +++ b/Source/Editor/Editor.cpp @@ -20,6 +20,7 @@ #include "Engine/Engine/Engine.h" #include "Engine/ShadowsOfMordor/Builder.h" #include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "FlaxEngine.Gen.h" #if PLATFORM_LINUX #include "Engine/Tools/TextureTool/TextureTool.h" @@ -47,6 +48,7 @@ void Editor::CloseSplashScreen() bool Editor::CheckProjectUpgrade() { + PROFILE_MEM(Editor); const auto versionFilePath = Globals::ProjectCacheFolder / TEXT("version"); // Load version cache file @@ -366,6 +368,8 @@ bool Editor::BackupProject() int32 Editor::LoadProduct() { + PROFILE_MEM(Editor); + // Flax Editor product Globals::ProductName = TEXT("Flax Editor"); Globals::CompanyName = TEXT("Flax"); @@ -626,6 +630,7 @@ int32 Editor::LoadProduct() Window* Editor::CreateMainWindow() { + PROFILE_MEM(Editor); Window* window = Managed->GetMainWindow(); #if PLATFORM_LINUX @@ -662,6 +667,7 @@ bool Editor::Init() return true; } PROFILE_CPU(); + PROFILE_MEM(Editor); // If during last lightmaps baking engine crashed we could try to restore the progress ShadowsOfMordor::Builder::Instance()->CheckIfRestoreState(); @@ -693,11 +699,13 @@ bool Editor::Init() void Editor::BeforeRun() { + PROFILE_MEM(Editor); Managed->BeforeRun(); } void Editor::BeforeExit() { + PROFILE_MEM(Editor); CloseSplashScreen(); Managed->Exit(); @@ -708,6 +716,8 @@ void Editor::BeforeExit() void EditorImpl::OnUpdate() { + PROFILE_MEM(Editor); + // Update c# editor Editor::Managed->Update(); diff --git a/Source/Editor/ProjectInfo.cpp b/Source/Editor/ProjectInfo.cpp index 6f2743fbf..bc9c1ecdb 100644 --- a/Source/Editor/ProjectInfo.cpp +++ b/Source/Editor/ProjectInfo.cpp @@ -6,6 +6,7 @@ #include "Engine/Core/Log.h" #include "Engine/Engine/Globals.h" #include "Engine/Core/Math/Quaternion.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Serialization/JsonWriters.h" #include "Engine/Serialization/JsonTools.h" #include @@ -327,6 +328,7 @@ ProjectInfo* ProjectInfo::Load(const String& path) } // Load + PROFILE_MEM(Editor); auto project = New(); if (project->LoadProject(path)) { diff --git a/Source/Editor/Scripting/CodeEditor.cpp b/Source/Editor/Scripting/CodeEditor.cpp index c78c9f48a..b372da189 100644 --- a/Source/Editor/Scripting/CodeEditor.cpp +++ b/Source/Editor/Scripting/CodeEditor.cpp @@ -13,6 +13,7 @@ #include "Engine/Engine/EngineService.h" #include "Engine/Platform/Thread.h" #include "Engine/Threading/IRunnable.h" +#include "Engine/Profiler/ProfilerMemory.h" void OnAsyncBegin(Thread* thread); void OnAsyncEnd(); @@ -232,6 +233,8 @@ void OnAsyncEnd() bool CodeEditingManagerService::Init() { + PROFILE_MEM(Editor); + // Try get editors #if USE_VISUAL_STUDIO_DTE VisualStudioEditor::FindEditors(&CodeEditors); diff --git a/Source/Editor/Scripting/ScriptsBuilder.cpp b/Source/Editor/Scripting/ScriptsBuilder.cpp index 1bc67f79e..84df897e6 100644 --- a/Source/Editor/Scripting/ScriptsBuilder.cpp +++ b/Source/Editor/Scripting/ScriptsBuilder.cpp @@ -23,6 +23,7 @@ #include "Engine/Scripting/Scripting.h" #include "Engine/Scripting/Script.h" #include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Level/Level.h" #include "FlaxEngine.Gen.h" @@ -413,6 +414,7 @@ void ScriptsBuilder::GetBinariesConfiguration(const Char*& target, const Char*& bool ScriptsBuilderImpl::compileGameScriptsAsyncInner() { + PROFILE_MEM(Editor); LOG(Info, "Starting scripts compilation..."); CallEvent(EventType::CompileStarted); @@ -519,6 +521,8 @@ void ScriptsBuilderImpl::onEditorAssemblyUnloading(MAssembly* assembly) bool ScriptsBuilderImpl::compileGameScriptsAsync() { + PROFILE_MEM(Editor); + // Start { ScopeLock scopeLock(_locker); @@ -562,6 +566,7 @@ bool ScriptsBuilderService::Init() // Check flag if (_isInited) return false; + PROFILE_MEM(Editor); _isInited = true; // Link for Editor assembly unload event to clear cached Internal_OnCompilationEnd to prevent errors diff --git a/Source/Editor/Utilities/ViewportIconsRenderer.cpp b/Source/Editor/Utilities/ViewportIconsRenderer.cpp index 2562c9bf5..6bfdbb5f8 100644 --- a/Source/Editor/Utilities/ViewportIconsRenderer.cpp +++ b/Source/Editor/Utilities/ViewportIconsRenderer.cpp @@ -5,6 +5,7 @@ #include "Engine/Content/Assets/Model.h" #include "Engine/Content/Assets/MaterialInstance.h" #include "Engine/Content/Content.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Level/Level.h" #include "Engine/Level/Scene/Scene.h" #include "Engine/Level/Actors/PointLight.h" @@ -253,6 +254,7 @@ void ViewportIconsRendererService::DrawIcons(RenderContext& renderContext, Actor bool ViewportIconsRendererService::Init() { + PROFILE_MEM(Editor); QuadModel = Content::LoadAsyncInternal(TEXT("Engine/Models/Quad")); #define INIT(type, path) \ InstanceBuffers[static_cast(IconTypes::type)].Setup(1); \ diff --git a/Source/Engine/AI/Behavior.cpp b/Source/Engine/AI/Behavior.cpp index e70ca50a4..7e647e945 100644 --- a/Source/Engine/AI/Behavior.cpp +++ b/Source/Engine/AI/Behavior.cpp @@ -7,6 +7,7 @@ #include "Engine/Engine/Time.h" #include "Engine/Engine/EngineService.h" #include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Threading/TaskGraph.h" class BehaviorSystem : public TaskGraphSystem @@ -38,6 +39,7 @@ TaskGraphSystem* Behavior::System = nullptr; void BehaviorSystem::Job(int32 index) { PROFILE_CPU_NAMED("Behavior.Job"); + PROFILE_MEM(AI); Behaviors[index]->UpdateAsync(); } @@ -57,6 +59,7 @@ void BehaviorSystem::Execute(TaskGraph* graph) bool BehaviorService::Init() { + PROFILE_MEM(AI); Behavior::System = New(); Engine::UpdateGraph->AddSystem(Behavior::System); return false; diff --git a/Source/Engine/AI/BehaviorKnowledge.cpp b/Source/Engine/AI/BehaviorKnowledge.cpp index c71bb0724..4d8e2eed9 100644 --- a/Source/Engine/AI/BehaviorKnowledge.cpp +++ b/Source/Engine/AI/BehaviorKnowledge.cpp @@ -4,6 +4,7 @@ #include "BehaviorTree.h" #include "BehaviorTreeNodes.h" #include "BehaviorKnowledgeSelector.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Scripting/Scripting.h" #include "Engine/Scripting/BinaryModule.h" #include "Engine/Scripting/ManagedCLR/MProperty.h" @@ -144,6 +145,7 @@ BehaviorKnowledge::~BehaviorKnowledge() void BehaviorKnowledge::InitMemory(BehaviorTree* tree) { + PROFILE_MEM(AI); if (Tree) FreeMemory(); if (!tree) diff --git a/Source/Engine/AI/BehaviorTree.cpp b/Source/Engine/AI/BehaviorTree.cpp index 64491b10e..ae58e983a 100644 --- a/Source/Engine/AI/BehaviorTree.cpp +++ b/Source/Engine/AI/BehaviorTree.cpp @@ -10,6 +10,7 @@ #include "Engine/Serialization/JsonSerializer.h" #include "Engine/Serialization/MemoryReadStream.h" #include "Engine/Threading/Threading.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "FlaxEngine.Gen.h" #if USE_EDITOR #include "Engine/Level/Level.h" @@ -275,6 +276,7 @@ Asset::LoadResult BehaviorTree::load() if (surfaceChunk == nullptr) return LoadResult::MissingDataChunk; MemoryReadStream surfaceStream(surfaceChunk->Get(), surfaceChunk->Size()); + PROFILE_MEM(AI); if (Graph.Load(&surfaceStream, true)) { LOG(Warning, "Failed to load graph \'{0}\'", ToString()); diff --git a/Source/Engine/Animations/Animations.cpp b/Source/Engine/Animations/Animations.cpp index 0a5a129e1..cc3be45b0 100644 --- a/Source/Engine/Animations/Animations.cpp +++ b/Source/Engine/Animations/Animations.cpp @@ -4,6 +4,7 @@ #include "AnimEvent.h" #include "Engine/Engine/Engine.h" #include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Level/Actors/AnimatedModel.h" #include "Engine/Engine/Time.h" #include "Engine/Engine/EngineService.h" @@ -69,6 +70,7 @@ AnimContinuousEvent::AnimContinuousEvent(const SpawnParams& params) bool AnimationsService::Init() { + PROFILE_MEM(Animations); Animations::System = New(); Engine::UpdateGraph->AddSystem(Animations::System); return false; @@ -83,6 +85,7 @@ void AnimationsService::Dispose() void AnimationsSystem::Job(int32 index) { PROFILE_CPU_NAMED("Animations.Job"); + PROFILE_MEM(Animations); auto animatedModel = AnimationManagerInstance.UpdateList[index]; if (CanUpdateModel(animatedModel)) { @@ -147,6 +150,7 @@ void AnimationsSystem::PostExecute(TaskGraph* graph) if (!Active) return; PROFILE_CPU_NAMED("Animations.PostExecute"); + PROFILE_MEM(Animations); // Update gameplay for (int32 index = 0; index < AnimationManagerInstance.UpdateList.Count(); index++) diff --git a/Source/Engine/Animations/SceneAnimations/SceneAnimation.cpp b/Source/Engine/Animations/SceneAnimations/SceneAnimation.cpp index b1d51a89a..1a6c6fbee 100644 --- a/Source/Engine/Animations/SceneAnimations/SceneAnimation.cpp +++ b/Source/Engine/Animations/SceneAnimations/SceneAnimation.cpp @@ -7,6 +7,7 @@ #include "Engine/Content/Content.h" #include "Engine/Content/Deprecated.h" #include "Engine/Serialization/MemoryReadStream.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Audio/AudioClip.h" #include "Engine/Graphics/PostProcessSettings.h" #if USE_EDITOR @@ -249,6 +250,7 @@ bool SceneAnimation::Save(const StringView& path) Asset::LoadResult SceneAnimation::load() { TrackStatesCount = 0; + PROFILE_MEM(AnimationsData); // Get the data chunk if (LoadChunk(0)) diff --git a/Source/Engine/Animations/SceneAnimations/SceneAnimationPlayer.cpp b/Source/Engine/Animations/SceneAnimations/SceneAnimationPlayer.cpp index eb3bf966e..18234c7ef 100644 --- a/Source/Engine/Animations/SceneAnimations/SceneAnimationPlayer.cpp +++ b/Source/Engine/Animations/SceneAnimations/SceneAnimationPlayer.cpp @@ -12,6 +12,7 @@ #include "Engine/Audio/AudioSource.h" #include "Engine/Graphics/RenderTask.h" #include "Engine/Renderer/RenderList.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Scripting/Scripting.h" #include "Engine/Scripting/Script.h" #include "Engine/Scripting/ManagedCLR/MException.h" @@ -151,6 +152,7 @@ void SceneAnimationPlayer::Tick(float dt) SceneAnimation* anim = Animation.Get(); if (!anim || !anim->IsLoaded()) return; + PROFILE_MEM(Animations); // Setup state if (_tracks.Count() != anim->TrackStatesCount) @@ -229,6 +231,7 @@ void SceneAnimationPlayer::MapTrack(const StringView& from, const Guid& to) SceneAnimation* anim = Animation.Get(); if (!anim || !anim->IsLoaded()) return; + PROFILE_MEM(Animations); for (int32 j = 0; j < anim->Tracks.Count(); j++) { const auto& track = anim->Tracks[j]; diff --git a/Source/Engine/Audio/Audio.cpp b/Source/Engine/Audio/Audio.cpp index e19efabf1..5574919c4 100644 --- a/Source/Engine/Audio/Audio.cpp +++ b/Source/Engine/Audio/Audio.cpp @@ -8,6 +8,7 @@ #include "Engine/Scripting/BinaryModule.h" #include "Engine/Level/Level.h" #include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Engine/Engine.h" #include "Engine/Engine/CommandLine.h" #include "Engine/Core/Log.h" @@ -151,6 +152,7 @@ void Audio::SetEnableHRTF(bool value) bool AudioService::Init() { PROFILE_CPU_NAMED("Audio.Init"); + PROFILE_MEM(Audio); const auto settings = AudioSettings::Get(); const bool mute = CommandLine::Options.Mute.IsTrue() || settings->DisableAudio; @@ -211,6 +213,7 @@ bool AudioService::Init() void AudioService::Update() { PROFILE_CPU_NAMED("Audio.Update"); + PROFILE_MEM(Audio); // Update the master volume float masterVolume = MasterVolume; diff --git a/Source/Engine/Audio/AudioClip.cpp b/Source/Engine/Audio/AudioClip.cpp index 8835cddc7..2ac9d218c 100644 --- a/Source/Engine/Audio/AudioClip.cpp +++ b/Source/Engine/Audio/AudioClip.cpp @@ -10,6 +10,7 @@ #include "Engine/Scripting/ManagedCLR/MUtils.h" #include "Engine/Streaming/StreamingGroup.h" #include "Engine/Serialization/MemoryReadStream.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Tools/AudioTool/OggVorbisDecoder.h" #include "Engine/Tools/AudioTool/AudioTool.h" #include "Engine/Threading/Threading.h" @@ -318,6 +319,7 @@ bool AudioClip::init(AssetInitData& initData) Asset::LoadResult AudioClip::load() { + PROFILE_MEM(Audio); #if !COMPILE_WITH_OGG_VORBIS if (AudioHeader.Format == AudioFormat::Vorbis) { diff --git a/Source/Engine/Audio/OpenAL/AudioBackendOAL.cpp b/Source/Engine/Audio/OpenAL/AudioBackendOAL.cpp index dfdca18f6..86e828028 100644 --- a/Source/Engine/Audio/OpenAL/AudioBackendOAL.cpp +++ b/Source/Engine/Audio/OpenAL/AudioBackendOAL.cpp @@ -9,6 +9,7 @@ #include "Engine/Tools/AudioTool/AudioTool.h" #include "Engine/Engine/Units.h" #include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Audio/Audio.h" #include "Engine/Audio/AudioListener.h" #include "Engine/Audio/AudioSource.h" @@ -321,6 +322,8 @@ void AudioBackendOAL::Listener_ReinitializeAll() uint32 AudioBackendOAL::Source_Add(const AudioDataInfo& format, const Vector3& position, const Quaternion& orientation, float volume, float pitch, float pan, bool loop, bool spatial, float attenuation, float minDistance, float doppler) { + PROFILE_MEM(Audio); + uint32 sourceID = 0; ALC::Source::Rebuild(sourceID, position, orientation, volume, pitch, pan, loop, spatial, attenuation, minDistance, doppler); @@ -516,6 +519,7 @@ void AudioBackendOAL::Buffer_Delete(uint32 bufferID) void AudioBackendOAL::Buffer_Write(uint32 bufferID, byte* samples, const AudioDataInfo& info) { PROFILE_CPU(); + PROFILE_MEM(Audio); // Pick the format for the audio data (it might not be supported natively) ALenum format = GetOpenALBufferFormat(info.NumChannels, info.BitDepth); @@ -625,6 +629,8 @@ AudioBackend::FeatureFlags AudioBackendOAL::Base_Features() void AudioBackendOAL::Base_OnActiveDeviceChanged() { + PROFILE_MEM(Audio); + // Cleanup Array states; states.EnsureCapacity(Audio::Sources.Count()); diff --git a/Source/Engine/Content/Asset.cpp b/Source/Engine/Content/Asset.cpp index 0d5391482..3a6ed648e 100644 --- a/Source/Engine/Content/Asset.cpp +++ b/Source/Engine/Content/Asset.cpp @@ -526,6 +526,7 @@ ContentLoadTask* Asset::createLoadingTask() void Asset::startLoading() { + PROFILE_MEM(ContentAssets); ASSERT(!IsLoaded()); ASSERT(Platform::AtomicRead(&_loadingTask) == 0); auto loadingTask = createLoadingTask(); diff --git a/Source/Engine/Content/Assets/Animation.cpp b/Source/Engine/Content/Assets/Animation.cpp index 54c4d898e..8558e601d 100644 --- a/Source/Engine/Content/Assets/Animation.cpp +++ b/Source/Engine/Content/Assets/Animation.cpp @@ -9,6 +9,7 @@ #include "Engine/Animations/Animations.h" #include "Engine/Animations/SceneAnimations/SceneAnimation.h" #include "Engine/Scripting/Scripting.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Threading/Threading.h" #include "Engine/Serialization/MemoryReadStream.h" #if USE_EDITOR @@ -598,6 +599,7 @@ void Animation::OnScriptingDispose() Asset::LoadResult Animation::load() { + PROFILE_MEM(AnimationsData); ConcurrentSystemLocker::WriteScope systemScope(Animations::SystemLocker); // Get stream with animations data diff --git a/Source/Engine/Content/Assets/AnimationGraph.cpp b/Source/Engine/Content/Assets/AnimationGraph.cpp index 3e4a96ea2..acab48b2f 100644 --- a/Source/Engine/Content/Assets/AnimationGraph.cpp +++ b/Source/Engine/Content/Assets/AnimationGraph.cpp @@ -9,6 +9,7 @@ #include "Engine/Core/Types/DataContainer.h" #include "Engine/Serialization/MemoryReadStream.h" #include "Engine/Serialization/MemoryWriteStream.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Content/Factories/BinaryAssetFactory.h" #include "Engine/Animations/Animations.h" #include "Engine/Threading/Threading.h" @@ -25,6 +26,7 @@ AnimationGraph::AnimationGraph(const SpawnParams& params, const AssetInfo* info) Asset::LoadResult AnimationGraph::load() { + PROFILE_MEM(AnimationsData); ConcurrentSystemLocker::WriteScope systemScope(Animations::SystemLocker); // Get stream with graph data @@ -83,6 +85,7 @@ bool AnimationGraph::InitAsAnimation(SkinnedModel* baseModel, Animation* anim, b Log::ArgumentNullException(); return true; } + PROFILE_MEM(AnimationsData); ConcurrentSystemLocker::WriteScope systemScope(Animations::SystemLocker); // Create Graph data diff --git a/Source/Engine/Content/Assets/AnimationGraphFunction.cpp b/Source/Engine/Content/Assets/AnimationGraphFunction.cpp index 76c84977a..3e8ce62e8 100644 --- a/Source/Engine/Content/Assets/AnimationGraphFunction.cpp +++ b/Source/Engine/Content/Assets/AnimationGraphFunction.cpp @@ -8,6 +8,7 @@ #include "Engine/Serialization/MemoryWriteStream.h" #endif #include "Engine/Animations/Animations.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Content/Factories/BinaryAssetFactory.h" #include "Engine/Threading/Threading.h" @@ -20,6 +21,7 @@ AnimationGraphFunction::AnimationGraphFunction(const SpawnParams& params, const Asset::LoadResult AnimationGraphFunction::load() { + PROFILE_MEM(AnimationsData); ConcurrentSystemLocker::WriteScope systemScope(Animations::SystemLocker); // Get graph data from chunk diff --git a/Source/Engine/Content/Assets/Material.cpp b/Source/Engine/Content/Assets/Material.cpp index 85e63fc18..ce457c862 100644 --- a/Source/Engine/Content/Assets/Material.cpp +++ b/Source/Engine/Content/Assets/Material.cpp @@ -165,9 +165,13 @@ Asset::LoadResult Material::load() MaterialGenerator generator; generator.Error.Bind(&OnGeneratorError); if (_shaderHeader.Material.GraphVersion != MATERIAL_GRAPH_VERSION) + { LOG(Info, "Converting material \'{0}\', from version {1} to {2}...", name, _shaderHeader.Material.GraphVersion, MATERIAL_GRAPH_VERSION); + } else + { LOG(Info, "Updating material \'{0}\'...", name); + } // Load or create material surface MaterialLayer* layer; diff --git a/Source/Engine/Content/Assets/Model.cpp b/Source/Engine/Content/Assets/Model.cpp index 1f5768e6c..10c471f8c 100644 --- a/Source/Engine/Content/Assets/Model.cpp +++ b/Source/Engine/Content/Assets/Model.cpp @@ -18,6 +18,7 @@ #include "Engine/Graphics/Models/MeshDeformation.h" #include "Engine/Graphics/Textures/GPUTexture.h" #include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Renderer/DrawCall.h" #include "Engine/Threading/Threading.h" #include "Engine/Tools/ModelTool/ModelTool.h" @@ -304,6 +305,7 @@ bool Model::Init(const Span& meshesCountPerLod) Log::ArgumentOutOfRangeException(); return true; } + PROFILE_MEM(GraphicsMeshes); // Dispose previous data and disable streaming (will start data uploading tasks manually) StopStreaming(); @@ -343,6 +345,7 @@ bool Model::Init(const Span& meshesCountPerLod) bool Model::LoadHeader(ReadStream& stream, byte& headerVersion) { + PROFILE_MEM(GraphicsMeshes); if (ModelBase::LoadHeader(stream, headerVersion)) return true; @@ -509,6 +512,7 @@ bool Model::Save(bool withMeshDataFromGpu, Function& getChunk void Model::SetupMaterialSlots(int32 slotsCount) { + PROFILE_MEM(GraphicsMeshes); ModelBase::SetupMaterialSlots(slotsCount); // Adjust meshes indices for slots @@ -584,6 +588,8 @@ int32 Model::GetAllocatedResidency() const Asset::LoadResult Model::load() { + PROFILE_MEM(GraphicsMeshes); + // Get header chunk auto chunk0 = GetChunk(0); if (chunk0 == nullptr || chunk0->IsMissing()) diff --git a/Source/Engine/Content/Assets/ModelBase.cpp b/Source/Engine/Content/Assets/ModelBase.cpp index 243e429a5..5f2a89328 100644 --- a/Source/Engine/Content/Assets/ModelBase.cpp +++ b/Source/Engine/Content/Assets/ModelBase.cpp @@ -5,6 +5,7 @@ #include "Engine/Core/Math/Transform.h" #include "Engine/Content/WeakAssetReference.h" #include "Engine/Serialization/MemoryReadStream.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Graphics/Config.h" #include "Engine/Graphics/Models/MeshBase.h" #include "Engine/Graphics/Models/MeshDeformation.h" @@ -51,6 +52,7 @@ public: AssetReference model = _model.Get(); if (model == nullptr) return true; + PROFILE_MEM(GraphicsMeshes); // Get data BytesContainer data; @@ -334,6 +336,8 @@ bool ModelBase::LoadHeader(ReadStream& stream, byte& headerVersion) bool ModelBase::LoadMesh(MemoryReadStream& stream, byte meshVersion, MeshBase* mesh, MeshData* dataIfReadOnly) { + PROFILE_MEM(GraphicsMeshes); + // Load descriptor static_assert(MODEL_MESH_VERSION == 2, "Update code"); uint32 vertices, triangles; diff --git a/Source/Engine/Content/Assets/SkinnedModel.cpp b/Source/Engine/Content/Assets/SkinnedModel.cpp index 5271df723..7c51f4332 100644 --- a/Source/Engine/Content/Assets/SkinnedModel.cpp +++ b/Source/Engine/Content/Assets/SkinnedModel.cpp @@ -18,6 +18,7 @@ #include "Engine/Content/Upgraders/SkinnedModelAssetUpgrader.h" #include "Engine/Debug/Exceptions/ArgumentOutOfRangeException.h" #include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Renderer/DrawCall.h" #if USE_EDITOR #include "Engine/Graphics/Models/ModelData.h" @@ -458,6 +459,7 @@ bool SkinnedModel::Init(const Span& meshesCountPerLod) Log::ArgumentOutOfRangeException(); return true; } + PROFILE_MEM(GraphicsMeshes); // Dispose previous data and disable streaming (will start data uploading tasks manually) StopStreaming(); @@ -501,6 +503,7 @@ void BlendShape::LoadHeader(ReadStream& stream, byte headerVersion) void BlendShape::Load(ReadStream& stream, byte meshVersion) { + PROFILE_MEM(GraphicsMeshes); UseNormals = stream.ReadBool(); stream.ReadUint32(&MinVertexIndex); stream.ReadUint32(&MaxVertexIndex); @@ -531,6 +534,7 @@ void BlendShape::Save(WriteStream& stream) const bool SkinnedModel::LoadMesh(MemoryReadStream& stream, byte meshVersion, MeshBase* mesh, MeshData* dataIfReadOnly) { + PROFILE_MEM(GraphicsMeshes); if (ModelBase::LoadMesh(stream, meshVersion, mesh, dataIfReadOnly)) return true; static_assert(MODEL_MESH_VERSION == 2, "Update code"); @@ -560,6 +564,7 @@ bool SkinnedModel::LoadMesh(MemoryReadStream& stream, byte meshVersion, MeshBase bool SkinnedModel::LoadHeader(ReadStream& stream, byte& headerVersion) { + PROFILE_MEM(GraphicsMeshes); if (ModelBase::LoadHeader(stream, headerVersion)) return true; static_assert(MODEL_HEADER_VERSION == 2, "Update code"); @@ -861,6 +866,7 @@ uint64 SkinnedModel::GetMemoryUsage() const void SkinnedModel::SetupMaterialSlots(int32 slotsCount) { + PROFILE_MEM(GraphicsMeshes); ModelBase::SetupMaterialSlots(slotsCount); // Adjust meshes indices for slots @@ -954,6 +960,7 @@ Asset::LoadResult SkinnedModel::load() if (chunk0 == nullptr || chunk0->IsMissing()) return LoadResult::MissingDataChunk; MemoryReadStream headerStream(chunk0->Get(), chunk0->Size()); + PROFILE_MEM(GraphicsMeshes); // Load asset data (anything but mesh contents that use streaming) byte headerVersion; diff --git a/Source/Engine/Content/Assets/VisualScript.cpp b/Source/Engine/Content/Assets/VisualScript.cpp index 66d95ca87..a6d83919c 100644 --- a/Source/Engine/Content/Assets/VisualScript.cpp +++ b/Source/Engine/Content/Assets/VisualScript.cpp @@ -1900,9 +1900,13 @@ bool VisualScriptingBinaryModule::InvokeMethod(void* method, const Variant& inst if (!instanceObject || instanceObject->GetTypeHandle() != vsMethod->Script->GetScriptingType()) { if (!instanceObject) + { LOG(Error, "Failed to call method '{0}.{1}' (args count: {2}) without object instance", String(vsMethod->Script->GetScriptTypeName()), String(vsMethod->Name), vsMethod->ParamNames.Count()); + } else + { LOG(Error, "Failed to call method '{0}.{1}' (args count: {2}) with invalid object instance of type '{3}'", String(vsMethod->Script->GetScriptTypeName()), String(vsMethod->Name), vsMethod->ParamNames.Count(), String(instanceObject->GetType().Fullname)); + } return true; } } diff --git a/Source/Engine/Content/BinaryAsset.cpp b/Source/Engine/Content/BinaryAsset.cpp index 76980f3d6..9e7e51113 100644 --- a/Source/Engine/Content/BinaryAsset.cpp +++ b/Source/Engine/Content/BinaryAsset.cpp @@ -10,6 +10,7 @@ #include "Engine/Serialization/JsonTools.h" #include "Engine/Debug/Exceptions/JsonParseException.h" #include "Engine/Threading/ThreadPoolTask.h" +#include "Engine/Profiler/ProfilerMemory.h" #if USE_EDITOR #include "Engine/Platform/FileSystem.h" #include "Engine/Threading/Threading.h" @@ -527,6 +528,7 @@ protected: auto storage = ref->Storage; auto factory = (BinaryAssetFactoryBase*)Content::GetAssetFactory(ref->GetTypeName()); ASSERT(factory); + PROFILE_MEM(ContentAssets); // Here we should open storage and extract AssetInitData // This would also allow to convert/upgrade data diff --git a/Source/Engine/Content/Content.cpp b/Source/Engine/Content/Content.cpp index a6971e875..915f48140 100644 --- a/Source/Engine/Content/Content.cpp +++ b/Source/Engine/Content/Content.cpp @@ -28,6 +28,7 @@ #include "Engine/Engine/Globals.h" #include "Engine/Level/Types.h" #include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Scripting/ManagedCLR/MClass.h" #include "Engine/Scripting/Scripting.h" #if USE_EDITOR @@ -117,6 +118,8 @@ ContentService ContentServiceInstance; bool ContentService::Init() { + PROFILE_MEM(Content); + // Load assets registry Cache.Init(); @@ -159,6 +162,7 @@ void ContentService::Update() void ContentService::LateUpdate() { PROFILE_CPU(); + PROFILE_MEM(Content); // Check if need to perform an update of unloading assets const TimeSpan timeNow = Time::Update.UnscaledTime; @@ -324,6 +328,7 @@ String LoadingThread::ToString() const int32 LoadingThread::Run() { + PROFILE_MEM(Content); #if USE_EDITOR && PLATFORM_WINDOWS // Initialize COM // TODO: maybe add sth to Thread::Create to indicate that thread will use COM stuff @@ -416,6 +421,7 @@ bool Content::GetAssetInfo(const Guid& id, AssetInfo& info) if (Cache.FindAsset(id, info)) return true; PROFILE_CPU(); + PROFILE_MEM(Content); // Locking injects some stalls but we need to make it safe (only one thread can pass though it at once) ScopeLock lock(WorkspaceDiscoveryLocker); @@ -465,6 +471,7 @@ bool Content::GetAssetInfo(const StringView& path, AssetInfo& info) if (!FileSystem::FileExists(path)) return false; PROFILE_CPU(); + PROFILE_MEM(Content); const auto extension = FileSystem::GetExtension(path).ToLower(); @@ -593,6 +600,7 @@ Asset* Content::LoadAsyncInternal(const StringView& internalPath, const MClass* Asset* Content::LoadAsyncInternal(const StringView& internalPath, const ScriptingTypeHandle& type) { + PROFILE_MEM(Content); #if USE_EDITOR const String path = Globals::EngineContentFolder / internalPath + ASSET_FILES_EXTENSION_WITH_DOT; if (!FileSystem::FileExists(path)) @@ -635,6 +643,8 @@ Asset* Content::LoadAsync(const StringView& path, const MClass* type) Asset* Content::LoadAsync(const StringView& path, const ScriptingTypeHandle& type) { + PROFILE_MEM(Content); + // Ensure path is in a valid format String pathNorm(path); ContentStorageManager::FormatPath(pathNorm); @@ -687,7 +697,6 @@ Asset* Content::GetAsset(const StringView& outputPath) { if (outputPath.IsEmpty()) return nullptr; - ScopeLock lock(AssetsLocker); for (auto i = Assets.Begin(); i.IsNotEnd(); ++i) { @@ -1023,6 +1032,7 @@ Asset* Content::CreateVirtualAsset(const MClass* type) Asset* Content::CreateVirtualAsset(const ScriptingTypeHandle& type) { PROFILE_CPU(); + PROFILE_MEM(Content); auto& assetType = type.GetType(); // Init mock asset info @@ -1045,7 +1055,9 @@ Asset* Content::CreateVirtualAsset(const ScriptingTypeHandle& type) } // Create asset object + PROFILE_MEM_BEGIN(ContentAssets); auto asset = factory->NewVirtual(info); + PROFILE_MEM_END(); if (asset == nullptr) { LOG(Error, "Cannot create virtual asset object."); @@ -1054,7 +1066,9 @@ Asset* Content::CreateVirtualAsset(const ScriptingTypeHandle& type) asset->RegisterObject(); // Call initializer function + PROFILE_MEM_BEGIN(ContentAssets); asset->InitAsVirtual(); + PROFILE_MEM_END(); // Register asset AssetsLocker.Lock(); @@ -1209,6 +1223,7 @@ Asset* Content::LoadAsync(const Guid& id, const ScriptingTypeHandle& type) { if (!id.IsValid()) return nullptr; + PROFILE_MEM(Content); // Check if asset has been already loaded Asset* result = nullptr; @@ -1277,7 +1292,9 @@ Asset* Content::LoadAsync(const Guid& id, const ScriptingTypeHandle& type) } // Create asset object + PROFILE_MEM_BEGIN(ContentAssets); result = factory->New(assetInfo); + PROFILE_MEM_END(); if (result == nullptr) { LOG(Error, "Cannot create asset object. Info: {0}", assetInfo.ToString()); diff --git a/Source/Engine/Content/JsonAsset.cpp b/Source/Engine/Content/JsonAsset.cpp index 60f05d38e..04487eb65 100644 --- a/Source/Engine/Content/JsonAsset.cpp +++ b/Source/Engine/Content/JsonAsset.cpp @@ -20,6 +20,7 @@ #include "Engine/Core/Cache.h" #include "Engine/Debug/Exceptions/JsonParseException.h" #include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Scripting/Scripting.h" #include "Engine/Scripting/ManagedCLR/MClass.h" #include "Engine/Scripting/ManagedCLR/MField.h" @@ -39,6 +40,7 @@ String JsonAssetBase::GetData() const if (Data == nullptr) return String::Empty; PROFILE_CPU_NAMED("JsonAsset.GetData"); + PROFILE_MEM(ContentAssets); rapidjson_flax::StringBuffer buffer; OnGetData(buffer); return String((const char*)buffer.GetString(), (int32)buffer.GetSize()); @@ -49,6 +51,7 @@ void JsonAssetBase::SetData(const StringView& value) if (!IsLoaded()) return; PROFILE_CPU_NAMED("JsonAsset.SetData"); + PROFILE_MEM(ContentAssets); const StringAnsi dataJson(value); ScopeLock lock(Locker); const StringView dataTypeName = DataTypeName; @@ -60,6 +63,7 @@ void JsonAssetBase::SetData(const StringView& value) bool JsonAssetBase::Init(const StringView& dataTypeName, const StringAnsiView& dataJson) { + PROFILE_MEM(ContentAssets); unload(true); DataTypeName = dataTypeName; DataEngineBuild = FLAXENGINE_VERSION_BUILD; @@ -239,6 +243,7 @@ Asset::LoadResult JsonAssetBase::loadAsset() { if (IsVirtual() || _isVirtualDocument) return LoadResult::Ok; + PROFILE_MEM(ContentAssets); // Load data (raw json file in editor, cooked asset in build game) #if USE_EDITOR @@ -453,6 +458,7 @@ bool JsonAsset::CreateInstance() ScopeLock lock(Locker); if (Instance) return false; + PROFILE_MEM(ContentAssets); // Try to scripting type for this data const StringAsANSI<> dataTypeNameAnsi(DataTypeName.Get(), DataTypeName.Length()); diff --git a/Source/Engine/Content/Loading/Tasks/LoadAssetTask.h b/Source/Engine/Content/Loading/Tasks/LoadAssetTask.h index 18d870616..4eae2829b 100644 --- a/Source/Engine/Content/Loading/Tasks/LoadAssetTask.h +++ b/Source/Engine/Content/Loading/Tasks/LoadAssetTask.h @@ -8,6 +8,7 @@ #include "Engine/Content/WeakAssetReference.h" #include "Engine/Core/Log.h" #include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Profiler/ProfilerMemory.h" /// /// Asset loading task object. @@ -44,6 +45,7 @@ protected: Result run() override { PROFILE_CPU(); + PROFILE_MEM(ContentAssets); // Keep valid ref to the asset AssetReference<::Asset> ref = Asset.Get(); diff --git a/Source/Engine/Content/Storage/FlaxChunk.h b/Source/Engine/Content/Storage/FlaxChunk.h index 5121a0f0f..6e9887574 100644 --- a/Source/Engine/Content/Storage/FlaxChunk.h +++ b/Source/Engine/Content/Storage/FlaxChunk.h @@ -182,10 +182,5 @@ public: /// Clones this chunk data (doesn't copy location in file). /// /// The cloned chunk. - FlaxChunk* Clone() const - { - auto chunk = New(); - chunk->Data.Copy(Data); - return chunk; - } + FlaxChunk* Clone() const; }; diff --git a/Source/Engine/Content/Storage/FlaxStorage.cpp b/Source/Engine/Content/Storage/FlaxStorage.cpp index 9e36ad632..17daba278 100644 --- a/Source/Engine/Content/Storage/FlaxStorage.cpp +++ b/Source/Engine/Content/Storage/FlaxStorage.cpp @@ -8,6 +8,7 @@ #include "Engine/Core/Types/TimeSpan.h" #include "Engine/Platform/File.h" #include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Serialization/FileWriteStream.h" #include "Engine/Content/Asset.h" #include "Engine/Content/Content.h" @@ -63,6 +64,14 @@ void FlaxChunk::RegisterUsage() LastAccessTime = Platform::GetTimeSeconds(); } +FlaxChunk* FlaxChunk::Clone() const +{ + PROFILE_MEM(ContentFiles); + auto chunk = New(); + chunk->Data.Copy(Data); + return chunk; +} + const int32 FlaxStorage::MagicCode = 1180124739; FlaxStorage::LockData FlaxStorage::LockData::Invalid(nullptr); @@ -281,19 +290,12 @@ uint32 FlaxStorage::GetMemoryUsage() const bool FlaxStorage::Load() { - // Check if was already loaded if (IsLoaded()) - { return false; - } - - // Prevent loading by more than one thread + PROFILE_MEM(ContentFiles); ScopeLock lock(_loadLocker); if (IsLoaded()) - { - // Other thread loaded it return false; - } ASSERT(GetEntriesCount() == 0); // Open file @@ -693,6 +695,7 @@ bool FlaxStorage::LoadAssetHeader(const Guid& id, AssetInitData& data) bool FlaxStorage::LoadAssetChunk(FlaxChunk* chunk) { + PROFILE_MEM(ContentFiles); ASSERT(IsLoaded()); ASSERT(chunk != nullptr && _chunks.Contains(chunk)); @@ -866,6 +869,7 @@ FlaxChunk* FlaxStorage::AllocateChunk() { if (AllowDataModifications()) { + PROFILE_MEM(ContentFiles); auto chunk = New(); _chunks.Add(chunk); return chunk; @@ -1125,6 +1129,7 @@ bool FlaxStorage::Save(const AssetInitData& data, bool silentMode) bool FlaxStorage::LoadAssetHeader(const Entry& e, AssetInitData& data) { + PROFILE_MEM(ContentFiles); ASSERT(IsLoaded()); auto lock = Lock(); @@ -1396,6 +1401,8 @@ FileReadStream* FlaxStorage::OpenFile() auto& stream = _file.Get(); if (stream == nullptr) { + PROFILE_MEM(ContentFiles); + // Open file auto file = File::Open(_path, FileMode::OpenExisting, FileAccess::Read, FileShare::Read); if (file == nullptr) diff --git a/Source/Engine/ContentImporters/AssetsImportingManager.cpp b/Source/Engine/ContentImporters/AssetsImportingManager.cpp index b3cf8e419..9cad287dc 100644 --- a/Source/Engine/ContentImporters/AssetsImportingManager.cpp +++ b/Source/Engine/ContentImporters/AssetsImportingManager.cpp @@ -13,6 +13,7 @@ #include "Engine/Engine/EngineService.h" #include "Engine/Platform/FileSystem.h" #include "Engine/Platform/Platform.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Engine/Globals.h" #include "ImportTexture.h" #include "ImportModel.h" @@ -151,6 +152,7 @@ bool CreateAssetContext::AllocateChunk(int32 index) } // Create new chunk + PROFILE_MEM(ContentFiles); Data.Header.Chunks[index] = New(); return false; } diff --git a/Source/Engine/Core/Log.cpp b/Source/Engine/Core/Log.cpp index 215f490be..85cc3cc02 100644 --- a/Source/Engine/Core/Log.cpp +++ b/Source/Engine/Core/Log.cpp @@ -8,6 +8,7 @@ #include "Engine/Engine/Globals.h" #include "Engine/Platform/FileSystem.h" #include "Engine/Platform/CriticalSection.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Serialization/FileWriteStream.h" #include "Engine/Debug/Exceptions/Exceptions.h" #if USE_EDITOR @@ -42,6 +43,7 @@ bool Log::Logger::Init() // Skip if disabled if (!IsLogEnabled()) return false; + PROFILE_MEM(Engine); // Create logs directory (if is missing) #if USE_EDITOR @@ -119,6 +121,7 @@ void Log::Logger::Write(const StringView& msg) const auto length = msg.Length(); if (length <= 0) return; + PROFILE_MEM(Engine); LogLocker.Lock(); if (IsDuringLog) @@ -258,6 +261,7 @@ void Log::Logger::Write(LogType type, const StringView& msg) { if (msg.Length() <= 0) return; + PROFILE_MEM(Engine); const bool isError = IsError(type); // Create message for the log file diff --git a/Source/Engine/Debug/DebugDraw.cpp b/Source/Engine/Debug/DebugDraw.cpp index a026267cc..df2e41803 100644 --- a/Source/Engine/Debug/DebugDraw.cpp +++ b/Source/Engine/Debug/DebugDraw.cpp @@ -515,6 +515,7 @@ DebugDrawService DebugDrawServiceInstance; bool DebugDrawService::Init() { + PROFILE_MEM(Graphics); Context = &GlobalContext; // Init wireframe sphere cache @@ -633,6 +634,7 @@ void DebugDrawService::Update() } PROFILE_CPU(); + PROFILE_MEM(Graphics); // Update lists float deltaTime = Time::Update.DeltaTime.GetTotalSeconds(); diff --git a/Source/Engine/Graphics/GPUBuffer.cpp b/Source/Engine/Graphics/GPUBuffer.cpp index 0e71ea8b3..db7845227 100644 --- a/Source/Engine/Graphics/GPUBuffer.cpp +++ b/Source/Engine/Graphics/GPUBuffer.cpp @@ -15,6 +15,7 @@ #include "Engine/Debug/Exceptions/ArgumentNullException.h" #include "Engine/Debug/Exceptions/ArgumentOutOfRangeException.h" #include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Scripting/Enums.h" #include "Engine/Threading/ThreadPoolTask.h" #include "Engine/Threading/Threading.h" @@ -188,6 +189,8 @@ bool GPUBuffer::IsDynamic() const bool GPUBuffer::Init(const GPUBufferDescription& desc) { + PROFILE_MEM(GraphicsBuffers); + // Validate description #if !BUILD_RELEASE #define GET_NAME() GetName() @@ -241,6 +244,7 @@ bool GPUBuffer::Init(const GPUBufferDescription& desc) LOG(Warning, "Cannot initialize buffer. Description: {0}", desc.ToString()); return true; } + PROFILE_MEM_INC(GraphicsBuffers, GetMemoryUsage()); return false; } @@ -476,6 +480,7 @@ GPUResourceType GPUBuffer::GetResourceType() const void GPUBuffer::OnReleaseGPU() { + PROFILE_MEM_DEC(GraphicsBuffers, GetMemoryUsage()); _desc.Clear(); _isLocked = false; } diff --git a/Source/Engine/Graphics/GPUDevice.cpp b/Source/Engine/Graphics/GPUDevice.cpp index e4bbc170a..1ea008913 100644 --- a/Source/Engine/Graphics/GPUDevice.cpp +++ b/Source/Engine/Graphics/GPUDevice.cpp @@ -650,6 +650,7 @@ GPUTasksExecutor* GPUDevice::CreateTasksExecutor() void GPUDevice::Draw() { + PROFILE_MEM(Graphics); DrawBegin(); auto context = GetMainContext(); diff --git a/Source/Engine/Graphics/Graphics.cpp b/Source/Engine/Graphics/Graphics.cpp index 7ffba3957..43bd1a76d 100644 --- a/Source/Engine/Graphics/Graphics.cpp +++ b/Source/Engine/Graphics/Graphics.cpp @@ -9,6 +9,7 @@ #include "Engine/Engine/CommandLine.h" #include "Engine/Engine/EngineService.h" #include "Engine/Profiler/ProfilerGPU.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Render2D/Font.h" bool Graphics::UseVSync = false; @@ -97,6 +98,7 @@ void Graphics::DisposeDevice() bool GraphicsService::Init() { ASSERT(GPUDevice::Instance == nullptr); + PROFILE_MEM(Graphics); // Create and initialize graphics device Log::Logger::WriteFloor(); diff --git a/Source/Engine/Graphics/Materials/MaterialParams.cpp b/Source/Engine/Graphics/Materials/MaterialParams.cpp index e31697f77..55726c20c 100644 --- a/Source/Engine/Graphics/Materials/MaterialParams.cpp +++ b/Source/Engine/Graphics/Materials/MaterialParams.cpp @@ -15,6 +15,7 @@ #include "Engine/Renderer/GlobalSignDistanceFieldPass.h" #include "Engine/Scripting/Enums.h" #include "Engine/Streaming/Streaming.h" +#include "Engine/Profiler/ProfilerMemory.h" bool MaterialInfo8::operator==(const MaterialInfo8& other) const { @@ -638,6 +639,7 @@ void MaterialParams::Dispose() bool MaterialParams::Load(ReadStream* stream) { + PROFILE_MEM(GraphicsMaterials); bool result = false; // Release diff --git a/Source/Engine/Graphics/Materials/MaterialShader.cpp b/Source/Engine/Graphics/Materials/MaterialShader.cpp index 1b0b6937b..c24631d56 100644 --- a/Source/Engine/Graphics/Materials/MaterialShader.cpp +++ b/Source/Engine/Graphics/Materials/MaterialShader.cpp @@ -11,6 +11,7 @@ #include "Engine/Graphics/Shaders/GPUConstantBuffer.h" #include "Engine/Graphics/Shaders/GPUShader.h" #include "Engine/Engine/Time.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "DecalMaterialShader.h" #include "PostFxMaterialShader.h" #include "ForwardMaterialShader.h" @@ -136,6 +137,7 @@ MaterialShader::~MaterialShader() MaterialShader* MaterialShader::Create(const StringView& name, MemoryReadStream& shaderCacheStream, const MaterialInfo& info) { + PROFILE_MEM(GraphicsMaterials); MaterialShader* material; switch (info.Domain) { @@ -199,6 +201,7 @@ protected: MaterialShader* MaterialShader::CreateDummy(MemoryReadStream& shaderCacheStream, const MaterialInfo& info) { + PROFILE_MEM(GraphicsMaterials); MaterialShader* material = New(); if (material->Load(shaderCacheStream, info)) { @@ -225,6 +228,7 @@ bool MaterialShader::IsReady() const bool MaterialShader::Load(MemoryReadStream& shaderCacheStream, const MaterialInfo& info) { + PROFILE_MEM(GraphicsMaterials); ASSERT(!_isLoaded); // Cache material info diff --git a/Source/Engine/Graphics/Models/Mesh.cpp b/Source/Engine/Graphics/Models/Mesh.cpp index 36dc18af4..32df730e8 100644 --- a/Source/Engine/Graphics/Models/Mesh.cpp +++ b/Source/Engine/Graphics/Models/Mesh.cpp @@ -14,6 +14,7 @@ #include "Engine/Renderer/RenderList.h" #include "Engine/Scripting/ManagedCLR/MCore.h" #include "Engine/Threading/Threading.h" +#include "Engine/Profiler/ProfilerMemory.h" #if USE_EDITOR #include "Engine/Renderer/GBufferPass.h" #endif @@ -48,6 +49,7 @@ namespace { bool UpdateMesh(MeshBase* mesh, uint32 vertexCount, uint32 triangleCount, PixelFormat indexFormat, const Float3* vertices, const void* triangles, const Float3* normals, const Float3* tangents, const Float2* uvs, const Color32* colors) { + PROFILE_MEM(GraphicsMeshes); auto model = mesh->GetModelBase(); CHECK_RETURN(model && model->IsVirtual(), true); CHECK_RETURN(triangles && vertices, true); @@ -172,6 +174,7 @@ bool Mesh::UpdateMesh(uint32 vertexCount, uint32 triangleCount, const VB0Element bool Mesh::UpdateMesh(uint32 vertexCount, uint32 triangleCount, const VB0ElementType* vb0, const VB1ElementType* vb1, const VB2ElementType* vb2, const void* ib, bool use16BitIndices) { + PROFILE_MEM(GraphicsMeshes); Release(); // Setup GPU resources diff --git a/Source/Engine/Graphics/Models/ModelInstanceEntry.cpp b/Source/Engine/Graphics/Models/ModelInstanceEntry.cpp index ace033d6d..1c9440b39 100644 --- a/Source/Engine/Graphics/Models/ModelInstanceEntry.cpp +++ b/Source/Engine/Graphics/Models/ModelInstanceEntry.cpp @@ -4,6 +4,7 @@ #include "Engine/Serialization/Serialization.h" #include "Engine/Content/Assets/Model.h" #include "Engine/Content/Assets/SkinnedModel.h" +#include "Engine/Profiler/ProfilerMemory.h" bool ModelInstanceEntries::HasContentLoaded() const { @@ -41,6 +42,7 @@ void ModelInstanceEntries::Serialize(SerializeStream& stream, const void* otherO void ModelInstanceEntries::Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) { + PROFILE_MEM(Graphics); const DeserializeStream& entries = stream["Entries"]; ASSERT(entries.IsArray()); Resize(entries.Size()); @@ -85,6 +87,7 @@ void ModelInstanceEntries::Setup(const SkinnedModel* model) void ModelInstanceEntries::Setup(int32 slotsCount) { + PROFILE_MEM(Graphics); Clear(); Resize(slotsCount); } diff --git a/Source/Engine/Graphics/RenderTask.cpp b/Source/Engine/Graphics/RenderTask.cpp index df45d981c..ecdcd572c 100644 --- a/Source/Engine/Graphics/RenderTask.cpp +++ b/Source/Engine/Graphics/RenderTask.cpp @@ -417,6 +417,7 @@ void SceneRenderTask::OnEnd(GPUContext* context) bool SceneRenderTask::Resize(int32 width, int32 height) { + PROFILE_MEM(Graphics); if (Output && Output->Resize(width, height)) return true; if (Buffers && Buffers->Init((int32)((float)width * RenderingPercentage), (int32)((float)height * RenderingPercentage))) diff --git a/Source/Engine/Graphics/Shaders/GPUShader.cpp b/Source/Engine/Graphics/Shaders/GPUShader.cpp index 2d14c1796..694b13f40 100644 --- a/Source/Engine/Graphics/Shaders/GPUShader.cpp +++ b/Source/Engine/Graphics/Shaders/GPUShader.cpp @@ -8,6 +8,7 @@ #include "Engine/Graphics/GPUDevice.h" #include "Engine/Graphics/Shaders/GPUVertexLayout.h" #include "Engine/Serialization/MemoryReadStream.h" +#include "Engine/Profiler/ProfilerMemory.h" static FORCE_INLINE uint32 HashPermutation(const StringAnsiView& name, int32 permutationIndex) { @@ -33,6 +34,7 @@ GPUShader::GPUShader() bool GPUShader::Create(MemoryReadStream& stream) { ReleaseGPU(); + _memoryUsage = sizeof(GPUShader); // Version int32 version; @@ -111,6 +113,7 @@ bool GPUShader::Create(MemoryReadStream& stream) const uint32 hash = HashPermutation(shader->GetName(), permutationIndex); ASSERT_LOW_LAYER(!_shaders.ContainsKey(hash)); _shaders.Add(hash, shader); + _memoryUsage += sizeof(GPUShaderProgram) + bytecodeSize; } } @@ -142,11 +145,12 @@ bool GPUShader::Create(MemoryReadStream& stream) return true; } _constantBuffers[slotIndex] = cb; + _memoryUsage += sizeof(GPUConstantBuffer); } // Don't read additional data - _memoryUsage = 1; + PROFILE_MEM_INC(GraphicsShaders, _memoryUsage); return false; } @@ -208,6 +212,7 @@ GPUResourceType GPUShader::GetResourceType() const void GPUShader::OnReleaseGPU() { + PROFILE_MEM_DEC(GraphicsShaders, _memoryUsage); for (GPUConstantBuffer*& cb : _constantBuffers) { if (cb) diff --git a/Source/Engine/Graphics/Textures/GPUTexture.cpp b/Source/Engine/Graphics/Textures/GPUTexture.cpp index 127cf2f5b..6d138a40c 100644 --- a/Source/Engine/Graphics/Textures/GPUTexture.cpp +++ b/Source/Engine/Graphics/Textures/GPUTexture.cpp @@ -16,6 +16,7 @@ #include "Engine/Threading/ThreadPoolTask.h" #include "Engine/Graphics/GPUDevice.h" #include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Scripting/Enums.h" namespace @@ -353,6 +354,8 @@ int32 GPUTexture::ComputeRowPitch(int32 mipLevel, int32 rowAlign) const bool GPUTexture::Init(const GPUTextureDescription& desc) { + PROFILE_MEM(GraphicsTextures); + // Validate description const auto device = GPUDevice::Instance; if (desc.Usage == GPUResourceUsage::Dynamic) @@ -500,6 +503,7 @@ bool GPUTexture::Init(const GPUTextureDescription& desc) LOG(Warning, "Cannot initialize texture. Description: {0}", desc.ToString()); return true; } + PROFILE_MEM_INC(GraphicsTextures, GetMemoryUsage()); // Render targets and depth buffers doesn't support normal textures streaming and are considered to be always resident if (IsRegularTexture() == false) @@ -589,6 +593,7 @@ GPUResourceType GPUTexture::GetResourceType() const void GPUTexture::OnReleaseGPU() { + PROFILE_MEM_DEC(GraphicsTextures, GetMemoryUsage()); _desc.Clear(); _residentMipLevels = 0; } diff --git a/Source/Engine/GraphicsDevice/DirectX/DX11/GPUDeviceDX11.cpp b/Source/Engine/GraphicsDevice/DirectX/DX11/GPUDeviceDX11.cpp index ad39b777d..c578fd295 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX11/GPUDeviceDX11.cpp +++ b/Source/Engine/GraphicsDevice/DirectX/DX11/GPUDeviceDX11.cpp @@ -19,6 +19,7 @@ #include "Engine/GraphicsDevice/DirectX/RenderToolsDX.h" #include "Engine/Graphics/PixelFormatExtensions.h" #include "Engine/Engine/CommandLine.h" +#include "Engine/Profiler/ProfilerMemory.h" #if !USE_EDITOR && PLATFORM_WINDOWS #include "Engine/Core/Config/PlatformSettings.h" @@ -810,16 +811,19 @@ void GPUDeviceDX11::DrawEnd() GPUTexture* GPUDeviceDX11::CreateTexture(const StringView& name) { + PROFILE_MEM(GraphicsTextures); return New(this, name); } GPUShader* GPUDeviceDX11::CreateShader(const StringView& name) { + PROFILE_MEM(GraphicsShaders); return New(this, name); } GPUPipelineState* GPUDeviceDX11::CreatePipelineState() { + PROFILE_MEM(GraphicsCommands); return New(this); } @@ -830,6 +834,7 @@ GPUTimerQuery* GPUDeviceDX11::CreateTimerQuery() GPUBuffer* GPUDeviceDX11::CreateBuffer(const StringView& name) { + PROFILE_MEM(GraphicsBuffers); return New(this, name); } @@ -850,6 +855,7 @@ GPUSwapChain* GPUDeviceDX11::CreateSwapChain(Window* window) GPUConstantBuffer* GPUDeviceDX11::CreateConstantBuffer(uint32 size, const StringView& name) { + PROFILE_MEM(GraphicsShaders); ID3D11Buffer* buffer = nullptr; uint32 memorySize = 0; if (size) diff --git a/Source/Engine/GraphicsDevice/DirectX/DX11/GPUSwapChainDX11.cpp b/Source/Engine/GraphicsDevice/DirectX/DX11/GPUSwapChainDX11.cpp index ba7226250..7a106d377 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX11/GPUSwapChainDX11.cpp +++ b/Source/Engine/GraphicsDevice/DirectX/DX11/GPUSwapChainDX11.cpp @@ -6,6 +6,7 @@ #include "Engine/Platform/Window.h" #include "Engine/Graphics/RenderTools.h" #include "Engine/GraphicsDevice/DirectX/RenderToolsDX.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "GPUContextDX11.h" GPUSwapChainDX11::GPUSwapChainDX11(GPUDeviceDX11* device, Window* window) @@ -60,9 +61,11 @@ void GPUSwapChainDX11::OnReleaseGPU() #endif // Release data + PROFILE_MEM_DEC(Graphics, _memoryUsage); releaseBackBuffer(); DX_SAFE_RELEASE_CHECK(_swapChain, 0); _width = _height = 0; + _memoryUsage = 0; } ID3D11Resource* GPUSwapChainDX11::GetResource() @@ -262,6 +265,7 @@ bool GPUSwapChainDX11::Resize(int32 width, int32 height) _width = width; _height = height; _memoryUsage = RenderTools::CalculateTextureMemoryUsage(_format, _width, _height, 1) * swapChainDesc.BufferCount; + PROFILE_MEM_INC(Graphics, _memoryUsage); getBackBuffer(); diff --git a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUDeviceDX12.cpp b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUDeviceDX12.cpp index 036454589..40e081175 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUDeviceDX12.cpp +++ b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUDeviceDX12.cpp @@ -18,6 +18,7 @@ #include "Engine/Graphics/PixelFormatExtensions.h" #include "Engine/GraphicsDevice/DirectX/RenderToolsDX.h" #include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Core/Log.h" #include "Engine/Core/Config/PlatformSettings.h" #include "UploadBufferDX12.h" @@ -833,16 +834,19 @@ void GPUDeviceDX12::WaitForGPU() GPUTexture* GPUDeviceDX12::CreateTexture(const StringView& name) { + PROFILE_MEM(GraphicsTextures); return New(this, name); } GPUShader* GPUDeviceDX12::CreateShader(const StringView& name) { + PROFILE_MEM(GraphicsShaders); return New(this, name); } GPUPipelineState* GPUDeviceDX12::CreatePipelineState() { + PROFILE_MEM(GraphicsCommands); return New(this); } @@ -853,6 +857,7 @@ GPUTimerQuery* GPUDeviceDX12::CreateTimerQuery() GPUBuffer* GPUDeviceDX12::CreateBuffer(const StringView& name) { + PROFILE_MEM(GraphicsBuffers); return New(this, name); } @@ -873,6 +878,7 @@ GPUSwapChain* GPUDeviceDX12::CreateSwapChain(Window* window) GPUConstantBuffer* GPUDeviceDX12::CreateConstantBuffer(uint32 size, const StringView& name) { + PROFILE_MEM(GraphicsShaders); return New(this, size, name); } diff --git a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUSwapChainDX12.cpp b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUSwapChainDX12.cpp index bfbf662b7..fa6dfa881 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUSwapChainDX12.cpp +++ b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUSwapChainDX12.cpp @@ -6,6 +6,7 @@ #include "GPUContextDX12.h" #include "../IncludeDirectXHeaders.h" #include "Engine/GraphicsDevice/DirectX/RenderToolsDX.h" +#include "Engine/Profiler/ProfilerMemory.h" void BackBufferDX12::Setup(GPUSwapChainDX12* window, ID3D12Resource* backbuffer) { @@ -71,6 +72,7 @@ void GPUSwapChainDX12::OnReleaseGPU() #endif // Release data + PROFILE_MEM_DEC(Graphics, _memoryUsage); releaseBackBuffer(); _backBuffers.Resize(0); if (_swapChain) @@ -79,6 +81,7 @@ void GPUSwapChainDX12::OnReleaseGPU() _swapChain = nullptr; } _width = _height = 0; + _memoryUsage = 0; } void GPUSwapChainDX12::releaseBackBuffer() @@ -244,6 +247,7 @@ bool GPUSwapChainDX12::Resize(int32 width, int32 height) _width = width; _height = height; _memoryUsage = RenderTools::CalculateTextureMemoryUsage(_format, _width, _height, 1) * swapChainDesc.BufferCount; + PROFILE_MEM_INC(Graphics, _memoryUsage); getBackBuffer(); #endif diff --git a/Source/Engine/GraphicsDevice/DirectX/DX12/UploadBufferDX12.cpp b/Source/Engine/GraphicsDevice/DirectX/DX12/UploadBufferDX12.cpp index 1e6613744..8fdfd5ac3 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX12/UploadBufferDX12.cpp +++ b/Source/Engine/GraphicsDevice/DirectX/DX12/UploadBufferDX12.cpp @@ -6,6 +6,7 @@ #include "GPUTextureDX12.h" #include "GPUContextDX12.h" #include "../RenderToolsDX.h" +#include "Engine/Profiler/ProfilerMemory.h" UploadBufferDX12::UploadBufferDX12(GPUDeviceDX12* device) : _device(device) @@ -235,6 +236,7 @@ UploadBufferPageDX12::UploadBufferPageDX12(GPUDeviceDX12* device, uint64 size) initResource(resource, D3D12_RESOURCE_STATE_GENERIC_READ, 1); DX_SET_DEBUG_NAME(_resource, GPUResourceDX12::GetName()); _memoryUsage = size; + PROFILE_MEM_INC(GraphicsCommands, _memoryUsage); GPUAddress = _resource->GetGPUVirtualAddress(); // Map buffer @@ -243,6 +245,8 @@ UploadBufferPageDX12::UploadBufferPageDX12(GPUDeviceDX12* device, uint64 size) void UploadBufferPageDX12::OnReleaseGPU() { + PROFILE_MEM_DEC(GraphicsCommands, _memoryUsage); + // Unmap if (_resource && CPUAddress) { diff --git a/Source/Engine/GraphicsDevice/Null/GPUDeviceNull.cpp b/Source/Engine/GraphicsDevice/Null/GPUDeviceNull.cpp index 41ec9f76a..a1582102f 100644 --- a/Source/Engine/GraphicsDevice/Null/GPUDeviceNull.cpp +++ b/Source/Engine/GraphicsDevice/Null/GPUDeviceNull.cpp @@ -14,6 +14,7 @@ #include "GPUVertexLayoutNull.h" #include "GPUSwapChainNull.h" #include "Engine/Core/Log.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Graphics/Async/GPUTasksManager.h" GPUDeviceNull::GPUDeviceNull() @@ -145,16 +146,19 @@ void GPUDeviceNull::WaitForGPU() GPUTexture* GPUDeviceNull::CreateTexture(const StringView& name) { + PROFILE_MEM(GraphicsTextures); return New(); } GPUShader* GPUDeviceNull::CreateShader(const StringView& name) { + PROFILE_MEM(GraphicsShaders); return New(); } GPUPipelineState* GPUDeviceNull::CreatePipelineState() { + PROFILE_MEM(GraphicsCommands); return New(); } @@ -165,6 +169,7 @@ GPUTimerQuery* GPUDeviceNull::CreateTimerQuery() GPUBuffer* GPUDeviceNull::CreateBuffer(const StringView& name) { + PROFILE_MEM(GraphicsBuffers); return New(); } diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp b/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp index 359ac0993..73eb90755 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp +++ b/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp @@ -34,6 +34,7 @@ #include "Engine/Engine/CommandLine.h" #include "Engine/Utilities/StringConverter.h" #include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Threading/Threading.h" #include "Engine/Scripting/Enums.h" @@ -229,9 +230,13 @@ static VKAPI_ATTR VkBool32 VKAPI_PTR DebugUtilsCallback(VkDebugUtilsMessageSever const String message(callbackData->pMessage); if (callbackData->pMessageIdName) + { LOG(Info, "[Vulkan] {0} {1}:{2}({3}) {4}", type, severity, callbackData->messageIdNumber, String(callbackData->pMessageIdName), message); + } else + { LOG(Info, "[Vulkan] {0} {1}:{2} {3}", type, severity, callbackData->messageIdNumber, message); + } #if BUILD_DEBUG if (auto* context = (GPUContextVulkan*)GPUDevice::Instance->GetMainContext()) @@ -2095,16 +2100,19 @@ void GPUDeviceVulkan::WaitForGPU() GPUTexture* GPUDeviceVulkan::CreateTexture(const StringView& name) { + PROFILE_MEM(GraphicsTextures); return New(this, name); } GPUShader* GPUDeviceVulkan::CreateShader(const StringView& name) { + PROFILE_MEM(GraphicsShaders); return New(this, name); } GPUPipelineState* GPUDeviceVulkan::CreatePipelineState() { + PROFILE_MEM(GraphicsCommands); return New(this); } @@ -2115,6 +2123,7 @@ GPUTimerQuery* GPUDeviceVulkan::CreateTimerQuery() GPUBuffer* GPUDeviceVulkan::CreateBuffer(const StringView& name) { + PROFILE_MEM(GraphicsBuffers); return New(this, name); } @@ -2135,6 +2144,7 @@ GPUSwapChain* GPUDeviceVulkan::CreateSwapChain(Window* window) GPUConstantBuffer* GPUDeviceVulkan::CreateConstantBuffer(uint32 size, const StringView& name) { + PROFILE_MEM(GraphicsShaders); return New(this, size); } diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUShaderVulkan.cpp b/Source/Engine/GraphicsDevice/Vulkan/GPUShaderVulkan.cpp index f6fbe4838..853fcf693 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GPUShaderVulkan.cpp +++ b/Source/Engine/GraphicsDevice/Vulkan/GPUShaderVulkan.cpp @@ -12,6 +12,7 @@ #include "Engine/Core/Types/DataContainer.h" #include "Engine/Serialization/MemoryReadStream.h" #include "Engine/Graphics/PixelFormatExtensions.h" +#include "Engine/Profiler/ProfilerMemory.h" #if PLATFORM_DESKTOP #define VULKAN_UNIFORM_RING_BUFFER_SIZE (24 * 1024 * 1024) @@ -41,6 +42,7 @@ UniformBufferUploaderVulkan::UniformBufferUploaderVulkan(GPUDeviceVulkan* device VkResult result = vmaCreateBuffer(_device->Allocator, &bufferInfo, &allocInfo, &_buffer, &_allocation, nullptr); LOG_VULKAN_RESULT(result); _memoryUsage = bufferInfo.size; + PROFILE_MEM_INC(GraphicsCommands, _memoryUsage); // Map buffer result = vmaMapMemory(_device->Allocator, _allocation, (void**)&_mapped); @@ -87,6 +89,7 @@ void UniformBufferUploaderVulkan::OnReleaseGPU() { if (_allocation != VK_NULL_HANDLE) { + PROFILE_MEM_DEC(GraphicsCommands, _memoryUsage); if (_mapped) { vmaUnmapMemory(_device->Allocator, _allocation); diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUSwapChainVulkan.cpp b/Source/Engine/GraphicsDevice/Vulkan/GPUSwapChainVulkan.cpp index 18e2cd95c..801ba1fc1 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GPUSwapChainVulkan.cpp +++ b/Source/Engine/GraphicsDevice/Vulkan/GPUSwapChainVulkan.cpp @@ -12,6 +12,7 @@ #include "Engine/Graphics/GPULimits.h" #include "Engine/Scripting/Enums.h" #include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Profiler/ProfilerMemory.h" void BackBufferVulkan::Setup(GPUSwapChainVulkan* window, VkImage backbuffer, PixelFormat format, VkExtent3D extent) { @@ -61,6 +62,7 @@ void GPUSwapChainVulkan::OnReleaseGPU() ReleaseBackBuffer(); // Release data + PROFILE_MEM_DEC(Graphics, _memoryUsage); _currentImageIndex = -1; _semaphoreIndex = 0; _acquiredImageIndex = -1; @@ -76,6 +78,7 @@ void GPUSwapChainVulkan::OnReleaseGPU() _surface = VK_NULL_HANDLE; } _width = _height = 0; + _memoryUsage = 0; } bool GPUSwapChainVulkan::IsFullscreen() @@ -412,6 +415,7 @@ bool GPUSwapChainVulkan::CreateSwapChain(int32 width, int32 height) // Estimate memory usage _memoryUsage = 1024 + RenderTools::CalculateTextureMemoryUsage(_format, _width, _height, 1) * _backBuffers.Count(); + PROFILE_MEM_INC(Graphics, _memoryUsage); return false; } diff --git a/Source/Engine/Input/Input.cpp b/Source/Engine/Input/Input.cpp index 7a4d0592c..dc5ecc236 100644 --- a/Source/Engine/Input/Input.cpp +++ b/Source/Engine/Input/Input.cpp @@ -14,6 +14,7 @@ #include "Engine/Scripting/ScriptingType.h" #include "Engine/Scripting/BinaryModule.h" #include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Serialization/JsonTools.h" struct AxisEvaluation @@ -89,12 +90,14 @@ Array Input::AxisMappings; void InputSettings::Apply() { + PROFILE_MEM(Input); Input::ActionMappings = ActionMappings; Input::AxisMappings = AxisMappings; } void InputSettings::Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) { + PROFILE_MEM(Input); const auto actionMappings = stream.FindMember("ActionMappings"); if (actionMappings != stream.MemberEnd()) { @@ -615,6 +618,7 @@ float Input::GetAxisRaw(const StringView& name) void Input::SetInputMappingFromSettings(const JsonAssetReference& settings) { + PROFILE_MEM(Input); auto actionMappings = settings.GetInstance()->ActionMappings; ActionMappings.Resize(actionMappings.Count(), false); for (int i = 0; i < actionMappings.Count(); i++) @@ -634,6 +638,7 @@ void Input::SetInputMappingFromSettings(const JsonAssetReference& void Input::SetInputMappingToDefaultSettings() { + PROFILE_MEM(Input); InputSettings* settings = InputSettings::Get(); if (settings) { @@ -696,6 +701,7 @@ Array Input::GetAllAxisConfigsByName(const StringView& name) void Input::SetAxisConfigByName(const StringView& name, AxisConfig& config, bool all) { + PROFILE_MEM(Input); for (int i = 0; i < AxisMappings.Count(); ++i) { auto& mapping = AxisMappings.At(i); @@ -712,6 +718,7 @@ void Input::SetAxisConfigByName(const StringView& name, AxisConfig& config, bool void Input::SetAxisConfigByName(const StringView& name, InputAxisType inputType, const KeyboardKeys positiveButton, const KeyboardKeys negativeButton, bool all) { + PROFILE_MEM(Input); for (int i = 0; i < AxisMappings.Count(); ++i) { auto& mapping = AxisMappings.At(i); @@ -727,6 +734,7 @@ void Input::SetAxisConfigByName(const StringView& name, InputAxisType inputType, void Input::SetAxisConfigByName(const StringView& name, InputAxisType inputType, const GamepadButton positiveButton, const GamepadButton negativeButton, InputGamepadIndex gamepadIndex, bool all) { + PROFILE_MEM(Input); for (int i = 0; i < AxisMappings.Count(); ++i) { auto& mapping = AxisMappings.At(i); @@ -742,6 +750,7 @@ void Input::SetAxisConfigByName(const StringView& name, InputAxisType inputType, void Input::SetAxisConfigByName(const StringView& name, InputAxisType inputType, const float gravity, const float deadZone, const float sensitivity, const float scale, const bool snap, bool all) { + PROFILE_MEM(Input); for (int i = 0; i < AxisMappings.Count(); ++i) { auto& mapping = AxisMappings.At(i); @@ -760,6 +769,7 @@ void Input::SetAxisConfigByName(const StringView& name, InputAxisType inputType, void Input::SetActionConfigByName(const StringView& name, const KeyboardKeys key, bool all) { + PROFILE_MEM(Input); for (int i = 0; i < ActionMappings.Count(); ++i) { auto& mapping = ActionMappings.At(i); @@ -774,6 +784,7 @@ void Input::SetActionConfigByName(const StringView& name, const KeyboardKeys key void Input::SetActionConfigByName(const StringView& name, const MouseButton mouseButton, bool all) { + PROFILE_MEM(Input); for (int i = 0; i < ActionMappings.Count(); ++i) { auto& mapping = ActionMappings.At(i); @@ -788,6 +799,7 @@ void Input::SetActionConfigByName(const StringView& name, const MouseButton mous void Input::SetActionConfigByName(const StringView& name, const GamepadButton gamepadButton, InputGamepadIndex gamepadIndex, bool all) { + PROFILE_MEM(Input); for (int i = 0; i < ActionMappings.Count(); ++i) { auto& mapping = ActionMappings.At(i); @@ -802,6 +814,7 @@ void Input::SetActionConfigByName(const StringView& name, const GamepadButton ga void Input::SetActionConfigByName(const StringView& name, ActionConfig& config, bool all) { + PROFILE_MEM(Input); for (int i = 0; i < ActionMappings.Count(); ++i) { auto& mapping = ActionMappings.At(i); @@ -819,6 +832,7 @@ void Input::SetActionConfigByName(const StringView& name, ActionConfig& config, void InputService::Update() { PROFILE_CPU(); + PROFILE_MEM(Input); const auto frame = Time::Update.TicksCount; const auto dt = Time::Update.UnscaledDeltaTime.GetTotalSeconds(); InputEvents.Clear(); diff --git a/Source/Engine/Level/Actor.cpp b/Source/Engine/Level/Actor.cpp index 4989f2c49..12039da5e 100644 --- a/Source/Engine/Level/Actor.cpp +++ b/Source/Engine/Level/Actor.cpp @@ -1127,9 +1127,13 @@ void Actor::Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) else if (!parent && parentId.IsValid()) { if (_prefabObjectID.IsValid()) + { LOG(Warning, "Missing parent actor {0} for \'{1}\', prefab object {2}", parentId, ToString(), _prefabObjectID); + } else + { LOG(Warning, "Missing parent actor {0} for \'{1}\'", parentId, ToString()); + } } } } diff --git a/Source/Engine/Level/Level.cpp b/Source/Engine/Level/Level.cpp index a96ba936a..5bcd98994 100644 --- a/Source/Engine/Level/Level.cpp +++ b/Source/Engine/Level/Level.cpp @@ -24,6 +24,7 @@ #include "Engine/Platform/File.h" #include "Engine/Platform/FileSystem.h" #include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Scripting/Script.h" #include "Engine/Engine/Time.h" #include "Engine/Scripting/ManagedCLR/MAssembly.h" @@ -248,6 +249,7 @@ void LayersAndTagsSettings::Apply() #define TICK_LEVEL(tickingStage, name) \ PROFILE_CPU_NAMED(name); \ + PROFILE_MEM(Level); \ ScopeLock lock(Level::ScenesLock); \ auto& scenes = Level::Scenes; \ if (!Time::GetGamePaused() && Level::TickEnabled) \ @@ -504,6 +506,7 @@ public: // Note: we don't want to override original scene files PROFILE_CPU_NAMED("Level.ReloadScripts"); + PROFILE_MEM(Level); LOG(Info, "Scripts reloading start"); const auto startTime = DateTime::NowUTC(); @@ -784,6 +787,7 @@ bool LevelImpl::unloadScene(Scene* scene) const auto sceneId = scene->GetID(); PROFILE_CPU_NAMED("Level.UnloadScene"); + PROFILE_MEM(Level); // Fire event CallSceneEvent(SceneEventType::OnSceneUnloading, scene, sceneId); @@ -838,6 +842,7 @@ bool Level::loadScene(const BytesContainer& sceneData, Scene** outScene) LOG(Error, "Missing scene data."); return true; } + PROFILE_MEM(Level); // Parse scene JSON file rapidjson_flax::Document document; @@ -870,6 +875,7 @@ bool Level::loadScene(rapidjson_flax::Document& document, Scene** outScene) bool Level::loadScene(rapidjson_flax::Value& data, int32 engineBuild, Scene** outScene, const String* assetPath) { PROFILE_CPU_NAMED("Level.LoadScene"); + PROFILE_MEM(Level); if (outScene) *outScene = nullptr; #if USE_EDITOR @@ -954,6 +960,7 @@ bool Level::loadScene(rapidjson_flax::Value& data, int32 engineBuild, Scene** ou ScenesLock.Unlock(); // Unlock scenes from Main Thread so Job Threads can use it to safely setup actors hierarchy (see Actor::Deserialize) JobSystem::Execute([&](int32 i) { + PROFILE_MEM(Level); i++; // Start from 1. at index [0] was scene auto& stream = data[i]; auto obj = SceneObjectsFactory::Spawn(context, stream); @@ -1165,6 +1172,7 @@ bool LevelImpl::saveScene(Scene* scene) bool LevelImpl::saveScene(Scene* scene, const String& path) { PROFILE_CPU_NAMED("Level.SaveScene"); + PROFILE_MEM(Level); ASSERT(scene && EnumHasNoneFlags(scene->Flags, ObjectFlags::WasMarkedToDelete)); auto sceneId = scene->GetID(); @@ -1208,6 +1216,7 @@ bool LevelImpl::saveScene(Scene* scene, const String& path) bool LevelImpl::saveScene(Scene* scene, rapidjson_flax::StringBuffer& outBuffer, bool prettyJson) { PROFILE_CPU_NAMED("Level.SaveScene"); + PROFILE_MEM(Level); if (prettyJson) { PrettyJsonWriter writerObj(outBuffer); diff --git a/Source/Engine/Level/Scene/SceneRendering.cpp b/Source/Engine/Level/Scene/SceneRendering.cpp index 445447cd1..c6f5669a5 100644 --- a/Source/Engine/Level/Scene/SceneRendering.cpp +++ b/Source/Engine/Level/Scene/SceneRendering.cpp @@ -9,6 +9,7 @@ #include "Engine/Threading/JobSystem.h" #include "Engine/Threading/Threading.h" #include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Profiler/ProfilerMemory.h" ISceneRenderingListener::~ISceneRenderingListener() { @@ -41,6 +42,7 @@ FORCE_INLINE bool FrustumsListCull(const BoundingSphere& bounds, const Array_drawCategory; ScopeLock lock(Locker); auto& list = Actors[category]; @@ -214,6 +217,7 @@ void SceneRendering::RemoveActor(Actor* a, int32& key) void SceneRendering::DrawActorsJob(int32) { PROFILE_CPU(); + PROFILE_MEM(Graphics); auto& mainContext = _drawBatch->GetMainContext(); const auto& view = mainContext.View; if (view.StaticFlagsMask != StaticFlags::None) diff --git a/Source/Engine/Localization/CultureInfo.cpp b/Source/Engine/Localization/CultureInfo.cpp index 4595703af..7d53489b5 100644 --- a/Source/Engine/Localization/CultureInfo.cpp +++ b/Source/Engine/Localization/CultureInfo.cpp @@ -3,6 +3,7 @@ #include "CultureInfo.h" #include "Engine/Core/Log.h" #include "Engine/Core/Types/StringView.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Utilities/StringConverter.h" #include "Engine/Scripting/Types.h" #include "Engine/Scripting/ManagedCLR/MProperty.h" @@ -51,6 +52,7 @@ CultureInfo::CultureInfo(int32 lcid) _data = nullptr; if (lcid == 0) return; + PROFILE_MEM(Localization); if (lcid == 127) { _englishName = TEXT("Invariant Culture"); @@ -88,6 +90,7 @@ CultureInfo::CultureInfo(const StringView& name) CultureInfo::CultureInfo(const StringAnsiView& name) { + PROFILE_MEM(Localization); _data = nullptr; if (name.IsEmpty()) { @@ -160,6 +163,7 @@ bool CultureInfo::operator==(const CultureInfo& other) const void* MUtils::ToManaged(const CultureInfo& value) { #if USE_CSHARP + PROFILE_MEM(Localization); auto scriptingClass = Scripting::GetStaticClass(); CHECK_RETURN(scriptingClass, nullptr); auto cultureInfoToManaged = scriptingClass->GetMethod("CultureInfoToManaged", 1); @@ -182,6 +186,7 @@ CultureInfo MUtils::ToNative(void* value) if (value) lcid = static_cast(value)->lcid; #elif USE_CSHARP + PROFILE_MEM(Localization); const MClass* klass = GetBinaryModuleCorlib()->Assembly->GetClass("System.Globalization.CultureInfo"); if (value && klass) { diff --git a/Source/Engine/Localization/Localization.cpp b/Source/Engine/Localization/Localization.cpp index 00a6a8deb..d1b3a036f 100644 --- a/Source/Engine/Localization/Localization.cpp +++ b/Source/Engine/Localization/Localization.cpp @@ -9,6 +9,7 @@ #include "Engine/Engine/EngineService.h" #include "Engine/Content/Content.h" #include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Serialization/Serialization.h" #include @@ -171,6 +172,7 @@ String LocalizedString::ToStringPlural(int32 n) const void LocalizationService::OnLocalizationChanged() { PROFILE_CPU(); + PROFILE_MEM(Localization); Instance.LocalizedStringTables.Clear(); Instance.FallbackStringTables.Clear(); @@ -279,6 +281,8 @@ void LocalizationService::OnLocalizationChanged() bool LocalizationService::Init() { + PROFILE_MEM(Localization); + // Use system language as default CurrentLanguage = CurrentCulture = CultureInfo(Platform::GetUserLocaleName()); diff --git a/Source/Engine/Localization/LocalizedStringTable.cpp b/Source/Engine/Localization/LocalizedStringTable.cpp index 84aca852d..e99b87a27 100644 --- a/Source/Engine/Localization/LocalizedStringTable.cpp +++ b/Source/Engine/Localization/LocalizedStringTable.cpp @@ -5,6 +5,7 @@ #include "Engine/Serialization/JsonWriters.h" #include "Engine/Serialization/SerializationFwd.h" #include "Engine/Content/Factories/JsonAssetFactory.h" +#include "Engine/Profiler/ProfilerMemory.h" #if USE_EDITOR #include "Engine/Threading/Threading.h" #include "Engine/Core/Log.h" @@ -20,6 +21,7 @@ LocalizedStringTable::LocalizedStringTable(const SpawnParams& params, const Asse void LocalizedStringTable::AddString(const StringView& id, const StringView& value) { + PROFILE_MEM(Localization); auto& values = Entries[id]; values.Resize(1); values[0] = value; @@ -27,6 +29,7 @@ void LocalizedStringTable::AddString(const StringView& id, const StringView& val void LocalizedStringTable::AddPluralString(const StringView& id, const StringView& value, int32 n) { + PROFILE_MEM(Localization); CHECK(n >= 0 && n < 1024); auto& values = Entries[id]; values.Resize(Math::Max(values.Count(), n + 1)); @@ -57,6 +60,8 @@ String LocalizedStringTable::GetPluralString(const String& id, int32 n) const Asset::LoadResult LocalizedStringTable::loadAsset() { + PROFILE_MEM(Localization); + // Base auto result = JsonAssetBase::loadAsset(); if (result != LoadResult::Ok || IsInternalType()) diff --git a/Source/Engine/Navigation/NavCrowd.cpp b/Source/Engine/Navigation/NavCrowd.cpp index c9a56a08a..cb2a4ebee 100644 --- a/Source/Engine/Navigation/NavCrowd.cpp +++ b/Source/Engine/Navigation/NavCrowd.cpp @@ -34,9 +34,13 @@ bool NavCrowd::Init(const NavAgentProperties& agentProperties, int32 maxAgents) if (!navMeshRuntime) { if (NavMeshRuntime::Get()) + { LOG(Error, "Cannot create crowd. Failed to find a navmesh that matches a given agent properties."); + } else + { LOG(Error, "Cannot create crowd. No navmesh is loaded."); + } } #endif return Init(agentProperties.Radius * 3.0f, maxAgents, navMeshRuntime); diff --git a/Source/Engine/Navigation/NavMeshData.cpp b/Source/Engine/Navigation/NavMeshData.cpp index 7dfa597a8..6fbf5e33e 100644 --- a/Source/Engine/Navigation/NavMeshData.cpp +++ b/Source/Engine/Navigation/NavMeshData.cpp @@ -4,6 +4,7 @@ #include "Engine/Core/Log.h" #include "Engine/Serialization/WriteStream.h" #include "Engine/Serialization/MemoryReadStream.h" +#include "Engine/Profiler/ProfilerMemory.h" void NavMeshData::Save(WriteStream& stream) { @@ -47,6 +48,7 @@ bool NavMeshData::Load(BytesContainer& data, bool copyData) return true; } MemoryReadStream stream(data.Get(), data.Length()); + PROFILE_MEM(Navigation); // Read header const auto header = stream.Move(); diff --git a/Source/Engine/Navigation/NavMeshRuntime.cpp b/Source/Engine/Navigation/NavMeshRuntime.cpp index baa8b0320..f90d5efd1 100644 --- a/Source/Engine/Navigation/NavMeshRuntime.cpp +++ b/Source/Engine/Navigation/NavMeshRuntime.cpp @@ -6,6 +6,7 @@ #include "Engine/Core/Log.h" #include "Engine/Core/Random.h" #include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Threading/Threading.h" #include #include @@ -312,6 +313,7 @@ void NavMeshRuntime::EnsureCapacity(int32 tilesToAddCount) if (newTilesCount <= capacity) return; PROFILE_CPU_NAMED("NavMeshRuntime.EnsureCapacity"); + PROFILE_MEM(Navigation); // Navmesh tiles capacity growing rule int32 newCapacity = capacity ? capacity : 32; @@ -380,6 +382,7 @@ void NavMeshRuntime::AddTiles(NavMesh* navMesh) return; auto& data = navMesh->Data; PROFILE_CPU_NAMED("NavMeshRuntime.AddTiles"); + PROFILE_MEM(Navigation); ScopeLock lock(Locker); // Validate data (must match navmesh) or init navmesh to match the tiles options @@ -411,6 +414,7 @@ void NavMeshRuntime::AddTile(NavMesh* navMesh, NavMeshTileData& tileData) ASSERT(navMesh); auto& data = navMesh->Data; PROFILE_CPU_NAMED("NavMeshRuntime.AddTile"); + PROFILE_MEM(Navigation); ScopeLock lock(Locker); // Validate data (must match navmesh) or init navmesh to match the tiles options diff --git a/Source/Engine/Navigation/Navigation.cpp b/Source/Engine/Navigation/Navigation.cpp index 446464634..1d54550df 100644 --- a/Source/Engine/Navigation/Navigation.cpp +++ b/Source/Engine/Navigation/Navigation.cpp @@ -18,6 +18,7 @@ #include "Engine/Content/Deprecated.h" #include "Engine/Engine/EngineService.h" #include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Serialization/Serialization.h" #include #include @@ -93,6 +94,7 @@ NavMeshRuntime* NavMeshRuntime::Get(const NavMeshProperties& navMeshProperties, if (!result && createIfMissing) { // Create a new navmesh + PROFILE_MEM(Navigation); result = New(navMeshProperties); NavMeshes.Add(result); } @@ -178,16 +180,20 @@ NavigationService NavigationServiceInstance; void* dtAllocDefault(size_t size, dtAllocHint) { + PROFILE_MEM(Navigation); return Allocator::Allocate(size); } void* rcAllocDefault(size_t size, rcAllocHint) { + PROFILE_MEM(Navigation); return Allocator::Allocate(size); } NavigationSettings::NavigationSettings() { + PROFILE_MEM(Navigation); + // Init navmeshes NavMeshes.Resize(1); auto& navMesh = NavMeshes[0]; diff --git a/Source/Engine/Networking/NetworkManager.cpp b/Source/Engine/Networking/NetworkManager.cpp index af84b8d8c..3dc244bba 100644 --- a/Source/Engine/Networking/NetworkManager.cpp +++ b/Source/Engine/Networking/NetworkManager.cpp @@ -14,6 +14,7 @@ #include "Engine/Engine/EngineService.h" #include "Engine/Engine/Time.h" #include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Scripting/Scripting.h" float NetworkManager::NetworkFPS = 60.0f; @@ -414,6 +415,7 @@ NetworkManagerService NetworkManagerServiceInstance; bool StartPeer() { PROFILE_CPU(); + PROFILE_MEM(Networking); ASSERT_LOW_LAYER(!NetworkManager::Peer); NetworkManager::State = NetworkConnectionState::Connecting; NetworkManager::StateChanged(); @@ -504,6 +506,7 @@ NetworkClient* NetworkManager::GetClient(uint32 clientId) bool NetworkManager::StartServer() { PROFILE_CPU(); + PROFILE_MEM(Networking); Stop(); LOG(Info, "Starting network manager as server"); @@ -529,6 +532,7 @@ bool NetworkManager::StartServer() bool NetworkManager::StartClient() { PROFILE_CPU(); + PROFILE_MEM(Networking); Stop(); LOG(Info, "Starting network manager as client"); @@ -553,6 +557,7 @@ bool NetworkManager::StartClient() bool NetworkManager::StartHost() { PROFILE_CPU(); + PROFILE_MEM(Networking); Stop(); LOG(Info, "Starting network manager as host"); @@ -586,6 +591,7 @@ void NetworkManager::Stop() if (Mode == NetworkManagerMode::Offline && State == NetworkConnectionState::Offline) return; PROFILE_CPU(); + PROFILE_MEM(Networking); LOG(Info, "Stopping network manager"); State = NetworkConnectionState::Disconnecting; @@ -632,6 +638,7 @@ void NetworkManager::Stop() void NetworkKeys::SendPending() { PROFILE_CPU(); + PROFILE_MEM(Networking); ScopeLock lock(Lock); // Add new keys @@ -718,6 +725,7 @@ void NetworkManagerService::Update() if (NetworkManager::Mode == NetworkManagerMode::Offline || (float)(currentTime - LastUpdateTime) < minDeltaTime || !peer) return; PROFILE_CPU(); + PROFILE_MEM(Networking); LastUpdateTime = currentTime; NetworkManager::Frame++; NetworkInternal::NetworkReplicatorPreUpdate(); diff --git a/Source/Engine/Networking/NetworkPeer.cpp b/Source/Engine/Networking/NetworkPeer.cpp index 0f815a1ec..073d3d060 100644 --- a/Source/Engine/Networking/NetworkPeer.cpp +++ b/Source/Engine/Networking/NetworkPeer.cpp @@ -7,6 +7,7 @@ #include "Engine/Core/Math/Math.h" #include "Engine/Platform/CPUInfo.h" #include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Profiler/ProfilerMemory.h" Array NetworkPeer::Peers; @@ -85,6 +86,7 @@ void NetworkPeer::Shutdown() void NetworkPeer::CreateMessageBuffers() { + PROFILE_MEM(Networking); ASSERT(MessageBuffer == nullptr); const uint32 pageSize = Platform::GetCPUInfo().PageSize; @@ -198,6 +200,8 @@ bool NetworkPeer::EndSendMessage(const NetworkChannelType channelType, const Net NetworkPeer* NetworkPeer::CreatePeer(const NetworkConfig& config) { + PROFILE_MEM(Networking); + // Validate the address for listen/connect if (config.Address != TEXT("any")) { diff --git a/Source/Engine/Networking/NetworkReplicator.cpp b/Source/Engine/Networking/NetworkReplicator.cpp index af478a019..fba916891 100644 --- a/Source/Engine/Networking/NetworkReplicator.cpp +++ b/Source/Engine/Networking/NetworkReplicator.cpp @@ -24,6 +24,7 @@ #include "Engine/Level/Prefabs/Prefab.h" #include "Engine/Level/Prefabs/PrefabManager.h" #include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Scripting/Script.h" #include "Engine/Scripting/Scripting.h" #include "Engine/Scripting/ScriptingObjectReference.h" @@ -1112,6 +1113,7 @@ void NetworkReplicator::AddSerializer(const ScriptingTypeHandle& typeHandle, Ser { if (!typeHandle) return; + PROFILE_MEM(Networking); const Serializer serializer{ { serialize, deserialize }, { serializeTag, deserializeTag } }; SerializersTable[typeHandle] = serializer; } @@ -1145,6 +1147,7 @@ bool NetworkReplicator::InvokeSerializer(const ScriptingTypeHandle& typeHandle, serializer.Methods[1] = INetworkSerializable_Script_Deserialize; serializer.Tags[0] = serializer.Tags[1] = nullptr; } + PROFILE_MEM(Networking); SerializersTable.Add(typeHandle, serializer); } else if (const ScriptingTypeHandle baseTypeHandle = typeHandle.GetType().GetBaseType()) @@ -1166,6 +1169,7 @@ void NetworkReplicator::AddObject(ScriptingObject* obj, const ScriptingObject* p { if (!obj || NetworkManager::IsOffline()) return; + PROFILE_MEM(Networking); ScopeLock lock(ObjectsLock); if (Objects.Contains(obj)) return; @@ -1235,6 +1239,7 @@ void NetworkReplicator::SpawnObject(ScriptingObject* obj, const DataContainerGetID()); if (it != Objects.End() && it->Item.Spawned) @@ -1250,6 +1255,7 @@ void NetworkReplicator::DespawnObject(ScriptingObject* obj) { if (!obj || NetworkManager::IsOffline()) return; + PROFILE_MEM(Networking); ScopeLock lock(ObjectsLock); const auto it = Objects.Find(obj->GetID()); if (it == Objects.End()) @@ -1524,6 +1530,7 @@ Dictionary NetworkRpcInfo::RPCsTable; NetworkStream* NetworkReplicator::BeginInvokeRPC() { + PROFILE_MEM(Networking); if (CachedWriteStream == nullptr) CachedWriteStream = New(); CachedWriteStream->Initialize(); @@ -1540,6 +1547,7 @@ bool NetworkReplicator::EndInvokeRPC(ScriptingObject* obj, const ScriptingTypeHa const NetworkRpcInfo* info = NetworkRpcInfo::RPCsTable.TryGet(NetworkRpcName(type, name)); if (!info || !obj || NetworkManager::IsOffline()) return false; + PROFILE_MEM(Networking); ObjectsLock.Lock(); auto& rpc = RpcQueue.AddOne(); rpc.Object = obj; diff --git a/Source/Engine/Networking/NetworkStream.cpp b/Source/Engine/Networking/NetworkStream.cpp index 5c4a367f1..1542c98bd 100644 --- a/Source/Engine/Networking/NetworkStream.cpp +++ b/Source/Engine/Networking/NetworkStream.cpp @@ -4,6 +4,7 @@ #include "INetworkSerializable.h" #include "Engine/Core/Math/Quaternion.h" #include "Engine/Core/Math/Transform.h" +#include "Engine/Profiler/ProfilerMemory.h" // Quaternion quantized for optimized network data size. struct NetworkQuaternion @@ -119,6 +120,7 @@ void NetworkStream::Initialize(uint32 minCapacity) Allocator::Free(_buffer); // Allocate new one + PROFILE_MEM(Networking); _buffer = (byte*)Allocator::Allocate(minCapacity); _length = minCapacity; _allocated = true; @@ -246,6 +248,7 @@ void NetworkStream::WriteBytes(const void* data, uint32 bytes) uint32 newLength = _length != 0 ? _length * 2 : 256; while (newLength < position + bytes) newLength *= 2; + PROFILE_MEM(Networking); byte* newBuf = (byte*)Allocator::Allocate(newLength); if (_buffer && _length) Platform::MemoryCopy(newBuf, _buffer, _length); diff --git a/Source/Engine/Particles/ParticleEffect.cpp b/Source/Engine/Particles/ParticleEffect.cpp index c1031f4ac..1359dbcf2 100644 --- a/Source/Engine/Particles/ParticleEffect.cpp +++ b/Source/Engine/Particles/ParticleEffect.cpp @@ -6,6 +6,7 @@ #include "Engine/Content/Deprecated.h" #include "Engine/Serialization/JsonTools.h" #include "Engine/Serialization/Serialization.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Level/Scene/SceneRendering.h" #include "Engine/Level/Scene/Scene.h" #include "Engine/Engine/Time.h" @@ -380,6 +381,7 @@ void ParticleEffect::Sync() Instance.ClearState(); return; } + PROFILE_MEM(Particles); Instance.Sync(system); @@ -498,6 +500,7 @@ void ParticleEffect::CacheModifiedParameters() { if (_parameters.IsEmpty()) return; + PROFILE_MEM(Particles); _parametersOverrides.Clear(); auto& parameters = GetParameters(); for (auto& param : parameters) @@ -516,6 +519,7 @@ void ParticleEffect::ApplyModifiedParameters() { if (_parametersOverrides.IsEmpty()) return; + PROFILE_MEM(Particles); // Parameters getter applies the parameters overrides if (_parameters.IsEmpty()) @@ -658,6 +662,7 @@ void ParticleEffect::Deserialize(DeserializeStream& stream, ISerializeModifier* // Base Actor::Deserialize(stream, modifier); + PROFILE_MEM(Particles); const auto overridesMember = stream.FindMember("Overrides"); if (overridesMember != stream.MemberEnd()) { diff --git a/Source/Engine/Particles/ParticleEmitter.cpp b/Source/Engine/Particles/ParticleEmitter.cpp index 452d4560a..c7bc647bf 100644 --- a/Source/Engine/Particles/ParticleEmitter.cpp +++ b/Source/Engine/Particles/ParticleEmitter.cpp @@ -13,6 +13,7 @@ #include "Engine/Serialization/MemoryReadStream.h" #include "Engine/Serialization/MemoryWriteStream.h" #include "Engine/Threading/Threading.h" +#include "Engine/Profiler/ProfilerMemory.h" #if USE_EDITOR #include "ParticleEmitterFunction.h" #include "Engine/ShadersCompilation/Config.h" @@ -41,6 +42,7 @@ ParticleEmitter::ParticleEmitter(const SpawnParams& params, const AssetInfo* inf ParticleEffect* ParticleEmitter::Spawn(Actor* parent, const Transform& transform, float duration, bool autoDestroy) { + PROFILE_MEM(Particles); CHECK_RETURN(!WaitForLoaded(), nullptr); auto system = Content::CreateVirtualAsset(); CHECK_RETURN(system, nullptr); @@ -72,6 +74,7 @@ namespace Asset::LoadResult ParticleEmitter::load() { + PROFILE_MEM(Particles); ConcurrentSystemLocker::WriteScope systemScope(Particles::SystemLocker); // Load the graph diff --git a/Source/Engine/Particles/ParticleEmitterFunction.cpp b/Source/Engine/Particles/ParticleEmitterFunction.cpp index 3aa0ec115..f8aa5c62a 100644 --- a/Source/Engine/Particles/ParticleEmitterFunction.cpp +++ b/Source/Engine/Particles/ParticleEmitterFunction.cpp @@ -5,6 +5,7 @@ #include "Engine/Core/Log.h" #include "Engine/Serialization/MemoryReadStream.h" #include "Engine/Threading/Threading.h" +#include "Engine/Profiler/ProfilerMemory.h" #if USE_EDITOR #include "Engine/Core/Types/DataContainer.h" #include "Engine/Serialization/MemoryWriteStream.h" @@ -41,6 +42,7 @@ ParticleEmitterFunction::ParticleEmitterFunction(const SpawnParams& params, cons Asset::LoadResult ParticleEmitterFunction::load() { + PROFILE_MEM(Particles); ConcurrentSystemLocker::WriteScope systemScope(Particles::SystemLocker); // Load graph diff --git a/Source/Engine/Particles/ParticleSystem.cpp b/Source/Engine/Particles/ParticleSystem.cpp index 7eea5a08d..8354f48cb 100644 --- a/Source/Engine/Particles/ParticleSystem.cpp +++ b/Source/Engine/Particles/ParticleSystem.cpp @@ -6,6 +6,7 @@ #include "Engine/Level/Level.h" #include "Engine/Content/Deprecated.h" #include "Engine/Content/Factories/BinaryAssetFactory.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Serialization/MemoryReadStream.h" #include "Engine/Serialization/MemoryWriteStream.h" #include "Engine/Threading/Threading.h" @@ -146,6 +147,7 @@ bool ParticleSystem::SaveTimeline(const BytesContainer& data) const ParticleEffect* ParticleSystem::Spawn(Actor* parent, const Transform& transform, bool autoDestroy) { + PROFILE_MEM(Particles); CHECK_RETURN(!WaitForLoaded(), nullptr); auto effect = New(); @@ -202,6 +204,7 @@ bool ParticleSystem::Save(const StringView& path) Asset::LoadResult ParticleSystem::load() { + PROFILE_MEM(Particles); Version++; // Get the data chunk diff --git a/Source/Engine/Particles/Particles.cpp b/Source/Engine/Particles/Particles.cpp index e895e0b6d..3cf25eec6 100644 --- a/Source/Engine/Particles/Particles.cpp +++ b/Source/Engine/Particles/Particles.cpp @@ -16,6 +16,7 @@ #include "Engine/Graphics/RenderTools.h" #include "Engine/Graphics/Shaders/GPUVertexLayout.h" #include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Renderer/DrawCall.h" #include "Engine/Renderer/RenderList.h" #include "Engine/Threading/TaskGraph.h" @@ -167,6 +168,7 @@ ParticleManagerService ParticleManagerServiceInstance; void Particles::UpdateEffect(ParticleEffect* effect) { + PROFILE_MEM(Particles); UpdateList.Add(effect); } @@ -933,6 +935,7 @@ void Particles::DrawParticles(RenderContext& renderContext, ParticleEffect* effe const DrawPass drawModes = view.Pass & effect->DrawModes; if (drawModes == DrawPass::None || SpriteRenderer.Init()) return; + PROFILE_MEM(Particles); Matrix worlds[2]; Matrix::Translation(-renderContext.View.Origin, worlds[0]); // World renderContext.View.GetWorldMatrix(effect->GetTransform(), worlds[1]); // Local @@ -1073,6 +1076,7 @@ void UpdateGPU(RenderTask* task, GPUContext* context) if (GpuUpdateList.IsEmpty()) return; PROFILE_GPU("GPU Particles"); + PROFILE_MEM(Particles); for (ParticleEffect* effect : GpuUpdateList) { @@ -1112,6 +1116,7 @@ void UpdateGPU(RenderTask* task, GPUContext* context) ParticleBuffer* Particles::AcquireParticleBuffer(ParticleEmitter* emitter) { PROFILE_CPU(); + PROFILE_MEM(Particles); ParticleBuffer* result = nullptr; ASSERT(emitter && emitter->IsLoaded()); @@ -1161,6 +1166,7 @@ ParticleBuffer* Particles::AcquireParticleBuffer(ParticleEmitter* emitter) void Particles::RecycleParticleBuffer(ParticleBuffer* buffer) { PROFILE_CPU(); + PROFILE_MEM(Particles); if (buffer->Emitter->EnablePooling && EnableParticleBufferPooling) { // Return to pool @@ -1208,6 +1214,7 @@ void Particles::OnEmitterUnload(ParticleEmitter* emitter) bool ParticleManagerService::Init() { + PROFILE_MEM(Particles); Particles::System = New(); Particles::System->Order = 10000; Engine::UpdateGraph->AddSystem(Particles::System); @@ -1253,6 +1260,7 @@ void ParticleManagerService::Dispose() void ParticlesSystem::Job(int32 index) { PROFILE_CPU_NAMED("Particles.Job"); + PROFILE_MEM(Particles); auto effect = UpdateList[index]; auto& instance = effect->Instance; const auto particleSystem = effect->ParticleSystem.Get(); @@ -1432,6 +1440,7 @@ void ParticlesSystem::PostExecute(TaskGraph* graph) if (!Active) return; PROFILE_CPU_NAMED("Particles.PostExecute"); + PROFILE_MEM(Particles); // Cleanup Particles::SystemLocker.End(false); diff --git a/Source/Engine/Particles/ParticlesData.cpp b/Source/Engine/Particles/ParticlesData.cpp index dcdef46d7..10988fd34 100644 --- a/Source/Engine/Particles/ParticlesData.cpp +++ b/Source/Engine/Particles/ParticlesData.cpp @@ -5,6 +5,7 @@ #include "Engine/Graphics/GPUBuffer.h" #include "Engine/Graphics/GPUDevice.h" #include "Engine/Graphics/DynamicBuffer.h" +#include "Engine/Profiler/ProfilerMemory.h" ParticleBuffer::ParticleBuffer() { @@ -23,6 +24,7 @@ ParticleBuffer::~ParticleBuffer() bool ParticleBuffer::Init(ParticleEmitter* emitter) { + PROFILE_MEM(Particles); ASSERT(emitter && emitter->IsLoaded()); Version = emitter->Graph.Version; diff --git a/Source/Engine/Physics/Actors/Cloth.cpp b/Source/Engine/Physics/Actors/Cloth.cpp index 889a0874e..037dc0000 100644 --- a/Source/Engine/Physics/Actors/Cloth.cpp +++ b/Source/Engine/Physics/Actors/Cloth.cpp @@ -11,6 +11,7 @@ #include "Engine/Physics/PhysicsBackend.h" #include "Engine/Physics/PhysicsScene.h" #include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Serialization/Serialization.h" #include "Engine/Level/Actors/AnimatedModel.h" #include "Engine/Level/Scene/SceneRendering.h" @@ -132,6 +133,7 @@ Array Cloth::GetParticles() const if (_cloth) { PROFILE_CPU(); + PROFILE_MEM(Physics); PhysicsBackend::LockClothParticles(_cloth); const Span particles = PhysicsBackend::GetClothParticles(_cloth); result.Resize(particles.Length()); @@ -148,6 +150,7 @@ Array Cloth::GetParticles() const void Cloth::SetParticles(Span value) { PROFILE_CPU(); + PROFILE_MEM(Physics); #if USE_CLOTH_SANITY_CHECKS { // Sanity check @@ -177,6 +180,7 @@ Span Cloth::GetPaint() const void Cloth::SetPaint(Span value) { PROFILE_CPU(); + PROFILE_MEM(Physics); #if USE_CLOTH_SANITY_CHECKS { // Sanity check @@ -302,6 +306,7 @@ void Cloth::Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) { Actor::Deserialize(stream, modifier); + PROFILE_MEM(Physics); DESERIALIZE_MEMBER(Mesh, _mesh); _mesh.Actor = nullptr; // Don't store this reference DESERIALIZE_MEMBER(Force, _forceSettings); @@ -536,6 +541,7 @@ bool Cloth::CreateCloth() { #if WITH_CLOTH PROFILE_CPU(); + PROFILE_MEM(Physics); // Skip if all vertices are fixed so cloth sim doesn't make sense if (_paint.HasItems()) @@ -631,6 +637,7 @@ void Cloth::CalculateInvMasses(Array& invMasses) if (_paint.IsEmpty()) return; PROFILE_CPU(); + PROFILE_MEM(Physics); // Get mesh data const ModelInstanceActor::MeshReference mesh = GetMesh(); @@ -918,6 +925,7 @@ void Cloth::RunClothDeformer(const MeshBase* mesh, MeshDeformationData& deformat return; #if WITH_CLOTH PROFILE_CPU_NAMED("Cloth"); + PROFILE_MEM(Physics); PhysicsBackend::LockClothParticles(_cloth); const Span particles = PhysicsBackend::GetClothParticles(_cloth); auto vbCount = (uint32)mesh->GetVertexCount(); diff --git a/Source/Engine/Physics/Actors/SplineRopeBody.cpp b/Source/Engine/Physics/Actors/SplineRopeBody.cpp index 2cf81e228..ea020b5c5 100644 --- a/Source/Engine/Physics/Actors/SplineRopeBody.cpp +++ b/Source/Engine/Physics/Actors/SplineRopeBody.cpp @@ -7,6 +7,7 @@ #include "Engine/Physics/PhysicsScene.h" #include "Engine/Engine/Time.h" #include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Serialization/Serialization.h" SplineRopeBody::SplineRopeBody(const SpawnParams& params) @@ -19,6 +20,7 @@ void SplineRopeBody::Tick() if (!_spline || _spline->GetSplinePointsCount() < 2) return; PROFILE_CPU(); + PROFILE_MEM(Physics); // Cache data const Vector3 gravity = GetPhysicsScene()->GetGravity() * GravityScale; diff --git a/Source/Engine/Physics/CollisionCooking.cpp b/Source/Engine/Physics/CollisionCooking.cpp index 4522d6862..bbf3f4f91 100644 --- a/Source/Engine/Physics/CollisionCooking.cpp +++ b/Source/Engine/Physics/CollisionCooking.cpp @@ -10,11 +10,13 @@ #include "Engine/Graphics/Models/MeshAccessor.h" #include "Engine/Threading/Threading.h" #include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Core/Log.h" bool CollisionCooking::CookCollision(const Argument& arg, CollisionData::SerializedOptions& outputOptions, BytesContainer& outputData) { PROFILE_CPU(); + PROFILE_MEM(Physics); int32 convexVertexLimit = Math::Clamp(arg.ConvexVertexLimit, CONVEX_VERTEX_MIN, CONVEX_VERTEX_MAX); if (arg.ConvexVertexLimit == 0) convexVertexLimit = CONVEX_VERTEX_MAX; diff --git a/Source/Engine/Physics/CollisionData.cpp b/Source/Engine/Physics/CollisionData.cpp index e7e02c464..c65ea8a6b 100644 --- a/Source/Engine/Physics/CollisionData.cpp +++ b/Source/Engine/Physics/CollisionData.cpp @@ -9,6 +9,7 @@ #include "Engine/Physics/PhysicsBackend.h" #include "Engine/Physics/CollisionCooking.h" #include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Threading/Threading.h" REGISTER_BINARY_ASSET(CollisionData, "FlaxEngine.CollisionData", true); @@ -35,6 +36,7 @@ bool CollisionData::CookCollision(CollisionDataType type, ModelBase* modelObj, i return true; } PROFILE_CPU(); + PROFILE_MEM(Physics); // Prepare CollisionCooking::Argument arg; @@ -64,6 +66,7 @@ bool CollisionData::CookCollision(CollisionDataType type, ModelBase* modelObj, i bool CollisionData::CookCollision(CollisionDataType type, const Span& vertices, const Span& triangles, ConvexMeshGenerationFlags convexFlags, int32 convexVertexLimit) { PROFILE_CPU(); + PROFILE_MEM(Physics); CHECK_RETURN(vertices.Length() != 0, true); CHECK_RETURN(triangles.Length() != 0 && triangles.Length() % 3 == 0, true); ModelData modelData; @@ -78,6 +81,7 @@ bool CollisionData::CookCollision(CollisionDataType type, const Span& ve bool CollisionData::CookCollision(CollisionDataType type, const Span& vertices, const Span& triangles, ConvexMeshGenerationFlags convexFlags, int32 convexVertexLimit) { PROFILE_CPU(); + PROFILE_MEM(Physics); CHECK_RETURN(vertices.Length() != 0, true); CHECK_RETURN(triangles.Length() != 0 && triangles.Length() % 3 == 0, true); ModelData modelData; @@ -99,6 +103,7 @@ bool CollisionData::CookCollision(CollisionDataType type, ModelData* modelData, return true; } PROFILE_CPU(); + PROFILE_MEM(Physics); // Prepare CollisionCooking::Argument arg; @@ -180,6 +185,7 @@ bool CollisionData::GetModelTriangle(uint32 faceIndex, MeshBase*& mesh, uint32& void CollisionData::ExtractGeometry(Array& vertexBuffer, Array& indexBuffer) const { PROFILE_CPU(); + PROFILE_MEM(Physics); vertexBuffer.Clear(); indexBuffer.Clear(); @@ -197,6 +203,7 @@ const Array& CollisionData::GetDebugLines() if (_hasMissingDebugLines && IsLoaded()) { PROFILE_CPU(); + PROFILE_MEM(Physics); ScopeLock lock(Locker); _hasMissingDebugLines = false; @@ -250,6 +257,8 @@ Asset::LoadResult CollisionData::load() CollisionData::LoadResult CollisionData::load(const SerializedOptions* options, byte* dataPtr, int32 dataSize) { + PROFILE_MEM(Physics); + // Load options _options.Type = options->Type; _options.Model = options->Model; diff --git a/Source/Engine/Physics/PhysX/PhysicsBackendPhysX.cpp b/Source/Engine/Physics/PhysX/PhysicsBackendPhysX.cpp index e4636a568..5023b69c7 100644 --- a/Source/Engine/Physics/PhysX/PhysicsBackendPhysX.cpp +++ b/Source/Engine/Physics/PhysX/PhysicsBackendPhysX.cpp @@ -24,6 +24,7 @@ #include "Engine/Platform/CPUInfo.h" #include "Engine/Platform/CriticalSection.h" #include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Serialization/WriteStream.h" #include #include @@ -117,6 +118,7 @@ class AllocatorPhysX : public PxAllocatorCallback void* allocate(size_t size, const char* typeName, const char* filename, int line) override { ASSERT(size < 1024 * 1024 * 1024); // Prevent invalid allocation size + PROFILE_MEM(Physics); return Allocator::Allocate(size, 16); } @@ -725,6 +727,7 @@ void ScenePhysX::UpdateVehicles(float dt) if (WheelVehicles.IsEmpty()) return; PROFILE_CPU_NAMED("Physics.Vehicles"); + PROFILE_MEM(Physics); // Update vehicles steering WheelVehiclesCache.Clear(); @@ -1861,6 +1864,7 @@ void PhysicsBackend::DestroyScene(void* scene) void PhysicsBackend::StartSimulateScene(void* scene, float dt) { + PROFILE_MEM(Physics); auto scenePhysX = (ScenePhysX*)scene; const auto& settings = *PhysicsSettings::Get(); @@ -1895,6 +1899,7 @@ void PhysicsBackend::StartSimulateScene(void* scene, float dt) void PhysicsBackend::EndSimulateScene(void* scene) { + PROFILE_MEM(Physics); auto scenePhysX = (ScenePhysX*)scene; { @@ -3880,6 +3885,7 @@ void PhysicsBackend::RemoveVehicle(void* scene, WheeledVehicle* actor) void* PhysicsBackend::CreateCloth(const PhysicsClothDesc& desc) { PROFILE_CPU(); + PROFILE_MEM(Physics); #if USE_CLOTH_SANITY_CHECKS { // Sanity check diff --git a/Source/Engine/Physics/PhysX/SimulationEventCallbackPhysX.cpp b/Source/Engine/Physics/PhysX/SimulationEventCallbackPhysX.cpp index b35538711..73135c3a3 100644 --- a/Source/Engine/Physics/PhysX/SimulationEventCallbackPhysX.cpp +++ b/Source/Engine/Physics/PhysX/SimulationEventCallbackPhysX.cpp @@ -6,6 +6,7 @@ #include "Engine/Physics/Colliders/Collider.h" #include "Engine/Physics/Joints/Joint.h" #include "Engine/Physics/Actors/RigidBody.h" +#include "Engine/Profiler/ProfilerMemory.h" #include #include @@ -91,6 +92,7 @@ void SimulationEventCallback::OnJointRemoved(Joint* joint) void SimulationEventCallback::onConstraintBreak(PxConstraintInfo* constraints, PxU32 count) { + PROFILE_MEM(Physics); for (uint32 i = 0; i < count; i++) { PxJoint* joint = reinterpret_cast(constraints[i].externalReference); @@ -114,6 +116,7 @@ void SimulationEventCallback::onContact(const PxContactPairHeader& pairHeader, c // Skip sending events to removed actors if (pairHeader.flags & (PxContactPairHeaderFlag::eREMOVED_ACTOR_0 | PxContactPairHeaderFlag::eREMOVED_ACTOR_1)) return; + PROFILE_MEM(Physics); Collision c; PxContactPairExtraDataIterator j(pairHeader.extraDataStream, pairHeader.extraDataStreamSize); @@ -185,6 +188,7 @@ void SimulationEventCallback::onContact(const PxContactPairHeader& pairHeader, c void SimulationEventCallback::onTrigger(PxTriggerPair* pairs, PxU32 count) { + PROFILE_MEM(Physics); for (PxU32 i = 0; i < count; i++) { const PxTriggerPair& pair = pairs[i]; diff --git a/Source/Engine/Physics/Physics.cpp b/Source/Engine/Physics/Physics.cpp index 6b48bc157..ecd7c1093 100644 --- a/Source/Engine/Physics/Physics.cpp +++ b/Source/Engine/Physics/Physics.cpp @@ -10,6 +10,7 @@ #include "Engine/Engine/Time.h" #include "Engine/Engine/EngineService.h" #include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Serialization/Serialization.h" #include "Engine/Threading/Threading.h" @@ -117,6 +118,8 @@ PhysicalMaterial::~PhysicalMaterial() bool PhysicsService::Init() { + PROFILE_MEM(Physics); + // Initialize backend if (PhysicsBackend::Init()) return true; @@ -153,6 +156,7 @@ void PhysicsService::Dispose() PhysicsScene* Physics::FindOrCreateScene(const StringView& name) { + PROFILE_MEM(Physics); auto scene = FindScene(name); if (scene == nullptr) { @@ -244,6 +248,7 @@ bool Physics::IsDuringSimulation() void Physics::FlushRequests() { PROFILE_CPU_NAMED("Physics.FlushRequests"); + PROFILE_MEM(Physics); for (PhysicsScene* scene : Scenes) PhysicsBackend::FlushRequests(scene->GetPhysicsScene()); PhysicsBackend::FlushRequests(); @@ -492,6 +497,7 @@ PhysicsStatistics PhysicsScene::GetStatistics() const bool PhysicsScene::Init(const StringView& name, const PhysicsSettings& settings) { + PROFILE_MEM(Physics); if (_scene) { PhysicsBackend::DestroyScene(_scene); diff --git a/Source/Engine/Platform/Base/WindowBase.cpp b/Source/Engine/Platform/Base/WindowBase.cpp index de64dfd94..3bd34a1a0 100644 --- a/Source/Engine/Platform/Base/WindowBase.cpp +++ b/Source/Engine/Platform/Base/WindowBase.cpp @@ -10,6 +10,7 @@ #include "Engine/Platform/IGuiData.h" #include "Engine/Scripting/ScriptingType.h" #include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Scripting/ManagedCLR/MException.h" #include "Engine/Scripting/ManagedCLR/MUtils.h" #include "Engine/Scripting/ManagedCLR/MMethod.h" @@ -204,6 +205,7 @@ void WindowBase::SetRenderingEnabled(bool value) void WindowBase::OnCharInput(Char c) { PROFILE_CPU_NAMED("GUI.OnCharInput"); + PROFILE_MEM(UI); CharInput(c); INVOKE_EVENT_PARAMS_1(OnCharInput, &c); } @@ -211,6 +213,7 @@ void WindowBase::OnCharInput(Char c) void WindowBase::OnKeyDown(KeyboardKeys key) { PROFILE_CPU_NAMED("GUI.OnKeyDown"); + PROFILE_MEM(UI); KeyDown(key); INVOKE_EVENT_PARAMS_1(OnKeyDown, &key); } @@ -218,6 +221,7 @@ void WindowBase::OnKeyDown(KeyboardKeys key) void WindowBase::OnKeyUp(KeyboardKeys key) { PROFILE_CPU_NAMED("GUI.OnKeyUp"); + PROFILE_MEM(UI); KeyUp(key); INVOKE_EVENT_PARAMS_1(OnKeyUp, &key); } @@ -225,6 +229,7 @@ void WindowBase::OnKeyUp(KeyboardKeys key) void WindowBase::OnMouseDown(const Float2& mousePosition, MouseButton button) { PROFILE_CPU_NAMED("GUI.OnMouseDown"); + PROFILE_MEM(UI); MouseDown(mousePosition, button); INVOKE_EVENT_PARAMS_2(OnMouseDown, (void*)&mousePosition, &button); } @@ -232,6 +237,7 @@ void WindowBase::OnMouseDown(const Float2& mousePosition, MouseButton button) void WindowBase::OnMouseUp(const Float2& mousePosition, MouseButton button) { PROFILE_CPU_NAMED("GUI.OnMouseUp"); + PROFILE_MEM(UI); MouseUp(mousePosition, button); INVOKE_EVENT_PARAMS_2(OnMouseUp, (void*)&mousePosition, &button); } @@ -239,6 +245,7 @@ void WindowBase::OnMouseUp(const Float2& mousePosition, MouseButton button) void WindowBase::OnMouseDoubleClick(const Float2& mousePosition, MouseButton button) { PROFILE_CPU_NAMED("GUI.OnMouseDoubleClick"); + PROFILE_MEM(UI); MouseDoubleClick(mousePosition, button); INVOKE_EVENT_PARAMS_2(OnMouseDoubleClick, (void*)&mousePosition, &button); } @@ -246,6 +253,7 @@ void WindowBase::OnMouseDoubleClick(const Float2& mousePosition, MouseButton but void WindowBase::OnMouseWheel(const Float2& mousePosition, float delta) { PROFILE_CPU_NAMED("GUI.OnMouseWheel"); + PROFILE_MEM(UI); MouseWheel(mousePosition, delta); INVOKE_EVENT_PARAMS_2(OnMouseWheel, (void*)&mousePosition, &delta); } @@ -253,6 +261,7 @@ void WindowBase::OnMouseWheel(const Float2& mousePosition, float delta) void WindowBase::OnMouseMove(const Float2& mousePosition) { PROFILE_CPU_NAMED("GUI.OnMouseMove"); + PROFILE_MEM(UI); MouseMove(mousePosition); INVOKE_EVENT_PARAMS_1(OnMouseMove, (void*)&mousePosition); } @@ -260,6 +269,7 @@ void WindowBase::OnMouseMove(const Float2& mousePosition) void WindowBase::OnMouseLeave() { PROFILE_CPU_NAMED("GUI.OnMouseLeave"); + PROFILE_MEM(UI); MouseLeave(); INVOKE_EVENT_PARAMS_0(OnMouseLeave); } @@ -267,6 +277,7 @@ void WindowBase::OnMouseLeave() void WindowBase::OnTouchDown(const Float2& pointerPosition, int32 pointerId) { PROFILE_CPU_NAMED("GUI.OnTouchDown"); + PROFILE_MEM(UI); TouchDown(pointerPosition, pointerId); INVOKE_EVENT_PARAMS_2(OnTouchDown, (void*)&pointerPosition, &pointerId); } @@ -274,6 +285,7 @@ void WindowBase::OnTouchDown(const Float2& pointerPosition, int32 pointerId) void WindowBase::OnTouchMove(const Float2& pointerPosition, int32 pointerId) { PROFILE_CPU_NAMED("GUI.OnTouchMove"); + PROFILE_MEM(UI); TouchMove(pointerPosition, pointerId); INVOKE_EVENT_PARAMS_2(OnTouchMove, (void*)&pointerPosition, &pointerId); } @@ -281,6 +293,7 @@ void WindowBase::OnTouchMove(const Float2& pointerPosition, int32 pointerId) void WindowBase::OnTouchUp(const Float2& pointerPosition, int32 pointerId) { PROFILE_CPU_NAMED("GUI.OnTouchUp"); + PROFILE_MEM(UI); TouchUp(pointerPosition, pointerId); INVOKE_EVENT_PARAMS_2(OnTouchUp, (void*)&pointerPosition, &pointerId); } @@ -391,6 +404,7 @@ bool WindowBase::GetMouseButtonUp(MouseButton button) const void WindowBase::OnShow() { PROFILE_CPU_NAMED("GUI.OnShow"); + PROFILE_MEM(UI); INVOKE_EVENT_PARAMS_0(OnShow); Shown(); } @@ -398,10 +412,13 @@ void WindowBase::OnShow() void WindowBase::OnResize(int32 width, int32 height) { PROFILE_CPU_NAMED("GUI.OnResize"); + PROFILE_MEM_BEGIN(Graphics); if (_swapChain) _swapChain->Resize(width, height); if (RenderTask) RenderTask->Resize(width, height); + PROFILE_MEM_END(); + PROFILE_MEM(UI); Resized({ static_cast(width), static_cast(height) }); INVOKE_EVENT_PARAMS_2(OnResize, &width, &height); } @@ -453,6 +470,7 @@ void WindowBase::OnLostFocus() void WindowBase::OnUpdate(float dt) { PROFILE_CPU_NAMED("GUI.OnUpdate"); + PROFILE_MEM(UI); Update(dt); INVOKE_EVENT_PARAMS_1(OnUpdate, &dt); } @@ -460,6 +478,7 @@ void WindowBase::OnUpdate(float dt) void WindowBase::OnDraw() { PROFILE_CPU_NAMED("GUI.OnDraw"); + PROFILE_MEM(UI); INVOKE_EVENT_PARAMS_0(OnDraw); Draw(); } @@ -467,6 +486,7 @@ void WindowBase::OnDraw() bool WindowBase::InitSwapChain() { // Setup swapchain + PROFILE_MEM(Graphics); if (_swapChain == nullptr) { _swapChain = GPUDevice::Instance->CreateSwapChain((Window*)this); diff --git a/Source/Engine/Platform/Unix/UnixThread.cpp b/Source/Engine/Platform/Unix/UnixThread.cpp index c58c009be..ff6e61b2a 100644 --- a/Source/Engine/Platform/Unix/UnixThread.cpp +++ b/Source/Engine/Platform/Unix/UnixThread.cpp @@ -4,6 +4,9 @@ #include "UnixThread.h" #include "Engine/Core/Log.h" +#if PLATFORM_APPLE_FAMILY +#include "Engine/Utilities/StringConverter.h" +#endif #include "Engine/Threading/IRunnable.h" #include "Engine/Threading/ThreadRegistry.h" @@ -29,7 +32,8 @@ void* UnixThread::ThreadProc(void* pThis) #if PLATFORM_APPLE_FAMILY // Apple doesn't support creating named thread so assign name here { - pthread_setname_np(StringAnsi(thread->GetName()).Get()); + const String& name = thread->GetName(); + pthread_setname_np(StringAsANSI<>(name.Get(), name.Length()).Get()); } #endif const int32 exitCode = thread->Run(); diff --git a/Source/Engine/Profiler/ProfilingTools.cpp b/Source/Engine/Profiler/ProfilingTools.cpp index ea50d2183..0e7ac1566 100644 --- a/Source/Engine/Profiler/ProfilingTools.cpp +++ b/Source/Engine/Profiler/ProfilingTools.cpp @@ -33,6 +33,7 @@ ProfilingToolsService ProfilingToolsServiceInstance; void ProfilingToolsService::Update() { ZoneScoped; + PROFILE_MEM(Profiler); // Capture stats { diff --git a/Source/Engine/Render2D/Render2D.cpp b/Source/Engine/Render2D/Render2D.cpp index 057265aae..251781c99 100644 --- a/Source/Engine/Render2D/Render2D.cpp +++ b/Source/Engine/Render2D/Render2D.cpp @@ -597,6 +597,8 @@ void OnGUIShaderReloading(Asset* obj) bool Render2DService::Init() { + PROFILE_MEM(UI); + // GUI Shader GUIShader = Content::LoadAsyncInternal(TEXT("Shaders/GUI")); if (GUIShader == nullptr) diff --git a/Source/Engine/Renderer/RenderList.cpp b/Source/Engine/Renderer/RenderList.cpp index 97a157355..2a6540da5 100644 --- a/Source/Engine/Renderer/RenderList.cpp +++ b/Source/Engine/Renderer/RenderList.cpp @@ -626,6 +626,7 @@ void RenderList::BuildObjectsBuffer() if (count == 0) return; PROFILE_CPU(); + PROFILE_MEM(GraphicsCommands); ObjectBuffer.Data.Resize(count * sizeof(ShaderObjectData)); auto* src = (const DrawCall*)DrawCalls.Get(); auto* dst = (ShaderObjectData*)ObjectBuffer.Data.Get(); @@ -648,6 +649,7 @@ void RenderList::BuildObjectsBuffer() void RenderList::SortDrawCalls(const RenderContext& renderContext, bool reverseDistance, DrawCallsList& list, const RenderListBuffer& drawCalls, DrawPass pass, bool stable) { PROFILE_CPU(); + PROFILE_MEM(GraphicsCommands); const auto* drawCallsData = drawCalls.Get(); const auto* listData = list.Indices.Get(); const int32 listSize = list.Indices.Count(); @@ -754,6 +756,7 @@ void RenderList::ExecuteDrawCalls(const RenderContext& renderContext, DrawCallsL if (list.IsEmpty()) return; PROFILE_GPU_CPU("Drawing"); + PROFILE_MEM(GraphicsCommands); const auto* drawCallsData = drawCallsList->DrawCalls.Get(); const auto* listData = list.Indices.Get(); const auto* batchesData = list.Batches.Get(); diff --git a/Source/Engine/Renderer/Renderer.cpp b/Source/Engine/Renderer/Renderer.cpp index 26f3a636e..56c78600b 100644 --- a/Source/Engine/Renderer/Renderer.cpp +++ b/Source/Engine/Renderer/Renderer.cpp @@ -36,6 +36,7 @@ #include "Engine/Level/Scene/SceneRendering.h" #include "Engine/Core/Config/GraphicsSettings.h" #include "Engine/Threading/JobSystem.h" +#include "Engine/Profiler/ProfilerMemory.h" #if USE_EDITOR #include "Editor/Editor.h" #include "Editor/QuadOverdrawPass.h" @@ -68,6 +69,8 @@ void RenderInner(SceneRenderTask* task, RenderContext& renderContext, RenderCont bool RendererService::Init() { + PROFILE_MEM(Graphics); + // Register passes PassList.Add(GBufferPass::Instance()); PassList.Add(ShadowsPass::Instance()); diff --git a/Source/Engine/Scripting/BinaryModule.cpp b/Source/Engine/Scripting/BinaryModule.cpp index 8d61e2bb5..3030b041d 100644 --- a/Source/Engine/Scripting/BinaryModule.cpp +++ b/Source/Engine/Scripting/BinaryModule.cpp @@ -6,6 +6,7 @@ #include "Engine/Core/Utilities.h" #include "Engine/Threading/Threading.h" #include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "ManagedCLR/MAssembly.h" #include "ManagedCLR/MClass.h" #include "ManagedCLR/MMethod.h" @@ -762,6 +763,8 @@ ManagedBinaryModule* ManagedBinaryModule::GetModule(const MAssembly* assembly) ScriptingObject* ManagedBinaryModule::ManagedObjectSpawn(const ScriptingObjectSpawnParams& params) { + PROFILE_MEM(Scripting); + // Create native object ScriptingTypeHandle managedTypeHandle = params.Type; const ScriptingType* managedTypePtr = &managedTypeHandle.GetType(); @@ -932,6 +935,7 @@ void ManagedBinaryModule::OnLoaded(MAssembly* assembly) { #if !COMPILE_WITHOUT_CSHARP PROFILE_CPU(); + PROFILE_MEM(Scripting); ASSERT(ClassToTypeIndex.IsEmpty()); ScopeLock lock(Locker); @@ -1028,6 +1032,7 @@ void ManagedBinaryModule::InitType(MClass* mclass) const StringAnsi& typeName = mclass->GetFullName(); if (TypeNameToTypeIndex.ContainsKey(typeName)) return; + PROFILE_MEM(Scripting); // Find first native base C++ class of this C# class MClass* baseClass = mclass->GetBaseClass(); @@ -1057,9 +1062,13 @@ void ManagedBinaryModule::InitType(MClass* mclass) if (baseType.TypeIndex == -1 || baseType.Module == nullptr) { if (baseType.Module) + { LOG(Error, "Missing base class for managed class {0} from assembly {1}.", String(baseClass->GetFullName()), baseType.Module->GetName().ToString()); + } else + { LOG(Error, "Missing base class for managed class {0} from unknown assembly.", String(baseClass->GetFullName())); + } return; } @@ -1183,6 +1192,7 @@ void ManagedBinaryModule::OnUnloading(MAssembly* assembly) void ManagedBinaryModule::OnUnloaded(MAssembly* assembly) { PROFILE_CPU(); + PROFILE_MEM(Scripting); // Clear managed-only types Types.Resize(_firstManagedTypeIndex); @@ -1495,9 +1505,13 @@ bool ManagedBinaryModule::GetFieldValue(void* field, const Variant& instance, Va if (!instanceObject || !MCore::Object::GetClass(instanceObject)->IsSubClassOf(parentClass)) { if (!instanceObject) + { LOG(Error, "Failed to get '{0}.{1}' without object instance", String(parentClass->GetFullName()), String(name)); + } else + { LOG(Error, "Failed to get '{0}.{1}' with invalid object instance of type '{2}'", String(parentClass->GetFullName()), String(name), String(MUtils::GetClassFullname(instanceObject))); + } return true; } } @@ -1553,9 +1567,13 @@ bool ManagedBinaryModule::SetFieldValue(void* field, const Variant& instance, Va if (!instanceObject || !MCore::Object::GetClass(instanceObject)->IsSubClassOf(parentClass)) { if (!instanceObject) + { LOG(Error, "Failed to set '{0}.{1}' without object instance", String(parentClass->GetFullName()), String(name)); + } else + { LOG(Error, "Failed to set '{0}.{1}' with invalid object instance of type '{2}'", String(parentClass->GetFullName()), String(name), String(MUtils::GetClassFullname(instanceObject))); + } return true; } } diff --git a/Source/Engine/Scripting/ManagedCLR/MCore.cpp b/Source/Engine/Scripting/ManagedCLR/MCore.cpp index db184afd9..8761c309c 100644 --- a/Source/Engine/Scripting/ManagedCLR/MCore.cpp +++ b/Source/Engine/Scripting/ManagedCLR/MCore.cpp @@ -14,6 +14,7 @@ #include "Engine/Core/Types/TimeSpan.h" #include "Engine/Platform/FileSystem.h" #include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Debug/Exceptions/FileNotFoundException.h" #include "Engine/Debug/Exceptions/InvalidOperationException.h" @@ -80,6 +81,7 @@ bool MAssembly::Load(const String& assemblyPath, const StringView& nativePath) if (IsLoaded()) return false; PROFILE_CPU(); + PROFILE_MEM(Scripting); ZoneText(*assemblyPath, assemblyPath.Length()); Stopwatch stopwatch; diff --git a/Source/Engine/Scripting/Plugins/PluginManager.cpp b/Source/Engine/Scripting/Plugins/PluginManager.cpp index 7645d9bdd..c040acfbb 100644 --- a/Source/Engine/Scripting/Plugins/PluginManager.cpp +++ b/Source/Engine/Scripting/Plugins/PluginManager.cpp @@ -11,6 +11,7 @@ #include "Engine/Scripting/ManagedCLR/MUtils.h" #include "Engine/Platform/FileSystem.h" #include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Engine/EngineService.h" #include "Engine/Core/Log.h" #include "Engine/Scripting/ManagedCLR/MField.h" @@ -186,6 +187,7 @@ void PluginManagerService::InvokeDeinitialize(Plugin* plugin) void PluginManagerImpl::OnAssemblyLoaded(MAssembly* assembly) { PROFILE_CPU_NAMED("Load Assembly Plugins"); + PROFILE_MEM(Scripting); const auto gamePluginClass = GamePlugin::GetStaticClass(); if (gamePluginClass == nullptr) @@ -318,6 +320,7 @@ void PluginManagerImpl::InitializePlugins() if (EditorPlugins.Count() + GamePlugins.Count() == 0) return; PROFILE_CPU_NAMED("InitializePlugins"); + PROFILE_MEM(Scripting); auto engineAssembly = ((NativeBinaryModule*)GetBinaryModuleFlaxEngine())->Assembly; auto pluginLoadOrderAttribute = engineAssembly->GetClass("FlaxEngine.PluginLoadOrderAttribute"); @@ -345,6 +348,7 @@ void PluginManagerImpl::DeinitializePlugins() if (EditorPlugins.Count() + GamePlugins.Count() == 0) return; PROFILE_CPU_NAMED("DeinitializePlugins"); + PROFILE_MEM(Scripting); auto engineAssembly = ((NativeBinaryModule*)GetBinaryModuleFlaxEngine())->Assembly; auto pluginLoadOrderAttribute = engineAssembly->GetClass("FlaxEngine.PluginLoadOrderAttribute"); @@ -375,6 +379,7 @@ void PluginManagerImpl::DeinitializePlugins() bool PluginManagerService::Init() { Initialized = false; + PROFILE_MEM(Scripting); // Process already loaded modules for (auto module : BinaryModule::GetModules()) @@ -472,6 +477,7 @@ Plugin* PluginManager::GetPlugin(const ScriptingTypeHandle& type) void PluginManager::InitializeGamePlugins() { PROFILE_CPU(); + PROFILE_MEM(Scripting); auto engineAssembly = ((NativeBinaryModule*)GetBinaryModuleFlaxEngine())->Assembly; auto pluginLoadOrderAttribute = engineAssembly->GetClass("FlaxEngine.PluginLoadOrderAttribute"); @@ -488,6 +494,7 @@ void PluginManager::InitializeGamePlugins() void PluginManager::DeinitializeGamePlugins() { PROFILE_CPU(); + PROFILE_MEM(Scripting); auto engineAssembly = ((NativeBinaryModule*)GetBinaryModuleFlaxEngine())->Assembly; auto pluginLoadOrderAttribute = engineAssembly->GetClass("FlaxEngine.PluginLoadOrderAttribute"); diff --git a/Source/Engine/Scripting/Runtime/DotNet.cpp b/Source/Engine/Scripting/Runtime/DotNet.cpp index 106736d6b..d56c0e5ea 100644 --- a/Source/Engine/Scripting/Runtime/DotNet.cpp +++ b/Source/Engine/Scripting/Runtime/DotNet.cpp @@ -29,6 +29,7 @@ #include "Engine/Scripting/BinaryModule.h" #include "Engine/Engine/Globals.h" #include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Threading/Threading.h" #include "Engine/Debug/Exceptions/CLRInnerException.h" #if DOTNET_HOST_CORECLR @@ -281,6 +282,7 @@ void MCore::UnloadDomain(const StringAnsi& domainName) bool MCore::LoadEngine() { PROFILE_CPU(); + PROFILE_MEM(Scripting); // Initialize hostfxr if (InitHostfxr()) @@ -735,6 +737,7 @@ const MAssembly::ClassesDictionary& MAssembly::GetClasses() const if (_hasCachedClasses || !IsLoaded()) return _classes; PROFILE_CPU(); + PROFILE_MEM(Scripting); Stopwatch stopwatch; #if TRACY_ENABLE @@ -796,6 +799,7 @@ void GetAssemblyName(void* assemblyHandle, StringAnsi& name, StringAnsi& fullnam DEFINE_INTERNAL_CALL(void) NativeInterop_CreateClass(NativeClassDefinitions* managedClass, void* assemblyHandle) { + PROFILE_MEM(Scripting); ScopeLock lock(BinaryModule::Locker); MAssembly* assembly = GetAssembly(assemblyHandle); if (assembly == nullptr) @@ -831,6 +835,7 @@ bool MAssembly::LoadCorlib() if (IsLoaded()) return false; PROFILE_CPU(); + PROFILE_MEM(Scripting); #if TRACY_ENABLE const StringAnsiView name("Corlib"); ZoneText(*name, name.Length()); @@ -1056,6 +1061,7 @@ const Array& MClass::GetMethods() const { if (_hasCachedMethods) return _methods; + PROFILE_MEM(Scripting); ScopeLock lock(BinaryModule::Locker); if (_hasCachedMethods) return _methods; @@ -1093,6 +1099,7 @@ const Array& MClass::GetFields() const { if (_hasCachedFields) return _fields; + PROFILE_MEM(Scripting); ScopeLock lock(BinaryModule::Locker); if (_hasCachedFields) return _fields; @@ -1119,6 +1126,7 @@ const Array& MClass::GetEvents() const { if (_hasCachedEvents) return _events; + PROFILE_MEM(Scripting); // TODO: implement MEvent in .NET @@ -1141,6 +1149,7 @@ const Array& MClass::GetProperties() const { if (_hasCachedProperties) return _properties; + PROFILE_MEM(Scripting); ScopeLock lock(BinaryModule::Locker); if (_hasCachedProperties) return _properties; @@ -1167,6 +1176,7 @@ const Array& MClass::GetInterfaces() const { if (_hasCachedInterfaces) return _interfaces; + PROFILE_MEM(Scripting); ScopeLock lock(BinaryModule::Locker); if (_hasCachedInterfaces) return _interfaces; @@ -1206,6 +1216,7 @@ const Array& MClass::GetAttributes() const { if (_hasCachedAttributes) return _attributes; + PROFILE_MEM(Scripting); ScopeLock lock(BinaryModule::Locker); if (_hasCachedAttributes) return _attributes; @@ -1388,6 +1399,7 @@ const Array& MField::GetAttributes() const { if (_hasCachedAttributes) return _attributes; + PROFILE_MEM(Scripting); ScopeLock lock(BinaryModule::Locker); if (_hasCachedAttributes) return _attributes; @@ -1450,6 +1462,7 @@ void MMethod::CacheSignature() const ScopeLock lock(BinaryModule::Locker); if (_hasCachedSignature) return; + PROFILE_MEM(Scripting); static void* GetMethodReturnTypePtr = GetStaticMethodPointer(TEXT("GetMethodReturnType")); static void* GetMethodParameterTypesPtr = GetStaticMethodPointer(TEXT("GetMethodParameterTypes")); @@ -1550,6 +1563,7 @@ const Array& MMethod::GetAttributes() const { if (_hasCachedAttributes) return _attributes; + PROFILE_MEM(Scripting); ScopeLock lock(BinaryModule::Locker); if (_hasCachedAttributes) return _attributes; @@ -1628,6 +1642,7 @@ const Array& MProperty::GetAttributes() const { if (_hasCachedAttributes) return _attributes; + PROFILE_MEM(Scripting); ScopeLock lock(BinaryModule::Locker); if (_hasCachedAttributes) return _attributes; @@ -1658,6 +1673,7 @@ MClass* GetOrCreateClass(MType* typeHandle) { if (!typeHandle) return nullptr; + PROFILE_MEM(Scripting); ScopeLock lock(BinaryModule::Locker); MClass* klass; if (!CachedClassHandles.TryGet(typeHandle, klass)) @@ -1781,9 +1797,13 @@ bool InitHostfxr() if (hostfxr == nullptr) { if (FileSystem::FileExists(path)) + { LOG(Fatal, "Failed to load hostfxr library, possible platform/architecture mismatch with the library. See log for more information. ({0})", path); + } else + { LOG(Fatal, "Failed to load hostfxr library ({0})", path); + } return true; } hostfxr_initialize_for_runtime_config = (hostfxr_initialize_for_runtime_config_fn)Platform::GetProcAddress(hostfxr, "hostfxr_initialize_for_runtime_config"); diff --git a/Source/Engine/Scripting/Scripting.cpp b/Source/Engine/Scripting/Scripting.cpp index 593092b8f..8c27dc09f 100644 --- a/Source/Engine/Scripting/Scripting.cpp +++ b/Source/Engine/Scripting/Scripting.cpp @@ -33,6 +33,7 @@ #include "Engine/Graphics/RenderTask.h" #include "Engine/Serialization/JsonTools.h" #include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Profiler/ProfilerMemory.h" extern void registerFlaxEngineInternalCalls(); @@ -173,6 +174,7 @@ void onEngineUnloading(MAssembly* assembly); bool ScriptingService::Init() { + PROFILE_MEM(Scripting); Stopwatch stopwatch; // Initialize managed runtime @@ -254,30 +256,35 @@ void ScriptingService::Update() void ScriptingService::LateUpdate() { PROFILE_CPU_NAMED("Scripting::LateUpdate"); + PROFILE_MEM(Scripting); INVOKE_EVENT(LateUpdate); } void ScriptingService::FixedUpdate() { PROFILE_CPU_NAMED("Scripting::FixedUpdate"); + PROFILE_MEM(Scripting); INVOKE_EVENT(FixedUpdate); } void ScriptingService::LateFixedUpdate() { PROFILE_CPU_NAMED("Scripting::LateFixedUpdate"); + PROFILE_MEM(Scripting); INVOKE_EVENT(LateFixedUpdate); } void ScriptingService::Draw() { PROFILE_CPU_NAMED("Scripting::Draw"); + PROFILE_MEM(Scripting); INVOKE_EVENT(Draw); } void ScriptingService::BeforeExit() { PROFILE_CPU_NAMED("Scripting::BeforeExit"); + PROFILE_MEM(Scripting); INVOKE_EVENT(Exit); } @@ -306,6 +313,7 @@ void Scripting::ProcessBuildInfoPath(String& path, const String& projectFolderPa bool Scripting::LoadBinaryModules(const String& path, const String& projectFolderPath) { PROFILE_CPU_NAMED("LoadBinaryModules"); + PROFILE_MEM(Scripting); LOG(Info, "Loading binary modules from build info file {0}", path); // Read file contents @@ -482,6 +490,7 @@ bool Scripting::LoadBinaryModules(const String& path, const String& projectFolde bool Scripting::Load() { PROFILE_CPU(); + PROFILE_MEM(Scripting); // Note: this action can be called from main thread (due to Mono problems with assemblies actions from other threads) ASSERT(IsInMainThread()); ScopeLock lock(BinaryModule::Locker); @@ -1034,6 +1043,7 @@ bool Scripting::IsTypeFromGameScripts(const MClass* type) void Scripting::RegisterObject(ScriptingObject* obj) { + PROFILE_MEM(Scripting); const Guid id = obj->GetID(); ScopeLock lock(_objectsLocker); @@ -1116,6 +1126,7 @@ bool initFlaxEngine() void onEngineLoaded(MAssembly* assembly) { + PROFILE_MEM(Scripting); if (initFlaxEngine()) { LOG(Fatal, "Failed to initialize Flax Engine runtime."); diff --git a/Source/Engine/Scripting/ScriptingObject.cpp b/Source/Engine/Scripting/ScriptingObject.cpp index 624a3f0e9..eb9afdeae 100644 --- a/Source/Engine/Scripting/ScriptingObject.cpp +++ b/Source/Engine/Scripting/ScriptingObject.cpp @@ -745,9 +745,13 @@ DEFINE_INTERNAL_CALL(MObject*) ObjectInternal_FindObject(Guid* id, MTypeObject* if (!skipLog) { if (klass) + { LOG(Warning, "Unable to find scripting object with ID={0} of type {1}", *id, String(klass->GetFullName())); + } else + { LOG(Warning, "Unable to find scripting object with ID={0}", *id); + } LogContext::Print(LogType::Warning); } return nullptr; diff --git a/Source/Engine/Streaming/Streaming.cpp b/Source/Engine/Streaming/Streaming.cpp index 2d233edc9..5ddbd0996 100644 --- a/Source/Engine/Streaming/Streaming.cpp +++ b/Source/Engine/Streaming/Streaming.cpp @@ -7,6 +7,7 @@ #include "Engine/Engine/Engine.h" #include "Engine/Engine/EngineService.h" #include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Threading/Threading.h" #include "Engine/Threading/TaskGraph.h" #include "Engine/Threading/Task.h" @@ -55,6 +56,7 @@ Array> Streaming::TextureGroups; void StreamingSettings::Apply() { + PROFILE_MEM(ContentStreaming); Streaming::TextureGroups = TextureGroups; SAFE_DELETE_GPU_RESOURCES(TextureGroupSamplers); TextureGroupSamplers.Resize(TextureGroups.Count(), false); @@ -91,6 +93,7 @@ void StreamableResource::StartStreaming(bool isDynamic) _isDynamic = isDynamic; if (!_isStreaming) { + PROFILE_MEM(ContentStreaming); _isStreaming = true; ResourcesLock.Lock(); Resources.Add(this); @@ -201,6 +204,7 @@ void UpdateResource(StreamableResource* resource, double currentTime) bool StreamingService::Init() { + PROFILE_MEM(ContentStreaming); System = New(); Engine::UpdateGraph->AddSystem(System); return false; @@ -217,6 +221,7 @@ void StreamingService::BeforeExit() void StreamingSystem::Job(int32 index) { PROFILE_CPU_NAMED("Streaming.Job"); + PROFILE_MEM(ContentStreaming); // TODO: use streaming settings const double ResourceUpdatesInterval = 0.1; diff --git a/Source/Engine/Threading/TaskGraph.cpp b/Source/Engine/Threading/TaskGraph.cpp index 10b6ea0c8..c016bfd40 100644 --- a/Source/Engine/Threading/TaskGraph.cpp +++ b/Source/Engine/Threading/TaskGraph.cpp @@ -4,6 +4,7 @@ #include "JobSystem.h" #include "Engine/Core/Collections/Sorting.h" #include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Profiler/ProfilerMemory.h" namespace { @@ -67,6 +68,7 @@ const Array>& TaskGraph::GetSystems() co void TaskGraph::AddSystem(TaskGraphSystem* system) { + PROFILE_MEM(Engine); _systems.Add(system); } @@ -78,6 +80,7 @@ void TaskGraph::RemoveSystem(TaskGraphSystem* system) void TaskGraph::Execute() { PROFILE_CPU(); + PROFILE_MEM(Engine); for (auto system : _systems) system->PreExecute(this); diff --git a/Source/Engine/UI/TextRender.cpp b/Source/Engine/UI/TextRender.cpp index bc7b88647..951da2316 100644 --- a/Source/Engine/UI/TextRender.cpp +++ b/Source/Engine/UI/TextRender.cpp @@ -13,6 +13,8 @@ #include "Engine/Render2D/FontManager.h" #include "Engine/Render2D/FontTextureAtlas.h" #include "Engine/Renderer/RenderList.h" +#include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Serialization/Serialization.h" #include "Engine/Content/Assets/MaterialInstance.h" #include "Engine/Content/Content.h" @@ -120,6 +122,9 @@ void TextRender::SetLayoutOptions(TextLayoutOptions& value) void TextRender::UpdateLayout() { + PROFILE_CPU(); + PROFILE_MEM(UI); + // Clear _ib.Clear(); _vb.Clear(); diff --git a/Source/Engine/UI/UICanvas.cpp b/Source/Engine/UI/UICanvas.cpp index 107a9eded..bf87fd676 100644 --- a/Source/Engine/UI/UICanvas.cpp +++ b/Source/Engine/UI/UICanvas.cpp @@ -6,6 +6,7 @@ #include "Engine/Scripting/ManagedCLR/MClass.h" #include "Engine/Scripting/ManagedCLR/MUtils.h" #include "Engine/Serialization/Serialization.h" +#include "Engine/Profiler/ProfilerMemory.h" #if COMPILE_WITHOUT_CSHARP #define UICANVAS_INVOKE(event) @@ -26,6 +27,7 @@ MMethod* UICanvas_ParentChanged = nullptr; auto* managed = GetManagedInstance(); \ if (managed) \ { \ + PROFILE_MEM(UI); \ MObject* exception = nullptr; \ UICanvas_##event->Invoke(managed, nullptr, &exception); \ if (exception) \ @@ -77,6 +79,7 @@ void UICanvas::Serialize(SerializeStream& stream, const void* otherObj) SERIALIZE_GET_OTHER_OBJ(UICanvas); #if !COMPILE_WITHOUT_CSHARP + PROFILE_MEM(UI); stream.JKEY("V"); void* params[1]; params[0] = other ? other->GetOrCreateManagedInstance() : nullptr; @@ -109,6 +112,7 @@ void UICanvas::Deserialize(DeserializeStream& stream, ISerializeModifier* modifi const auto dataMember = stream.FindMember("V"); if (dataMember != stream.MemberEnd()) { + PROFILE_MEM(UI); rapidjson_flax::StringBuffer buffer; rapidjson_flax::Writer writer(buffer); dataMember->value.Accept(writer); diff --git a/Source/Engine/UI/UIControl.cpp b/Source/Engine/UI/UIControl.cpp index 8321c33fc..06554542b 100644 --- a/Source/Engine/UI/UIControl.cpp +++ b/Source/Engine/UI/UIControl.cpp @@ -7,6 +7,7 @@ #include "Engine/Scripting/ManagedCLR/MClass.h" #include "Engine/Scripting/ManagedCLR/MCore.h" #include "Engine/Serialization/Serialization.h" +#include "Engine/Profiler/ProfilerMemory.h" #if COMPILE_WITHOUT_CSHARP #define UICONTROL_INVOKE(event) @@ -25,6 +26,7 @@ MMethod* UIControl_EndPlay = nullptr; auto* managed = GetManagedInstance(); \ if (managed) \ { \ + PROFILE_MEM(UI); \ MObject* exception = nullptr; \ UIControl_##event->Invoke(managed, nullptr, &exception); \ if (exception) \ @@ -78,6 +80,7 @@ void UIControl::Serialize(SerializeStream& stream, const void* otherObj) SERIALIZE_MEMBER(NavTargetRight, _navTargetRight); #if !COMPILE_WITHOUT_CSHARP + PROFILE_MEM(UI); void* params[2]; MString* controlType = nullptr; params[0] = &controlType; @@ -129,6 +132,7 @@ void UIControl::Deserialize(DeserializeStream& stream, ISerializeModifier* modif DESERIALIZE_MEMBER(NavTargetRight, _navTargetRight); #if !COMPILE_WITHOUT_CSHARP + PROFILE_MEM(UI); MTypeObject* typeObj = nullptr; const auto controlMember = stream.FindMember("Control"); if (controlMember != stream.MemberEnd()) diff --git a/Source/Engine/Video/AV/VideoBackendAV.cpp b/Source/Engine/Video/AV/VideoBackendAV.cpp index 2d73144c9..c9563d9e2 100644 --- a/Source/Engine/Video/AV/VideoBackendAV.cpp +++ b/Source/Engine/Video/AV/VideoBackendAV.cpp @@ -5,6 +5,7 @@ #include "VideoBackendAV.h" #include "Engine/Platform/Apple/AppleUtils.h" #include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Threading/TaskGraph.h" #include "Engine/Core/Log.h" #include "Engine/Engine/Globals.h" @@ -39,6 +40,7 @@ namespace AV void UpdatePlayer(int32 index) { PROFILE_CPU(); + PROFILE_MEM(Video); auto& player = *Players[index]; ZoneText(player.DebugUrl, player.DebugUrlLen); auto& playerAV = player.GetBackendState(); @@ -152,6 +154,7 @@ namespace AV bool VideoBackendAV::Player_Create(const VideoBackendPlayerInfo& info, VideoBackendPlayer& player) { PROFILE_CPU(); + PROFILE_MEM(Video); player = VideoBackendPlayer(); auto& playerAV = player.GetBackendState(); @@ -210,6 +213,7 @@ void VideoBackendAV::Player_Destroy(VideoBackendPlayer& player) void VideoBackendAV::Player_UpdateInfo(VideoBackendPlayer& player, const VideoBackendPlayerInfo& info) { PROFILE_CPU(); + PROFILE_MEM(Video); auto& playerAV = player.GetBackendState(); playerAV.Player.actionAtItemEnd = info.Loop ? AVPlayerActionAtItemEndNone : AVPlayerActionAtItemEndPause; // TODO: spatial audio diff --git a/Source/Engine/Video/MF/VideoBackendMF.cpp b/Source/Engine/Video/MF/VideoBackendMF.cpp index c6af1cef8..01d6ec481 100644 --- a/Source/Engine/Video/MF/VideoBackendMF.cpp +++ b/Source/Engine/Video/MF/VideoBackendMF.cpp @@ -4,6 +4,7 @@ #include "VideoBackendMF.h" #include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Threading/TaskGraph.h" #include "Engine/Core/Log.h" #include "Engine/Engine/Time.h" @@ -43,6 +44,7 @@ namespace MF bool Configure(VideoBackendPlayer& player, VideoPlayerMF& playerMF, DWORD streamIndex) { PROFILE_CPU_NAMED("Configure"); + PROFILE_MEM(Video); IMFMediaType *mediaType = nullptr, *nativeType = nullptr; bool result = true; @@ -367,6 +369,7 @@ namespace MF void UpdatePlayer(int32 index) { PROFILE_CPU(); + PROFILE_MEM(Video); auto& player = *Players[index]; ZoneText(player.DebugUrl, player.DebugUrlLen); auto& playerMF = player.GetBackendState(); @@ -453,6 +456,7 @@ namespace MF bool VideoBackendMF::Player_Create(const VideoBackendPlayerInfo& info, VideoBackendPlayer& player) { PROFILE_CPU(); + PROFILE_MEM(Video); player = VideoBackendPlayer(); auto& playerMF = player.GetBackendState(); @@ -572,6 +576,7 @@ const Char* VideoBackendMF::Base_Name() bool VideoBackendMF::Base_Init() { PROFILE_CPU(); + PROFILE_MEM(Video); // Init COM HRESULT hr = CoInitializeEx(0, COINIT_MULTITHREADED); diff --git a/Source/Engine/Video/Video.cpp b/Source/Engine/Video/Video.cpp index 2e76d8960..6b44102d9 100644 --- a/Source/Engine/Video/Video.cpp +++ b/Source/Engine/Video/Video.cpp @@ -7,6 +7,7 @@ #include "Engine/Core/Math/Quaternion.h" #include "Engine/Core/Math/Transform.h" #include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Engine/Engine.h" #include "Engine/Engine/EngineService.h" #include "Engine/Graphics/GPUDevice.h" @@ -70,6 +71,7 @@ protected: if (!frame->IsAllocated()) return Result::MissingResources; PROFILE_CPU(); + PROFILE_MEM(Video); ZoneText(_player->DebugUrl, _player->DebugUrlLen); if (PixelFormatExtensions::IsVideo(_player->Format)) @@ -159,6 +161,7 @@ public: void InitBackend(int32 index, VideoBackend* backend) { + PROFILE_MEM(Video); LOG(Info, "Video initialization... (backend: {0})", backend->Base_Name()); if (backend->Base_Init()) { @@ -177,6 +180,7 @@ TaskGraphSystem* Video::System = nullptr; void VideoSystem::Execute(TaskGraph* graph) { PROFILE_CPU_NAMED("Video.Update"); + PROFILE_MEM(Video); // Update backends for (VideoBackend*& backend : VideoServiceInstance.Backends) @@ -309,6 +313,7 @@ void VideoBackendPlayer::InitVideoFrame() void VideoBackendPlayer::UpdateVideoFrame(Span data, TimeSpan time, TimeSpan duration) { PROFILE_CPU(); + PROFILE_MEM(Video); ZoneText(DebugUrl, DebugUrlLen); VideoFrameTime = time; VideoFrameDuration = duration; @@ -356,6 +361,7 @@ void VideoBackendPlayer::UpdateVideoFrame(Span data, TimeSpan time, TimeSp void VideoBackendPlayer::UpdateAudioBuffer(Span data, TimeSpan time, TimeSpan duration) { PROFILE_CPU(); + PROFILE_MEM(Video); ZoneText(DebugUrl, DebugUrlLen); AudioBufferTime = time; AudioBufferDuration = duration;