diff options
35 files changed, 733 insertions, 427 deletions
diff --git a/doc/classes/Performance.xml b/doc/classes/Performance.xml index b6013fa83e..a141961df5 100644 --- a/doc/classes/Performance.xml +++ b/doc/classes/Performance.xml @@ -168,58 +168,42 @@ <constant name="OBJECT_ORPHAN_NODE_COUNT" value="9" enum="Monitor"> Number of orphan nodes, i.e. nodes which are not parented to a node of the scene tree. </constant> - <constant name="RENDER_OBJECTS_IN_FRAME" value="10" enum="Monitor"> - 3D objects drawn per frame. + <constant name="RENDER_TOTAL_OBJECTS_IN_FRAME" value="10" enum="Monitor"> </constant> - <constant name="RENDER_VERTICES_IN_FRAME" value="11" enum="Monitor"> - Vertices drawn per frame. 3D only. + <constant name="RENDER_TOTAL_PRIMITIVES_IN_FRAME" value="11" enum="Monitor"> </constant> - <constant name="RENDER_MATERIAL_CHANGES_IN_FRAME" value="12" enum="Monitor"> - Material changes per frame. 3D only. + <constant name="RENDER_TOTAL_DRAW_CALLS_IN_FRAME" value="12" enum="Monitor"> </constant> - <constant name="RENDER_SHADER_CHANGES_IN_FRAME" value="13" enum="Monitor"> - Shader changes per frame. 3D only. - </constant> - <constant name="RENDER_SURFACE_CHANGES_IN_FRAME" value="14" enum="Monitor"> - Render surface changes per frame. 3D only. - </constant> - <constant name="RENDER_DRAW_CALLS_IN_FRAME" value="15" enum="Monitor"> - Draw calls per frame. 3D only. - </constant> - <constant name="RENDER_VIDEO_MEM_USED" value="16" enum="Monitor"> + <constant name="RENDER_VIDEO_MEM_USED" value="13" enum="Monitor"> The amount of video memory used, i.e. texture and vertex memory combined. </constant> - <constant name="RENDER_TEXTURE_MEM_USED" value="17" enum="Monitor"> + <constant name="RENDER_TEXTURE_MEM_USED" value="14" enum="Monitor"> The amount of texture memory used. </constant> - <constant name="RENDER_VERTEX_MEM_USED" value="18" enum="Monitor"> - The amount of vertex memory used. - </constant> - <constant name="RENDER_USAGE_VIDEO_MEM_TOTAL" value="19" enum="Monitor"> - Unimplemented in the GLES2 rendering backend, always returns 0. + <constant name="RENDER_BUFFER_MEM_USED" value="15" enum="Monitor"> </constant> - <constant name="PHYSICS_2D_ACTIVE_OBJECTS" value="20" enum="Monitor"> + <constant name="PHYSICS_2D_ACTIVE_OBJECTS" value="16" enum="Monitor"> Number of active [RigidBody2D] nodes in the game. </constant> - <constant name="PHYSICS_2D_COLLISION_PAIRS" value="21" enum="Monitor"> + <constant name="PHYSICS_2D_COLLISION_PAIRS" value="17" enum="Monitor"> Number of collision pairs in the 2D physics engine. </constant> - <constant name="PHYSICS_2D_ISLAND_COUNT" value="22" enum="Monitor"> + <constant name="PHYSICS_2D_ISLAND_COUNT" value="18" enum="Monitor"> Number of islands in the 2D physics engine. </constant> - <constant name="PHYSICS_3D_ACTIVE_OBJECTS" value="23" enum="Monitor"> + <constant name="PHYSICS_3D_ACTIVE_OBJECTS" value="19" enum="Monitor"> Number of active [RigidBody3D] and [VehicleBody3D] nodes in the game. </constant> - <constant name="PHYSICS_3D_COLLISION_PAIRS" value="24" enum="Monitor"> + <constant name="PHYSICS_3D_COLLISION_PAIRS" value="20" enum="Monitor"> Number of collision pairs in the 3D physics engine. </constant> - <constant name="PHYSICS_3D_ISLAND_COUNT" value="25" enum="Monitor"> + <constant name="PHYSICS_3D_ISLAND_COUNT" value="21" enum="Monitor"> Number of islands in the 3D physics engine. </constant> - <constant name="AUDIO_OUTPUT_LATENCY" value="26" enum="Monitor"> + <constant name="AUDIO_OUTPUT_LATENCY" value="22" enum="Monitor"> Output latency of the [AudioServer]. </constant> - <constant name="MONITOR_MAX" value="27" enum="Monitor"> + <constant name="MONITOR_MAX" value="23" enum="Monitor"> Represents the size of the [enum Monitor] enum. </constant> </constants> diff --git a/doc/classes/RenderingDevice.xml b/doc/classes/RenderingDevice.xml index b66b945025..f2b22af8c6 100644 --- a/doc/classes/RenderingDevice.xml +++ b/doc/classes/RenderingDevice.xml @@ -515,6 +515,14 @@ <description> </description> </method> + <method name="get_memory_usage" qualifiers="const"> + <return type="int"> + </return> + <argument index="0" name="arg0" type="int" enum="RenderingDevice.MemoryType"> + </argument> + <description> + </description> + </method> <method name="index_array_create"> <return type="RID"> </return> @@ -1771,6 +1779,12 @@ </constant> <constant name="LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Z" value="34" enum="Limit"> </constant> + <constant name="MEMORY_TEXTURES" value="0" enum="MemoryType"> + </constant> + <constant name="MEMORY_BUFFERS" value="1" enum="MemoryType"> + </constant> + <constant name="MEMORY_TOTAL" value="2" enum="MemoryType"> + </constant> <constant name="INVALID_ID" value="-1"> </constant> <constant name="INVALID_FORMAT_ID" value="-1"> diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml index 8b24893513..6b45653bf2 100644 --- a/doc/classes/RenderingServer.xml +++ b/doc/classes/RenderingServer.xml @@ -1666,13 +1666,12 @@ <description> </description> </method> - <method name="get_render_info"> + <method name="get_rendering_info"> <return type="int"> </return> - <argument index="0" name="info" type="int" enum="RenderingServer.RenderInfo"> + <argument index="0" name="info" type="int" enum="RenderingServer.RenderingInfo"> </argument> <description> - Returns a certain information, see [enum RenderInfo] for options. </description> </method> <method name="get_test_cube"> @@ -4101,10 +4100,11 @@ </return> <argument index="0" name="viewport" type="RID"> </argument> - <argument index="1" name="info" type="int" enum="RenderingServer.ViewportRenderInfo"> + <argument index="1" name="type" type="int" enum="RenderingServer.ViewportRenderInfoType"> + </argument> + <argument index="2" name="info" type="int" enum="RenderingServer.ViewportRenderInfo"> </argument> <description> - Returns a viewport's render information. For options, see the [enum ViewportRenderInfo] constants. </description> </method> <method name="viewport_get_texture" qualifiers="const"> @@ -5124,23 +5124,20 @@ <constant name="VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME" value="0" enum="ViewportRenderInfo"> Number of objects drawn in a single frame. </constant> - <constant name="VIEWPORT_RENDER_INFO_VERTICES_IN_FRAME" value="1" enum="ViewportRenderInfo"> + <constant name="VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME" value="1" enum="ViewportRenderInfo"> Number of vertices drawn in a single frame. </constant> - <constant name="VIEWPORT_RENDER_INFO_MATERIAL_CHANGES_IN_FRAME" value="2" enum="ViewportRenderInfo"> - Number of material changes during this frame. + <constant name="VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME" value="2" enum="ViewportRenderInfo"> + Number of draw calls during this frame. </constant> - <constant name="VIEWPORT_RENDER_INFO_SHADER_CHANGES_IN_FRAME" value="3" enum="ViewportRenderInfo"> - Number of shader changes during this frame. + <constant name="VIEWPORT_RENDER_INFO_MAX" value="3" enum="ViewportRenderInfo"> + Represents the size of the [enum ViewportRenderInfo] enum. </constant> - <constant name="VIEWPORT_RENDER_INFO_SURFACE_CHANGES_IN_FRAME" value="4" enum="ViewportRenderInfo"> - Number of surface changes during this frame. + <constant name="VIEWPORT_RENDER_INFO_TYPE_VISIBLE" value="0" enum="ViewportRenderInfoType"> </constant> - <constant name="VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME" value="5" enum="ViewportRenderInfo"> - Number of draw calls during this frame. + <constant name="VIEWPORT_RENDER_INFO_TYPE_SHADOW" value="1" enum="ViewportRenderInfoType"> </constant> - <constant name="VIEWPORT_RENDER_INFO_MAX" value="6" enum="ViewportRenderInfo"> - Represents the size of the [enum ViewportRenderInfo] enum. + <constant name="VIEWPORT_RENDER_INFO_TYPE_MAX" value="2" enum="ViewportRenderInfoType"> </constant> <constant name="VIEWPORT_DEBUG_DRAW_DISABLED" value="0" enum="ViewportDebugDraw"> Debug draw is disabled. Default setting. @@ -5615,35 +5612,17 @@ </constant> <constant name="GLOBAL_VAR_TYPE_MAX" value="28" enum="GlobalVariableType"> </constant> - <constant name="INFO_OBJECTS_IN_FRAME" value="0" enum="RenderInfo"> - The amount of objects in the frame. - </constant> - <constant name="INFO_VERTICES_IN_FRAME" value="1" enum="RenderInfo"> - The amount of vertices in the frame. - </constant> - <constant name="INFO_MATERIAL_CHANGES_IN_FRAME" value="2" enum="RenderInfo"> - The amount of modified materials in the frame. - </constant> - <constant name="INFO_SHADER_CHANGES_IN_FRAME" value="3" enum="RenderInfo"> - The amount of shader rebinds in the frame. - </constant> - <constant name="INFO_SURFACE_CHANGES_IN_FRAME" value="4" enum="RenderInfo"> - The amount of surface changes in the frame. + <constant name="RENDERING_INFO_TOTAL_OBJECTS_IN_FRAME" value="0" enum="RenderingInfo"> </constant> - <constant name="INFO_DRAW_CALLS_IN_FRAME" value="5" enum="RenderInfo"> - The amount of draw calls in frame. + <constant name="RENDERING_INFO_TOTAL_PRIMITIVES_IN_FRAME" value="1" enum="RenderingInfo"> </constant> - <constant name="INFO_USAGE_VIDEO_MEM_TOTAL" value="6" enum="RenderInfo"> - Unimplemented in the GLES2 rendering backend, always returns 0. + <constant name="RENDERING_INFO_TOTAL_DRAW_CALLS_IN_FRAME" value="2" enum="RenderingInfo"> </constant> - <constant name="INFO_VIDEO_MEM_USED" value="7" enum="RenderInfo"> - The amount of video memory used, i.e. texture and vertex memory combined. + <constant name="RENDERING_INFO_TEXTURE_MEM_USED" value="3" enum="RenderingInfo"> </constant> - <constant name="INFO_TEXTURE_MEM_USED" value="8" enum="RenderInfo"> - The amount of texture memory used. + <constant name="RENDERING_INFO_BUFFER_MEM_USED" value="4" enum="RenderingInfo"> </constant> - <constant name="INFO_VERTEX_MEM_USED" value="9" enum="RenderInfo"> - The amount of vertex memory used. + <constant name="RENDERING_INFO_VIDEO_MEM_USED" value="5" enum="RenderingInfo"> </constant> <constant name="FEATURE_SHADERS" value="0" enum="Features"> Hardware supports shaders. This enum is currently unused in Godot 3.x. diff --git a/doc/classes/Viewport.xml b/doc/classes/Viewport.xml index bc0c3c5516..00827fe324 100644 --- a/doc/classes/Viewport.xml +++ b/doc/classes/Viewport.xml @@ -60,10 +60,11 @@ <method name="get_render_info"> <return type="int"> </return> - <argument index="0" name="info" type="int" enum="Viewport.RenderInfo"> + <argument index="0" name="type" type="int" enum="Viewport.RenderInfoType"> + </argument> + <argument index="1" name="info" type="int" enum="Viewport.RenderInfo"> </argument> <description> - Returns information about the viewport from the rendering pipeline. </description> </method> <method name="get_shadow_atlas_quadrant_subdiv" qualifiers="const"> @@ -350,23 +351,20 @@ <constant name="RENDER_INFO_OBJECTS_IN_FRAME" value="0" enum="RenderInfo"> Amount of objects in frame. </constant> - <constant name="RENDER_INFO_VERTICES_IN_FRAME" value="1" enum="RenderInfo"> + <constant name="RENDER_INFO_PRIMITIVES_IN_FRAME" value="1" enum="RenderInfo"> Amount of vertices in frame. </constant> - <constant name="RENDER_INFO_MATERIAL_CHANGES_IN_FRAME" value="2" enum="RenderInfo"> - Amount of material changes in frame. + <constant name="RENDER_INFO_DRAW_CALLS_IN_FRAME" value="2" enum="RenderInfo"> + Amount of draw calls in frame. </constant> - <constant name="RENDER_INFO_SHADER_CHANGES_IN_FRAME" value="3" enum="RenderInfo"> - Amount of shader changes in frame. + <constant name="RENDER_INFO_MAX" value="3" enum="RenderInfo"> + Represents the size of the [enum RenderInfo] enum. </constant> - <constant name="RENDER_INFO_SURFACE_CHANGES_IN_FRAME" value="4" enum="RenderInfo"> - Amount of surface changes in frame. + <constant name="RENDER_INFO_TYPE_VISIBLE" value="0" enum="RenderInfoType"> </constant> - <constant name="RENDER_INFO_DRAW_CALLS_IN_FRAME" value="5" enum="RenderInfo"> - Amount of draw calls in frame. + <constant name="RENDER_INFO_TYPE_SHADOW" value="1" enum="RenderInfoType"> </constant> - <constant name="RENDER_INFO_MAX" value="6" enum="RenderInfo"> - Represents the size of the [enum RenderInfo] enum. + <constant name="RENDER_INFO_TYPE_MAX" value="2" enum="RenderInfoType"> </constant> <constant name="DEBUG_DRAW_DISABLED" value="0" enum="DebugDraw"> Objects are displayed normally. diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp index 6c4e590586..2a8d4fcded 100644 --- a/drivers/vulkan/rendering_device_vulkan.cpp +++ b/drivers/vulkan/rendering_device_vulkan.cpp @@ -1398,12 +1398,15 @@ Error RenderingDeviceVulkan::_buffer_allocate(Buffer *p_buffer, uint32_t p_size, p_buffer->buffer_info.range = p_size; p_buffer->usage = p_usage; + buffer_memory += p_size; + return OK; } Error RenderingDeviceVulkan::_buffer_free(Buffer *p_buffer) { ERR_FAIL_COND_V(p_buffer->size == 0, ERR_INVALID_PARAMETER); + buffer_memory -= p_buffer->size; vmaDestroyBuffer(allocator, p_buffer->buffer, p_buffer->allocation); p_buffer->buffer = VK_NULL_HANDLE; p_buffer->allocation = nullptr; @@ -1896,7 +1899,7 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T VkResult err = vmaCreateImage(allocator, &image_create_info, &allocInfo, &texture.image, &texture.allocation, &texture.allocation_info); ERR_FAIL_COND_V_MSG(err, RID(), "vmaCreateImage failed with error " + itos(err) + "."); - + image_memory += texture.allocation_info.size; texture.type = p_format.texture_type; texture.format = p_format.format; texture.width = image_create_info.extent.width; @@ -8121,6 +8124,7 @@ void RenderingDeviceVulkan::_free_pending_resources(int p_frame) { vkDestroyImageView(device, texture->view, nullptr); if (texture->owner.is_null()) { //actually owns the image and the allocation too + image_memory -= texture->allocation_info.size; vmaDestroyImage(allocator, texture->image, texture->allocation); } frames[p_frame].textures_to_dispose_of.pop_front(); @@ -8144,10 +8148,16 @@ uint32_t RenderingDeviceVulkan::get_frame_delay() const { return frame_count; } -uint64_t RenderingDeviceVulkan::get_memory_usage() const { - VmaStats stats; - vmaCalculateStats(allocator, &stats); - return stats.total.usedBytes; +uint64_t RenderingDeviceVulkan::get_memory_usage(MemoryType p_type) const { + if (p_type == MEMORY_BUFFERS) { + return buffer_memory; + } else if (p_type == MEMORY_TEXTURES) { + return image_memory; + } else { + VmaStats stats; + vmaCalculateStats(allocator, &stats); + return stats.total.usedBytes; + } } void RenderingDeviceVulkan::_flush(bool p_current_frame) { diff --git a/drivers/vulkan/rendering_device_vulkan.h b/drivers/vulkan/rendering_device_vulkan.h index 9f5830103d..1f86fe9e48 100644 --- a/drivers/vulkan/rendering_device_vulkan.h +++ b/drivers/vulkan/rendering_device_vulkan.h @@ -1005,6 +1005,9 @@ class RenderingDeviceVulkan : public RenderingDevice { VulkanContext *context = nullptr; + uint64_t image_memory = 0; + uint64_t buffer_memory = 0; + void _free_internal(RID p_id); void _flush(bool p_current_frame); @@ -1191,7 +1194,7 @@ public: virtual RenderingDevice *create_local_device(); - virtual uint64_t get_memory_usage() const; + virtual uint64_t get_memory_usage(MemoryType p_type) const; virtual void set_resource_name(RID p_id, const String p_name); diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index 228fe1649b..5a4d79cdc8 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -2505,24 +2505,20 @@ void Node3DEditorViewport::_notification(int p_what) { if (show_info) { String text; - text += "X: " + rtos(current_camera->get_position().x).pad_decimals(1) + "\n"; - text += "Y: " + rtos(current_camera->get_position().y).pad_decimals(1) + "\n"; - text += "Z: " + rtos(current_camera->get_position().z).pad_decimals(1) + "\n"; - text += TTR("Pitch") + ": " + itos(Math::round(Math::rad2deg(current_camera->get_rotation().x))) + "\n"; - text += TTR("Yaw") + ": " + itos(Math::round(Math::rad2deg(current_camera->get_rotation().y))) + "\n\n"; - - text += TTR("Size") + - vformat( - ": %dx%d (%.1fMP)\n", - viewport->get_size().x, - viewport->get_size().y, - viewport->get_size().x * viewport->get_size().y * 0.000'001); - text += TTR("Objects Drawn") + ": " + itos(viewport->get_render_info(Viewport::RENDER_INFO_OBJECTS_IN_FRAME)) + "\n"; - text += TTR("Material Changes") + ": " + itos(viewport->get_render_info(Viewport::RENDER_INFO_MATERIAL_CHANGES_IN_FRAME)) + "\n"; - text += TTR("Shader Changes") + ": " + itos(viewport->get_render_info(Viewport::RENDER_INFO_SHADER_CHANGES_IN_FRAME)) + "\n"; - text += TTR("Surface Changes") + ": " + itos(viewport->get_render_info(Viewport::RENDER_INFO_SURFACE_CHANGES_IN_FRAME)) + "\n"; - text += TTR("Draw Calls") + ": " + itos(viewport->get_render_info(Viewport::RENDER_INFO_DRAW_CALLS_IN_FRAME)) + "\n"; - text += TTR("Vertices") + ": " + itos(viewport->get_render_info(Viewport::RENDER_INFO_VERTICES_IN_FRAME)); + text += vformat(TTR("X: %s\n"), rtos(current_camera->get_position().x).pad_decimals(1)); + text += vformat(TTR("Y: %s\n"), rtos(current_camera->get_position().y).pad_decimals(1)); + text += vformat(TTR("Z: %s\n"), rtos(current_camera->get_position().z).pad_decimals(1)); + text += "\n"; + text += vformat( + TTR("Size: %dx%d (%.1fMP)\n"), + viewport->get_size().x, + viewport->get_size().y, + viewport->get_size().x * viewport->get_size().y * 0.000001); + + text += "\n"; + text += vformat(TTR("Objects: %d\n"), viewport->get_render_info(Viewport::RENDER_INFO_TYPE_VISIBLE, Viewport::RENDER_INFO_OBJECTS_IN_FRAME)); + text += vformat(TTR("Primitives: %d\n"), viewport->get_render_info(Viewport::RENDER_INFO_TYPE_VISIBLE, Viewport::RENDER_INFO_PRIMITIVES_IN_FRAME)); + text += vformat(TTR("Draw Calls: %d"), viewport->get_render_info(Viewport::RENDER_INFO_TYPE_VISIBLE, Viewport::RENDER_INFO_DRAW_CALLS_IN_FRAME)); info_label->set_text(text); } diff --git a/main/performance.cpp b/main/performance.cpp index a2e53f2ee2..9f5be7b8c4 100644 --- a/main/performance.cpp +++ b/main/performance.cpp @@ -60,16 +60,12 @@ void Performance::_bind_methods() { BIND_ENUM_CONSTANT(OBJECT_RESOURCE_COUNT); BIND_ENUM_CONSTANT(OBJECT_NODE_COUNT); BIND_ENUM_CONSTANT(OBJECT_ORPHAN_NODE_COUNT); - BIND_ENUM_CONSTANT(RENDER_OBJECTS_IN_FRAME); - BIND_ENUM_CONSTANT(RENDER_VERTICES_IN_FRAME); - BIND_ENUM_CONSTANT(RENDER_MATERIAL_CHANGES_IN_FRAME); - BIND_ENUM_CONSTANT(RENDER_SHADER_CHANGES_IN_FRAME); - BIND_ENUM_CONSTANT(RENDER_SURFACE_CHANGES_IN_FRAME); - BIND_ENUM_CONSTANT(RENDER_DRAW_CALLS_IN_FRAME); + BIND_ENUM_CONSTANT(RENDER_TOTAL_OBJECTS_IN_FRAME); + BIND_ENUM_CONSTANT(RENDER_TOTAL_PRIMITIVES_IN_FRAME); + BIND_ENUM_CONSTANT(RENDER_TOTAL_DRAW_CALLS_IN_FRAME); BIND_ENUM_CONSTANT(RENDER_VIDEO_MEM_USED); BIND_ENUM_CONSTANT(RENDER_TEXTURE_MEM_USED); - BIND_ENUM_CONSTANT(RENDER_VERTEX_MEM_USED); - BIND_ENUM_CONSTANT(RENDER_USAGE_VIDEO_MEM_TOTAL); + BIND_ENUM_CONSTANT(RENDER_BUFFER_MEM_USED); BIND_ENUM_CONSTANT(PHYSICS_2D_ACTIVE_OBJECTS); BIND_ENUM_CONSTANT(PHYSICS_2D_COLLISION_PAIRS); BIND_ENUM_CONSTANT(PHYSICS_2D_ISLAND_COUNT); @@ -103,16 +99,12 @@ String Performance::get_monitor_name(Monitor p_monitor) const { "object/resources", "object/nodes", "object/orphan_nodes", - "raster/objects_drawn", - "raster/vertices_drawn", - "raster/mat_changes", - "raster/shader_changes", - "raster/surface_changes", - "raster/draw_calls", + "raster/total_objects_drawn", + "raster/total_primitives_drawn", + "raster/total_draw_calls", "video/video_mem", "video/texture_mem", - "video/vertex_mem", - "video/video_mem_max", + "video/buffer_mem", "physics_2d/active_objects", "physics_2d/collision_pairs", "physics_2d/islands", @@ -148,26 +140,18 @@ float Performance::get_monitor(Monitor p_monitor) const { return _get_node_count(); case OBJECT_ORPHAN_NODE_COUNT: return Node::orphan_node_count; - case RENDER_OBJECTS_IN_FRAME: - return RS::get_singleton()->get_render_info(RS::INFO_OBJECTS_IN_FRAME); - case RENDER_VERTICES_IN_FRAME: - return RS::get_singleton()->get_render_info(RS::INFO_VERTICES_IN_FRAME); - case RENDER_MATERIAL_CHANGES_IN_FRAME: - return RS::get_singleton()->get_render_info(RS::INFO_MATERIAL_CHANGES_IN_FRAME); - case RENDER_SHADER_CHANGES_IN_FRAME: - return RS::get_singleton()->get_render_info(RS::INFO_SHADER_CHANGES_IN_FRAME); - case RENDER_SURFACE_CHANGES_IN_FRAME: - return RS::get_singleton()->get_render_info(RS::INFO_SURFACE_CHANGES_IN_FRAME); - case RENDER_DRAW_CALLS_IN_FRAME: - return RS::get_singleton()->get_render_info(RS::INFO_DRAW_CALLS_IN_FRAME); + case RENDER_TOTAL_OBJECTS_IN_FRAME: + return RS::get_singleton()->get_rendering_info(RS::RENDERING_INFO_TOTAL_OBJECTS_IN_FRAME); + case RENDER_TOTAL_PRIMITIVES_IN_FRAME: + return RS::get_singleton()->get_rendering_info(RS::RENDERING_INFO_TOTAL_PRIMITIVES_IN_FRAME); + case RENDER_TOTAL_DRAW_CALLS_IN_FRAME: + return RS::get_singleton()->get_rendering_info(RS::RENDERING_INFO_TOTAL_DRAW_CALLS_IN_FRAME); case RENDER_VIDEO_MEM_USED: - return RS::get_singleton()->get_render_info(RS::INFO_VIDEO_MEM_USED); + return RS::get_singleton()->get_rendering_info(RS::RENDERING_INFO_VIDEO_MEM_USED); case RENDER_TEXTURE_MEM_USED: - return RS::get_singleton()->get_render_info(RS::INFO_TEXTURE_MEM_USED); - case RENDER_VERTEX_MEM_USED: - return RS::get_singleton()->get_render_info(RS::INFO_VERTEX_MEM_USED); - case RENDER_USAGE_VIDEO_MEM_TOTAL: - return RS::get_singleton()->get_render_info(RS::INFO_USAGE_VIDEO_MEM_TOTAL); + return RS::get_singleton()->get_rendering_info(RS::RENDERING_INFO_TEXTURE_MEM_USED); + case RENDER_BUFFER_MEM_USED: + return RS::get_singleton()->get_rendering_info(RS::RENDERING_INFO_BUFFER_MEM_USED); case PHYSICS_2D_ACTIVE_OBJECTS: return PhysicsServer2D::get_singleton()->get_process_info(PhysicsServer2D::INFO_ACTIVE_OBJECTS); case PHYSICS_2D_COLLISION_PAIRS: @@ -207,10 +191,6 @@ Performance::MonitorType Performance::get_monitor_type(Monitor p_monitor) const MONITOR_TYPE_QUANTITY, MONITOR_TYPE_QUANTITY, MONITOR_TYPE_QUANTITY, - MONITOR_TYPE_QUANTITY, - MONITOR_TYPE_QUANTITY, - MONITOR_TYPE_QUANTITY, - MONITOR_TYPE_MEMORY, MONITOR_TYPE_MEMORY, MONITOR_TYPE_MEMORY, MONITOR_TYPE_MEMORY, diff --git a/main/performance.h b/main/performance.h index 122e5a4f9a..174b3500d1 100644 --- a/main/performance.h +++ b/main/performance.h @@ -73,16 +73,12 @@ public: OBJECT_RESOURCE_COUNT, OBJECT_NODE_COUNT, OBJECT_ORPHAN_NODE_COUNT, - RENDER_OBJECTS_IN_FRAME, - RENDER_VERTICES_IN_FRAME, - RENDER_MATERIAL_CHANGES_IN_FRAME, - RENDER_SHADER_CHANGES_IN_FRAME, - RENDER_SURFACE_CHANGES_IN_FRAME, - RENDER_DRAW_CALLS_IN_FRAME, + RENDER_TOTAL_OBJECTS_IN_FRAME, + RENDER_TOTAL_PRIMITIVES_IN_FRAME, + RENDER_TOTAL_DRAW_CALLS_IN_FRAME, RENDER_VIDEO_MEM_USED, RENDER_TEXTURE_MEM_USED, - RENDER_VERTEX_MEM_USED, - RENDER_USAGE_VIDEO_MEM_TOTAL, + RENDER_BUFFER_MEM_USED, PHYSICS_2D_ACTIVE_OBJECTS, PHYSICS_2D_COLLISION_PAIRS, PHYSICS_2D_ISLAND_COUNT, diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 319e589036..9a2e0c5230 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -3268,8 +3268,8 @@ Viewport::DebugDraw Viewport::get_debug_draw() const { return debug_draw; } -int Viewport::get_render_info(RenderInfo p_info) { - return RS::get_singleton()->viewport_get_render_info(viewport, RS::ViewportRenderInfo(p_info)); +int Viewport::get_render_info(RenderInfoType p_type, RenderInfo p_info) { + return RS::get_singleton()->viewport_get_render_info(viewport, RS::ViewportRenderInfoType(p_type), RS::ViewportRenderInfo(p_info)); } void Viewport::set_snap_controls_to_pixels(bool p_enable) { @@ -3499,7 +3499,7 @@ void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("set_debug_draw", "debug_draw"), &Viewport::set_debug_draw); ClassDB::bind_method(D_METHOD("get_debug_draw"), &Viewport::get_debug_draw); - ClassDB::bind_method(D_METHOD("get_render_info", "info"), &Viewport::get_render_info); + ClassDB::bind_method(D_METHOD("get_render_info", "type", "info"), &Viewport::get_render_info); ClassDB::bind_method(D_METHOD("set_use_xr", "use"), &Viewport::set_use_xr); ClassDB::bind_method(D_METHOD("is_using_xr"), &Viewport::is_using_xr); @@ -3650,13 +3650,14 @@ void Viewport::_bind_methods() { BIND_ENUM_CONSTANT(SCREEN_SPACE_AA_MAX); BIND_ENUM_CONSTANT(RENDER_INFO_OBJECTS_IN_FRAME); - BIND_ENUM_CONSTANT(RENDER_INFO_VERTICES_IN_FRAME); - BIND_ENUM_CONSTANT(RENDER_INFO_MATERIAL_CHANGES_IN_FRAME); - BIND_ENUM_CONSTANT(RENDER_INFO_SHADER_CHANGES_IN_FRAME); - BIND_ENUM_CONSTANT(RENDER_INFO_SURFACE_CHANGES_IN_FRAME); + BIND_ENUM_CONSTANT(RENDER_INFO_PRIMITIVES_IN_FRAME); BIND_ENUM_CONSTANT(RENDER_INFO_DRAW_CALLS_IN_FRAME); BIND_ENUM_CONSTANT(RENDER_INFO_MAX); + BIND_ENUM_CONSTANT(RENDER_INFO_TYPE_VISIBLE); + BIND_ENUM_CONSTANT(RENDER_INFO_TYPE_SHADOW); + BIND_ENUM_CONSTANT(RENDER_INFO_TYPE_MAX); + BIND_ENUM_CONSTANT(DEBUG_DRAW_DISABLED); BIND_ENUM_CONSTANT(DEBUG_DRAW_UNSHADED); BIND_ENUM_CONSTANT(DEBUG_DRAW_LIGHTING); diff --git a/scene/main/viewport.h b/scene/main/viewport.h index 29491a1178..0f3bb8707d 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -115,14 +115,17 @@ public: enum RenderInfo { RENDER_INFO_OBJECTS_IN_FRAME, - RENDER_INFO_VERTICES_IN_FRAME, - RENDER_INFO_MATERIAL_CHANGES_IN_FRAME, - RENDER_INFO_SHADER_CHANGES_IN_FRAME, - RENDER_INFO_SURFACE_CHANGES_IN_FRAME, + RENDER_INFO_PRIMITIVES_IN_FRAME, RENDER_INFO_DRAW_CALLS_IN_FRAME, RENDER_INFO_MAX }; + enum RenderInfoType { + RENDER_INFO_TYPE_VISIBLE, + RENDER_INFO_TYPE_SHADOW, + RENDER_INFO_TYPE_MAX + }; + enum DebugDraw { DEBUG_DRAW_DISABLED, DEBUG_DRAW_UNSHADED, @@ -596,7 +599,7 @@ public: void set_debug_draw(DebugDraw p_debug_draw); DebugDraw get_debug_draw() const; - int get_render_info(RenderInfo p_info); + int get_render_info(RenderInfoType p_type, RenderInfo p_info); void set_snap_controls_to_pixels(bool p_enable); bool is_snap_controls_to_pixels_enabled() const; @@ -699,6 +702,7 @@ VARIANT_ENUM_CAST(Viewport::SDFScale); VARIANT_ENUM_CAST(Viewport::SDFOversize); VARIANT_ENUM_CAST(SubViewport::ClearMode); VARIANT_ENUM_CAST(Viewport::RenderInfo); +VARIANT_ENUM_CAST(Viewport::RenderInfoType); VARIANT_ENUM_CAST(Viewport::DefaultCanvasItemTextureFilter); VARIANT_ENUM_CAST(Viewport::DefaultCanvasItemTextureRepeat); diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index ce942817c0..c5bfbc39db 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -590,157 +590,320 @@ Transform3D Mesh::get_builtin_bind_pose(int p_index) const { Mesh::Mesh() { } -#if 0 -static Vector<uint8_t> _fix_array_compatibility(const Vector<uint8_t> &p_src, uint32_t p_format, uint32_t p_elements) { - enum ArrayType { - OLD_ARRAY_VERTEX = 0, - OLD_ARRAY_NORMAL = 1, - OLD_ARRAY_TANGENT = 2, - OLD_ARRAY_COLOR = 3, - OLD_ARRAY_TEX_UV = 4, - OLD_ARRAY_TEX_UV2 = 5, - OLD_ARRAY_BONES = 6, - OLD_ARRAY_WEIGHTS = 7, - OLD_ARRAY_INDEX = 8, - OLD_ARRAY_MAX = 9 - }; - - enum ArrayFormat { - /* OLD_ARRAY FORMAT FLAGS */ - OLD_ARRAY_FORMAT_VERTEX = 1 << OLD_ARRAY_VERTEX, // mandatory - OLD_ARRAY_FORMAT_NORMAL = 1 << OLD_ARRAY_NORMAL, - OLD_ARRAY_FORMAT_TANGENT = 1 << OLD_ARRAY_TANGENT, - OLD_ARRAY_FORMAT_COLOR = 1 << OLD_ARRAY_COLOR, - OLD_ARRAY_FORMAT_TEX_UV = 1 << OLD_ARRAY_TEX_UV, - OLD_ARRAY_FORMAT_TEX_UV2 = 1 << OLD_ARRAY_TEX_UV2, - OLD_ARRAY_FORMAT_BONES = 1 << OLD_ARRAY_BONES, - OLD_ARRAY_FORMAT_WEIGHTS = 1 << OLD_ARRAY_WEIGHTS, - OLD_ARRAY_FORMAT_INDEX = 1 << OLD_ARRAY_INDEX, - - OLD_ARRAY_COMPRESS_BASE = (OLD_ARRAY_INDEX + 1), - OLD_ARRAY_COMPRESS_NORMAL = 1 << (OLD_ARRAY_NORMAL + OLD_ARRAY_COMPRESS_BASE), - OLD_ARRAY_COMPRESS_TANGENT = 1 << (OLD_ARRAY_TANGENT + OLD_ARRAY_COMPRESS_BASE), - OLD_ARRAY_COMPRESS_COLOR = 1 << (OLD_ARRAY_COLOR + OLD_ARRAY_COMPRESS_BASE), - OLD_ARRAY_COMPRESS_TEX_UV = 1 << (OLD_ARRAY_TEX_UV + OLD_ARRAY_COMPRESS_BASE), - OLD_ARRAY_COMPRESS_TEX_UV2 = 1 << (OLD_ARRAY_TEX_UV2 + OLD_ARRAY_COMPRESS_BASE), - OLD_ARRAY_COMPRESS_INDEX = 1 << (OLD_ARRAY_INDEX + OLD_ARRAY_COMPRESS_BASE), - OLD_ARRAY_COMPRESS_DEFAULT = OLD_ARRAY_COMPRESS_NORMAL | OLD_ARRAY_COMPRESS_TANGENT | OLD_ARRAY_COMPRESS_COLOR | OLD_ARRAY_COMPRESS_TEX_UV | OLD_ARRAY_COMPRESS_TEX_UV2, - - OLD_ARRAY_FLAG_USE_2D_VERTICES = OLD_ARRAY_COMPRESS_INDEX << 1, - OLD_ARRAY_FLAG_USE_DYNAMIC_UPDATE = OLD_ARRAY_COMPRESS_INDEX << 3, - }; - - bool vertex_16bit = p_format & ((1 << (OLD_ARRAY_VERTEX + OLD_ARRAY_COMPRESS_BASE))); - bool has_bones = (p_format & OLD_ARRAY_FORMAT_BONES); - bool bone_8 = has_bones && !(p_format & (OLD_ARRAY_COMPRESS_INDEX << 2)); - bool weight_32 = has_bones && !(p_format & (OLD_ARRAY_COMPRESS_TEX_UV2 << 2)); - - print_line("convert vertex16: " + itos(vertex_16bit) + " convert bone 8 " + itos(bone_8) + " convert weight 32 " + itos(weight_32)); - - if (!vertex_16bit && !bone_8 && !weight_32) { - return p_src; - } +enum OldArrayType { + OLD_ARRAY_VERTEX, + OLD_ARRAY_NORMAL, + OLD_ARRAY_TANGENT, + OLD_ARRAY_COLOR, + OLD_ARRAY_TEX_UV, + OLD_ARRAY_TEX_UV2, + OLD_ARRAY_BONES, + OLD_ARRAY_WEIGHTS, + OLD_ARRAY_INDEX, + OLD_ARRAY_MAX, +}; - bool vertex_2d = (p_format & (OLD_ARRAY_COMPRESS_INDEX << 1)); +enum OldArrayFormat { + /* OLD_ARRAY FORMAT FLAGS */ + OLD_ARRAY_FORMAT_VERTEX = 1 << OLD_ARRAY_VERTEX, // mandatory + OLD_ARRAY_FORMAT_NORMAL = 1 << OLD_ARRAY_NORMAL, + OLD_ARRAY_FORMAT_TANGENT = 1 << OLD_ARRAY_TANGENT, + OLD_ARRAY_FORMAT_COLOR = 1 << OLD_ARRAY_COLOR, + OLD_ARRAY_FORMAT_TEX_UV = 1 << OLD_ARRAY_TEX_UV, + OLD_ARRAY_FORMAT_TEX_UV2 = 1 << OLD_ARRAY_TEX_UV2, + OLD_ARRAY_FORMAT_BONES = 1 << OLD_ARRAY_BONES, + OLD_ARRAY_FORMAT_WEIGHTS = 1 << OLD_ARRAY_WEIGHTS, + OLD_ARRAY_FORMAT_INDEX = 1 << OLD_ARRAY_INDEX, + + OLD_ARRAY_COMPRESS_BASE = (OLD_ARRAY_INDEX + 1), + OLD_ARRAY_COMPRESS_VERTEX = 1 << (OLD_ARRAY_VERTEX + OLD_ARRAY_COMPRESS_BASE), // mandatory + OLD_ARRAY_COMPRESS_NORMAL = 1 << (OLD_ARRAY_NORMAL + OLD_ARRAY_COMPRESS_BASE), + OLD_ARRAY_COMPRESS_TANGENT = 1 << (OLD_ARRAY_TANGENT + OLD_ARRAY_COMPRESS_BASE), + OLD_ARRAY_COMPRESS_COLOR = 1 << (OLD_ARRAY_COLOR + OLD_ARRAY_COMPRESS_BASE), + OLD_ARRAY_COMPRESS_TEX_UV = 1 << (OLD_ARRAY_TEX_UV + OLD_ARRAY_COMPRESS_BASE), + OLD_ARRAY_COMPRESS_TEX_UV2 = 1 << (OLD_ARRAY_TEX_UV2 + OLD_ARRAY_COMPRESS_BASE), + OLD_ARRAY_COMPRESS_BONES = 1 << (OLD_ARRAY_BONES + OLD_ARRAY_COMPRESS_BASE), + OLD_ARRAY_COMPRESS_WEIGHTS = 1 << (OLD_ARRAY_WEIGHTS + OLD_ARRAY_COMPRESS_BASE), + OLD_ARRAY_COMPRESS_INDEX = 1 << (OLD_ARRAY_INDEX + OLD_ARRAY_COMPRESS_BASE), + + OLD_ARRAY_FLAG_USE_2D_VERTICES = OLD_ARRAY_COMPRESS_INDEX << 1, + OLD_ARRAY_FLAG_USE_16_BIT_BONES = OLD_ARRAY_COMPRESS_INDEX << 2, + OLD_ARRAY_FLAG_USE_DYNAMIC_UPDATE = OLD_ARRAY_COMPRESS_INDEX << 3, - uint32_t src_stride = p_src.size() / p_elements; - uint32_t dst_stride = src_stride + (vertex_16bit ? 4 : 0) + (bone_8 ? 4 : 0) - (weight_32 ? 8 : 0); +}; - Vector<uint8_t> ret = p_src; +static Array _convert_old_array(const Array &p_old) { + Array new_array; + new_array.resize(Mesh::ARRAY_MAX); + new_array[Mesh::ARRAY_VERTEX] = p_old[OLD_ARRAY_VERTEX]; + new_array[Mesh::ARRAY_NORMAL] = p_old[OLD_ARRAY_NORMAL]; + new_array[Mesh::ARRAY_TANGENT] = p_old[OLD_ARRAY_TANGENT]; + new_array[Mesh::ARRAY_COLOR] = p_old[OLD_ARRAY_COLOR]; + new_array[Mesh::ARRAY_TEX_UV] = p_old[OLD_ARRAY_TEX_UV]; + new_array[Mesh::ARRAY_TEX_UV2] = p_old[OLD_ARRAY_TEX_UV2]; + new_array[Mesh::ARRAY_BONES] = p_old[OLD_ARRAY_BONES]; + new_array[Mesh::ARRAY_WEIGHTS] = p_old[OLD_ARRAY_WEIGHTS]; + new_array[Mesh::ARRAY_INDEX] = p_old[OLD_ARRAY_INDEX]; + return new_array; +} + +static Mesh::PrimitiveType _old_primitives[7] = { + Mesh::PRIMITIVE_POINTS, + Mesh::PRIMITIVE_LINES, + Mesh::PRIMITIVE_LINE_STRIP, + Mesh::PRIMITIVE_LINES, + Mesh::PRIMITIVE_TRIANGLES, + Mesh::PRIMITIVE_TRIANGLE_STRIP, + Mesh::PRIMITIVE_TRIANGLE_STRIP +}; - ret.resize(dst_stride * p_elements); - { - uint8_t *w = ret.ptrw(); - const uint8_t *r = p_src.ptr(); - - for (uint32_t i = 0; i < p_elements; i++) { - uint32_t remaining = src_stride; - const uint8_t *src = (const uint8_t *)(r + src_stride * i); - uint8_t *dst = (uint8_t *)(w + dst_stride * i); - - if (!vertex_2d) { //3D - if (vertex_16bit) { - float *dstw = (float *)dst; - const uint16_t *srcr = (const uint16_t *)src; - dstw[0] = Math::half_to_float(srcr[0]); - dstw[1] = Math::half_to_float(srcr[1]); - dstw[2] = Math::half_to_float(srcr[2]); - remaining -= 8; - src += 8; +void _fix_array_compatibility(const Vector<uint8_t> &p_src, uint32_t p_old_format, uint32_t p_new_format, uint32_t p_elements, Vector<uint8_t> &vertex_data, Vector<uint8_t> &attribute_data, Vector<uint8_t> &skin_data) { + uint32_t dst_vertex_stride; + uint32_t dst_attribute_stride; + uint32_t dst_skin_stride; + uint32_t dst_offsets[Mesh::ARRAY_MAX]; + RenderingServer::get_singleton()->mesh_surface_make_offsets_from_format(p_new_format & (~RS::ARRAY_FORMAT_INDEX), p_elements, 0, dst_offsets, dst_vertex_stride, dst_attribute_stride, dst_skin_stride); + + vertex_data.resize(dst_vertex_stride * p_elements); + attribute_data.resize(dst_attribute_stride * p_elements); + skin_data.resize(dst_skin_stride * p_elements); + + uint8_t *dst_vertex_ptr = vertex_data.ptrw(); + uint8_t *dst_attribute_ptr = attribute_data.ptrw(); + uint8_t *dst_skin_ptr = skin_data.ptrw(); + + const uint8_t *src_vertex_ptr = p_src.ptr(); + uint32_t src_vertex_stride = p_src.size() / p_elements; + + uint32_t src_offset = 0; + for (uint32_t j = 0; j < OLD_ARRAY_INDEX; j++) { + if (!(p_old_format & (1 << j))) { + continue; + } + switch (j) { + case OLD_ARRAY_VERTEX: { + if (p_old_format & OLD_ARRAY_FLAG_USE_2D_VERTICES) { + if (p_old_format & OLD_ARRAY_COMPRESS_VERTEX) { + for (uint32_t i = 0; i < p_elements; i++) { + const uint16_t *src = (const uint16_t *)&src_vertex_ptr[i * src_vertex_stride]; + float *dst = (float *)&dst_vertex_ptr[i * dst_vertex_stride]; + dst[0] = Math::half_to_float(src[0]); + dst[1] = Math::half_to_float(src[1]); + } + src_offset += sizeof(uint16_t) * 2; + } else { + for (uint32_t i = 0; i < p_elements; i++) { + const float *src = (const float *)&src_vertex_ptr[i * src_vertex_stride]; + float *dst = (float *)&dst_vertex_ptr[i * dst_vertex_stride]; + dst[0] = src[0]; + dst[1] = src[1]; + } + src_offset += sizeof(float) * 2; + } } else { - src += 12; - remaining -= 12; + if (p_old_format & OLD_ARRAY_COMPRESS_VERTEX) { + for (uint32_t i = 0; i < p_elements; i++) { + const uint16_t *src = (const uint16_t *)&src_vertex_ptr[i * src_vertex_stride]; + float *dst = (float *)&dst_vertex_ptr[i * dst_vertex_stride]; + dst[0] = Math::half_to_float(src[0]); + dst[1] = Math::half_to_float(src[1]); + dst[2] = Math::half_to_float(src[2]); + } + src_offset += sizeof(uint16_t) * 4; //+pad + } else { + for (uint32_t i = 0; i < p_elements; i++) { + const float *src = (const float *)&src_vertex_ptr[i * src_vertex_stride]; + float *dst = (float *)&dst_vertex_ptr[i * dst_vertex_stride]; + dst[0] = src[0]; + dst[1] = src[1]; + dst[2] = src[2]; + } + src_offset += sizeof(float) * 3; + } } - dst += 12; - } else { - if (vertex_16bit) { - float *dstw = (float *)dst; - const uint16_t *srcr = (const uint16_t *)src; - dstw[0] = Math::half_to_float(srcr[0]); - dstw[1] = Math::half_to_float(srcr[1]); - remaining -= 4; - src += 4; + } break; + case OLD_ARRAY_NORMAL: { + if (p_old_format & OLD_ARRAY_COMPRESS_NORMAL) { + const float multiplier = 1.f / 127.f * 1023.0f; + + for (uint32_t i = 0; i < p_elements; i++) { + const int8_t *src = (const int8_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; + uint32_t *dst = (uint32_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_NORMAL]]; + + *dst = 0; + *dst |= CLAMP(int(src[0] * multiplier), 0, 1023); + *dst |= CLAMP(int(src[1] * multiplier), 0, 1023) << 10; + *dst |= CLAMP(int(src[2] * multiplier), 0, 1023) << 20; + } + src_offset += sizeof(uint32_t); } else { - src += 8; - remaining -= 8; + for (uint32_t i = 0; i < p_elements; i++) { + const float *src = (const float *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; + uint32_t *dst = (uint32_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_NORMAL]]; + + *dst = 0; + *dst |= CLAMP(int(src[0] * 1023.0), 0, 1023); + *dst |= CLAMP(int(src[1] * 1023.0), 0, 1023) << 10; + *dst |= CLAMP(int(src[2] * 1023.0), 0, 1023) << 20; + } + src_offset += sizeof(float) * 3; } - dst += 8; - } - - if (has_bones) { - remaining -= bone_8 ? 4 : 8; - remaining -= weight_32 ? 16 : 8; - } - - for (uint32_t j = 0; j < remaining; j++) { - dst[j] = src[j]; - } - - if (has_bones) { - dst += remaining; - src += remaining; - if (bone_8) { - const uint8_t *src_bones = (const uint8_t *)src; - uint16_t *dst_bones = (uint16_t *)dst; + } break; + case OLD_ARRAY_TANGENT: { + if (p_old_format & OLD_ARRAY_COMPRESS_TANGENT) { + const float multiplier = 1.f / 127.f * 1023.0f; + + for (uint32_t i = 0; i < p_elements; i++) { + const int8_t *src = (const int8_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; + uint32_t *dst = (uint32_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_TANGENT]]; + + *dst = 0; + *dst |= CLAMP(int(src[0] * multiplier), 0, 1023); + *dst |= CLAMP(int(src[1] * multiplier), 0, 1023) << 10; + *dst |= CLAMP(int(src[2] * multiplier), 0, 1023) << 20; + if (src[3] > 0) { + *dst |= 3 << 30; + } + } + src_offset += sizeof(uint32_t); + } else { + for (uint32_t i = 0; i < p_elements; i++) { + const float *src = (const float *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; + uint32_t *dst = (uint32_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_TANGENT]]; + + *dst = 0; + *dst |= CLAMP(int(src[0] * 1023.0), 0, 1023); + *dst |= CLAMP(int(src[1] * 1023.0), 0, 1023) << 10; + *dst |= CLAMP(int(src[2] * 1023.0), 0, 1023) << 20; + if (src[3] > 0) { + *dst |= 3 << 30; + } + } + src_offset += sizeof(float) * 4; + } - dst_bones[0] = src_bones[0]; - dst_bones[1] = src_bones[1]; - dst_bones[2] = src_bones[2]; - dst_bones[3] = src_bones[3]; + } break; + case OLD_ARRAY_COLOR: { + if (p_old_format & OLD_ARRAY_COMPRESS_COLOR) { + for (uint32_t i = 0; i < p_elements; i++) { + const uint32_t *src = (const uint32_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; + uint32_t *dst = (uint32_t *)&dst_attribute_ptr[i * dst_attribute_stride + dst_offsets[Mesh::ARRAY_COLOR]]; - src += 4; + *dst = *src; + } + src_offset += sizeof(uint32_t); } else { - for (uint32_t j = 0; j < 8; j++) { - dst[j] = src[j]; + for (uint32_t i = 0; i < p_elements; i++) { + const float *src = (const float *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; + uint8_t *dst = (uint8_t *)&dst_attribute_ptr[i * dst_attribute_stride + dst_offsets[Mesh::ARRAY_COLOR]]; + + dst[0] = uint8_t(CLAMP(src[0] * 255.0, 0.0, 255.0)); + dst[1] = uint8_t(CLAMP(src[1] * 255.0, 0.0, 255.0)); + dst[2] = uint8_t(CLAMP(src[2] * 255.0, 0.0, 255.0)); + dst[3] = uint8_t(CLAMP(src[3] * 255.0, 0.0, 255.0)); } - - src += 8; + src_offset += sizeof(float) * 4; } + } break; + case OLD_ARRAY_TEX_UV: { + if (p_old_format & OLD_ARRAY_COMPRESS_TEX_UV) { + for (uint32_t i = 0; i < p_elements; i++) { + const uint16_t *src = (const uint16_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; + float *dst = (float *)&dst_attribute_ptr[i * dst_attribute_stride + dst_offsets[Mesh::ARRAY_TEX_UV]]; + + dst[0] = Math::half_to_float(src[0]); + dst[1] = Math::half_to_float(src[1]); + } + src_offset += sizeof(uint16_t) * 2; + } else { + for (uint32_t i = 0; i < p_elements; i++) { + const float *src = (const float *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; + float *dst = (float *)&dst_attribute_ptr[i * dst_attribute_stride + dst_offsets[Mesh::ARRAY_TEX_UV]]; - dst += 8; + dst[0] = src[0]; + dst[1] = src[1]; + } + src_offset += sizeof(float) * 2; + } - if (weight_32) { - const float *src_weights = (const float *)src; - uint16_t *dst_weights = (uint16_t *)dst; + } break; + case OLD_ARRAY_TEX_UV2: { + if (p_old_format & OLD_ARRAY_COMPRESS_TEX_UV2) { + for (uint32_t i = 0; i < p_elements; i++) { + const uint16_t *src = (const uint16_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; + float *dst = (float *)&dst_attribute_ptr[i * dst_attribute_stride + dst_offsets[Mesh::ARRAY_TEX_UV2]]; - dst_weights[0] = CLAMP(src_weights[0] * 65535, 0, 65535); //16bits unorm - dst_weights[1] = CLAMP(src_weights[1] * 65535, 0, 65535); - dst_weights[2] = CLAMP(src_weights[2] * 65535, 0, 65535); - dst_weights[3] = CLAMP(src_weights[3] * 65535, 0, 65535); + dst[0] = Math::half_to_float(src[0]); + dst[1] = Math::half_to_float(src[1]); + } + src_offset += sizeof(uint16_t) * 2; + } else { + for (uint32_t i = 0; i < p_elements; i++) { + const float *src = (const float *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; + float *dst = (float *)&dst_attribute_ptr[i * dst_attribute_stride + dst_offsets[Mesh::ARRAY_TEX_UV2]]; + dst[0] = src[0]; + dst[1] = src[1]; + } + src_offset += sizeof(float) * 2; + } + } break; + case OLD_ARRAY_BONES: { + if (p_old_format & OLD_ARRAY_FLAG_USE_16_BIT_BONES) { + for (uint32_t i = 0; i < p_elements; i++) { + const uint16_t *src = (const uint16_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; + uint16_t *dst = (uint16_t *)&dst_skin_ptr[i * dst_skin_stride + dst_offsets[Mesh::ARRAY_BONES]]; + + dst[0] = src[0]; + dst[1] = src[1]; + dst[2] = src[2]; + dst[3] = src[3]; + } + src_offset += sizeof(uint16_t) * 4; } else { - for (uint32_t j = 0; j < 8; j++) { - dst[j] = src[j]; + for (uint32_t i = 0; i < p_elements; i++) { + const uint8_t *src = (const uint8_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; + uint16_t *dst = (uint16_t *)&dst_skin_ptr[i * dst_skin_stride + dst_offsets[Mesh::ARRAY_BONES]]; + + dst[0] = src[0]; + dst[1] = src[1]; + dst[2] = src[2]; + dst[3] = src[3]; } + src_offset += sizeof(uint8_t) * 4; } + } break; + case OLD_ARRAY_WEIGHTS: { + if (p_old_format & OLD_ARRAY_COMPRESS_WEIGHTS) { + for (uint32_t i = 0; i < p_elements; i++) { + const uint16_t *src = (const uint16_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; + uint16_t *dst = (uint16_t *)&dst_skin_ptr[i * dst_skin_stride + dst_offsets[Mesh::ARRAY_WEIGHTS]]; + + dst[0] = src[0]; + dst[1] = src[1]; + dst[2] = src[2]; + dst[3] = src[3]; + } + src_offset += sizeof(uint16_t) * 4; + } else { + for (uint32_t i = 0; i < p_elements; i++) { + const float *src = (const float *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; + uint16_t *dst = (uint16_t *)&dst_skin_ptr[i * dst_skin_stride + dst_offsets[Mesh::ARRAY_WEIGHTS]]; + + dst[0] = uint16_t(CLAMP(src[0] * 65535.0, 0, 65535.0)); + dst[1] = uint16_t(CLAMP(src[1] * 65535.0, 0, 65535.0)); + dst[2] = uint16_t(CLAMP(src[2] * 65535.0, 0, 65535.0)); + dst[3] = uint16_t(CLAMP(src[3] * 65535.0, 0, 65535.0)); + } + src_offset += sizeof(float) * 4; + } + } break; + default: { } } } - - return ret; } -#endif bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) { String sname = p_name; @@ -779,10 +942,13 @@ bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) { if (d.has("arrays")) { //oldest format (2.x) ERR_FAIL_COND_V(!d.has("morph_arrays"), false); - add_surface_from_arrays(PrimitiveType(int(d["primitive"])), d["arrays"], d["morph_arrays"]); + Array morph_arrays = d["morph_arrays"]; + for (int i = 0; i < morph_arrays.size(); i++) { + morph_arrays[i] = _convert_old_array(morph_arrays[i]); + } + add_surface_from_arrays(_old_primitives[int(d["primitive"])], _convert_old_array(d["arrays"]), morph_arrays); } else if (d.has("array_data")) { -#if 0 //print_line("array data (old style"); //older format (3.x) Vector<uint8_t> array_data = d["array_data"]; @@ -792,48 +958,76 @@ bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) { } ERR_FAIL_COND_V(!d.has("format"), false); - uint32_t format = d["format"]; + uint32_t old_format = d["format"]; uint32_t primitive = d["primitive"]; - uint32_t primitive_remap[7] = { - PRIMITIVE_POINTS, - PRIMITIVE_LINES, - PRIMITIVE_LINE_STRIP, - PRIMITIVE_LINES, - PRIMITIVE_TRIANGLES, - PRIMITIVE_TRIANGLE_STRIP, - PRIMITIVE_TRIANGLE_STRIP - }; - - primitive = primitive_remap[primitive]; //compatibility + primitive = _old_primitives[primitive]; //compatibility ERR_FAIL_COND_V(!d.has("vertex_count"), false); int vertex_count = d["vertex_count"]; - array_data = _fix_array_compatibility(array_data, format, vertex_count); + uint32_t new_format = ARRAY_FORMAT_VERTEX; + + if (old_format & OLD_ARRAY_FORMAT_NORMAL) { + new_format |= ARRAY_FORMAT_NORMAL; + } + if (old_format & OLD_ARRAY_FORMAT_TANGENT) { + new_format |= ARRAY_FORMAT_TANGENT; + } + if (old_format & OLD_ARRAY_FORMAT_COLOR) { + new_format |= ARRAY_FORMAT_COLOR; + } + if (old_format & OLD_ARRAY_FORMAT_TEX_UV) { + new_format |= ARRAY_FORMAT_TEX_UV; + } + if (old_format & OLD_ARRAY_FORMAT_TEX_UV2) { + new_format |= ARRAY_FORMAT_TEX_UV2; + } + if (old_format & OLD_ARRAY_FORMAT_BONES) { + new_format |= ARRAY_FORMAT_BONES; + } + if (old_format & OLD_ARRAY_FORMAT_WEIGHTS) { + new_format |= ARRAY_FORMAT_WEIGHTS; + } + if (old_format & OLD_ARRAY_FORMAT_INDEX) { + new_format |= ARRAY_FORMAT_INDEX; + } + if (old_format & OLD_ARRAY_FLAG_USE_2D_VERTICES) { + new_format |= OLD_ARRAY_FLAG_USE_2D_VERTICES; + } + + Vector<uint8_t> vertex_array; + Vector<uint8_t> attribute_array; + Vector<uint8_t> skin_array; + + _fix_array_compatibility(array_data, old_format, new_format, vertex_count, vertex_array, attribute_array, skin_array); int index_count = 0; if (d.has("index_count")) { index_count = d["index_count"]; } - Vector<Vector<uint8_t>> blend_shapes; + Vector<uint8_t> blend_shapes; if (d.has("blend_shape_data")) { Array blend_shape_data = d["blend_shape_data"]; for (int i = 0; i < blend_shape_data.size(); i++) { + Vector<uint8_t> blend_vertex_array; + Vector<uint8_t> blend_attribute_array; + Vector<uint8_t> blend_skin_array; + Vector<uint8_t> shape = blend_shape_data[i]; - shape = _fix_array_compatibility(shape, format, vertex_count); + _fix_array_compatibility(shape, old_format, new_format, vertex_count, blend_vertex_array, blend_attribute_array, blend_skin_array); - blend_shapes.push_back(shape); + blend_shapes.append_array(blend_vertex_array); } } //clear unused flags - print_line("format pre: " + itos(format)); - format &= ~uint32_t((1 << (ARRAY_VERTEX + ARRAY_COMPRESS_BASE)) | (ARRAY_COMPRESS_INDEX << 2) | (ARRAY_COMPRESS_TEX_UV2 << 2)); - print_line("format post: " + itos(format)); + print_line("format pre: " + itos(old_format)); + + print_line("format post: " + itos(new_format)); ERR_FAIL_COND_V(!d.has("aabb"), false); AABB aabb = d["aabb"]; @@ -848,8 +1042,8 @@ bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) { } } - add_surface(format, PrimitiveType(primitive), array_data, vertex_count, array_index_data, index_count, aabb, blend_shapes, bone_aabb); -#endif + add_surface(new_format, PrimitiveType(primitive), vertex_array, attribute_array, skin_array, vertex_count, array_index_data, index_count, aabb, blend_shapes, bone_aabb); + } else { ERR_FAIL_V(false); } diff --git a/servers/rendering/rasterizer_dummy.h b/servers/rendering/rasterizer_dummy.h index 3d4cca3586..f22ca738ae 100644 --- a/servers/rendering/rasterizer_dummy.h +++ b/servers/rendering/rasterizer_dummy.h @@ -36,6 +36,7 @@ #include "core/templates/self_list.h" #include "scene/resources/mesh.h" #include "servers/rendering/renderer_compositor.h" +#include "servers/rendering/renderer_scene_render.h" #include "servers/rendering_server.h" class RasterizerSceneDummy : public RendererSceneRender { @@ -175,7 +176,7 @@ public: void voxel_gi_set_quality(RS::VoxelGIQuality) override {} - void render_scene(RID p_render_buffers, const CameraData *p_camera_data, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr) override {} + void render_scene(RID p_render_buffers, const CameraData *p_camera_data, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RendererScene::RenderInfo *r_info = nullptr) override {} void render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override {} void render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<GeometryInstance *> &p_instances) override {} @@ -662,17 +663,15 @@ public: return true; } + virtual void update_memory_info() override {} + virtual uint64_t get_rendering_info(RS::RenderingInfo p_info) override { return 0; } + bool has_os_feature(const String &p_feature) const override { return false; } void update_dirty_resources() override {} void set_debug_generate_wireframes(bool p_generate) override {} - void render_info_begin_capture() override {} - void render_info_end_capture() override {} - int get_captured_render_info(RS::RenderInfo p_info) override { return 0; } - - uint64_t get_render_info(RS::RenderInfo p_info) override { return 0; } String get_video_adapter_name() const override { return String(); } String get_video_adapter_vendor() const override { return String(); } diff --git a/servers/rendering/renderer_compositor.h b/servers/rendering/renderer_compositor.h index eabdebf4b3..5fe9cdffba 100644 --- a/servers/rendering/renderer_compositor.h +++ b/servers/rendering/renderer_compositor.h @@ -36,10 +36,9 @@ #include "core/templates/self_list.h" #include "servers/rendering/renderer_canvas_render.h" #include "servers/rendering/renderer_scene.h" -#include "servers/rendering/renderer_scene_render.h" #include "servers/rendering/renderer_storage.h" #include "servers/rendering_server.h" - +class RendererSceneRender; struct BlitToScreen { RID render_target; Rect2i rect; diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp index b66b9b597c..2c913ca295 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp @@ -801,13 +801,16 @@ void RenderForwardClustered::_update_instance_data_buffer(RenderListType p_rende RD::get_singleton()->buffer_update(scene_state.instance_buffer[p_render_list], 0, sizeof(SceneState::InstanceData) * scene_state.instance_data[p_render_list].size(), scene_state.instance_data[p_render_list].ptr(), RD::BARRIER_MASK_RASTER); } } -void RenderForwardClustered::_fill_instance_data(RenderListType p_render_list, uint32_t p_offset, int32_t p_max_elements, bool p_update_buffer) { +void RenderForwardClustered::_fill_instance_data(RenderListType p_render_list, int *p_render_info, uint32_t p_offset, int32_t p_max_elements, bool p_update_buffer) { RenderList *rl = &render_list[p_render_list]; uint32_t element_total = p_max_elements >= 0 ? uint32_t(p_max_elements) : rl->elements.size(); scene_state.instance_data[p_render_list].resize(p_offset + element_total); rl->element_info.resize(p_offset + element_total); + if (p_render_info) { + p_render_info[RS::VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME] += element_total; + } uint32_t repeats = 0; GeometryInstanceSurfaceDataCache *prev_surface = nullptr; for (uint32_t i = 0; i < element_total; i++) { @@ -843,6 +846,9 @@ void RenderForwardClustered::_fill_instance_data(RenderListType p_render_list, u } } repeats = 1; + if (p_render_info) { + p_render_info[RS::VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME]++; + } } RenderElementInfo &element_info = rl->element_info[p_offset + i]; @@ -869,6 +875,11 @@ void RenderForwardClustered::_fill_instance_data(RenderListType p_render_list, u } } +_FORCE_INLINE_ static uint32_t _indices_to_primitives(RS::PrimitiveType p_primitive, uint32_t p_indices) { + static const uint32_t divisor[RS::PRIMITIVE_MAX] = { 1, 2, 1, 3, 1 }; + static const uint32_t subtractor[RS::PRIMITIVE_MAX] = { 0, 0, 1, 0, 1 }; + return (p_indices - subtractor[p_primitive]) / divisor[p_primitive]; +} void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, const RenderDataRD *p_render_data, PassMode p_pass_mode, bool p_using_sdfgi, bool p_using_opaque_gi, bool p_append) { if (p_render_list == RENDER_LIST_OPAQUE) { scene_state.used_sss = false; @@ -1011,9 +1022,28 @@ void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, con distance = -distance_max; } - surf->sort.lod_index = storage->mesh_surface_get_lod(surf->surface, inst->lod_model_scale * inst->lod_bias, distance * p_render_data->lod_distance_multiplier, p_render_data->screen_lod_threshold); + uint32_t indices; + surf->sort.lod_index = storage->mesh_surface_get_lod(surf->surface, inst->lod_model_scale * inst->lod_bias, distance * p_render_data->lod_distance_multiplier, p_render_data->screen_lod_threshold, &indices); + if (p_render_data->render_info) { + indices = _indices_to_primitives(surf->primitive, indices); + if (p_render_list == RENDER_LIST_OPAQUE) { //opaque + p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += indices; + } else if (p_render_list == RENDER_LIST_SECONDARY) { //shadow + p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_SHADOW][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += indices; + } + } } else { surf->sort.lod_index = 0; + if (p_render_data->render_info) { + uint32_t to_draw = storage->mesh_surface_get_vertices_drawn_count(surf->surface); + to_draw = _indices_to_primitives(surf->primitive, to_draw); + to_draw *= inst->instance_count; + if (p_render_list == RENDER_LIST_OPAQUE) { //opaque + p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += storage->mesh_surface_get_vertices_drawn_count(surf->surface); + } else if (p_render_list == RENDER_LIST_SECONDARY) { //shadow + p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_SHADOW][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += storage->mesh_surface_get_vertices_drawn_count(surf->surface); + } + } } // ADD Element @@ -1213,7 +1243,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co _fill_render_list(RENDER_LIST_OPAQUE, p_render_data, PASS_MODE_COLOR, using_sdfgi, using_sdfgi || using_voxelgi); render_list[RENDER_LIST_OPAQUE].sort_by_key(); render_list[RENDER_LIST_ALPHA].sort_by_depth(); - _fill_instance_data(RENDER_LIST_OPAQUE); + _fill_instance_data(RENDER_LIST_OPAQUE, p_render_data->render_info ? p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE] : (int *)nullptr); _fill_instance_data(RENDER_LIST_ALPHA); RD::get_singleton()->draw_command_end_label(); @@ -1506,7 +1536,7 @@ void RenderForwardClustered::_render_shadow_begin() { scene_state.instance_data[RENDER_LIST_SECONDARY].clear(); } -void RenderForwardClustered::_render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold, const Rect2i &p_rect, bool p_flip_y, bool p_clear_region, bool p_begin, bool p_end) { +void RenderForwardClustered::_render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold, const Rect2i &p_rect, bool p_flip_y, bool p_clear_region, bool p_begin, bool p_end, RendererScene::RenderInfo *p_render_info) { uint32_t shadow_pass_index = scene_state.shadow_passes.size(); SceneState::ShadowPass shadow_pass; @@ -1521,6 +1551,7 @@ void RenderForwardClustered::_render_shadow_append(RID p_framebuffer, const Page render_data.instances = &p_instances; render_data.lod_camera_plane = p_camera_plane; render_data.lod_distance_multiplier = p_lod_distance_multiplier; + render_data.render_info = p_render_info; scene_state.ubo.dual_paraboloid_side = p_use_dp_flip ? -1 : 1; @@ -1538,7 +1569,7 @@ void RenderForwardClustered::_render_shadow_append(RID p_framebuffer, const Page _fill_render_list(RENDER_LIST_SECONDARY, &render_data, pass_mode, false, false, true); uint32_t render_list_size = render_list[RENDER_LIST_SECONDARY].elements.size() - render_list_from; render_list[RENDER_LIST_SECONDARY].sort_by_key_range(render_list_from, render_list_size); - _fill_instance_data(RENDER_LIST_SECONDARY, render_list_from, render_list_size, false); + _fill_instance_data(RENDER_LIST_SECONDARY, p_render_info ? p_render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_SHADOW] : (int *)nullptr, render_list_from, render_list_size, false); { //regular forward for now diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h index 97b7124cc1..6cb9fea91a 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h @@ -371,7 +371,7 @@ class RenderForwardClustered : public RendererSceneRenderRD { uint32_t render_list_thread_threshold = 500; void _update_instance_data_buffer(RenderListType p_render_list); - void _fill_instance_data(RenderListType p_render_list, uint32_t p_offset = 0, int32_t p_max_elements = -1, bool p_update_buffer = true); + void _fill_instance_data(RenderListType p_render_list, int *p_render_info = nullptr, uint32_t p_offset = 0, int32_t p_max_elements = -1, bool p_update_buffer = true); void _fill_render_list(RenderListType p_render_list, const RenderDataRD *p_render_data, PassMode p_pass_mode, bool p_using_sdfgi = false, bool p_using_opaque_gi = false, bool p_append = false); Map<Size2i, RID> sdfgi_framebuffer_size_cache; @@ -568,7 +568,7 @@ protected: virtual void _render_scene(RenderDataRD *p_render_data, const Color &p_default_bg_color) override; virtual void _render_shadow_begin() override; - virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true) override; + virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RendererScene::RenderInfo *p_render_info = nullptr) override; virtual void _render_shadow_process() override; virtual void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL) override; diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp index fdcf4394a7..10dce7ff0f 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp @@ -335,6 +335,11 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color bool using_ssr = false; bool using_sss = false; + if (p_render_data->render_info) { + p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE][RS::VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME] = p_render_data->instances->size(); + p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE][RS::VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME] = p_render_data->instances->size(); + } + if (render_buffer) { // setup rendering to render buffer screen_size.x = render_buffer->width; @@ -555,11 +560,15 @@ void RenderForwardMobile::_render_shadow_begin() { render_list[RENDER_LIST_SECONDARY].clear(); } -void RenderForwardMobile::_render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold, const Rect2i &p_rect, bool p_flip_y, bool p_clear_region, bool p_begin, bool p_end) { +void RenderForwardMobile::_render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold, const Rect2i &p_rect, bool p_flip_y, bool p_clear_region, bool p_begin, bool p_end, RendererScene::RenderInfo *p_render_info) { uint32_t shadow_pass_index = scene_state.shadow_passes.size(); SceneState::ShadowPass shadow_pass; + if (p_render_info) { + p_render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_SHADOW][RS::VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME] = p_instances.size(); + p_render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_SHADOW][RS::VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME] = p_instances.size(); + } RenderDataRD render_data; render_data.cam_projection = p_projection; render_data.cam_transform = p_transform; @@ -567,6 +576,7 @@ void RenderForwardMobile::_render_shadow_append(RID p_framebuffer, const PagedAr render_data.z_near = 0.0; render_data.z_far = p_zfar; render_data.instances = &p_instances; + render_data.render_info = p_render_info; render_data.lod_camera_plane = p_camera_plane; render_data.lod_distance_multiplier = p_lod_distance_multiplier; @@ -927,6 +937,12 @@ RID RenderForwardMobile::_render_buffers_get_normal_texture(RID p_render_buffers return RID(); } +_FORCE_INLINE_ static uint32_t _indices_to_primitives(RS::PrimitiveType p_primitive, uint32_t p_indices) { + static const uint32_t divisor[RS::PRIMITIVE_MAX] = { 1, 2, 1, 3, 1 }; + static const uint32_t subtractor[RS::PRIMITIVE_MAX] = { 0, 0, 1, 0, 1 }; + return (p_indices - subtractor[p_primitive]) / divisor[p_primitive]; +} + void RenderForwardMobile::_fill_render_list(RenderListType p_render_list, const RenderDataRD *p_render_data, PassMode p_pass_mode, bool p_append) { if (p_render_list == RENDER_LIST_OPAQUE) { scene_state.used_sss = false; @@ -1036,9 +1052,28 @@ void RenderForwardMobile::_fill_render_list(RenderListType p_render_list, const distance = -distance_max; } - surf->lod_index = storage->mesh_surface_get_lod(surf->surface, inst->lod_model_scale * inst->lod_bias, distance * p_render_data->lod_distance_multiplier, p_render_data->screen_lod_threshold); + uint32_t indices; + surf->lod_index = storage->mesh_surface_get_lod(surf->surface, inst->lod_model_scale * inst->lod_bias, distance * p_render_data->lod_distance_multiplier, p_render_data->screen_lod_threshold, &indices); + if (p_render_data->render_info) { + indices = _indices_to_primitives(surf->primitive, indices); + if (p_render_list == RENDER_LIST_OPAQUE) { //opaque + p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += indices; + } else if (p_render_list == RENDER_LIST_SECONDARY) { //shadow + p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_SHADOW][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += indices; + } + } } else { surf->lod_index = 0; + if (p_render_data->render_info) { + uint32_t to_draw = storage->mesh_surface_get_vertices_drawn_count(surf->surface); + to_draw = _indices_to_primitives(surf->primitive, to_draw); + to_draw *= inst->instance_count; + if (p_render_list == RENDER_LIST_OPAQUE) { //opaque + p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += storage->mesh_surface_get_vertices_drawn_count(surf->surface); + } else if (p_render_list == RENDER_LIST_SECONDARY) { //shadow + p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_SHADOW][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += storage->mesh_surface_get_vertices_drawn_count(surf->surface); + } + } } // ADD Element diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h index b51a58295d..d5c0cca6c7 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h @@ -155,7 +155,7 @@ protected: virtual void _render_scene(RenderDataRD *p_render_data, const Color &p_default_bg_color) override; virtual void _render_shadow_begin() override; - virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true) override; + virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RendererScene::RenderInfo *p_render_info = nullptr) override; virtual void _render_shadow_process() override; virtual void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL) override; diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index 089651cbfb..44ca17e273 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -3522,7 +3522,6 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool Plane camera_plane(p_render_data->cam_transform.origin, -p_render_data->cam_transform.basis.get_axis(Vector3::AXIS_Z)); float lod_distance_multiplier = p_render_data->cam_projection.get_lod_multiplier(); - { for (int i = 0; i < render_state.render_shadow_count; i++) { LightInstance *li = light_instance_owner.getornull(render_state.render_shadows[i].light); @@ -3538,7 +3537,7 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool //cube shadows are rendered in their own way for (uint32_t i = 0; i < render_state.cube_shadows.size(); i++) { - _render_shadow_pass(render_state.render_shadows[render_state.cube_shadows[i]].light, p_render_data->shadow_atlas, render_state.render_shadows[render_state.cube_shadows[i]].pass, render_state.render_shadows[render_state.cube_shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->screen_lod_threshold, true, true, true); + _render_shadow_pass(render_state.render_shadows[render_state.cube_shadows[i]].light, p_render_data->shadow_atlas, render_state.render_shadows[render_state.cube_shadows[i]].pass, render_state.render_shadows[render_state.cube_shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->screen_lod_threshold, true, true, true, p_render_data->render_info); } if (render_state.directional_shadows.size()) { @@ -3568,11 +3567,11 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool //render directional shadows for (uint32_t i = 0; i < render_state.directional_shadows.size(); i++) { - _render_shadow_pass(render_state.render_shadows[render_state.directional_shadows[i]].light, p_render_data->shadow_atlas, render_state.render_shadows[render_state.directional_shadows[i]].pass, render_state.render_shadows[render_state.directional_shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->screen_lod_threshold, false, i == render_state.directional_shadows.size() - 1, false); + _render_shadow_pass(render_state.render_shadows[render_state.directional_shadows[i]].light, p_render_data->shadow_atlas, render_state.render_shadows[render_state.directional_shadows[i]].pass, render_state.render_shadows[render_state.directional_shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->screen_lod_threshold, false, i == render_state.directional_shadows.size() - 1, false, p_render_data->render_info); } //render positional shadows for (uint32_t i = 0; i < render_state.shadows.size(); i++) { - _render_shadow_pass(render_state.render_shadows[render_state.shadows[i]].light, p_render_data->shadow_atlas, render_state.render_shadows[render_state.shadows[i]].pass, render_state.render_shadows[render_state.shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->screen_lod_threshold, i == 0, i == render_state.shadows.size() - 1, true); + _render_shadow_pass(render_state.render_shadows[render_state.shadows[i]].light, p_render_data->shadow_atlas, render_state.render_shadows[render_state.shadows[i]].pass, render_state.render_shadows[render_state.shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->screen_lod_threshold, i == 0, i == render_state.shadows.size() - 1, true, p_render_data->render_info); } _render_shadow_process(); @@ -3641,7 +3640,7 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool } } -void RendererSceneRenderRD::render_scene(RID p_render_buffers, const CameraData *p_camera_data, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data) { +void RendererSceneRenderRD::render_scene(RID p_render_buffers, const CameraData *p_camera_data, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data, RendererScene::RenderInfo *r_render_info) { // getting this here now so we can direct call a bunch of things more easily RenderBuffers *rb = nullptr; if (p_render_buffers.is_valid()) { @@ -3696,6 +3695,7 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const CameraData render_state.render_sdfgi_regions = p_render_sdfgi_regions; render_state.render_sdfgi_region_count = p_render_sdfgi_region_count; render_state.sdfgi_update_data = p_sdfgi_update_data; + render_data.render_info = r_render_info; } PagedArray<RID> empty; @@ -3808,7 +3808,7 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const CameraData } } -void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<GeometryInstance *> &p_instances, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold, bool p_open_pass, bool p_close_pass, bool p_clear_region) { +void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<GeometryInstance *> &p_instances, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold, bool p_open_pass, bool p_close_pass, bool p_clear_region, RendererScene::RenderInfo *p_render_info) { LightInstance *light_instance = light_instance_owner.getornull(p_light); ERR_FAIL_COND(!light_instance); @@ -3954,7 +3954,7 @@ void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas, if (render_cubemap) { //rendering to cubemap - _render_shadow_append(render_fb, p_instances, light_projection, light_transform, zfar, 0, 0, false, false, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold, Rect2(), false, true, true, true); + _render_shadow_append(render_fb, p_instances, light_projection, light_transform, zfar, 0, 0, false, false, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold, Rect2(), false, true, true, true, p_render_info); if (finalize_cubemap) { _render_shadow_process(); _render_shadow_end(); @@ -3975,7 +3975,7 @@ void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas, } else { //render shadow - _render_shadow_append(render_fb, p_instances, light_projection, light_transform, zfar, 0, 0, using_dual_paraboloid, using_dual_paraboloid_flip, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold, atlas_rect, flip_y, p_clear_region, p_open_pass, p_close_pass); + _render_shadow_append(render_fb, p_instances, light_projection, light_transform, zfar, 0, 0, using_dual_paraboloid, using_dual_paraboloid_flip, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold, atlas_rect, flip_y, p_clear_region, p_open_pass, p_close_pass, p_render_info); } } diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h index d9df467d48..be3d3551c7 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h @@ -40,6 +40,7 @@ #include "servers/rendering/renderer_rd/renderer_scene_sky_rd.h" #include "servers/rendering/renderer_rd/renderer_storage_rd.h" #include "servers/rendering/renderer_rd/shaders/volumetric_fog.glsl.gen.h" +#include "servers/rendering/renderer_scene.h" #include "servers/rendering/renderer_scene_render.h" #include "servers/rendering/rendering_device.h" @@ -79,6 +80,8 @@ struct RenderDataRD { uint32_t cluster_max_elements = 0; uint32_t directional_light_count = 0; + + RendererScene::RenderInfo *render_info = nullptr; }; class RendererSceneRenderRD : public RendererSceneRender { @@ -103,7 +106,7 @@ protected: virtual void _render_scene(RenderDataRD *p_render_data, const Color &p_default_color) = 0; virtual void _render_shadow_begin() = 0; - virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true) = 0; + virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RendererScene::RenderInfo *p_render_info = nullptr) = 0; virtual void _render_shadow_process() = 0; virtual void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL) = 0; @@ -746,7 +749,7 @@ private: uint32_t max_cluster_elements = 512; - void _render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<GeometryInstance *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_lod_threshold = 0.0, bool p_open_pass = true, bool p_close_pass = true, bool p_clear_region = true); + void _render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<GeometryInstance *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_lod_threshold = 0.0, bool p_open_pass = true, bool p_close_pass = true, bool p_clear_region = true, RendererScene::RenderInfo *p_render_info = nullptr); public: virtual Transform3D geometry_instance_get_transform(GeometryInstance *p_instance) = 0; @@ -1156,7 +1159,7 @@ public: float render_buffers_get_volumetric_fog_end(RID p_render_buffers); float render_buffers_get_volumetric_fog_detail_spread(RID p_render_buffers); - virtual void render_scene(RID p_render_buffers, const CameraData *p_camera_data, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr) override; + virtual void render_scene(RID p_render_buffers, const CameraData *p_camera_data, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RendererScene::RenderInfo *r_render_info = nullptr) override; virtual void render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.cpp b/servers/rendering/renderer_rd/renderer_storage_rd.cpp index 3809c93e67..942684fc3a 100644 --- a/servers/rendering/renderer_rd/renderer_storage_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_storage_rd.cpp @@ -2548,6 +2548,7 @@ void RendererStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_su s->lods[i].index_buffer = RD::get_singleton()->index_buffer_create(indices, is_index_16 ? RD::INDEX_BUFFER_FORMAT_UINT16 : RD::INDEX_BUFFER_FORMAT_UINT32, p_surface.lods[i].index_data); s->lods[i].index_array = RD::get_singleton()->index_array_create(s->lods[i].index_buffer, 0, indices); s->lods[i].edge_length = p_surface.lods[i].edge_length; + s->lods[i].index_count = indices; } } } @@ -8805,6 +8806,29 @@ String RendererStorageRD::get_captured_timestamp_name(uint32_t p_index) const { return RD::get_singleton()->get_captured_timestamp_name(p_index); } +void RendererStorageRD::update_memory_info() { + texture_mem_cache = RenderingDevice::get_singleton()->get_memory_usage(RenderingDevice::MEMORY_TEXTURES); + buffer_mem_cache = RenderingDevice::get_singleton()->get_memory_usage(RenderingDevice::MEMORY_BUFFERS); + total_mem_cache = RenderingDevice::get_singleton()->get_memory_usage(RenderingDevice::MEMORY_TOTAL); +} +uint64_t RendererStorageRD::get_rendering_info(RS::RenderingInfo p_info) { + if (p_info == RS::RENDERING_INFO_TEXTURE_MEM_USED) { + return texture_mem_cache; + } else if (p_info == RS::RENDERING_INFO_BUFFER_MEM_USED) { + return buffer_mem_cache; + } else if (p_info == RS::RENDERING_INFO_VIDEO_MEM_USED) { + return total_mem_cache; + } + return 0; +} + +String RendererStorageRD::get_video_adapter_name() const { + return RenderingDevice::get_singleton()->get_device_name(); +} +String RendererStorageRD::get_video_adapter_vendor() const { + return RenderingDevice::get_singleton()->get_device_vendor_name(); +} + RendererStorageRD *RendererStorageRD::base_singleton = nullptr; RendererStorageRD::RendererStorageRD() { diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.h b/servers/rendering/renderer_rd/renderer_storage_rd.h index 26739b11da..80dea6e5ea 100644 --- a/servers/rendering/renderer_rd/renderer_storage_rd.h +++ b/servers/rendering/renderer_rd/renderer_storage_rd.h @@ -434,6 +434,7 @@ private: struct LOD { float edge_length = 0.0; + uint32_t index_count = 0; RID index_buffer; RID index_array; }; @@ -1524,10 +1525,18 @@ public: return s->lod_count > 0; } - _FORCE_INLINE_ uint32_t mesh_surface_get_lod(void *p_surface, float p_model_scale, float p_distance_threshold, float p_lod_threshold) const { + _FORCE_INLINE_ uint32_t mesh_surface_get_vertices_drawn_count(void *p_surface) const { + Mesh::Surface *s = reinterpret_cast<Mesh::Surface *>(p_surface); + return s->index_count ? s->index_count : s->vertex_count; + } + + _FORCE_INLINE_ uint32_t mesh_surface_get_lod(void *p_surface, float p_model_scale, float p_distance_threshold, float p_lod_threshold, uint32_t *r_index_count = nullptr) const { Mesh::Surface *s = reinterpret_cast<Mesh::Surface *>(p_surface); int32_t current_lod = -1; + if (r_index_count) { + *r_index_count = s->index_count; + } for (uint32_t i = 0; i < s->lod_count; i++) { float screen_size = s->lods[i].edge_length * p_model_scale / p_distance_threshold; if (screen_size > p_lod_threshold) { @@ -1538,6 +1547,9 @@ public: if (current_lod == -1) { return 0; } else { + if (r_index_count) { + *r_index_count = s->lods[current_lod].index_count; + } return current_lod + 1; } } @@ -2322,13 +2334,16 @@ public: void set_debug_generate_wireframes(bool p_generate) {} - void render_info_begin_capture() {} - void render_info_end_capture() {} - int get_captured_render_info(RS::RenderInfo p_info) { return 0; } + //keep cached since it can be called form any thread + uint64_t texture_mem_cache = 0; + uint64_t buffer_mem_cache = 0; + uint64_t total_mem_cache = 0; + + virtual void update_memory_info(); + virtual uint64_t get_rendering_info(RS::RenderingInfo p_info); - uint64_t get_render_info(RS::RenderInfo p_info) { return 0; } - String get_video_adapter_name() const { return String(); } - String get_video_adapter_vendor() const { return String(); } + String get_video_adapter_name() const; + String get_video_adapter_vendor() const; virtual void capture_timestamps_begin(); virtual void capture_timestamp(const String &p_name); diff --git a/servers/rendering/renderer_scene.h b/servers/rendering/renderer_scene.h index d2e9f64335..8273e53d46 100644 --- a/servers/rendering/renderer_scene.h +++ b/servers/rendering/renderer_scene.h @@ -201,7 +201,12 @@ public: virtual void sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir) = 0; virtual void render_empty_scene(RID p_render_buffers, RID p_scenario, RID p_shadow_atlas) = 0; - virtual void render_camera(RID p_render_buffers, RID p_camera, RID p_scenario, RID p_viewport, Size2 p_viewport_size, float p_lod_threshold, RID p_shadow_atlas, Ref<XRInterface> &p_xr_interface) = 0; + + struct RenderInfo { + int info[RS::VIEWPORT_RENDER_INFO_TYPE_MAX][RS::VIEWPORT_RENDER_INFO_MAX] = {}; + }; + + virtual void render_camera(RID p_render_buffers, RID p_camera, RID p_scenario, RID p_viewport, Size2 p_viewport_size, float p_lod_threshold, RID p_shadow_atlas, Ref<XRInterface> &p_xr_interface, RenderInfo *r_render_info = nullptr) = 0; virtual void update() = 0; virtual void render_probes() = 0; diff --git a/servers/rendering/renderer_scene_cull.cpp b/servers/rendering/renderer_scene_cull.cpp index 2e148fefcf..84299b4ab2 100644 --- a/servers/rendering/renderer_scene_cull.cpp +++ b/servers/rendering/renderer_scene_cull.cpp @@ -2372,7 +2372,7 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons return animated_material_found; } -void RendererSceneCull::render_camera(RID p_render_buffers, RID p_camera, RID p_scenario, RID p_viewport, Size2 p_viewport_size, float p_screen_lod_threshold, RID p_shadow_atlas, Ref<XRInterface> &p_xr_interface) { +void RendererSceneCull::render_camera(RID p_render_buffers, RID p_camera, RID p_scenario, RID p_viewport, Size2 p_viewport_size, float p_screen_lod_threshold, RID p_shadow_atlas, Ref<XRInterface> &p_xr_interface, RenderInfo *r_render_info) { #ifndef _3D_DISABLED Camera *camera = camera_owner.getornull(p_camera); @@ -2454,7 +2454,7 @@ void RendererSceneCull::render_camera(RID p_render_buffers, RID p_camera, RID p_ // For now just cull on the first camera RendererSceneOcclusionCull::get_singleton()->buffer_update(p_viewport, camera_data.main_transform, camera_data.main_projection, camera_data.is_ortogonal, RendererThreadPool::singleton->thread_work_pool); - _render_scene(&camera_data, p_render_buffers, environment, camera->effects, camera->visible_layers, p_scenario, p_viewport, p_shadow_atlas, RID(), -1, p_screen_lod_threshold); + _render_scene(&camera_data, p_render_buffers, environment, camera->effects, camera->visible_layers, p_scenario, p_viewport, p_shadow_atlas, RID(), -1, p_screen_lod_threshold, true, r_render_info); #endif } @@ -2760,7 +2760,7 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul } } -void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_camera_data, RID p_render_buffers, RID p_environment, RID p_force_camera_effects, uint32_t p_visible_layers, RID p_scenario, RID p_viewport, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold, bool p_using_shadows) { +void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_camera_data, RID p_render_buffers, RID p_environment, RID p_force_camera_effects, uint32_t p_visible_layers, RID p_scenario, RID p_viewport, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold, bool p_using_shadows, RendererScene::RenderInfo *r_render_info) { Instance *render_reflection_probe = instance_owner.getornull(p_reflection_probe); //if null, not rendering to it Scenario *scenario = scenario_owner.getornull(p_scenario); @@ -3105,7 +3105,7 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c } RENDER_TIMESTAMP("Render Scene "); - scene_render->render_scene(p_render_buffers, p_camera_data, scene_cull_result.geometry_instances, scene_cull_result.light_instances, scene_cull_result.reflections, scene_cull_result.voxel_gi_instances, scene_cull_result.decals, scene_cull_result.lightmaps, p_environment, camera_effects, p_shadow_atlas, occluders_tex, p_reflection_probe.is_valid() ? RID() : scenario->reflection_atlas, p_reflection_probe, p_reflection_probe_pass, p_screen_lod_threshold, render_shadow_data, max_shadows_used, render_sdfgi_data, cull.sdfgi.region_count, &sdfgi_update_data); + scene_render->render_scene(p_render_buffers, p_camera_data, scene_cull_result.geometry_instances, scene_cull_result.light_instances, scene_cull_result.reflections, scene_cull_result.voxel_gi_instances, scene_cull_result.decals, scene_cull_result.lightmaps, p_environment, camera_effects, p_shadow_atlas, occluders_tex, p_reflection_probe.is_valid() ? RID() : scenario->reflection_atlas, p_reflection_probe, p_reflection_probe_pass, p_screen_lod_threshold, render_shadow_data, max_shadows_used, render_sdfgi_data, cull.sdfgi.region_count, &sdfgi_update_data, r_render_info); for (uint32_t i = 0; i < max_shadows_used; i++) { render_shadow_data[i].instances.clear(); @@ -3142,7 +3142,6 @@ RID RendererSceneCull::_render_get_environment(RID p_camera, RID p_scenario) { void RendererSceneCull::render_empty_scene(RID p_render_buffers, RID p_scenario, RID p_shadow_atlas) { #ifndef _3D_DISABLED - Scenario *scenario = scenario_owner.getornull(p_scenario); RID environment; diff --git a/servers/rendering/renderer_scene_cull.h b/servers/rendering/renderer_scene_cull.h index 53fb197fcc..d586fb531f 100644 --- a/servers/rendering/renderer_scene_cull.h +++ b/servers/rendering/renderer_scene_cull.h @@ -1019,10 +1019,10 @@ public: void _scene_cull(CullData &cull_data, InstanceCullResult &cull_result, uint64_t p_from, uint64_t p_to); bool _render_reflection_probe_step(Instance *p_instance, int p_step); - void _render_scene(const RendererSceneRender::CameraData *p_camera_data, RID p_render_buffers, RID p_environment, RID p_force_camera_effects, uint32_t p_visible_layers, RID p_scenario, RID p_viewport, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold, bool p_using_shadows = true); + void _render_scene(const RendererSceneRender::CameraData *p_camera_data, RID p_render_buffers, RID p_environment, RID p_force_camera_effects, uint32_t p_visible_layers, RID p_scenario, RID p_viewport, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold, bool p_using_shadows = true, RenderInfo *r_render_info = nullptr); void render_empty_scene(RID p_render_buffers, RID p_scenario, RID p_shadow_atlas); - void render_camera(RID p_render_buffers, RID p_camera, RID p_scenario, RID p_viewport, Size2 p_viewport_size, float p_screen_lod_threshold, RID p_shadow_atlas, Ref<XRInterface> &p_xr_interface); + void render_camera(RID p_render_buffers, RID p_camera, RID p_scenario, RID p_viewport, Size2 p_viewport_size, float p_screen_lod_threshold, RID p_shadow_atlas, Ref<XRInterface> &p_xr_interface, RendererScene::RenderInfo *r_render_info = nullptr); void update_dirty_instances(); void render_particle_colliders(); diff --git a/servers/rendering/renderer_scene_render.h b/servers/rendering/renderer_scene_render.h index 3682122dd3..ff0fea16d0 100644 --- a/servers/rendering/renderer_scene_render.h +++ b/servers/rendering/renderer_scene_render.h @@ -33,6 +33,7 @@ #include "core/math/camera_matrix.h" #include "core/templates/paged_array.h" +#include "servers/rendering/renderer_scene.h" #include "servers/rendering/renderer_storage.h" class RendererSceneRender { @@ -234,7 +235,7 @@ public: void set_multiview_camera(uint32_t p_view_count, const Transform3D *p_transforms, const CameraMatrix *p_projections, bool p_is_ortogonal, bool p_vaspect); }; - virtual void render_scene(RID p_render_buffers, const CameraData *p_camera_data, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr) = 0; + virtual void render_scene(RID p_render_buffers, const CameraData *p_camera_data, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RendererScene::RenderInfo *r_render_info = nullptr) = 0; virtual void render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0; virtual void render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<GeometryInstance *> &p_instances) = 0; diff --git a/servers/rendering/renderer_storage.h b/servers/rendering/renderer_storage.h index c491e05be5..b2aa0d27d3 100644 --- a/servers/rendering/renderer_storage.h +++ b/servers/rendering/renderer_storage.h @@ -599,11 +599,9 @@ public: virtual void set_debug_generate_wireframes(bool p_generate) = 0; - virtual void render_info_begin_capture() = 0; - virtual void render_info_end_capture() = 0; - virtual int get_captured_render_info(RS::RenderInfo p_info) = 0; + virtual void update_memory_info() = 0; - virtual uint64_t get_render_info(RS::RenderInfo p_info) = 0; + virtual uint64_t get_rendering_info(RS::RenderingInfo p_info) = 0; virtual String get_video_adapter_name() const = 0; virtual String get_video_adapter_vendor() const = 0; diff --git a/servers/rendering/renderer_viewport.cpp b/servers/rendering/renderer_viewport.cpp index b3301fc607..46e340c0ac 100644 --- a/servers/rendering/renderer_viewport.cpp +++ b/servers/rendering/renderer_viewport.cpp @@ -95,7 +95,7 @@ void RendererViewport::_draw_3d(Viewport *p_viewport) { } float screen_lod_threshold = p_viewport->lod_threshold / float(p_viewport->size.width); - RSG::scene->render_camera(p_viewport->render_buffers, p_viewport->camera, p_viewport->scenario, p_viewport->self, p_viewport->size, screen_lod_threshold, p_viewport->shadow_atlas, xr_interface); + RSG::scene->render_camera(p_viewport->render_buffers, p_viewport->camera, p_viewport->scenario, p_viewport->self, p_viewport->size, screen_lod_threshold, p_viewport->shadow_atlas, xr_interface, &p_viewport->render_info); RENDER_TIMESTAMP("<End Rendering 3D Scene"); } @@ -112,6 +112,12 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport, uint32_t p_view_coun bool scenario_draw_canvas_bg = false; //draw canvas, or some layer of it, as BG for 3D instead of in front int scenario_canvas_max_layer = 0; + for (int i = 0; i < RS::VIEWPORT_RENDER_INFO_TYPE_MAX; i++) { + for (int j = 0; j < RS::VIEWPORT_RENDER_INFO_MAX; j++) { + p_viewport->render_info.info[i][j] = 0; + } + } + Color bgcolor = RSG::storage->get_default_clear_color(); if (!p_viewport->disable_2d && !p_viewport->disable_environment && RSG::scene->is_scenario(p_viewport->scenario)) { @@ -522,6 +528,10 @@ void RendererViewport::draw_viewports() { } } + int vertices_drawn = 0; + int objects_drawn = 0; + int draw_calls_used = 0; + for (int i = 0; i < active_viewports.size(); i++) { Viewport *vp = active_viewports[i]; @@ -544,19 +554,11 @@ void RendererViewport::draw_viewports() { // render... RSG::scene->set_debug_draw_mode(vp->debug_draw); - RSG::storage->render_info_begin_capture(); // and draw viewport _draw_viewport(vp, view_count); // measure - RSG::storage->render_info_end_capture(); - vp->render_info[RS::VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME] = RSG::storage->get_captured_render_info(RS::INFO_OBJECTS_IN_FRAME); - vp->render_info[RS::VIEWPORT_RENDER_INFO_VERTICES_IN_FRAME] = RSG::storage->get_captured_render_info(RS::INFO_VERTICES_IN_FRAME); - vp->render_info[RS::VIEWPORT_RENDER_INFO_MATERIAL_CHANGES_IN_FRAME] = RSG::storage->get_captured_render_info(RS::INFO_MATERIAL_CHANGES_IN_FRAME); - vp->render_info[RS::VIEWPORT_RENDER_INFO_SHADER_CHANGES_IN_FRAME] = RSG::storage->get_captured_render_info(RS::INFO_SHADER_CHANGES_IN_FRAME); - vp->render_info[RS::VIEWPORT_RENDER_INFO_SURFACE_CHANGES_IN_FRAME] = RSG::storage->get_captured_render_info(RS::INFO_SURFACE_CHANGES_IN_FRAME); - vp->render_info[RS::VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME] = RSG::storage->get_captured_render_info(RS::INFO_DRAW_CALLS_IN_FRAME); // commit our eyes Vector<BlitToScreen> blits = xr_interface->commit_views(vp->render_target, vp->viewport_to_screen_rect); @@ -576,19 +578,10 @@ void RendererViewport::draw_viewports() { RSG::storage->render_target_set_external_texture(vp->render_target, 0); RSG::scene->set_debug_draw_mode(vp->debug_draw); - RSG::storage->render_info_begin_capture(); // render standard mono camera _draw_viewport(vp, 1); - RSG::storage->render_info_end_capture(); - vp->render_info[RS::VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME] = RSG::storage->get_captured_render_info(RS::INFO_OBJECTS_IN_FRAME); - vp->render_info[RS::VIEWPORT_RENDER_INFO_VERTICES_IN_FRAME] = RSG::storage->get_captured_render_info(RS::INFO_VERTICES_IN_FRAME); - vp->render_info[RS::VIEWPORT_RENDER_INFO_MATERIAL_CHANGES_IN_FRAME] = RSG::storage->get_captured_render_info(RS::INFO_MATERIAL_CHANGES_IN_FRAME); - vp->render_info[RS::VIEWPORT_RENDER_INFO_SHADER_CHANGES_IN_FRAME] = RSG::storage->get_captured_render_info(RS::INFO_SHADER_CHANGES_IN_FRAME); - vp->render_info[RS::VIEWPORT_RENDER_INFO_SURFACE_CHANGES_IN_FRAME] = RSG::storage->get_captured_render_info(RS::INFO_SURFACE_CHANGES_IN_FRAME); - vp->render_info[RS::VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME] = RSG::storage->get_captured_render_info(RS::INFO_DRAW_CALLS_IN_FRAME); - if (vp->viewport_to_screen != DisplayServer::INVALID_WINDOW_ID && (!vp->viewport_render_direct_to_screen || !RSG::rasterizer->is_low_end())) { //copy to screen if set as such BlitToScreen blit; @@ -613,9 +606,17 @@ void RendererViewport::draw_viewports() { } RENDER_TIMESTAMP("<Rendering Viewport " + itos(i)); + + objects_drawn += vp->render_info.info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE][RS::VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME] + vp->render_info.info[RS::VIEWPORT_RENDER_INFO_TYPE_SHADOW][RS::VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME]; + vertices_drawn += vp->render_info.info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] + vp->render_info.info[RS::VIEWPORT_RENDER_INFO_TYPE_SHADOW][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME]; + draw_calls_used += vp->render_info.info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE][RS::VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME] + vp->render_info.info[RS::VIEWPORT_RENDER_INFO_TYPE_SHADOW][RS::VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME]; } RSG::scene->set_debug_draw_mode(RS::VIEWPORT_DEBUG_DRAW_DISABLED); + total_objects_drawn = objects_drawn; + total_vertices_drawn = vertices_drawn; + total_draw_calls_used = draw_calls_used; + RENDER_TIMESTAMP("<Render Viewports"); //this needs to be called to make screen swapping more efficient RSG::rasterizer->prepare_for_blitting_render_targets(); @@ -987,7 +988,7 @@ void RendererViewport::viewport_set_lod_threshold(RID p_viewport, float p_pixels viewport->lod_threshold = p_pixels; } -int RendererViewport::viewport_get_render_info(RID p_viewport, RS::ViewportRenderInfo p_info) { +int RendererViewport::viewport_get_render_info(RID p_viewport, RS::ViewportRenderInfoType p_type, RS::ViewportRenderInfo p_info) { ERR_FAIL_INDEX_V(p_info, RS::VIEWPORT_RENDER_INFO_MAX, -1); Viewport *viewport = viewport_owner.getornull(p_viewport); @@ -995,7 +996,7 @@ int RendererViewport::viewport_get_render_info(RID p_viewport, RS::ViewportRende return 0; //there should be a lock here.. } - return viewport->render_info[p_info]; + return viewport->render_info.info[p_type][p_info]; } void RendererViewport::viewport_set_debug_draw(RID p_viewport, RS::ViewportDebugDraw p_draw) { @@ -1120,6 +1121,16 @@ void RendererViewport::call_set_use_vsync(bool p_enable) { DisplayServer::get_singleton()->_set_use_vsync(p_enable); } +int RendererViewport::get_total_objects_drawn() const { + return total_objects_drawn; +} +int RendererViewport::get_total_vertices_drawn() const { + return total_vertices_drawn; +} +int RendererViewport::get_total_draw_calls_used() const { + return total_draw_calls_used; +} + RendererViewport::RendererViewport() { occlusion_rays_per_thread = GLOBAL_GET("rendering/occlusion_culling/occlusion_rays_per_thread"); } diff --git a/servers/rendering/renderer_viewport.h b/servers/rendering/renderer_viewport.h index bf47bda148..b449a9fa1a 100644 --- a/servers/rendering/renderer_viewport.h +++ b/servers/rendering/renderer_viewport.h @@ -34,6 +34,7 @@ #include "core/templates/local_vector.h" #include "core/templates/rid_owner.h" #include "core/templates/self_list.h" +#include "servers/rendering/renderer_scene.h" #include "servers/rendering_server.h" #include "servers/xr/xr_interface.h" @@ -92,7 +93,6 @@ public: uint64_t last_pass = 0; - int render_info[RS::VIEWPORT_RENDER_INFO_MAX]; RS::ViewportDebugDraw debug_draw; RS::ViewportClearMode clear_mode; @@ -133,6 +133,8 @@ public: Map<RID, CanvasData> canvas_map; + RendererScene::RenderInfo render_info; + Viewport() { update_mode = RS::VIEWPORT_UPDATE_WHEN_VISIBLE; clear_mode = RS::VIEWPORT_CLEAR_ALWAYS; @@ -152,9 +154,6 @@ public: snap_2d_transforms_to_pixel = false; snap_2d_vertices_to_pixel = false; - for (int i = 0; i < RS::VIEWPORT_RENDER_INFO_MAX; i++) { - render_info[i] = 0; - } use_xr = false; sdf_active = false; @@ -188,6 +187,10 @@ public: Vector<Viewport *> active_viewports; + int total_objects_drawn = 0; + int total_vertices_drawn = 0; + int total_draw_calls_used = 0; + private: void _draw_3d(Viewport *p_viewport); void _draw_viewport(Viewport *p_viewport, uint32_t p_view_count = 1); @@ -242,7 +245,7 @@ public: void viewport_set_occlusion_culling_build_quality(RS::ViewportOcclusionCullingBuildQuality p_quality); void viewport_set_lod_threshold(RID p_viewport, float p_pixels); - virtual int viewport_get_render_info(RID p_viewport, RS::ViewportRenderInfo p_info); + virtual int viewport_get_render_info(RID p_viewport, RS::ViewportRenderInfoType p_type, RS::ViewportRenderInfo p_info); virtual void viewport_set_debug_draw(RID p_viewport, RS::ViewportDebugDraw p_draw); void viewport_set_measure_render_time(RID p_viewport, bool p_enable); @@ -264,6 +267,10 @@ public: bool free(RID p_rid); + int get_total_objects_drawn() const; + int get_total_vertices_drawn() const; + int get_total_draw_calls_used() const; + //workaround for setting this on thread void call_set_use_vsync(bool p_enable); diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp index c52d97a3de..9f586b29fc 100644 --- a/servers/rendering/rendering_device.cpp +++ b/servers/rendering/rendering_device.cpp @@ -416,6 +416,8 @@ void RenderingDevice::_bind_methods() { ClassDB::bind_method(D_METHOD("get_device_name"), &RenderingDevice::get_device_name); ClassDB::bind_method(D_METHOD("get_device_pipeline_cache_uuid"), &RenderingDevice::get_device_pipeline_cache_uuid); + ClassDB::bind_method(D_METHOD("get_memory_usage"), &RenderingDevice::get_memory_usage); + BIND_CONSTANT(BARRIER_MASK_RASTER); BIND_CONSTANT(BARRIER_MASK_COMPUTE); BIND_CONSTANT(BARRIER_MASK_TRANSFER); @@ -887,6 +889,10 @@ void RenderingDevice::_bind_methods() { BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Y); BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Z); + BIND_ENUM_CONSTANT(MEMORY_TEXTURES); + BIND_ENUM_CONSTANT(MEMORY_BUFFERS); + BIND_ENUM_CONSTANT(MEMORY_TOTAL); + BIND_CONSTANT(INVALID_ID); BIND_CONSTANT(INVALID_FORMAT_ID); } diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h index be7e127491..ed5e73c16a 100644 --- a/servers/rendering/rendering_device.h +++ b/servers/rendering/rendering_device.h @@ -1128,7 +1128,13 @@ public: virtual void submit() = 0; virtual void sync() = 0; - virtual uint64_t get_memory_usage() const = 0; + enum MemoryType { + MEMORY_TEXTURES, + MEMORY_BUFFERS, + MEMORY_TOTAL + }; + + virtual uint64_t get_memory_usage(MemoryType p_type) const = 0; virtual RenderingDevice *create_local_device() = 0; @@ -1200,6 +1206,7 @@ VARIANT_ENUM_CAST(RenderingDevice::PipelineDynamicStateFlags) VARIANT_ENUM_CAST(RenderingDevice::InitialAction) VARIANT_ENUM_CAST(RenderingDevice::FinalAction) VARIANT_ENUM_CAST(RenderingDevice::Limit) +VARIANT_ENUM_CAST(RenderingDevice::MemoryType) typedef RenderingDevice RD; diff --git a/servers/rendering/rendering_server_default.cpp b/servers/rendering/rendering_server_default.cpp index aad6163a16..e3ebebca86 100644 --- a/servers/rendering/rendering_server_default.cpp +++ b/servers/rendering/rendering_server_default.cpp @@ -189,6 +189,8 @@ void RenderingServerDefault::_draw(bool p_swap_buffers, double frame_step) { print_frame_profile_frame_count = 0; } } + + RSG::storage->update_memory_info(); } float RenderingServerDefault::get_frame_setup_time_cpu() const { @@ -239,8 +241,15 @@ void RenderingServerDefault::finish() { /* STATUS INFORMATION */ -uint64_t RenderingServerDefault::get_render_info(RenderInfo p_info) { - return RSG::storage->get_render_info(p_info); +uint64_t RenderingServerDefault::get_rendering_info(RenderingInfo p_info) { + if (p_info == RENDERING_INFO_TOTAL_OBJECTS_IN_FRAME) { + return RSG::viewport->get_total_objects_drawn(); + } else if (p_info == RENDERING_INFO_TOTAL_PRIMITIVES_IN_FRAME) { + return RSG::viewport->get_total_vertices_drawn(); + } else if (p_info == RENDERING_INFO_TOTAL_DRAW_CALLS_IN_FRAME) { + return RSG::viewport->get_total_draw_calls_used(); + } + return RSG::storage->get_rendering_info(p_info); } String RenderingServerDefault::get_video_adapter_name() const { diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h index 70bba91bab..48c96cb02a 100644 --- a/servers/rendering/rendering_server_default.h +++ b/servers/rendering/rendering_server_default.h @@ -570,7 +570,7 @@ public: FUNC1(viewport_set_occlusion_culling_build_quality, ViewportOcclusionCullingBuildQuality) FUNC2(viewport_set_lod_threshold, RID, float) - FUNC2R(int, viewport_get_render_info, RID, ViewportRenderInfo) + FUNC3R(int, viewport_get_render_info, RID, ViewportRenderInfoType, ViewportRenderInfo) FUNC2(viewport_set_debug_draw, RID, ViewportDebugDraw) FUNC2(viewport_set_measure_render_time, RID, bool) @@ -876,7 +876,7 @@ public: /* STATUS INFORMATION */ - virtual uint64_t get_render_info(RenderInfo p_info) override; + virtual uint64_t get_rendering_info(RenderingInfo p_info) override; virtual String get_video_adapter_name() const override; virtual String get_video_adapter_vendor() const override; diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index a13588b722..4ac5f9399c 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -2136,7 +2136,7 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("viewport_set_occlusion_rays_per_thread", "rays_per_thread"), &RenderingServer::viewport_set_occlusion_rays_per_thread); ClassDB::bind_method(D_METHOD("viewport_set_occlusion_culling_build_quality", "quality"), &RenderingServer::viewport_set_occlusion_culling_build_quality); - ClassDB::bind_method(D_METHOD("viewport_get_render_info", "viewport", "info"), &RenderingServer::viewport_get_render_info); + ClassDB::bind_method(D_METHOD("viewport_get_render_info", "viewport", "type", "info"), &RenderingServer::viewport_get_render_info); ClassDB::bind_method(D_METHOD("viewport_set_debug_draw", "viewport", "draw"), &RenderingServer::viewport_set_debug_draw); ClassDB::bind_method(D_METHOD("viewport_set_measure_render_time", "viewport", "enable"), &RenderingServer::viewport_set_measure_render_time); @@ -2181,13 +2181,14 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(VIEWPORT_OCCLUSION_BUILD_QUALITY_HIGH); BIND_ENUM_CONSTANT(VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME); - BIND_ENUM_CONSTANT(VIEWPORT_RENDER_INFO_VERTICES_IN_FRAME); - BIND_ENUM_CONSTANT(VIEWPORT_RENDER_INFO_MATERIAL_CHANGES_IN_FRAME); - BIND_ENUM_CONSTANT(VIEWPORT_RENDER_INFO_SHADER_CHANGES_IN_FRAME); - BIND_ENUM_CONSTANT(VIEWPORT_RENDER_INFO_SURFACE_CHANGES_IN_FRAME); + BIND_ENUM_CONSTANT(VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME); BIND_ENUM_CONSTANT(VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME); BIND_ENUM_CONSTANT(VIEWPORT_RENDER_INFO_MAX); + BIND_ENUM_CONSTANT(VIEWPORT_RENDER_INFO_TYPE_VISIBLE); + BIND_ENUM_CONSTANT(VIEWPORT_RENDER_INFO_TYPE_SHADOW); + BIND_ENUM_CONSTANT(VIEWPORT_RENDER_INFO_TYPE_MAX); + BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_DISABLED); BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_UNSHADED); BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_LIGHTING); @@ -2626,7 +2627,7 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("request_frame_drawn_callback", "where", "method", "userdata"), &RenderingServer::request_frame_drawn_callback); ClassDB::bind_method(D_METHOD("has_changed"), &RenderingServer::has_changed); - ClassDB::bind_method(D_METHOD("get_render_info", "info"), &RenderingServer::get_render_info); + ClassDB::bind_method(D_METHOD("get_rendering_info", "info"), &RenderingServer::get_rendering_info); ClassDB::bind_method(D_METHOD("get_video_adapter_name"), &RenderingServer::get_video_adapter_name); ClassDB::bind_method(D_METHOD("get_video_adapter_vendor"), &RenderingServer::get_video_adapter_vendor); @@ -2650,16 +2651,12 @@ void RenderingServer::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "render_loop_enabled"), "set_render_loop_enabled", "is_render_loop_enabled"); - BIND_ENUM_CONSTANT(INFO_OBJECTS_IN_FRAME); - BIND_ENUM_CONSTANT(INFO_VERTICES_IN_FRAME); - BIND_ENUM_CONSTANT(INFO_MATERIAL_CHANGES_IN_FRAME); - BIND_ENUM_CONSTANT(INFO_SHADER_CHANGES_IN_FRAME); - BIND_ENUM_CONSTANT(INFO_SURFACE_CHANGES_IN_FRAME); - BIND_ENUM_CONSTANT(INFO_DRAW_CALLS_IN_FRAME); - BIND_ENUM_CONSTANT(INFO_USAGE_VIDEO_MEM_TOTAL); - BIND_ENUM_CONSTANT(INFO_VIDEO_MEM_USED); - BIND_ENUM_CONSTANT(INFO_TEXTURE_MEM_USED); - BIND_ENUM_CONSTANT(INFO_VERTEX_MEM_USED); + BIND_ENUM_CONSTANT(RENDERING_INFO_TOTAL_OBJECTS_IN_FRAME); + BIND_ENUM_CONSTANT(RENDERING_INFO_TOTAL_PRIMITIVES_IN_FRAME); + BIND_ENUM_CONSTANT(RENDERING_INFO_TOTAL_DRAW_CALLS_IN_FRAME); + BIND_ENUM_CONSTANT(RENDERING_INFO_TEXTURE_MEM_USED); + BIND_ENUM_CONSTANT(RENDERING_INFO_BUFFER_MEM_USED); + BIND_ENUM_CONSTANT(RENDERING_INFO_VIDEO_MEM_USED); BIND_ENUM_CONSTANT(FEATURE_SHADERS); BIND_ENUM_CONSTANT(FEATURE_MULTITHREADED); diff --git a/servers/rendering_server.h b/servers/rendering_server.h index e5a60ada4d..e260ff99a1 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -835,15 +835,18 @@ public: enum ViewportRenderInfo { VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME, - VIEWPORT_RENDER_INFO_VERTICES_IN_FRAME, - VIEWPORT_RENDER_INFO_MATERIAL_CHANGES_IN_FRAME, - VIEWPORT_RENDER_INFO_SHADER_CHANGES_IN_FRAME, - VIEWPORT_RENDER_INFO_SURFACE_CHANGES_IN_FRAME, + VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME, VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME, VIEWPORT_RENDER_INFO_MAX, }; - virtual int viewport_get_render_info(RID p_viewport, ViewportRenderInfo p_info) = 0; + enum ViewportRenderInfoType { + VIEWPORT_RENDER_INFO_TYPE_VISIBLE, + VIEWPORT_RENDER_INFO_TYPE_SHADOW, + VIEWPORT_RENDER_INFO_TYPE_MAX + }; + + virtual int viewport_get_render_info(RID p_viewport, ViewportRenderInfoType p_type, ViewportRenderInfo p_info) = 0; enum ViewportDebugDraw { VIEWPORT_DEBUG_DRAW_DISABLED, @@ -1395,20 +1398,17 @@ public: /* STATUS INFORMATION */ - enum RenderInfo { - INFO_OBJECTS_IN_FRAME, - INFO_VERTICES_IN_FRAME, - INFO_MATERIAL_CHANGES_IN_FRAME, - INFO_SHADER_CHANGES_IN_FRAME, - INFO_SURFACE_CHANGES_IN_FRAME, - INFO_DRAW_CALLS_IN_FRAME, - INFO_USAGE_VIDEO_MEM_TOTAL, - INFO_VIDEO_MEM_USED, - INFO_TEXTURE_MEM_USED, - INFO_VERTEX_MEM_USED, + enum RenderingInfo { + RENDERING_INFO_TOTAL_OBJECTS_IN_FRAME, + RENDERING_INFO_TOTAL_PRIMITIVES_IN_FRAME, + RENDERING_INFO_TOTAL_DRAW_CALLS_IN_FRAME, + RENDERING_INFO_TEXTURE_MEM_USED, + RENDERING_INFO_BUFFER_MEM_USED, + RENDERING_INFO_VIDEO_MEM_USED, + RENDERING_INFO_MAX }; - virtual uint64_t get_render_info(RenderInfo p_info) = 0; + virtual uint64_t get_rendering_info(RenderingInfo p_info) = 0; virtual String get_video_adapter_name() const = 0; virtual String get_video_adapter_vendor() const = 0; @@ -1513,6 +1513,7 @@ VARIANT_ENUM_CAST(RenderingServer::ViewportClearMode); VARIANT_ENUM_CAST(RenderingServer::ViewportMSAA); VARIANT_ENUM_CAST(RenderingServer::ViewportScreenSpaceAA); VARIANT_ENUM_CAST(RenderingServer::ViewportRenderInfo); +VARIANT_ENUM_CAST(RenderingServer::ViewportRenderInfoType); VARIANT_ENUM_CAST(RenderingServer::ViewportDebugDraw); VARIANT_ENUM_CAST(RenderingServer::ViewportOcclusionCullingBuildQuality); VARIANT_ENUM_CAST(RenderingServer::ViewportSDFOversize); @@ -1546,7 +1547,7 @@ VARIANT_ENUM_CAST(RenderingServer::CanvasLightBlendMode); VARIANT_ENUM_CAST(RenderingServer::CanvasLightShadowFilter); VARIANT_ENUM_CAST(RenderingServer::CanvasOccluderPolygonCullMode); VARIANT_ENUM_CAST(RenderingServer::GlobalVariableType); -VARIANT_ENUM_CAST(RenderingServer::RenderInfo); +VARIANT_ENUM_CAST(RenderingServer::RenderingInfo); VARIANT_ENUM_CAST(RenderingServer::Features); VARIANT_ENUM_CAST(RenderingServer::CanvasTextureChannel); VARIANT_ENUM_CAST(RenderingServer::BakeChannels); |