summaryrefslogtreecommitdiff
path: root/servers
diff options
context:
space:
mode:
authorJuan Linietsky <reduzio@gmail.com>2019-09-20 17:58:06 -0300
committerJuan Linietsky <reduzio@gmail.com>2020-02-11 12:01:26 +0100
commit123ee5995c989d7c2f0bb320fe94ef1702a48c13 (patch)
tree97855b3218f56dcaaeb5e737bf1a919f28ac36db /servers
parentdc32083681a770e9d7e332c5beed30b52c793752 (diff)
Visual GPU profiler and related profiling support in Vulkan.
Diffstat (limited to 'servers')
-rw-r--r--servers/visual/rasterizer.h14
-rw-r--r--servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.cpp13
-rw-r--r--servers/visual/rasterizer_rd/rasterizer_storage_rd.cpp25
-rw-r--r--servers/visual/rasterizer_rd/rasterizer_storage_rd.h8
-rw-r--r--servers/visual/rendering_device.h12
-rw-r--r--servers/visual/visual_server_canvas.cpp8
-rw-r--r--servers/visual/visual_server_raster.cpp37
-rw-r--r--servers/visual/visual_server_raster.h7
-rw-r--r--servers/visual/visual_server_scene.cpp18
-rw-r--r--servers/visual/visual_server_viewport.cpp18
-rw-r--r--servers/visual/visual_server_wrap_mt.h12
-rw-r--r--servers/visual_server.h10
12 files changed, 181 insertions, 1 deletions
diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h
index f5ce604b04..02d44c5c5d 100644
--- a/servers/visual/rasterizer.h
+++ b/servers/visual/rasterizer.h
@@ -638,6 +638,20 @@ public:
Color get_default_clear_color() const {
return default_clear_color;
}
+#define RENDER_TIMESTAMP(m_text) \
+ { \
+ if (VSG::storage->capturing_timestamps) VSG::storage->capture_timestamp(m_text); \
+ }
+
+ bool capturing_timestamps = false;
+
+ virtual void capture_timestamps_begin() = 0;
+ virtual void capture_timestamp(const String &p_name) = 0;
+ virtual uint32_t get_captured_timestamps_count() const = 0;
+ virtual uint64_t get_captured_timestamps_frame() const = 0;
+ virtual uint64_t get_captured_timestamp_gpu_time(uint32_t p_index) const = 0;
+ virtual uint64_t get_captured_timestamp_cpu_time(uint32_t p_index) const = 0;
+ virtual String get_captured_timestamp_name(uint32_t p_index) const = 0;
RasterizerStorage();
virtual ~RasterizerStorage() {}
diff --git a/servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.cpp b/servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.cpp
index 82a5d8ba65..2ef331291a 100644
--- a/servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.cpp
+++ b/servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.cpp
@@ -1654,6 +1654,8 @@ void RasterizerSceneForwardRD::_render_scene(RenderBufferData *p_buffer_data, co
}
#endif
+ RENDER_TIMESTAMP("Setup 3D Scene");
+
bool using_shadows = true;
if (p_reflection_probe.is_valid()) {
@@ -2085,6 +2087,8 @@ void RasterizerSceneForwardRD::_render_scene(RenderBufferData *p_buffer_data, co
}
}
+ RENDER_TIMESTAMP("Render Opaque Pass");
+
_setup_render_base_uniform_set(RID(), RID(), RID(), RID(), radiance_cubemap, p_shadow_atlas, p_reflection_atlas);
render_list.sort_by_key(false);
@@ -2104,6 +2108,7 @@ void RasterizerSceneForwardRD::_render_scene(RenderBufferData *p_buffer_data, co
}
if (draw_sky) {
+ RENDER_TIMESTAMP("Render Sky");
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(opaque_framebuffer, RD::INITIAL_ACTION_CONTINUE, can_continue ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ_COLOR_AND_DEPTH);
_draw_sky(draw_list, RD::get_singleton()->framebuffer_get_format(opaque_framebuffer), p_environment, p_cam_projection, p_cam_transform, 1.0);
RD::get_singleton()->draw_list_end();
@@ -2201,6 +2206,9 @@ void RasterizerSceneForwardRD::_render_scene(RenderBufferData *p_buffer_data, co
glEnable(GL_DEPTH_TEST);
glDisable(GL_SCISSOR_TEST);
#endif
+
+ RENDER_TIMESTAMP("Render Transparent Pass");
+
render_list.sort_by_reverse_depth_and_priority(true);
_fill_instances(&render_list.elements[render_list.max_elements - render_list.alpha_element_count], render_list.alpha_element_count);
@@ -2232,6 +2240,7 @@ void RasterizerSceneForwardRD::_render_scene(RenderBufferData *p_buffer_data, co
RasterizerEffectsRD *effects = storage->get_effects();
{
+ RENDER_TIMESTAMP("Tonemap");
//tonemap
RasterizerEffectsRD::TonemapSettings tonemap;
@@ -2326,6 +2335,8 @@ void RasterizerSceneForwardRD::_render_scene(RenderBufferData *p_buffer_data, co
}
void RasterizerSceneForwardRD::_render_shadow(RID p_framebuffer, InstanceBase **p_cull_result, int p_cull_count, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip) {
+ RENDER_TIMESTAMP("Setup Rendering Shadow");
+
render_pass++;
scene_state.ubo.shadow_z_offset = p_bias;
@@ -2343,6 +2354,8 @@ void RasterizerSceneForwardRD::_render_shadow(RID p_framebuffer, InstanceBase **
_setup_render_base_uniform_set(RID(), RID(), RID(), RID(), RID(), RID(), RID());
+ RENDER_TIMESTAMP("Render Shadow");
+
render_list.sort_by_key(false);
_fill_instances(render_list.elements, render_list.element_count);
diff --git a/servers/visual/rasterizer_rd/rasterizer_storage_rd.cpp b/servers/visual/rasterizer_rd/rasterizer_storage_rd.cpp
index e73efa1e12..639b78ec79 100644
--- a/servers/visual/rasterizer_rd/rasterizer_storage_rd.cpp
+++ b/servers/visual/rasterizer_rd/rasterizer_storage_rd.cpp
@@ -3656,6 +3656,31 @@ RasterizerEffectsRD *RasterizerStorageRD::get_effects() {
return &effects;
}
+void RasterizerStorageRD::capture_timestamps_begin() {
+ RD::get_singleton()->capture_timestamp("Frame Begin", false);
+}
+
+void RasterizerStorageRD::capture_timestamp(const String &p_name) {
+ RD::get_singleton()->capture_timestamp(p_name, true);
+}
+
+uint32_t RasterizerStorageRD::get_captured_timestamps_count() const {
+ return RD::get_singleton()->get_captured_timestamps_count();
+}
+uint64_t RasterizerStorageRD::get_captured_timestamps_frame() const {
+ return RD::get_singleton()->get_captured_timestamps_frame();
+}
+
+uint64_t RasterizerStorageRD::get_captured_timestamp_gpu_time(uint32_t p_index) const {
+ return RD::get_singleton()->get_captured_timestamp_gpu_time(p_index);
+}
+uint64_t RasterizerStorageRD::get_captured_timestamp_cpu_time(uint32_t p_index) const {
+ return RD::get_singleton()->get_captured_timestamp_cpu_time(p_index);
+}
+String RasterizerStorageRD::get_captured_timestamp_name(uint32_t p_index) const {
+ return RD::get_singleton()->get_captured_timestamp_name(p_index);
+}
+
RasterizerStorageRD::RasterizerStorageRD() {
for (int i = 0; i < SHADER_TYPE_MAX; i++) {
diff --git a/servers/visual/rasterizer_rd/rasterizer_storage_rd.h b/servers/visual/rasterizer_rd/rasterizer_storage_rd.h
index ef22a6689b..670c97a1c1 100644
--- a/servers/visual/rasterizer_rd/rasterizer_storage_rd.h
+++ b/servers/visual/rasterizer_rd/rasterizer_storage_rd.h
@@ -1018,6 +1018,14 @@ public:
String get_video_adapter_name() const { return String(); }
String get_video_adapter_vendor() const { return String(); }
+ virtual void capture_timestamps_begin();
+ virtual void capture_timestamp(const String &p_name);
+ virtual uint32_t get_captured_timestamps_count() const;
+ virtual uint64_t get_captured_timestamps_frame() const;
+ virtual uint64_t get_captured_timestamp_gpu_time(uint32_t p_index) const;
+ virtual uint64_t get_captured_timestamp_cpu_time(uint32_t p_index) const;
+ virtual String get_captured_timestamp_name(uint32_t p_index) const;
+
static RasterizerStorage *base_singleton;
RasterizerEffectsRD *get_effects();
diff --git a/servers/visual/rendering_device.h b/servers/visual/rendering_device.h
index 32d5520c0a..859a9e798c 100644
--- a/servers/visual/rendering_device.h
+++ b/servers/visual/rendering_device.h
@@ -937,6 +937,17 @@ public:
virtual void free(RID p_id) = 0;
/****************/
+ /**** Timing ****/
+ /****************/
+
+ virtual void capture_timestamp(const String &p_name, bool p_sync_to_draw) = 0;
+ virtual uint32_t get_captured_timestamps_count() const = 0;
+ virtual uint64_t get_captured_timestamps_frame() const = 0;
+ virtual uint64_t get_captured_timestamp_gpu_time(uint32_t p_index) const = 0;
+ virtual uint64_t get_captured_timestamp_cpu_time(uint32_t p_index) const = 0;
+ virtual String get_captured_timestamp_name(uint32_t p_index) const = 0;
+
+ /****************/
/**** LIMITS ****/
/****************/
@@ -976,6 +987,7 @@ public:
virtual void prepare_screen_for_drawing() = 0;
virtual void finalize_frame() = 0;
virtual void advance_frame() = 0;
+ virtual uint32_t get_frame_delay() const = 0;
static RenderingDevice *get_singleton();
diff --git a/servers/visual/visual_server_canvas.cpp b/servers/visual/visual_server_canvas.cpp
index 80d7f70f2b..69f843eb4b 100644
--- a/servers/visual/visual_server_canvas.cpp
+++ b/servers/visual/visual_server_canvas.cpp
@@ -37,6 +37,8 @@ static const int z_range = VS::CANVAS_ITEM_Z_MAX - VS::CANVAS_ITEM_Z_MIN + 1;
void VisualServerCanvas::_render_canvas_item_tree(RID p_to_render_target, Canvas::ChildItem *p_child_items, int p_child_item_count, Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RasterizerCanvas::Light *p_lights) {
+ RENDER_TIMESTAMP("Cull CanvasItem Tree");
+
memset(z_list, 0, z_range * sizeof(RasterizerCanvas::Item *));
memset(z_last_list, 0, z_range * sizeof(RasterizerCanvas::Item *));
@@ -62,6 +64,8 @@ void VisualServerCanvas::_render_canvas_item_tree(RID p_to_render_target, Canvas
}
}
+ RENDER_TIMESTAMP("Render Canvas Items");
+
VSG::canvas_render->canvas_render_items(p_to_render_target, list, p_modulate, p_lights, p_transform);
}
@@ -240,6 +244,8 @@ void VisualServerCanvas::_light_mask_canvas_items(int p_z, RasterizerCanvas::Ite
void VisualServerCanvas::render_canvas(RID p_render_target, Canvas *p_canvas, const Transform2D &p_transform, RasterizerCanvas::Light *p_lights, RasterizerCanvas::Light *p_masked_lights, const Rect2 &p_clip_rect) {
+ RENDER_TIMESTAMP(">Render Canvas");
+
if (p_canvas->children_order_dirty) {
p_canvas->child_items.sort();
@@ -286,6 +292,8 @@ void VisualServerCanvas::render_canvas(RID p_render_target, Canvas *p_canvas, co
}
}
}
+
+ RENDER_TIMESTAMP("<End Render Canvas");
}
RID VisualServerCanvas::canvas_create() {
diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp
index 2f25b8b015..513393c9c9 100644
--- a/servers/visual/visual_server_raster.cpp
+++ b/servers/visual/visual_server_raster.cpp
@@ -103,12 +103,14 @@ void VisualServerRaster::draw(bool p_swap_buffers, double frame_step) {
VSG::rasterizer->begin_frame(frame_step);
+ VSG::storage->capture_timestamps_begin();
+
VSG::scene_render->update(); //update scenes stuff before updating instances
VSG::scene->update_dirty_instances(); //update scene stuff
- VSG::viewport->draw_viewports();
VSG::scene->render_probes();
+ VSG::viewport->draw_viewports();
VSG::canvas_render->update();
_draw_margins();
@@ -130,6 +132,25 @@ void VisualServerRaster::draw(bool p_swap_buffers, double frame_step) {
frame_drawn_callbacks.pop_front();
}
VS::get_singleton()->emit_signal("frame_post_draw");
+
+ if (VSG::storage->get_captured_timestamps_count()) {
+ Vector<FrameProfileArea> new_profile;
+ new_profile.resize(VSG::storage->get_captured_timestamps_count());
+
+ uint64_t base_cpu = VSG::storage->get_captured_timestamp_cpu_time(0);
+ uint64_t base_gpu = VSG::storage->get_captured_timestamp_gpu_time(0);
+ for (int i = 0; i < VSG::storage->get_captured_timestamps_count(); i++) {
+ uint64_t time_cpu = VSG::storage->get_captured_timestamp_cpu_time(i) - base_cpu;
+ uint64_t time_gpu = VSG::storage->get_captured_timestamp_gpu_time(i) - base_gpu;
+ new_profile.write[i].gpu_msec = float(time_gpu / 1000) / 1000.0;
+ new_profile.write[i].cpu_msec = float(time_cpu) / 1000.0;
+ new_profile.write[i].name = VSG::storage->get_captured_timestamp_name(i);
+ }
+
+ frame_profile = new_profile;
+ }
+
+ frame_profile_frame = VSG::storage->get_captured_timestamps_frame();
}
void VisualServerRaster::sync() {
}
@@ -167,6 +188,18 @@ String VisualServerRaster::get_video_adapter_vendor() const {
return VSG::storage->get_video_adapter_vendor();
}
+void VisualServerRaster::set_frame_profiling_enabled(bool p_enable) {
+ VSG::storage->capturing_timestamps = p_enable;
+}
+
+uint64_t VisualServerRaster::get_frame_profile_frame() {
+ return frame_profile_frame;
+}
+
+Vector<VisualServer::FrameProfileArea> VisualServerRaster::get_frame_profile() {
+ return frame_profile;
+}
+
/* TESTING */
void VisualServerRaster::set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale, bool p_use_filter) {
@@ -217,6 +250,8 @@ VisualServerRaster::VisualServerRaster() {
VSG::canvas_render = VSG::rasterizer->get_canvas();
VSG::scene_render = VSG::rasterizer->get_scene();
+ frame_profile_frame = 0;
+
for (int i = 0; i < 4; i++) {
black_margin[i] = 0;
black_image[i] = RID();
diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h
index 8543289083..510296f11c 100644
--- a/servers/visual/visual_server_raster.h
+++ b/servers/visual/visual_server_raster.h
@@ -72,6 +72,9 @@ class VisualServerRaster : public VisualServer {
void _draw_margins();
static void _changes_changed() {}
+ uint64_t frame_profile_frame;
+ Vector<FrameProfileArea> frame_profile;
+
public:
//if editor is redrawing when it shouldn't, enable this and put a breakpoint in _changes_changed()
//#define DEBUG_CHANGES
@@ -693,6 +696,10 @@ public:
virtual String get_video_adapter_name() const;
virtual String get_video_adapter_vendor() const;
+ virtual void set_frame_profiling_enabled(bool p_enable);
+ virtual Vector<FrameProfileArea> get_frame_profile();
+ virtual uint64_t get_frame_profile_frame();
+
virtual RID get_test_cube();
/* TESTING */
diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp
index 96831d1cc2..f240f91b12 100644
--- a/servers/visual/visual_server_scene.cpp
+++ b/servers/visual/visual_server_scene.cpp
@@ -1366,6 +1366,8 @@ bool VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
for (int i = 0; i < splits; i++) {
+ RENDER_TIMESTAMP("Culling Directional Light split" + itos(i));
+
// setup a camera matrix for that range!
CameraMatrix camera_matrix;
@@ -1551,6 +1553,7 @@ bool VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
for (int i = 0; i < 2; i++) {
//using this one ensures that raster deferred will have it
+ RENDER_TIMESTAMP("Culling Shadow Paraboloid" + itos(i));
float radius = VSG::storage->light_get_param(p_instance->base, VS::LIGHT_PARAM_RANGE);
@@ -1594,6 +1597,7 @@ bool VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
for (int i = 0; i < 6; i++) {
+ RENDER_TIMESTAMP("Culling Shadow Cube side" + itos(i));
//using this one ensures that raster deferred will have it
static const Vector3 view_normals[6] = {
@@ -1647,6 +1651,8 @@ bool VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
} break;
case VS::LIGHT_SPOT: {
+ RENDER_TIMESTAMP("Culling Spot Light");
+
float radius = VSG::storage->light_get_param(p_instance->base, VS::LIGHT_PARAM_RANGE);
float angle = VSG::storage->light_get_param(p_instance->base, VS::LIGHT_PARAM_SPOT_ANGLE);
@@ -1829,6 +1835,8 @@ void VisualServerScene::_prepare_scene(const Transform p_cam_transform, const Ca
VSG::scene_render->set_scene_pass(render_pass);
+ RENDER_TIMESTAMP("Frustum Culling");
+
//rasterizer->set_camera(camera->transform, camera_matrix,ortho);
Vector<Plane> planes = p_cam_projection.get_projection_planes(p_cam_transform);
@@ -2037,7 +2045,11 @@ void VisualServerScene::_prepare_scene(const Transform p_cam_transform, const Ca
for (int i = 0; i < directional_shadow_count; i++) {
+ RENDER_TIMESTAMP(">Rendering Directional Light " + itos(i));
+
_light_instance_update_shadow(lights_with_shadow[i], p_cam_transform, p_cam_projection, p_cam_orthogonal, p_shadow_atlas, scenario);
+
+ RENDER_TIMESTAMP("<Rendering Directional Light " + itos(i));
}
}
@@ -2136,7 +2148,9 @@ void VisualServerScene::_prepare_scene(const Transform p_cam_transform, const Ca
if (redraw) {
//must redraw!
+ RENDER_TIMESTAMP(">Rendering Light " + itos(i));
light->shadow_dirty = _light_instance_update_shadow(ins, p_cam_transform, p_cam_projection, p_cam_orthogonal, p_shadow_atlas, scenario);
+ RENDER_TIMESTAMP("<Rendering Light " + itos(i));
}
}
}
@@ -2158,6 +2172,7 @@ void VisualServerScene::_render_scene(RID p_render_buffers, const Transform p_ca
/* PROCESS GEOMETRY AND DRAW SCENE */
+ RENDER_TIMESTAMP("Render Scene ");
VSG::scene_render->render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_orthogonal, (RasterizerScene::InstanceBase **)instance_cull_result, instance_cull_count, light_instance_cull_result, light_cull_count + directional_light_count, reflection_probe_instance_cull_result, reflection_probe_cull_count, environment, p_shadow_atlas, p_reflection_probe.is_valid() ? RID() : scenario->reflection_atlas, p_reflection_probe, p_reflection_probe_pass);
}
@@ -2172,6 +2187,7 @@ void VisualServerScene::render_empty_scene(RID p_render_buffers, RID p_scenario,
environment = scenario->environment;
else
environment = scenario->fallback_environment;
+ RENDER_TIMESTAMP("Render Empty Scene ");
VSG::scene_render->render_scene(p_render_buffers, Transform(), CameraMatrix(), true, NULL, 0, NULL, 0, NULL, 0, environment, p_shadow_atlas, scenario->reflection_atlas, RID(), 0);
#endif
}
@@ -2236,11 +2252,13 @@ bool VisualServerScene::_render_reflection_probe_step(Instance *p_instance, int
shadow_atlas = scenario->reflection_probe_shadow_atlas;
}
+ RENDER_TIMESTAMP("Render Reflection Probe, Step " + itos(p_step));
_prepare_scene(xform, cm, false, RID(), VSG::storage->reflection_probe_get_cull_mask(p_instance->base), p_instance->scenario->self, shadow_atlas, reflection_probe->instance, use_shadows);
_render_scene(RID(), xform, cm, false, RID(), p_instance->scenario->self, shadow_atlas, reflection_probe->instance, p_step);
} else {
//do roughness postprocess step until it believes it's done
+ RENDER_TIMESTAMP("Post-Process Reflection Probe, Step " + itos(p_step));
return VSG::scene_render->reflection_probe_instance_postprocess_step(reflection_probe->instance);
}
diff --git a/servers/visual/visual_server_viewport.cpp b/servers/visual/visual_server_viewport.cpp
index 75a90d988b..0bb16003a1 100644
--- a/servers/visual/visual_server_viewport.cpp
+++ b/servers/visual/visual_server_viewport.cpp
@@ -64,6 +64,8 @@ static Transform2D _canvas_get_transform(VisualServerViewport::Viewport *p_viewp
void VisualServerViewport::_draw_3d(Viewport *p_viewport, ARVRInterface::Eyes p_eye) {
+ RENDER_TIMESTAMP(">Begin Rendering 3D Scene");
+
Ref<ARVRInterface> arvr_interface;
if (ARVRServer::get_singleton() != NULL) {
arvr_interface = ARVRServer::get_singleton()->get_primary_interface();
@@ -74,6 +76,7 @@ void VisualServerViewport::_draw_3d(Viewport *p_viewport, ARVRInterface::Eyes p_
} else {
VSG::scene->render_camera(p_viewport->render_buffers, p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas);
}
+ RENDER_TIMESTAMP("<End Rendering 3D Scene");
}
void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::Eyes p_eye) {
@@ -132,6 +135,7 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E
int light_count = 0;
+ RENDER_TIMESTAMP("Cull Canvas Lights");
for (Map<RID, Viewport::CanvasData>::Element *E = p_viewport->canvas_map.front(); E; E = E->next()) {
VisualServerCanvas::Canvas *canvas = static_cast<VisualServerCanvas::Canvas *>(E->get().canvas);
@@ -194,6 +198,9 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E
RasterizerCanvas::LightOccluderInstance *occluders = NULL;
+ RENDER_TIMESTAMP(">Render 2D Shadows");
+ RENDER_TIMESTAMP("Cull Occluders");
+
//make list of occluders
for (Map<RID, Viewport::CanvasData>::Element *E = p_viewport->canvas_map.front(); E; E = E->next()) {
@@ -213,14 +220,18 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E
}
}
//update the light shadowmaps with them
+
RasterizerCanvas::Light *light = lights_with_shadow;
while (light) {
+ RENDER_TIMESTAMP("Render Shadow");
+
VSG::canvas_render->light_update_shadow(light->light_internal, light->xform_cache.affine_inverse(), light->item_shadow_mask, light->radius_cache / 1000.0, light->radius_cache * 1.1, occluders);
light = light->shadows_next_ptr;
}
//VSG::canvas_render->reset_canvas();
+ RENDER_TIMESTAMP("<End rendering 2D Shadows");
}
if (scenario_draw_canvas_bg && canvas_map.front() && canvas_map.front()->key().get_layer() > scenario_canvas_max_layer) {
@@ -303,6 +314,8 @@ void VisualServerViewport::draw_viewports() {
Map<int, Vector<Rasterizer::BlitToScreen> > blit_to_screen_list;
//draw viewports
+ RENDER_TIMESTAMP(">Render Viewports");
+
for (int i = 0; i < active_viewports.size(); i++) {
Viewport *vp = active_viewports[i];
@@ -321,6 +334,8 @@ void VisualServerViewport::draw_viewports() {
if (!visible)
continue;
+ RENDER_TIMESTAMP(">Rendering Viewport " + itos(i));
+
VSG::storage->render_target_set_as_unused(vp->render_target);
#if 0
if (vp->use_arvr && arvr_interface.is_valid()) {
@@ -391,9 +406,12 @@ void VisualServerViewport::draw_viewports() {
if (vp->update_mode == VS::VIEWPORT_UPDATE_ONCE) {
vp->update_mode = VS::VIEWPORT_UPDATE_DISABLED;
}
+
+ RENDER_TIMESTAMP("<Rendering Viewport " + itos(i));
}
VSG::scene_render->set_debug_draw_mode(VS::VIEWPORT_DEBUG_DRAW_DISABLED);
+ RENDER_TIMESTAMP("<Render Viewports");
//this needs to be called to make screen swapping more efficient
VSG::rasterizer->prepare_for_blitting_render_targets();
diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h
index a58d36f279..e1873e5999 100644
--- a/servers/visual/visual_server_wrap_mt.h
+++ b/servers/visual/visual_server_wrap_mt.h
@@ -628,6 +628,18 @@ public:
return visual_server->is_low_end();
}
+ virtual uint64_t get_frame_profile_frame() {
+ return visual_server->get_frame_profile_frame();
+ }
+
+ virtual void set_frame_profiling_enabled(bool p_enabled) {
+ visual_server->set_frame_profiling_enabled(p_enabled);
+ }
+
+ virtual Vector<FrameProfileArea> get_frame_profile() {
+ return visual_server->get_frame_profile();
+ }
+
VisualServerWrapMT(VisualServer *p_contained, bool p_create_thread);
~VisualServerWrapMT();
diff --git a/servers/visual_server.h b/servers/visual_server.h
index 06dba99860..4c89e3d976 100644
--- a/servers/visual_server.h
+++ b/servers/visual_server.h
@@ -1027,6 +1027,16 @@ public:
virtual String get_video_adapter_name() const = 0;
virtual String get_video_adapter_vendor() const = 0;
+ struct FrameProfileArea {
+ String name;
+ float gpu_msec;
+ float cpu_msec;
+ };
+
+ virtual void set_frame_profiling_enabled(bool p_enable) = 0;
+ virtual Vector<FrameProfileArea> get_frame_profile() = 0;
+ virtual uint64_t get_frame_profile_frame() = 0;
+
/* Materials for 2D on 3D */
/* TESTING */