Skip to content

Commit

Permalink
Make batch_and_prepare_binned_render_phase only record information …
Browse files Browse the repository at this point in the history
…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)
  • Loading branch information
pcwalton authored Feb 4, 2025
1 parent 0ca9d69 commit 18c4050
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 9 deletions.
8 changes: 5 additions & 3 deletions crates/bevy_render/src/batching/gpu_preprocessing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1362,15 +1362,16 @@ pub fn batch_and_prepare_binned_render_phase<BPI, GFBD>(
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())
as u32,
});
}
Some(ref mut batch_set) => {
batch_set.batches.push(batch);
batch_set.batch_count += 1;
}
}
}
Expand Down Expand Up @@ -1498,7 +1499,8 @@ pub fn batch_and_prepare_binned_render_phase<BPI, GFBD>(
// 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,
Expand Down
16 changes: 10 additions & 6 deletions crates/bevy_render/src/render_phase/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,9 +189,16 @@ pub enum BinnedRenderPhaseBatchSets<BK> {
MultidrawIndirect(Vec<BinnedRenderPhaseBatchSet<BK>>),
}

/// A group of entities that will be batched together into a single multi-draw
/// call.
pub struct BinnedRenderPhaseBatchSet<BK> {
pub(crate) batches: Vec<BinnedRenderPhaseBatch>,
/// 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,
}

Expand Down Expand Up @@ -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)
Expand All @@ -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,
}
}
Expand Down

0 comments on commit 18c4050

Please sign in to comment.