From c474f2e5228f0cb91eddf006aa457eb04645d31b Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Mon, 20 Apr 2026 09:46:43 +0200 Subject: [PATCH] Add `GPUDevice.DumpResources` command and fix output to be sorted by size and cleaner to read --- Source/Engine/Graphics/GPUDevice.cpp | 94 +++++++++++++++++++++++----- Source/Engine/Graphics/GPUDevice.h | 5 ++ 2 files changed, 84 insertions(+), 15 deletions(-) diff --git a/Source/Engine/Graphics/GPUDevice.cpp b/Source/Engine/Graphics/GPUDevice.cpp index 6aaee8d01..741d0474f 100644 --- a/Source/Engine/Graphics/GPUDevice.cpp +++ b/Source/Engine/Graphics/GPUDevice.cpp @@ -19,6 +19,7 @@ #include "Engine/Content/Assets/Material.h" #include "Engine/Content/Content.h" #include "Engine/Content/SoftAssetReference.h" +#include "Engine/Core/Collections/Sorting.h" #include "Engine/Render2D/Render2D.h" #include "Engine/Engine/CommandLine.h" #include "Engine/Engine/Engine.h" @@ -511,7 +512,7 @@ void GPUDevice::DumpResourcesToLog() const true, // CubeTexture true, // VolumeTexture true, // Buffer - true, // Shader + false, // Shader false, // PipelineState false, // Descriptor false, // Query @@ -522,29 +523,86 @@ void GPUDevice::DumpResourcesToLog() const const auto type = static_cast(typeIndex); const auto printType = printTypes[typeIndex]; - output.AppendFormat(TEXT("Group: {0}s"), ScriptingEnum::ToString(type)); - output.AppendLine(); - - int32 count = 0; + // Get resource sof a given type uint64 memUsage = 0; + struct Resource + { + const GPUResource* Object; + uint64 MemoryUsage; + + bool operator<(const Resource& other) const + { + if (MemoryUsage != other.MemoryUsage) + return MemoryUsage > other.MemoryUsage; + return Object->GetName().Compare(other.Object->GetName()) > 0; + } + }; + Array resources; for (int32 i = 0; i < _resources.Count(); i++) { const GPUResource* resource = _resources[i]; if (resource->GetResourceType() == type && resource->GetMemoryUsage() != 0) { - count++; - memUsage += resource->GetMemoryUsage(); - auto str = resource->ToString(); - if (str.HasChars() && printType) - { - output.Append(TEXT('\t')); - output.Append(str); - output.AppendLine(); - } + resources.Add({ resource, resource->GetMemoryUsage() }); } } + if (resources.IsEmpty()) + continue; + output.AppendFormat(TEXT("> {0}:"), ScriptingEnum::ToString(type)); + output.AppendLine(); - output.AppendFormat(TEXT("Total count: {0}, memory usage: {1}"), count, Utilities::BytesToText(memUsage)); + // Sort them by size + Sorting::QuickSort(resources); + + // Print resources + for (auto e : resources) + { + memUsage += e.MemoryUsage; + if (!printType) + continue; + output.Append(TEXT(" ")); + output.Append(Utilities::BytesToText(e.MemoryUsage)); + output.Append(TEXT(", ")); + if (e.Object->Is()) + { + auto texture = (GPUTexture*)e.Object; + auto& desc = texture->GetDescription(); + output.AppendFormat(TEXT("Size: {}x{}x{}[{}], "), desc.Width, desc.Height, desc.Depth, desc.ArraySize); + if (texture->ResidentMipLevels() == desc.MipLevels) + output.AppendFormat(TEXT("Mips: {}, "), desc.MipLevels); + else + output.AppendFormat(TEXT("Mips: {}/{}, "), texture->ResidentMipLevels(), desc.MipLevels); +#if GPU_ENABLE_RESOURCE_NAMING + auto name = texture->GetName(); +#else + StringView name; +#endif + output.AppendFormat(TEXT("Format: {}, Flags: {}, {}"), ScriptingEnum::ToString(desc.Format), ScriptingEnum::ToStringFlags(desc.Flags), name); + } + else if (e.Object->Is()) + { + auto buffer = (GPUBuffer*)e.Object; + auto& desc = buffer->GetDescription(); + output.AppendFormat(TEXT("Stride: {} bytes, "), desc.Stride); + if (desc.Format != PixelFormat::Unknown) + output.AppendFormat(TEXT("Format: {}, "), ScriptingEnum::ToString(desc.Format)); + if (desc.Usage != GPUResourceUsage::Default) + output.AppendFormat(TEXT("Usage: {}, "), ScriptingEnum::ToString(desc.Usage)); +#if GPU_ENABLE_RESOURCE_NAMING + auto name = buffer->GetName(); +#else + StringView name; +#endif + output.AppendFormat(TEXT("Flags: {}, {}"), ScriptingEnum::ToStringFlags(desc.Flags), name); + } + else + { + output.Append(e.Object->ToString()); + } + output.AppendLine(); + } + + output.AppendFormat(TEXT("Total count: {0}, memory usage: {1}"), resources.Count(), Utilities::BytesToText(memUsage)); output.AppendLine(); output.AppendLine(); } @@ -553,6 +611,12 @@ void GPUDevice::DumpResourcesToLog() const LOG_STR(Info, output.ToStringView()); } +void GPUDevice::DumpResources() +{ + if (GPUDevice::Instance) + GPUDevice::Instance->DumpResourcesToLog(); +} + extern void ClearVertexLayoutCache(); void GPUDevice::preDispose() diff --git a/Source/Engine/Graphics/GPUDevice.h b/Source/Engine/Graphics/GPUDevice.h index b9f681b5c..e6df74886 100644 --- a/Source/Engine/Graphics/GPUDevice.h +++ b/Source/Engine/Graphics/GPUDevice.h @@ -389,6 +389,11 @@ public: /// void DumpResourcesToLog() const; + /// + /// Dumps all GPU resources information to the log. + /// + API_FUNCTION(Attributes="DebugCommand") static void DumpResources(); + protected: virtual void preDispose();