Combine output_index and indirect_parameters_index into one field in PreprocessWorkItem. (#17853)

The `output_index` field is only used in direct mode, and the
`indirect_parameters_index` field is only used in indirect mode.
Consequently, we can combine them into a single field, reducing the size
of `PreprocessWorkItem`, which
`batch_and_prepare_{binned,sorted}_render_phase` must construct every
frame for every mesh instance, from 96 bits to 64 bits.
This commit is contained in:
Patrick Walton 2025-02-13 12:10:14 -08:00 committed by GitHub
parent 05e61d64f5
commit 101fcaa619
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 51 additions and 58 deletions

View File

@ -43,11 +43,10 @@ struct PreprocessWorkItem {
// The index of the `MeshInput` in the `current_input` buffer that we read // The index of the `MeshInput` in the `current_input` buffer that we read
// from. // from.
input_index: u32, input_index: u32,
// The index of the `Mesh` in `output` that we write to. // In direct mode, the index of the `Mesh` in `output` that we write to. In
output_index: u32, // indirect mode, the index of the `IndirectParameters` in
// The index of the `IndirectParameters` in `indirect_parameters` that we // `indirect_parameters` that we write to.
// write to. output_or_indirect_parameters_index: u32,
indirect_parameters_index: u32,
} }
// The parameters for the indirect compute dispatch for the late mesh // The parameters for the indirect compute dispatch for the late mesh
@ -171,8 +170,11 @@ fn main(@builtin(global_invocation_id) global_invocation_id: vec3<u32>) {
// Unpack the work item. // Unpack the work item.
let input_index = work_items[instance_index].input_index; let input_index = work_items[instance_index].input_index;
let output_index = work_items[instance_index].output_index; #ifdef INDIRECT
let indirect_parameters_index = work_items[instance_index].indirect_parameters_index; let indirect_parameters_index = work_items[instance_index].output_or_indirect_parameters_index;
#else // INDIRECT
let mesh_output_index = work_items[instance_index].output_or_indirect_parameters_index;
#endif // INDIRECT
// Unpack the input matrix. // Unpack the input matrix.
let world_from_local_affine_transpose = current_input[input_index].world_from_local; let world_from_local_affine_transpose = current_input[input_index].world_from_local;
@ -289,8 +291,7 @@ fn main(@builtin(global_invocation_id) global_invocation_id: vec3<u32>) {
// Enqueue a work item for the late prepass phase. // Enqueue a work item for the late prepass phase.
late_preprocess_work_items[output_work_item_index].input_index = input_index; late_preprocess_work_items[output_work_item_index].input_index = input_index;
late_preprocess_work_items[output_work_item_index].output_index = output_index; late_preprocess_work_items[output_work_item_index].output_or_indirect_parameters_index =
late_preprocess_work_items[output_work_item_index].indirect_parameters_index =
indirect_parameters_index; indirect_parameters_index;
#endif // EARLY_PHASE #endif // EARLY_PHASE
// This mesh is culled. Skip it. // This mesh is culled. Skip it.
@ -328,8 +329,6 @@ fn main(@builtin(global_invocation_id) global_invocation_id: vec3<u32>) {
indirect_parameters_metadata[indirect_parameters_index].base_output_index + indirect_parameters_metadata[indirect_parameters_index].base_output_index +
batch_output_index; batch_output_index;
#else // INDIRECT
let mesh_output_index = output_index;
#endif // INDIRECT #endif // INDIRECT
// Write the output. // Write the output.

View File

@ -621,14 +621,15 @@ pub struct PreprocessWorkItem {
/// The index of the batch input data in the input buffer that the shader /// The index of the batch input data in the input buffer that the shader
/// reads from. /// reads from.
pub input_index: u32, pub input_index: u32,
/// The index of the `MeshUniform` in the output buffer that we write to.
/// In direct mode, this is the index of the uniform. In indirect mode, this /// In direct mode, the index of the mesh uniform; in indirect mode, the
/// is the first index uniform in the batch set. /// index of the [`IndirectParametersMetadata`].
pub output_index: u32, ///
/// The index of the [`IndirectParametersMetadata`] in the /// In indirect mode, this is the index of the
/// [`IndirectParametersMetadata`] in the
/// `IndirectParametersBuffers::indexed_metadata` or /// `IndirectParametersBuffers::indexed_metadata` or
/// `IndirectParametersBuffers::non_indexed_metadata`. /// `IndirectParametersBuffers::non_indexed_metadata`.
pub indirect_parameters_index: u32, pub output_or_indirect_parameters_index: u32,
} }
/// The `wgpu` indirect parameters structure that specifies a GPU draw command. /// The `wgpu` indirect parameters structure that specifies a GPU draw command.
@ -1362,8 +1363,6 @@ pub fn batch_and_prepare_sorted_render_phase<I, GFBD>(
// Walk through the list of phase items, building up batches as we go. // Walk through the list of phase items, building up batches as we go.
let mut batch: Option<SortedRenderBatch<GFBD>> = None; let mut batch: Option<SortedRenderBatch<GFBD>> = None;
let mut first_output_index = data_buffer.len() as u32;
for current_index in 0..phase.items.len() { for current_index in 0..phase.items.len() {
// Get the index of the input data, and comparison metadata, for // Get the index of the input data, and comparison metadata, for
// this entity. // this entity.
@ -1439,8 +1438,6 @@ pub fn batch_and_prepare_sorted_render_phase<I, GFBD>(
indirect_parameters_index: indirect_parameters_index.and_then(NonMaxU32::new), indirect_parameters_index: indirect_parameters_index.and_then(NonMaxU32::new),
meta: current_meta, meta: current_meta,
}); });
first_output_index = output_index;
} }
// Add a new preprocessing work item so that the preprocessing // Add a new preprocessing work item so that the preprocessing
@ -1450,14 +1447,15 @@ pub fn batch_and_prepare_sorted_render_phase<I, GFBD>(
item_is_indexed, item_is_indexed,
PreprocessWorkItem { PreprocessWorkItem {
input_index: current_input_index.into(), input_index: current_input_index.into(),
output_index: if no_indirect_drawing { output_or_indirect_parameters_index: match (
output_index no_indirect_drawing,
} else { batch.indirect_parameters_index,
first_output_index ) {
}, (true, _) => output_index,
indirect_parameters_index: match batch.indirect_parameters_index { (false, Some(indirect_parameters_index)) => {
Some(indirect_parameters_index) => indirect_parameters_index.into(), indirect_parameters_index.into()
None => 0, }
(false, None) => 0,
}, },
}, },
); );
@ -1532,7 +1530,6 @@ pub fn batch_and_prepare_binned_render_phase<BPI, GFBD>(
.batch_count(batch_set_key.indexed()) .batch_count(batch_set_key.indexed())
as u32; as u32;
for (bin_key, bin) in bins { for (bin_key, bin) in bins {
let first_output_index = data_buffer.len() as u32;
let mut batch: Option<BinnedRenderPhaseBatch> = None; let mut batch: Option<BinnedRenderPhaseBatch> = None;
for (&main_entity, &input_index) in bin.entities() { for (&main_entity, &input_index) in bin.entities() {
@ -1546,8 +1543,7 @@ pub fn batch_and_prepare_binned_render_phase<BPI, GFBD>(
batch_set_key.indexed(), batch_set_key.indexed(),
PreprocessWorkItem { PreprocessWorkItem {
input_index: *input_index, input_index: *input_index,
output_index: first_output_index, output_or_indirect_parameters_index: match batch.extra_index {
indirect_parameters_index: match batch.extra_index {
PhaseItemExtraIndex::IndirectParametersIndex { PhaseItemExtraIndex::IndirectParametersIndex {
ref range, ref range,
.. ..
@ -1580,8 +1576,7 @@ pub fn batch_and_prepare_binned_render_phase<BPI, GFBD>(
batch_set_key.indexed(), batch_set_key.indexed(),
PreprocessWorkItem { PreprocessWorkItem {
input_index: *input_index, input_index: *input_index,
output_index: first_output_index, output_or_indirect_parameters_index: indirect_parameters_index,
indirect_parameters_index,
}, },
); );
batch = Some(BinnedRenderPhaseBatch { batch = Some(BinnedRenderPhaseBatch {
@ -1630,8 +1625,6 @@ pub fn batch_and_prepare_binned_render_phase<BPI, GFBD>(
// Prepare batchables. // Prepare batchables.
for (key, bin) in &phase.batchable_meshes { for (key, bin) in &phase.batchable_meshes {
let first_output_index = data_buffer.len() as u32;
let mut batch: Option<BinnedRenderPhaseBatch> = None; let mut batch: Option<BinnedRenderPhaseBatch> = None;
for (&main_entity, &input_index) in bin.entities() { for (&main_entity, &input_index) in bin.entities() {
let output_index = data_buffer.add() as u32; let output_index = data_buffer.add() as u32;
@ -1651,18 +1644,20 @@ pub fn batch_and_prepare_binned_render_phase<BPI, GFBD>(
key.0.indexed(), key.0.indexed(),
PreprocessWorkItem { PreprocessWorkItem {
input_index: *input_index, input_index: *input_index,
output_index: if no_indirect_drawing { output_or_indirect_parameters_index: match (
output_index no_indirect_drawing,
} else { &batch.extra_index,
first_output_index ) {
}, (true, _) => output_index,
indirect_parameters_index: match batch.extra_index { (
PhaseItemExtraIndex::IndirectParametersIndex { false,
range: ref indirect_parameters_range, PhaseItemExtraIndex::IndirectParametersIndex {
.. range: indirect_parameters_range,
} => indirect_parameters_range.start, ..
PhaseItemExtraIndex::DynamicOffset(_) },
| PhaseItemExtraIndex::None => 0, ) => indirect_parameters_range.start,
(false, &PhaseItemExtraIndex::DynamicOffset(_))
| (false, &PhaseItemExtraIndex::None) => 0,
}, },
}, },
); );
@ -1689,8 +1684,7 @@ pub fn batch_and_prepare_binned_render_phase<BPI, GFBD>(
key.0.indexed(), key.0.indexed(),
PreprocessWorkItem { PreprocessWorkItem {
input_index: *input_index, input_index: *input_index,
output_index: first_output_index, output_or_indirect_parameters_index: indirect_parameters_index,
indirect_parameters_index,
}, },
); );
batch = Some(BinnedRenderPhaseBatch { batch = Some(BinnedRenderPhaseBatch {
@ -1709,8 +1703,7 @@ pub fn batch_and_prepare_binned_render_phase<BPI, GFBD>(
key.0.indexed(), key.0.indexed(),
PreprocessWorkItem { PreprocessWorkItem {
input_index: *input_index, input_index: *input_index,
output_index, output_or_indirect_parameters_index: output_index,
indirect_parameters_index: 0,
}, },
); );
batch = Some(BinnedRenderPhaseBatch { batch = Some(BinnedRenderPhaseBatch {
@ -1790,8 +1783,7 @@ pub fn batch_and_prepare_binned_render_phase<BPI, GFBD>(
key.0.indexed(), key.0.indexed(),
PreprocessWorkItem { PreprocessWorkItem {
input_index: input_index.into(), input_index: input_index.into(),
output_index, output_or_indirect_parameters_index: *indirect_parameters_index,
indirect_parameters_index: *indirect_parameters_index,
}, },
); );
unbatchables unbatchables
@ -1812,8 +1804,7 @@ pub fn batch_and_prepare_binned_render_phase<BPI, GFBD>(
key.0.indexed(), key.0.indexed(),
PreprocessWorkItem { PreprocessWorkItem {
input_index: input_index.into(), input_index: input_index.into(),
output_index, output_or_indirect_parameters_index: output_index,
indirect_parameters_index: 0,
}, },
); );
unbatchables unbatchables

View File

@ -438,8 +438,11 @@ fn queue_custom_mesh_pipeline(
mesh.indexed(), mesh.indexed(),
PreprocessWorkItem { PreprocessWorkItem {
input_index: input_index.into(), input_index: input_index.into(),
output_index, output_or_indirect_parameters_index: if no_indirect_drawing {
indirect_parameters_index: mesh_info.indirect_parameters_index, output_index
} else {
mesh_info.indirect_parameters_index
},
}, },
); );
} }