Add some important profiling hooks.
This commit is contained in:
@ -33,6 +33,7 @@
|
||||
#include "core/config/project_settings.h"
|
||||
#include "core/math/transform_interpolator.h"
|
||||
#include "core/object/worker_thread_pool.h"
|
||||
#include "core/profiling/profiling.h"
|
||||
#include "renderer_canvas_cull.h"
|
||||
#include "renderer_scene_cull.h"
|
||||
#include "rendering_server_globals.h"
|
||||
@ -733,6 +734,7 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) {
|
||||
}
|
||||
|
||||
void RendererViewport::draw_viewports(bool p_swap_buffers) {
|
||||
GodotProfileZoneGroupedFirst(_profile_zone, "prepare viewports");
|
||||
timestamp_vp_map.clear();
|
||||
|
||||
#ifndef XR_DISABLED
|
||||
@ -750,6 +752,7 @@ void RendererViewport::draw_viewports(bool p_swap_buffers) {
|
||||
}
|
||||
|
||||
if (sorted_active_viewports_dirty) {
|
||||
GodotProfileZoneGrouped(_profile_zone, "_sort_active_viewports");
|
||||
sorted_active_viewports = _sort_active_viewports();
|
||||
sorted_active_viewports_dirty = false;
|
||||
}
|
||||
@ -758,11 +761,12 @@ void RendererViewport::draw_viewports(bool p_swap_buffers) {
|
||||
//draw viewports
|
||||
RENDER_TIMESTAMP("> Render Viewports");
|
||||
|
||||
GodotProfileZoneGrouped(_profile_zone, "render viewports");
|
||||
|
||||
//determine what is visible
|
||||
draw_viewports_pass++;
|
||||
|
||||
for (int i = sorted_active_viewports.size() - 1; i >= 0; i--) { //to compute parent dependency, must go in reverse draw order
|
||||
|
||||
Viewport *vp = sorted_active_viewports[i];
|
||||
|
||||
if (vp->update_mode == RS::VIEWPORT_UPDATE_DISABLED) {
|
||||
@ -821,6 +825,9 @@ void RendererViewport::draw_viewports(bool p_swap_buffers) {
|
||||
int draw_calls_used = 0;
|
||||
|
||||
for (int i = 0; i < sorted_active_viewports.size(); i++) {
|
||||
// TODO Somehow print the index
|
||||
GodotProfileZone("render viewport");
|
||||
|
||||
Viewport *vp = sorted_active_viewports[i];
|
||||
|
||||
if (vp->last_pass != draw_viewports_pass) {
|
||||
@ -925,6 +932,7 @@ void RendererViewport::draw_viewports(bool p_swap_buffers) {
|
||||
vertices_drawn += vp->render_info.info[RS::VIEWPORT_RENDER_INFO_TYPE_CANVAS][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME];
|
||||
draw_calls_used += vp->render_info.info[RS::VIEWPORT_RENDER_INFO_TYPE_CANVAS][RS::VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME];
|
||||
}
|
||||
|
||||
RSG::scene->set_debug_draw_mode(RS::VIEWPORT_DEBUG_DRAW_DISABLED);
|
||||
|
||||
total_objects_drawn = objects_drawn;
|
||||
@ -933,6 +941,7 @@ void RendererViewport::draw_viewports(bool p_swap_buffers) {
|
||||
|
||||
RENDER_TIMESTAMP("< Render Viewports");
|
||||
|
||||
GodotProfileZoneGrouped(_profile_zone, "rasterizer->blit_render_targets_to_screen");
|
||||
if (p_swap_buffers && !blit_to_screen_list.is_empty()) {
|
||||
for (const KeyValue<int, Vector<BlitToScreen>> &E : blit_to_screen_list) {
|
||||
RSG::rasterizer->blit_render_targets_to_screen(E.key, E.value.ptr(), E.value.size());
|
||||
|
||||
@ -37,6 +37,7 @@
|
||||
#include "core/config/project_settings.h"
|
||||
#include "core/io/dir_access.h"
|
||||
#include "core/io/file_access.h"
|
||||
#include "core/profiling/profiling.h"
|
||||
#include "modules/modules_enabled.gen.h"
|
||||
#include "servers/rendering/rendering_shader_container.h"
|
||||
|
||||
@ -6256,12 +6257,16 @@ String RenderingDevice::get_device_pipeline_cache_uuid() const {
|
||||
void RenderingDevice::swap_buffers(bool p_present) {
|
||||
ERR_RENDER_THREAD_GUARD();
|
||||
|
||||
GodotProfileZoneGroupedFirst(_profile_zone, "_end_frame");
|
||||
_end_frame();
|
||||
|
||||
GodotProfileZoneGrouped(_profile_zone, "_execute_frame");
|
||||
_execute_frame(p_present);
|
||||
|
||||
// Advance to the next frame and begin recording again.
|
||||
frame = (frame + 1) % frames.size();
|
||||
|
||||
GodotProfileZoneGrouped(_profile_zone, "_begin_frame");
|
||||
_begin_frame(true);
|
||||
}
|
||||
|
||||
@ -6389,27 +6394,34 @@ uint64_t RenderingDevice::get_memory_usage(MemoryType p_type) const {
|
||||
}
|
||||
|
||||
void RenderingDevice::_begin_frame(bool p_presented) {
|
||||
GodotProfileZoneGroupedFirst(_profile_zone, "_stall_for_frame");
|
||||
// Before writing to this frame, wait for it to be finished.
|
||||
_stall_for_frame(frame);
|
||||
|
||||
if (command_pool_reset_enabled) {
|
||||
GodotProfileZoneGrouped(_profile_zone, "driver->command_pool_reset");
|
||||
bool reset = driver->command_pool_reset(frames[frame].command_pool);
|
||||
ERR_FAIL_COND(!reset);
|
||||
}
|
||||
|
||||
if (p_presented) {
|
||||
GodotProfileZoneGrouped(_profile_zone, "update_perf_report");
|
||||
update_perf_report();
|
||||
driver->linear_uniform_set_pools_reset(frame);
|
||||
}
|
||||
|
||||
// Begin recording on the frame's command buffers.
|
||||
GodotProfileZoneGrouped(_profile_zone, "driver->begin_segment");
|
||||
driver->begin_segment(frame, frames_drawn++);
|
||||
GodotProfileZoneGrouped(_profile_zone, "driver->command_buffer_begin");
|
||||
driver->command_buffer_begin(frames[frame].command_buffer);
|
||||
|
||||
// Reset the graph.
|
||||
GodotProfileZoneGrouped(_profile_zone, "draw_graph.begin");
|
||||
draw_graph.begin();
|
||||
|
||||
// Erase pending resources.
|
||||
GodotProfileZoneGrouped(_profile_zone, "_free_pending_resources");
|
||||
_free_pending_resources(frame);
|
||||
|
||||
// Advance staging buffers if used.
|
||||
@ -6446,11 +6458,16 @@ void RenderingDevice::_end_frame() {
|
||||
|
||||
// The command buffer must be copied into a stack variable as the driver workarounds can change the command buffer in use.
|
||||
RDD::CommandBufferID command_buffer = frames[frame].command_buffer;
|
||||
GodotProfileZoneGroupedFirst(_profile_zone, "_submit_transfer_workers");
|
||||
_submit_transfer_workers(command_buffer);
|
||||
GodotProfileZoneGrouped(_profile_zone, "_submit_transfer_barriers");
|
||||
_submit_transfer_barriers(command_buffer);
|
||||
|
||||
GodotProfileZoneGrouped(_profile_zone, "draw_graph.end");
|
||||
draw_graph.end(RENDER_GRAPH_REORDER, RENDER_GRAPH_FULL_BARRIERS, command_buffer, frames[frame].command_buffer_pool);
|
||||
GodotProfileZoneGrouped(_profile_zone, "driver->command_buffer_end");
|
||||
driver->command_buffer_end(command_buffer);
|
||||
GodotProfileZoneGrouped(_profile_zone, "driver->end_segment");
|
||||
driver->end_segment();
|
||||
}
|
||||
|
||||
@ -6542,11 +6559,13 @@ void RenderingDevice::_stall_for_frame(uint32_t p_frame) {
|
||||
thread_local PackedByteArray packed_byte_array;
|
||||
|
||||
if (frames[p_frame].fence_signaled) {
|
||||
GodotProfileZoneGroupedFirst(_profile_zone, "driver->fence_wait");
|
||||
driver->fence_wait(frames[p_frame].fence);
|
||||
frames[p_frame].fence_signaled = false;
|
||||
|
||||
// Flush any pending requests for asynchronous buffer downloads.
|
||||
if (!frames[p_frame].download_buffer_get_data_requests.is_empty()) {
|
||||
GodotProfileZoneGrouped(_profile_zone, "flush asynchronous buffer downloads");
|
||||
for (uint32_t i = 0; i < frames[p_frame].download_buffer_get_data_requests.size(); i++) {
|
||||
const BufferGetDataRequest &request = frames[p_frame].download_buffer_get_data_requests[i];
|
||||
packed_byte_array.resize(request.size);
|
||||
@ -6571,6 +6590,7 @@ void RenderingDevice::_stall_for_frame(uint32_t p_frame) {
|
||||
|
||||
// Flush any pending requests for asynchronous texture downloads.
|
||||
if (!frames[p_frame].download_texture_get_data_requests.is_empty()) {
|
||||
GodotProfileZoneGrouped(_profile_zone, "flush asynchronous texture downloads");
|
||||
uint32_t pitch_step = driver->api_trait_get(RDD::API_TRAIT_TEXTURE_DATA_ROW_PITCH_STEP);
|
||||
for (uint32_t i = 0; i < frames[p_frame].download_texture_get_data_requests.size(); i++) {
|
||||
const TextureGetDataRequest &request = frames[p_frame].download_texture_get_data_requests[i];
|
||||
@ -6618,6 +6638,7 @@ void RenderingDevice::_stall_for_frame(uint32_t p_frame) {
|
||||
request.callback.call(packed_byte_array);
|
||||
}
|
||||
|
||||
GodotProfileZoneGrouped(_profile_zone, "clear buffers");
|
||||
frames[p_frame].download_texture_staging_buffers.clear();
|
||||
frames[p_frame].download_buffer_texture_copy_regions.clear();
|
||||
frames[p_frame].download_texture_mipmap_offsets.clear();
|
||||
|
||||
@ -31,6 +31,7 @@
|
||||
#include "rendering_server_default.h"
|
||||
|
||||
#include "core/os/os.h"
|
||||
#include "core/profiling/profiling.h"
|
||||
#include "renderer_canvas_cull.h"
|
||||
#include "renderer_scene_cull.h"
|
||||
#include "rendering_server_globals.h"
|
||||
@ -66,6 +67,7 @@ void RenderingServerDefault::request_frame_drawn_callback(const Callable &p_call
|
||||
}
|
||||
|
||||
void RenderingServerDefault::_draw(bool p_swap_buffers, double frame_step) {
|
||||
GodotProfileZoneGroupedFirst(_profile_zone, "rasterizer->begin_frame");
|
||||
RSG::rasterizer->begin_frame(frame_step);
|
||||
|
||||
TIMESTAMP_BEGIN()
|
||||
@ -75,6 +77,7 @@ void RenderingServerDefault::_draw(bool p_swap_buffers, double frame_step) {
|
||||
RENDER_TIMESTAMP("Prepare Render Frame");
|
||||
|
||||
#ifndef XR_DISABLED
|
||||
GodotProfileZoneGrouped(_profile_zone, "xr_server->pre_render");
|
||||
XRServer *xr_server = XRServer::get_singleton();
|
||||
if (xr_server != nullptr) {
|
||||
// Let XR server know we're about to render a frame.
|
||||
@ -82,30 +85,41 @@ void RenderingServerDefault::_draw(bool p_swap_buffers, double frame_step) {
|
||||
}
|
||||
#endif // XR_DISABLED
|
||||
|
||||
GodotProfileZoneGrouped(_profile_zone, "scene->update");
|
||||
RSG::scene->update(); //update scenes stuff before updating instances
|
||||
GodotProfileZoneGrouped(_profile_zone, "canvas->update");
|
||||
RSG::canvas->update();
|
||||
|
||||
frame_setup_time = double(OS::get_singleton()->get_ticks_usec() - time_usec) / 1000.0;
|
||||
|
||||
GodotProfileZoneGrouped(_profile_zone, "particles_storage->update_particles");
|
||||
RSG::particles_storage->update_particles(); //need to be done after instances are updated (colliders and particle transforms), and colliders are rendered
|
||||
|
||||
GodotProfileZoneGrouped(_profile_zone, "scene->render_probes");
|
||||
RSG::scene->render_probes();
|
||||
|
||||
GodotProfileZoneGrouped(_profile_zone, "viewport->draw_viewports");
|
||||
RSG::viewport->draw_viewports(p_swap_buffers);
|
||||
|
||||
GodotProfileZoneGrouped(_profile_zone, "canvas_render->update");
|
||||
RSG::canvas_render->update();
|
||||
|
||||
GodotProfileZoneGrouped(_profile_zone, "rasterizer->end_frame");
|
||||
RSG::rasterizer->end_frame(p_swap_buffers);
|
||||
|
||||
#ifndef XR_DISABLED
|
||||
if (xr_server != nullptr) {
|
||||
GodotProfileZone("xr_server->end_frame");
|
||||
// let our XR server know we're done so we can get our frame timing
|
||||
xr_server->end_frame();
|
||||
}
|
||||
#endif // XR_DISABLED
|
||||
|
||||
GodotProfileZoneGrouped(_profile_zone, "update_visibility_notifiers");
|
||||
RSG::canvas->update_visibility_notifiers();
|
||||
RSG::scene->update_visibility_notifiers();
|
||||
|
||||
GodotProfileZoneGrouped(_profile_zone, "post_draw_steps");
|
||||
if (create_thread) {
|
||||
callable_mp(this, &RenderingServerDefault::_run_post_draw_steps).call_deferred();
|
||||
} else {
|
||||
@ -113,6 +127,7 @@ void RenderingServerDefault::_draw(bool p_swap_buffers, double frame_step) {
|
||||
}
|
||||
|
||||
if (RSG::utilities->get_captured_timestamps_count()) {
|
||||
GodotProfileZoneGrouped(_profile_zone, "frame_profile");
|
||||
Vector<FrameProfileArea> new_profile;
|
||||
if (RSG::utilities->capturing_timestamps) {
|
||||
new_profile.resize(RSG::utilities->get_captured_timestamps_count());
|
||||
@ -143,6 +158,7 @@ void RenderingServerDefault::_draw(bool p_swap_buffers, double frame_step) {
|
||||
frame_profile_frame = RSG::utilities->get_captured_timestamps_frame();
|
||||
|
||||
if (print_gpu_profile) {
|
||||
GodotProfileZoneGrouped(_profile_zone, "gpu_profile");
|
||||
if (print_frame_profile_ticks_from == 0) {
|
||||
print_frame_profile_ticks_from = OS::get_singleton()->get_ticks_usec();
|
||||
}
|
||||
@ -185,6 +201,7 @@ void RenderingServerDefault::_draw(bool p_swap_buffers, double frame_step) {
|
||||
}
|
||||
}
|
||||
|
||||
GodotProfileZoneGrouped(_profile_zone, "memory_info");
|
||||
RSG::utilities->update_memory_info();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user