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)
This commit is contained in:
Patrick Walton 2025-02-04 11:26:36 -08:00 committed by GitHub
parent 0ca9d6968a
commit 18c4050dd2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 15 additions and 9 deletions

View File

@ -1362,7 +1362,8 @@ 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())
@ -1370,7 +1371,7 @@ pub fn batch_and_prepare_binned_render_phase<BPI, GFBD>(
});
}
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<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,

View File

@ -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,
}
@ -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,
}
}