From 18c4050dd2f2eb14e38f52c72cccef67786ef48a Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Tue, 4 Feb 2025 11:26:36 -0800 Subject: [PATCH] Make `batch_and_prepare_binned_render_phase` only record information about the first batch in each batch set. (#17680) Data for the other batches is only accessed by the GPU, not the CPU, so it's a waste of time and memory to store information relating to those other batches. On Bistro, this reduces time spent in `batch_and_prepare_binned_render_phase` from 85.9 us to 61.2 us, a 40% speedup. ![Screenshot 2025-02-04 093315](https://github.com/user-attachments/assets/eb00db93-a260-44f9-9ae0-4e90b0697138) --- .../src/batching/gpu_preprocessing.rs | 8 +++++--- crates/bevy_render/src/render_phase/mod.rs | 16 ++++++++++------ 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/crates/bevy_render/src/batching/gpu_preprocessing.rs b/crates/bevy_render/src/batching/gpu_preprocessing.rs index 7effe9d1d7..ff5f79f43d 100644 --- a/crates/bevy_render/src/batching/gpu_preprocessing.rs +++ b/crates/bevy_render/src/batching/gpu_preprocessing.rs @@ -1362,7 +1362,8 @@ pub fn batch_and_prepare_binned_render_phase( match batch_set { None => { batch_set = Some(BinnedRenderPhaseBatchSet { - batches: vec![batch], + first_batch: batch, + batch_count: 1, bin_key: bin_key.clone(), index: indirect_parameters_buffers .batch_set_count(batch_set_key.indexed()) @@ -1370,7 +1371,7 @@ pub fn batch_and_prepare_binned_render_phase( }); } Some(ref mut batch_set) => { - batch_set.batches.push(batch); + batch_set.batch_count += 1; } } } @@ -1498,7 +1499,8 @@ pub fn batch_and_prepare_binned_render_phase( // However, custom render pipelines might do so, such as // the `specialized_mesh_pipeline` example. vec.push(BinnedRenderPhaseBatchSet { - batches: vec![batch], + first_batch: batch, + batch_count: 1, bin_key: key.1.clone(), index: indirect_parameters_buffers.batch_set_count(key.0.indexed()) as u32, diff --git a/crates/bevy_render/src/render_phase/mod.rs b/crates/bevy_render/src/render_phase/mod.rs index 61b47b97ee..f8a2f7f3ad 100644 --- a/crates/bevy_render/src/render_phase/mod.rs +++ b/crates/bevy_render/src/render_phase/mod.rs @@ -189,9 +189,16 @@ pub enum BinnedRenderPhaseBatchSets { MultidrawIndirect(Vec>), } +/// A group of entities that will be batched together into a single multi-draw +/// call. pub struct BinnedRenderPhaseBatchSet { - pub(crate) batches: Vec, + /// The first batch in this batch set. + pub(crate) first_batch: BinnedRenderPhaseBatch, + /// The key of the bin that the first batch corresponds to. pub(crate) bin_key: BK, + /// The number of batches. + pub(crate) batch_count: u32, + /// The index of the batch set in the GPU buffer. pub(crate) index: u32, } @@ -527,9 +534,7 @@ where ) .zip(batch_sets.iter()) { - let Some(batch) = batch_set.batches.first() else { - continue; - }; + let batch = &batch_set.first_batch; let batch_set_index = if multi_draw_indirect_count_supported { NonMaxU32::new(batch_set.index) @@ -549,8 +554,7 @@ where } PhaseItemExtraIndex::IndirectParametersIndex { ref range, .. } => { PhaseItemExtraIndex::IndirectParametersIndex { - range: range.start - ..(range.start + batch_set.batches.len() as u32), + range: range.start..(range.start + batch_set.batch_count), batch_set_index, } }