1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-05 12:10:55 +00:00

Add Meshes to the Video RAM Profiler

Apply suggestions from code review

Co-Authored-By: Hugo Locurcio <hugo.locurcio@hugo.pro>
This commit is contained in:
Ryan
2025-02-23 23:25:31 -05:00
parent 1696ab0cb6
commit 4497e2a0d3
13 changed files with 177 additions and 9 deletions

View File

@@ -33,6 +33,7 @@
#include "core/config/project_settings.h"
#include "core/debugger/engine_debugger.h"
#include "core/debugger/engine_profiler.h"
#include "core/io/resource_loader.h"
#include "core/object/script_language.h"
#include "servers/display_server.h"
@@ -435,7 +436,24 @@ void ServersDebugger::_send_resource_usage() {
info.path = E.path;
info.vram = E.bytes;
info.id = E.texture;
info.type = "Texture";
switch (E.type) {
case RS::TextureType::TEXTURE_TYPE_2D:
info.type = "Texture2D";
break;
case RS::TextureType::TEXTURE_TYPE_3D:
info.type = "Texture3D";
break;
case RS::TextureType::TEXTURE_TYPE_LAYERED:
info.type = "TextureLayered";
break;
}
String possible_type = _get_resource_type_from_path(E.path);
if (!possible_type.is_empty()) {
info.type = possible_type;
}
if (E.depth == 0) {
info.format = itos(E.width) + "x" + itos(E.height) + " " + Image::get_format_name(E.format);
} else {
@@ -444,9 +462,61 @@ void ServersDebugger::_send_resource_usage() {
usage.infos.push_back(info);
}
List<RS::MeshInfo> mesh_info;
RS::get_singleton()->mesh_debug_usage(&mesh_info);
for (const RS::MeshInfo &E : mesh_info) {
ServersDebugger::ResourceInfo info;
info.path = E.path;
// We use 64-bit integers to avoid overflow, if for whatever reason, the sum is bigger than 4GB.
uint64_t vram = E.vertex_buffer_size + E.attribute_buffer_size + E.skin_buffer_size + E.index_buffer_size + E.blend_shape_buffer_size + E.lod_index_buffers_size;
// But can info.vram even hold that, and why is it an int instead of an uint?
info.vram = vram;
// Even though these empty meshes can be indicative of issues somewhere else
// for UX reasons, we don't want to show them.
if (vram == 0 && E.path.is_empty()) {
continue;
}
info.id = E.mesh;
info.type = "Mesh";
String possible_type = _get_resource_type_from_path(E.path);
if (!possible_type.is_empty()) {
info.type = possible_type;
}
info.format = itos(E.vertex_count) + " Vertices";
usage.infos.push_back(info);
}
EngineDebugger::get_singleton()->send_message("servers:memory_usage", usage.serialize());
}
// Done on a best-effort basis.
String ServersDebugger::_get_resource_type_from_path(const String &p_path) {
if (p_path.is_empty()) {
return "";
}
if (!ResourceLoader::exists(p_path)) {
return "";
}
if (ResourceCache::has(p_path)) {
Ref<Resource> resource = ResourceCache::get_ref(p_path);
return resource->get_class();
} else {
// This doesn't work all the time for embedded resources.
String resource_type = ResourceLoader::get_resource_type(p_path);
if (resource_type != "") {
return resource_type;
}
}
return "";
}
ServersDebugger::ServersDebugger() {
singleton = this;