diff options
author | Juan Linietsky <reduzio@gmail.com> | 2019-09-20 17:58:06 -0300 |
---|---|---|
committer | Juan Linietsky <reduzio@gmail.com> | 2020-02-11 12:01:26 +0100 |
commit | 123ee5995c989d7c2f0bb320fe94ef1702a48c13 (patch) | |
tree | 97855b3218f56dcaaeb5e737bf1a919f28ac36db /servers | |
parent | dc32083681a770e9d7e332c5beed30b52c793752 (diff) |
Visual GPU profiler and related profiling support in Vulkan.
Diffstat (limited to 'servers')
-rw-r--r-- | servers/visual/rasterizer.h | 14 | ||||
-rw-r--r-- | servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.cpp | 13 | ||||
-rw-r--r-- | servers/visual/rasterizer_rd/rasterizer_storage_rd.cpp | 25 | ||||
-rw-r--r-- | servers/visual/rasterizer_rd/rasterizer_storage_rd.h | 8 | ||||
-rw-r--r-- | servers/visual/rendering_device.h | 12 | ||||
-rw-r--r-- | servers/visual/visual_server_canvas.cpp | 8 | ||||
-rw-r--r-- | servers/visual/visual_server_raster.cpp | 37 | ||||
-rw-r--r-- | servers/visual/visual_server_raster.h | 7 | ||||
-rw-r--r-- | servers/visual/visual_server_scene.cpp | 18 | ||||
-rw-r--r-- | servers/visual/visual_server_viewport.cpp | 18 | ||||
-rw-r--r-- | servers/visual/visual_server_wrap_mt.h | 12 | ||||
-rw-r--r-- | servers/visual_server.h | 10 |
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 */ |