Skip to content

Commit 18c4050

Browse files
authored
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)
1 parent 0ca9d69 commit 18c4050

File tree

2 files changed

+15
-9
lines changed

2 files changed

+15
-9
lines changed

crates/bevy_render/src/batching/gpu_preprocessing.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1362,15 +1362,16 @@ pub fn batch_and_prepare_binned_render_phase<BPI, GFBD>(
13621362
match batch_set {
13631363
None => {
13641364
batch_set = Some(BinnedRenderPhaseBatchSet {
1365-
batches: vec![batch],
1365+
first_batch: batch,
1366+
batch_count: 1,
13661367
bin_key: bin_key.clone(),
13671368
index: indirect_parameters_buffers
13681369
.batch_set_count(batch_set_key.indexed())
13691370
as u32,
13701371
});
13711372
}
13721373
Some(ref mut batch_set) => {
1373-
batch_set.batches.push(batch);
1374+
batch_set.batch_count += 1;
13741375
}
13751376
}
13761377
}
@@ -1498,7 +1499,8 @@ pub fn batch_and_prepare_binned_render_phase<BPI, GFBD>(
14981499
// However, custom render pipelines might do so, such as
14991500
// the `specialized_mesh_pipeline` example.
15001501
vec.push(BinnedRenderPhaseBatchSet {
1501-
batches: vec![batch],
1502+
first_batch: batch,
1503+
batch_count: 1,
15021504
bin_key: key.1.clone(),
15031505
index: indirect_parameters_buffers.batch_set_count(key.0.indexed())
15041506
as u32,

crates/bevy_render/src/render_phase/mod.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -189,9 +189,16 @@ pub enum BinnedRenderPhaseBatchSets<BK> {
189189
MultidrawIndirect(Vec<BinnedRenderPhaseBatchSet<BK>>),
190190
}
191191

192+
/// A group of entities that will be batched together into a single multi-draw
193+
/// call.
192194
pub struct BinnedRenderPhaseBatchSet<BK> {
193-
pub(crate) batches: Vec<BinnedRenderPhaseBatch>,
195+
/// The first batch in this batch set.
196+
pub(crate) first_batch: BinnedRenderPhaseBatch,
197+
/// The key of the bin that the first batch corresponds to.
194198
pub(crate) bin_key: BK,
199+
/// The number of batches.
200+
pub(crate) batch_count: u32,
201+
/// The index of the batch set in the GPU buffer.
195202
pub(crate) index: u32,
196203
}
197204

@@ -527,9 +534,7 @@ where
527534
)
528535
.zip(batch_sets.iter())
529536
{
530-
let Some(batch) = batch_set.batches.first() else {
531-
continue;
532-
};
537+
let batch = &batch_set.first_batch;
533538

534539
let batch_set_index = if multi_draw_indirect_count_supported {
535540
NonMaxU32::new(batch_set.index)
@@ -549,8 +554,7 @@ where
549554
}
550555
PhaseItemExtraIndex::IndirectParametersIndex { ref range, .. } => {
551556
PhaseItemExtraIndex::IndirectParametersIndex {
552-
range: range.start
553-
..(range.start + batch_set.batches.len() as u32),
557+
range: range.start..(range.start + batch_set.batch_count),
554558
batch_set_index,
555559
}
556560
}

0 commit comments

Comments
 (0)