bevy_render2: Add tracing spans around render subapp and stages (#2907)

Add tracing spans around the renderer subapp and render stages in bevy_render2 to allow profiling / visualisation of stages.
From:
<img width="1181" alt="Screenshot 2021-10-02 122336" src="https://user-images.githubusercontent.com/302146/135712361-8aec28ae-0f1e-4c27-9b6e-ca5e5f45d6b9.png">
To:
<img width="1229" alt="Screenshot 2021-10-02 122509" src="https://user-images.githubusercontent.com/302146/135712365-6414d424-4e15-4265-9952-483876da9f9a.png">
This commit is contained in:
Robert Swain 2021-10-02 19:16:32 +00:00
parent d2bba8cb15
commit 44ed7e32d8
3 changed files with 100 additions and 45 deletions

View file

@ -15,7 +15,7 @@ categories = ["game-engines", "graphics", "gui", "rendering"]
[features]
wgpu_trace = ["bevy_wgpu/trace"]
trace = [ "bevy_app/trace", "bevy_ecs/trace" ]
trace = [ "bevy_app/trace", "bevy_ecs/trace", "bevy_render2/trace" ]
trace_chrome = [ "bevy_log/tracing-chrome" ]
# Image format support for texture loading (PNG and HDR are enabled by default)

View file

@ -51,3 +51,4 @@ dds = ["image/dds"]
tga = ["image/tga"]
jpeg = ["image/jpeg"]
bmp = ["image/bmp"]
trace = []

View file

@ -120,58 +120,112 @@ impl Plugin for RenderPlugin {
.init_resource::<RenderGraph>();
app.add_sub_app(RenderApp, render_app, move |app_world, render_app| {
// reserve all existing app entities for use in render_app
// they can only be spawned using `get_or_spawn()`
let meta_len = app_world.entities().meta.len();
render_app
.world
.entities()
.reserve_entities(meta_len as u32);
#[cfg(feature = "trace")]
let render_span = bevy_utils::tracing::info_span!("renderer subapp");
#[cfg(feature = "trace")]
let _render_guard = render_span.enter();
{
#[cfg(feature = "trace")]
let stage_span =
bevy_utils::tracing::info_span!("stage", name = "reserve_and_flush");
#[cfg(feature = "trace")]
let _stage_guard = stage_span.enter();
// flushing as "invalid" ensures that app world entities aren't added as "empty archetype" entities by default
// these entities cannot be accessed without spawning directly onto them
// this _only_ works as expected because clear_entities() is called at the end of every frame.
render_app.world.entities_mut().flush_as_invalid();
// reserve all existing app entities for use in render_app
// they can only be spawned using `get_or_spawn()`
let meta_len = app_world.entities().meta.len();
render_app
.world
.entities()
.reserve_entities(meta_len as u32);
// extract
extract(app_world, render_app);
// flushing as "invalid" ensures that app world entities aren't added as "empty archetype" entities by default
// these entities cannot be accessed without spawning directly onto them
// this _only_ works as expected because clear_entities() is called at the end of every frame.
render_app.world.entities_mut().flush_as_invalid();
}
// prepare
let prepare = render_app
.schedule
.get_stage_mut::<SystemStage>(&RenderStage::Prepare)
.unwrap();
prepare.run(&mut render_app.world);
{
#[cfg(feature = "trace")]
let stage_span = bevy_utils::tracing::info_span!("stage", name = "extract");
#[cfg(feature = "trace")]
let _stage_guard = stage_span.enter();
// queue
let queue = render_app
.schedule
.get_stage_mut::<SystemStage>(&RenderStage::Queue)
.unwrap();
queue.run(&mut render_app.world);
// extract
extract(app_world, render_app);
}
// phase sort
let phase_sort = render_app
.schedule
.get_stage_mut::<SystemStage>(&RenderStage::PhaseSort)
.unwrap();
phase_sort.run(&mut render_app.world);
{
#[cfg(feature = "trace")]
let stage_span = bevy_utils::tracing::info_span!("stage", name = "prepare");
#[cfg(feature = "trace")]
let _stage_guard = stage_span.enter();
// render
let render = render_app
.schedule
.get_stage_mut::<SystemStage>(&RenderStage::Render)
.unwrap();
render.run(&mut render_app.world);
// prepare
let prepare = render_app
.schedule
.get_stage_mut::<SystemStage>(&RenderStage::Prepare)
.unwrap();
prepare.run(&mut render_app.world);
}
// cleanup
let cleanup = render_app
.schedule
.get_stage_mut::<SystemStage>(&RenderStage::Cleanup)
.unwrap();
cleanup.run(&mut render_app.world);
{
#[cfg(feature = "trace")]
let stage_span = bevy_utils::tracing::info_span!("stage", name = "queue");
#[cfg(feature = "trace")]
let _stage_guard = stage_span.enter();
render_app.world.clear_entities();
// queue
let queue = render_app
.schedule
.get_stage_mut::<SystemStage>(&RenderStage::Queue)
.unwrap();
queue.run(&mut render_app.world);
}
{
#[cfg(feature = "trace")]
let stage_span = bevy_utils::tracing::info_span!("stage", name = "sort");
#[cfg(feature = "trace")]
let _stage_guard = stage_span.enter();
// phase sort
let phase_sort = render_app
.schedule
.get_stage_mut::<SystemStage>(&RenderStage::PhaseSort)
.unwrap();
phase_sort.run(&mut render_app.world);
}
{
#[cfg(feature = "trace")]
let stage_span = bevy_utils::tracing::info_span!("stage", name = "render");
#[cfg(feature = "trace")]
let _stage_guard = stage_span.enter();
// render
let render = render_app
.schedule
.get_stage_mut::<SystemStage>(&RenderStage::Render)
.unwrap();
render.run(&mut render_app.world);
}
{
#[cfg(feature = "trace")]
let stage_span = bevy_utils::tracing::info_span!("stage", name = "cleanup");
#[cfg(feature = "trace")]
let _stage_guard = stage_span.enter();
// cleanup
let cleanup = render_app
.schedule
.get_stage_mut::<SystemStage>(&RenderStage::Cleanup)
.unwrap();
cleanup.run(&mut render_app.world);
render_app.world.clear_entities();
}
});
app.add_plugin(WindowRenderPlugin)