diff --git a/crates/bevy_pbr/src/render/mesh_preprocess.wgsl b/crates/bevy_pbr/src/render/mesh_preprocess.wgsl index 9bbe96e80d..b99f77bf48 100644 --- a/crates/bevy_pbr/src/render/mesh_preprocess.wgsl +++ b/crates/bevy_pbr/src/render/mesh_preprocess.wgsl @@ -43,11 +43,10 @@ struct PreprocessWorkItem { // The index of the `MeshInput` in the `current_input` buffer that we read // from. input_index: u32, - // The index of the `Mesh` in `output` that we write to. - output_index: u32, - // The index of the `IndirectParameters` in `indirect_parameters` that we - // write to. - indirect_parameters_index: u32, + // In direct mode, the index of the `Mesh` in `output` that we write to. In + // indirect mode, the index of the `IndirectParameters` in + // `indirect_parameters` that we write to. + output_or_indirect_parameters_index: u32, } // 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) { // Unpack the work item. let input_index = work_items[instance_index].input_index; - let output_index = work_items[instance_index].output_index; - let indirect_parameters_index = work_items[instance_index].indirect_parameters_index; +#ifdef INDIRECT + 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. 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) { // 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].output_index = output_index; - late_preprocess_work_items[output_work_item_index].indirect_parameters_index = + late_preprocess_work_items[output_work_item_index].output_or_indirect_parameters_index = indirect_parameters_index; #endif // EARLY_PHASE // This mesh is culled. Skip it. @@ -328,8 +329,6 @@ fn main(@builtin(global_invocation_id) global_invocation_id: vec3) { indirect_parameters_metadata[indirect_parameters_index].base_output_index + batch_output_index; -#else // INDIRECT - let mesh_output_index = output_index; #endif // INDIRECT // Write the output. diff --git a/crates/bevy_render/src/batching/gpu_preprocessing.rs b/crates/bevy_render/src/batching/gpu_preprocessing.rs index 6637638f38..46198d681d 100644 --- a/crates/bevy_render/src/batching/gpu_preprocessing.rs +++ b/crates/bevy_render/src/batching/gpu_preprocessing.rs @@ -621,14 +621,15 @@ pub struct PreprocessWorkItem { /// The index of the batch input data in the input buffer that the shader /// reads from. 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 - /// is the first index uniform in the batch set. - pub output_index: u32, - /// The index of the [`IndirectParametersMetadata`] in the + + /// In direct mode, the index of the mesh uniform; in indirect mode, the + /// index of the [`IndirectParametersMetadata`]. + /// + /// In indirect mode, this is the index of the + /// [`IndirectParametersMetadata`] in the /// `IndirectParametersBuffers::indexed_metadata` or /// `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. @@ -1362,8 +1363,6 @@ pub fn batch_and_prepare_sorted_render_phase( // Walk through the list of phase items, building up batches as we go. let mut batch: Option> = None; - let mut first_output_index = data_buffer.len() as u32; - for current_index in 0..phase.items.len() { // Get the index of the input data, and comparison metadata, for // this entity. @@ -1439,8 +1438,6 @@ pub fn batch_and_prepare_sorted_render_phase( indirect_parameters_index: indirect_parameters_index.and_then(NonMaxU32::new), meta: current_meta, }); - - first_output_index = output_index; } // Add a new preprocessing work item so that the preprocessing @@ -1450,14 +1447,15 @@ pub fn batch_and_prepare_sorted_render_phase( item_is_indexed, PreprocessWorkItem { input_index: current_input_index.into(), - output_index: if no_indirect_drawing { - output_index - } else { - first_output_index - }, - indirect_parameters_index: match batch.indirect_parameters_index { - Some(indirect_parameters_index) => indirect_parameters_index.into(), - None => 0, + output_or_indirect_parameters_index: match ( + no_indirect_drawing, + batch.indirect_parameters_index, + ) { + (true, _) => output_index, + (false, Some(indirect_parameters_index)) => { + indirect_parameters_index.into() + } + (false, None) => 0, }, }, ); @@ -1532,7 +1530,6 @@ pub fn batch_and_prepare_binned_render_phase( .batch_count(batch_set_key.indexed()) as u32; for (bin_key, bin) in bins { - let first_output_index = data_buffer.len() as u32; let mut batch: Option = None; for (&main_entity, &input_index) in bin.entities() { @@ -1546,8 +1543,7 @@ pub fn batch_and_prepare_binned_render_phase( batch_set_key.indexed(), PreprocessWorkItem { input_index: *input_index, - output_index: first_output_index, - indirect_parameters_index: match batch.extra_index { + output_or_indirect_parameters_index: match batch.extra_index { PhaseItemExtraIndex::IndirectParametersIndex { ref range, .. @@ -1580,8 +1576,7 @@ pub fn batch_and_prepare_binned_render_phase( batch_set_key.indexed(), PreprocessWorkItem { input_index: *input_index, - output_index: first_output_index, - indirect_parameters_index, + output_or_indirect_parameters_index: indirect_parameters_index, }, ); batch = Some(BinnedRenderPhaseBatch { @@ -1630,8 +1625,6 @@ pub fn batch_and_prepare_binned_render_phase( // Prepare batchables. for (key, bin) in &phase.batchable_meshes { - let first_output_index = data_buffer.len() as u32; - let mut batch: Option = None; for (&main_entity, &input_index) in bin.entities() { let output_index = data_buffer.add() as u32; @@ -1651,18 +1644,20 @@ pub fn batch_and_prepare_binned_render_phase( key.0.indexed(), PreprocessWorkItem { input_index: *input_index, - output_index: if no_indirect_drawing { - output_index - } else { - first_output_index - }, - indirect_parameters_index: match batch.extra_index { - PhaseItemExtraIndex::IndirectParametersIndex { - range: ref indirect_parameters_range, - .. - } => indirect_parameters_range.start, - PhaseItemExtraIndex::DynamicOffset(_) - | PhaseItemExtraIndex::None => 0, + output_or_indirect_parameters_index: match ( + no_indirect_drawing, + &batch.extra_index, + ) { + (true, _) => output_index, + ( + false, + PhaseItemExtraIndex::IndirectParametersIndex { + range: indirect_parameters_range, + .. + }, + ) => indirect_parameters_range.start, + (false, &PhaseItemExtraIndex::DynamicOffset(_)) + | (false, &PhaseItemExtraIndex::None) => 0, }, }, ); @@ -1689,8 +1684,7 @@ pub fn batch_and_prepare_binned_render_phase( key.0.indexed(), PreprocessWorkItem { input_index: *input_index, - output_index: first_output_index, - indirect_parameters_index, + output_or_indirect_parameters_index: indirect_parameters_index, }, ); batch = Some(BinnedRenderPhaseBatch { @@ -1709,8 +1703,7 @@ pub fn batch_and_prepare_binned_render_phase( key.0.indexed(), PreprocessWorkItem { input_index: *input_index, - output_index, - indirect_parameters_index: 0, + output_or_indirect_parameters_index: output_index, }, ); batch = Some(BinnedRenderPhaseBatch { @@ -1790,8 +1783,7 @@ pub fn batch_and_prepare_binned_render_phase( key.0.indexed(), PreprocessWorkItem { input_index: input_index.into(), - output_index, - indirect_parameters_index: *indirect_parameters_index, + output_or_indirect_parameters_index: *indirect_parameters_index, }, ); unbatchables @@ -1812,8 +1804,7 @@ pub fn batch_and_prepare_binned_render_phase( key.0.indexed(), PreprocessWorkItem { input_index: input_index.into(), - output_index, - indirect_parameters_index: 0, + output_or_indirect_parameters_index: output_index, }, ); unbatchables diff --git a/examples/shader/specialized_mesh_pipeline.rs b/examples/shader/specialized_mesh_pipeline.rs index e228d77645..66f42f5872 100644 --- a/examples/shader/specialized_mesh_pipeline.rs +++ b/examples/shader/specialized_mesh_pipeline.rs @@ -438,8 +438,11 @@ fn queue_custom_mesh_pipeline( mesh.indexed(), PreprocessWorkItem { input_index: input_index.into(), - output_index, - indirect_parameters_index: mesh_info.indirect_parameters_index, + output_or_indirect_parameters_index: if no_indirect_drawing { + output_index + } else { + mesh_info.indirect_parameters_index + }, }, ); }