Skip to content

Commit

Permalink
Record render statistics only if RenderStatisticsPlugin is present
Browse files Browse the repository at this point in the history
  • Loading branch information
LeshaInc committed Jul 13, 2023
1 parent 2efd135 commit e666107
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 38 deletions.
17 changes: 3 additions & 14 deletions crates/bevy_render/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ pub mod prelude {
color::Color,
mesh::{morph::MorphWeights, shape, Mesh},
render_resource::Shader,
renderer::RenderStatistics,
renderer::{RenderPassStatistics, RenderStatistics, RenderStatisticsPlugin},
spatial_bundle::SpatialBundle,
texture::{Image, ImagePlugin},
view::{ComputedVisibility, Msaa, Visibility, VisibilityBundle},
Expand All @@ -44,10 +44,7 @@ pub mod prelude {

use bevy_window::{PrimaryWindow, RawHandleWrapper};
use globals::GlobalsPlugin;
use renderer::{
sync_render_statistics, RenderAdapter, RenderAdapterInfo, RenderDevice, RenderQueue,
RenderStatistics, RenderStatisticsMutex, StatisticsRecorder,
};
use renderer::{RenderAdapter, RenderAdapterInfo, RenderDevice, RenderQueue};
use wgpu::Instance;

use crate::{
Expand All @@ -58,7 +55,7 @@ use crate::{
settings::WgpuSettings,
view::{ViewPlugin, WindowRenderPlugin},
};
use bevy_app::{App, AppLabel, Plugin, PreUpdate, SubApp};
use bevy_app::{App, AppLabel, Plugin, SubApp};
use bevy_asset::{AddAsset, AssetServer};
use bevy_ecs::{prelude::*, schedule::ScheduleLabel, system::SystemState};
use bevy_utils::tracing::debug;
Expand Down Expand Up @@ -274,18 +271,11 @@ impl Plugin for RenderPlugin {
let mut extract_schedule = Schedule::new();
extract_schedule.set_apply_final_deferred(false);

let render_statistics = RenderStatisticsMutex::default();

app.insert_resource(render_statistics.clone())
.add_systems(PreUpdate, sync_render_statistics)
.init_resource::<RenderStatistics>();

render_app
.add_schedule(ExtractSchedule, extract_schedule)
.add_schedule(Render, Render::base_schedule())
.init_resource::<render_graph::RenderGraph>()
.insert_resource(app.world.resource::<AssetServer>().clone())
.insert_resource(render_statistics)
.add_systems(ExtractSchedule, PipelineCache::extract_shaders)
.add_systems(
Render,
Expand Down Expand Up @@ -380,7 +370,6 @@ impl Plugin for RenderPlugin {
render_app
.insert_resource(RenderInstance(instance))
.insert_resource(PipelineCache::new(device.clone()))
.insert_resource(StatisticsRecorder::new(&device, &queue))
.insert_resource(device)
.insert_resource(queue)
.insert_resource(render_adapter)
Expand Down
18 changes: 11 additions & 7 deletions crates/bevy_render/src/renderer/graph_runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,14 @@ impl RenderGraphRunner {
pub fn run(
graph: &RenderGraph,
render_device: RenderDevice,
mut statistics_recorder: StatisticsRecorder,
mut statistics_recorder: Option<StatisticsRecorder>,
queue: &wgpu::Queue,
world: &World,
finalizer: impl FnOnce(&mut wgpu::CommandEncoder),
) -> Result<StatisticsRecorder, RenderGraphRunnerError> {
statistics_recorder.begin_frame();
) -> Result<Option<StatisticsRecorder>, RenderGraphRunnerError> {
if let Some(recorder) = &mut statistics_recorder {
recorder.begin_frame();
}

let mut render_context = RenderContext::new(render_device, statistics_recorder);
Self::run_graph(graph, None, &mut render_context, world, &[], None)?;
Expand All @@ -78,10 +80,12 @@ impl RenderGraphRunner {
(render_device, statistics_recorder)
};

let render_statistics_mutex = world.resource::<RenderStatisticsMutex>().0.clone();
statistics_recorder.finish_frame(&render_device, move |statistics| {
*render_statistics_mutex.lock() = Some(statistics);
});
if let Some(recorder) = &mut statistics_recorder {
let render_statistics_mutex = world.resource::<RenderStatisticsMutex>().0.clone();
recorder.finish_frame(&render_device, move |statistics| {
*render_statistics_mutex.lock() = Some(statistics);
});
}

Ok(statistics_recorder)
}
Expand Down
27 changes: 19 additions & 8 deletions crates/bevy_render/src/renderer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pub fn render_system(world: &mut World) {
graph.update(world);
});

let statistics_recorder = world.remove_resource::<StatisticsRecorder>().unwrap();
let statistics_recorder = world.remove_resource::<StatisticsRecorder>();

let graph = world.resource::<RenderGraph>();
let render_device = world.resource::<RenderDevice>();
Expand All @@ -45,9 +45,10 @@ pub fn render_system(world: &mut World) {
crate::view::screenshot::submit_screenshot_commands(world, encoder);
},
) {
Ok(statistics_recorder) => {
Ok(Some(statistics_recorder)) => {
world.insert_resource(statistics_recorder);
}
Ok(None) => {}
Err(e) => {
error!("Error running render graph:");
{
Expand Down Expand Up @@ -302,12 +303,15 @@ pub struct RenderContext {
render_device: RenderDevice,
command_encoder: Option<CommandEncoder>,
command_buffers: Vec<CommandBuffer>,
statistics_recorder: StatisticsRecorder,
statistics_recorder: Option<StatisticsRecorder>,
}

impl RenderContext {
/// Creates a new [`RenderContext`] from a [`RenderDevice`].
pub fn new(render_device: RenderDevice, statistics_recorder: StatisticsRecorder) -> Self {
pub fn new(
render_device: RenderDevice,
statistics_recorder: Option<StatisticsRecorder>,
) -> Self {
Self {
render_device,
command_encoder: None,
Expand Down Expand Up @@ -340,8 +344,13 @@ impl RenderContext {
self.render_device
.create_command_encoder(&wgpu::CommandEncoderDescriptor::default())
});
let render_pass =
MeasuredRenderPass::new(command_encoder, &mut self.statistics_recorder, descriptor);

let render_pass = MeasuredRenderPass::new(
command_encoder,
self.statistics_recorder.as_mut(),
descriptor,
);

TrackedRenderPass::new(&self.render_device, render_pass)
}

Expand All @@ -358,13 +367,15 @@ impl RenderContext {
/// Finalizes the queue and returns the queue of [`CommandBuffer`]s.
///
/// When the render statistics become available, `statistics_callback` will be invoked.
pub fn finish(mut self) -> (Vec<CommandBuffer>, RenderDevice, StatisticsRecorder) {
pub fn finish(mut self) -> (Vec<CommandBuffer>, RenderDevice, Option<StatisticsRecorder>) {
let command_encoder = self.command_encoder.get_or_insert_with(|| {
self.render_device
.create_command_encoder(&wgpu::CommandEncoderDescriptor::default())
});

self.statistics_recorder.resolve(command_encoder);
if let Some(recorder) = &mut self.statistics_recorder {
recorder.resolve(command_encoder);
}

self.flush_encoder();

Expand Down
50 changes: 41 additions & 9 deletions crates/bevy_render/src/renderer/statistics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::sync::{
Arc,
};

use bevy_app::{App, Plugin, PreUpdate};
use bevy_derive::{Deref, DerefMut};
use bevy_ecs::system::{Res, ResMut, Resource};
use bevy_utils::{Duration, HashMap, Instant};
Expand All @@ -13,7 +14,9 @@ use wgpu::{
RenderPassDescriptor,
};

use super::RenderDevice;
use crate::RenderApp;

use super::{RenderDevice, RenderQueue};

// buffer offset must be divisible by 256, so this constant must be divisible by 32 (=256/8)
const MAX_TIMESTAMP_QUERIES: u32 = 256;
Expand All @@ -22,6 +25,33 @@ const MAX_PIPELINE_STATISTICS: u32 = 128;
const TIMESTAMP_SIZE: u64 = 8;
const PIPELINE_STATISTICS_SIZE: u64 = 40;

/// Enables collecting render pass statistics into [`RenderStatistics`] resource.
#[derive(Default)]
pub struct RenderStatisticsPlugin;

impl Plugin for RenderStatisticsPlugin {
fn build(&self, app: &mut App) {
let render_statistics_mutex = RenderStatisticsMutex::default();
app.insert_resource(render_statistics_mutex.clone())
.init_resource::<RenderStatistics>()
.add_systems(PreUpdate, sync_render_statistics);

if let Ok(render_app) = app.get_sub_app_mut(RenderApp) {
render_app.insert_resource(render_statistics_mutex);
}
}

fn finish(&self, app: &mut App) {
let Ok(render_app) = app.get_sub_app_mut(RenderApp) else {
return;
};

let device = render_app.world.resource::<RenderDevice>();
let queue = render_app.world.resource::<RenderQueue>();
render_app.insert_resource(StatisticsRecorder::new(device, queue));
}
}

/// Resource which stores statistics for each render pass.
#[derive(Debug, Default, Clone, Resource)]
pub struct RenderStatistics(pub HashMap<String, RenderPassStatistics>);
Expand Down Expand Up @@ -102,8 +132,6 @@ impl StatisticsRecorder {
}
}

dbg!(self.finished_frames.len() + self.submitted_frames.len() + 1);

self.current_frame.begin();
}

Expand Down Expand Up @@ -415,7 +443,7 @@ pub struct MeasuredRenderPass<'a> {
#[deref]
render_pass: RenderPass<'a>,
name: Option<String>,
recorder: &'a mut StatisticsRecorder,
recorder: Option<&'a mut StatisticsRecorder>,
}

impl MeasuredRenderPass<'_> {
Expand All @@ -424,13 +452,17 @@ impl MeasuredRenderPass<'_> {
/// [`RenderPassDescriptor`] must have a label, otherwise no statistics will be recorded.
pub fn new<'a>(
encoder: &'a mut CommandEncoder,
recorder: &'a mut StatisticsRecorder,
mut recorder: Option<&'a mut StatisticsRecorder>,
desc: RenderPassDescriptor<'a, '_>,
) -> MeasuredRenderPass<'a> {
let name = desc.label.map(|v| v.to_owned());
// copy label only if recording is enabled
let name = recorder
.as_ref()
.and_then(|_| desc.label.map(|v| v.to_owned()));

let mut render_pass = encoder.begin_render_pass(&desc);

if let Some(name) = &name {
if let (Some(recorder), Some(name)) = (&mut recorder, &name) {
recorder.begin_render_pass(&mut render_pass, name);
}

Expand All @@ -448,8 +480,8 @@ impl Drop for MeasuredRenderPass<'_> {
return;
}

if let Some(name) = &self.name {
self.recorder.end_render_pass(&mut self.render_pass, name);
if let (Some(recorder), Some(name)) = (&mut self.recorder, &self.name) {
recorder.end_render_pass(&mut self.render_pass, name);
}
}
}
Expand Down
1 change: 1 addition & 0 deletions examples/3d/3d_scene.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use bevy::prelude::*;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugins(RenderStatisticsPlugin)
.add_systems(Startup, setup)
.add_systems(Update, print_render_statistics)
.run();
Expand Down

0 comments on commit e666107

Please sign in to comment.