Skip to content

Commit 1410233

Browse files
danchiamyreprise1
authored andcommitted
Introduce detailed_trace macro, use in TrackedRenderPass (bevyengine#7639)
Profiles show that in extremely hot loops, like the draw loops in the renderer, invoking the trace! macro has noticeable overhead, even if the trace log level is not enabled. Solve this by introduce a 'wrapper' detailed_trace macro around trace, that wraps the trace! log statement in a trivially false if statement unless a cargo feature is enabled # Objective - Eliminate significant overhead observed with trace-level logging in render hot loops, even when trace log level is not enabled. - This is an alternative solution to the one proposed in bevyengine#7223 ## Solution - Introduce a wrapper around the `trace!` macro called `detailed_trace!`. This macro wraps the `trace!` macro with an if statement that is conditional on a new cargo feature, `detailed_trace`. When the feature is not enabled (the default), then the if statement is trivially false and should be optimized away at compile time. - Convert the observed hot occurrences of trace logging in `TrackedRenderPass` with this new macro. Testing the results of ``` cargo run --profile stress-test --features bevy/trace_tracy --example many_cubes -- spheres ``` ![image](https://user-images.githubusercontent.com/1222141/218298552-38551717-b062-4c64-afdc-a60267ac984d.png) shows significant improvement of the `main_opaque_pass_3d` of the renderer, a median time decrease from 6.0ms to 3.5ms. --- ## Changelog - For performance reasons, some detailed renderer trace logs now require the use of cargo feature `detailed_trace` in addition to setting the log level to `TRACE` in order to be shown. ## Migration Guide - Some detailed bevy trace events now require the use of the cargo feature `detailed_trace` in addition to enabling `TRACE` level logging to view. Should you wish to see these logs, please compile your code with the bevy feature `detailed_trace`. Currently, the only logs that are affected are the renderer logs pertaining to `TrackedRenderPass` functions
1 parent 4fa9aa4 commit 1410233

File tree

5 files changed

+42
-24
lines changed

5 files changed

+42
-24
lines changed

Cargo.toml

+4
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,10 @@ animation = ["bevy_internal/animation"]
121121
# Enable using a shared stdlib for cxx on Android.
122122
android_shared_stdcxx = ["bevy_internal/android_shared_stdcxx"]
123123

124+
# Enable detailed trace event logging.
125+
# These trace events are expensive even when off, thus they require compile time opt-in.
126+
detailed_trace = ["bevy_internal/detailed_trace"]
127+
124128
[dependencies]
125129
bevy_dylib = { path = "crates/bevy_dylib", version = "0.9.0", default-features = false, optional = true }
126130
bevy_internal = { path = "crates/bevy_internal", version = "0.9.0", default-features = false }

crates/bevy_internal/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ trace_chrome = [ "bevy_log/tracing-chrome" ]
2424
trace_tracy = ["bevy_render?/tracing-tracy", "bevy_log/tracing-tracy" ]
2525
wgpu_trace = ["bevy_render/wgpu_trace"]
2626
debug_asset_server = ["bevy_asset/debug_asset_server"]
27+
detailed_trace = ["bevy_utils/detailed_trace"]
2728

2829
# Image format support for texture loading (PNG and HDR are enabled by default)
2930
hdr = ["bevy_render/hdr"]

crates/bevy_render/src/render_phase/draw_state.rs

+24-24
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::{
77
},
88
renderer::RenderDevice,
99
};
10-
use bevy_utils::{default, tracing::trace};
10+
use bevy_utils::{default, detailed_trace};
1111
use std::ops::Range;
1212
use wgpu::{IndexFormat, RenderPass};
1313
use wgpu_hal::{MAX_BIND_GROUPS, MAX_VERTEX_BUFFERS};
@@ -126,7 +126,7 @@ impl<'a> TrackedRenderPass<'a> {
126126
///
127127
/// Subsequent draw calls will exhibit the behavior defined by the `pipeline`.
128128
pub fn set_render_pipeline(&mut self, pipeline: &'a RenderPipeline) {
129-
trace!("set pipeline: {:?}", pipeline);
129+
detailed_trace!("set pipeline: {:?}", pipeline);
130130
if self.state.is_pipeline_set(pipeline.id()) {
131131
return;
132132
}
@@ -151,15 +151,15 @@ impl<'a> TrackedRenderPass<'a> {
151151
.state
152152
.is_bind_group_set(index, bind_group.id(), dynamic_uniform_indices)
153153
{
154-
trace!(
154+
detailed_trace!(
155155
"set bind_group {} (already set): {:?} ({:?})",
156156
index,
157157
bind_group,
158158
dynamic_uniform_indices
159159
);
160160
return;
161161
}
162-
trace!(
162+
detailed_trace!(
163163
"set bind_group {}: {:?} ({:?})",
164164
index,
165165
bind_group,
@@ -188,15 +188,15 @@ impl<'a> TrackedRenderPass<'a> {
188188
.state
189189
.is_vertex_buffer_set(slot_index, buffer_slice.id(), offset)
190190
{
191-
trace!(
191+
detailed_trace!(
192192
"set vertex buffer {} (already set): {:?} ({})",
193193
slot_index,
194194
buffer_slice.id(),
195195
offset
196196
);
197197
return;
198198
}
199-
trace!(
199+
detailed_trace!(
200200
"set vertex buffer {}: {:?} ({})",
201201
slot_index,
202202
buffer_slice.id(),
@@ -223,14 +223,14 @@ impl<'a> TrackedRenderPass<'a> {
223223
.state
224224
.is_index_buffer_set(buffer_slice.id(), offset, index_format)
225225
{
226-
trace!(
226+
detailed_trace!(
227227
"set index buffer (already set): {:?} ({})",
228228
buffer_slice.id(),
229229
offset
230230
);
231231
return;
232232
}
233-
trace!("set index buffer: {:?} ({})", buffer_slice.id(), offset);
233+
detailed_trace!("set index buffer: {:?} ({})", buffer_slice.id(), offset);
234234
self.pass.set_index_buffer(*buffer_slice, index_format);
235235
self.state
236236
.set_index_buffer(buffer_slice.id(), offset, index_format);
@@ -240,7 +240,7 @@ impl<'a> TrackedRenderPass<'a> {
240240
///
241241
/// The active vertex buffer(s) can be set with [`TrackedRenderPass::set_vertex_buffer`].
242242
pub fn draw(&mut self, vertices: Range<u32>, instances: Range<u32>) {
243-
trace!("draw: {:?} {:?}", vertices, instances);
243+
detailed_trace!("draw: {:?} {:?}", vertices, instances);
244244
self.pass.draw(vertices, instances);
245245
}
246246

@@ -249,7 +249,7 @@ impl<'a> TrackedRenderPass<'a> {
249249
/// The active index buffer can be set with [`TrackedRenderPass::set_index_buffer`], while the
250250
/// active vertex buffer(s) can be set with [`TrackedRenderPass::set_vertex_buffer`].
251251
pub fn draw_indexed(&mut self, indices: Range<u32>, base_vertex: i32, instances: Range<u32>) {
252-
trace!(
252+
detailed_trace!(
253253
"draw indexed: {:?} {} {:?}",
254254
indices,
255255
base_vertex,
@@ -276,7 +276,7 @@ impl<'a> TrackedRenderPass<'a> {
276276
/// }
277277
/// ```
278278
pub fn draw_indirect(&mut self, indirect_buffer: &'a Buffer, indirect_offset: u64) {
279-
trace!("draw indirect: {:?} {}", indirect_buffer, indirect_offset);
279+
detailed_trace!("draw indirect: {:?} {}", indirect_buffer, indirect_offset);
280280
self.pass.draw_indirect(indirect_buffer, indirect_offset);
281281
}
282282

@@ -300,7 +300,7 @@ impl<'a> TrackedRenderPass<'a> {
300300
/// }
301301
/// ```
302302
pub fn draw_indexed_indirect(&mut self, indirect_buffer: &'a Buffer, indirect_offset: u64) {
303-
trace!(
303+
detailed_trace!(
304304
"draw indexed indirect: {:?} {}",
305305
indirect_buffer,
306306
indirect_offset
@@ -332,7 +332,7 @@ impl<'a> TrackedRenderPass<'a> {
332332
indirect_offset: u64,
333333
count: u32,
334334
) {
335-
trace!(
335+
detailed_trace!(
336336
"multi draw indirect: {:?} {}, {}x",
337337
indirect_buffer,
338338
indirect_offset,
@@ -372,7 +372,7 @@ impl<'a> TrackedRenderPass<'a> {
372372
count_offset: u64,
373373
max_count: u32,
374374
) {
375-
trace!(
375+
detailed_trace!(
376376
"multi draw indirect count: {:?} {}, ({:?} {})x, max {}x",
377377
indirect_buffer,
378378
indirect_offset,
@@ -414,7 +414,7 @@ impl<'a> TrackedRenderPass<'a> {
414414
indirect_offset: u64,
415415
count: u32,
416416
) {
417-
trace!(
417+
detailed_trace!(
418418
"multi draw indexed indirect: {:?} {}, {}x",
419419
indirect_buffer,
420420
indirect_offset,
@@ -456,7 +456,7 @@ impl<'a> TrackedRenderPass<'a> {
456456
count_offset: u64,
457457
max_count: u32,
458458
) {
459-
trace!(
459+
detailed_trace!(
460460
"multi draw indexed indirect count: {:?} {}, ({:?} {})x, max {}x",
461461
indirect_buffer,
462462
indirect_offset,
@@ -477,23 +477,23 @@ impl<'a> TrackedRenderPass<'a> {
477477
///
478478
/// Subsequent stencil tests will test against this value.
479479
pub fn set_stencil_reference(&mut self, reference: u32) {
480-
trace!("set stencil reference: {}", reference);
480+
detailed_trace!("set stencil reference: {}", reference);
481481
self.pass.set_stencil_reference(reference);
482482
}
483483

484484
/// Sets the scissor region.
485485
///
486486
/// Subsequent draw calls will discard any fragments that fall outside this region.
487487
pub fn set_scissor_rect(&mut self, x: u32, y: u32, width: u32, height: u32) {
488-
trace!("set_scissor_rect: {} {} {} {}", x, y, width, height);
488+
detailed_trace!("set_scissor_rect: {} {} {} {}", x, y, width, height);
489489
self.pass.set_scissor_rect(x, y, width, height);
490490
}
491491

492492
/// Set push constant data.
493493
///
494494
/// `Features::PUSH_CONSTANTS` must be enabled on the device in order to call these functions.
495495
pub fn set_push_constants(&mut self, stages: ShaderStages, offset: u32, data: &[u8]) {
496-
trace!(
496+
detailed_trace!(
497497
"set push constants: {:?} offset: {} data.len: {}",
498498
stages,
499499
offset,
@@ -514,7 +514,7 @@ impl<'a> TrackedRenderPass<'a> {
514514
min_depth: f32,
515515
max_depth: f32,
516516
) {
517-
trace!(
517+
detailed_trace!(
518518
"set viewport: {} {} {} {} {} {}",
519519
x,
520520
y,
@@ -545,7 +545,7 @@ impl<'a> TrackedRenderPass<'a> {
545545
///
546546
/// This is a GPU debugging feature. This has no effect on the rendering itself.
547547
pub fn insert_debug_marker(&mut self, label: &str) {
548-
trace!("insert debug marker: {}", label);
548+
detailed_trace!("insert debug marker: {}", label);
549549
self.pass.insert_debug_marker(label);
550550
}
551551

@@ -570,7 +570,7 @@ impl<'a> TrackedRenderPass<'a> {
570570
/// [`push_debug_group`]: TrackedRenderPass::push_debug_group
571571
/// [`pop_debug_group`]: TrackedRenderPass::pop_debug_group
572572
pub fn push_debug_group(&mut self, label: &str) {
573-
trace!("push_debug_group marker: {}", label);
573+
detailed_trace!("push_debug_group marker: {}", label);
574574
self.pass.push_debug_group(label);
575575
}
576576

@@ -587,15 +587,15 @@ impl<'a> TrackedRenderPass<'a> {
587587
/// [`push_debug_group`]: TrackedRenderPass::push_debug_group
588588
/// [`pop_debug_group`]: TrackedRenderPass::pop_debug_group
589589
pub fn pop_debug_group(&mut self) {
590-
trace!("pop_debug_group");
590+
detailed_trace!("pop_debug_group");
591591
self.pass.pop_debug_group();
592592
}
593593

594594
/// Sets the blend color as used by some of the blending modes.
595595
///
596596
/// Subsequent blending tests will test against this value.
597597
pub fn set_blend_constant(&mut self, color: Color) {
598-
trace!("set blend constant: {:?}", color);
598+
detailed_trace!("set blend constant: {:?}", color);
599599
self.pass.set_blend_constant(wgpu::Color::from(color));
600600
}
601601
}

crates/bevy_utils/Cargo.toml

+3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ repository = "https://github.com/bevyengine/bevy"
88
license = "MIT OR Apache-2.0"
99
keywords = ["bevy"]
1010

11+
[features]
12+
detailed_trace = []
13+
1114
[dependencies]
1215
ahash = "0.7.0"
1316
tracing = { version = "0.1", default-features = false, features = ["std"] }

crates/bevy_utils/src/lib.rs

+10
Original file line numberDiff line numberDiff line change
@@ -292,3 +292,13 @@ impl<F: FnOnce()> Drop for OnDrop<F> {
292292
callback();
293293
}
294294
}
295+
296+
/// Like [`tracing::trace`], but conditional on cargo feature `detailed_trace`.
297+
#[macro_export]
298+
macro_rules! detailed_trace {
299+
($($tts:tt)*) => {
300+
if cfg!(detailed_trace) {
301+
bevy_utils::tracing::trace!($($tts)*);
302+
}
303+
}
304+
}

0 commit comments

Comments
 (0)