Skip to content

Commit

Permalink
Allow extract_meshes_for_gpu_building and extract_mesh_materials to
Browse files Browse the repository at this point in the history
run in parallel.

The only thing that was preventing `extract_meshes_for_gpu_building` and
`extract_mesh_materials` from running in parallel was the
`ResMut<RenderMeshMaterialIds>`. This lookup can be safely moved to the
`collect_meshes_for_gpu_building` phase, which runs after the extraction
phase.

This results in a small win on `many_cubes`.
  • Loading branch information
pcwalton committed Dec 13, 2024
1 parent 00722b8 commit a572915
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 25 deletions.
7 changes: 1 addition & 6 deletions crates/bevy_pbr/src/material.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,12 +283,7 @@ where
.add_render_command::<Opaque3d, DrawMaterial<M>>()
.add_render_command::<AlphaMask3d, DrawMaterial<M>>()
.init_resource::<SpecializedMeshPipelines<MaterialPipeline<M>>>()
.add_systems(
ExtractSchedule,
extract_mesh_materials::<M>
.before(extract_meshes_for_cpu_building)
.before(extract_meshes_for_gpu_building),
)
.add_systems(ExtractSchedule, extract_mesh_materials::<M>)
.add_systems(
Render,
queue_material_meshes::<M>
Expand Down
36 changes: 17 additions & 19 deletions crates/bevy_pbr/src/render/mesh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use bevy_render::{
camera::Camera,
mesh::*,
primitives::Aabb,
render_asset::{ExtractAssetsSet, RenderAssets},
render_asset::RenderAssets,
render_phase::{
BinnedRenderPhasePlugin, PhaseItem, PhaseItemExtraIndex, RenderCommand,
RenderCommandResult, SortedRenderPhasePlugin, TrackedRenderPass,
Expand All @@ -44,6 +44,7 @@ use bevy_render::{
};
use bevy_transform::components::GlobalTransform;
use bevy_utils::{
default,
hashbrown::hash_map::Entry,
tracing::{error, warn},
HashMap, Parallel,
Expand Down Expand Up @@ -208,8 +209,7 @@ impl Plugin for MeshRenderPlugin {
.add_systems(
ExtractSchedule,
extract_meshes_for_gpu_building
.in_set(ExtractMeshesSet)
.after(ExtractAssetsSet),
.in_set(ExtractMeshesSet),
)
.add_systems(
Render,
Expand Down Expand Up @@ -237,9 +237,7 @@ impl Plugin for MeshRenderPlugin {
.insert_resource(cpu_batched_instance_buffer)
.add_systems(
ExtractSchedule,
extract_meshes_for_cpu_building
.in_set(ExtractMeshesSet)
.after(ExtractAssetsSet),
extract_meshes_for_cpu_building.in_set(ExtractMeshesSet),
)
.add_systems(
Render,
Expand Down Expand Up @@ -612,7 +610,6 @@ impl RenderMeshInstanceShared {
fn from_components(
previous_transform: Option<&PreviousGlobalTransform>,
mesh: &Mesh3d,
material_bindings_index: MaterialBindingId,
not_shadow_caster: bool,
no_automatic_batching: bool,
) -> Self {
Expand All @@ -630,7 +627,8 @@ impl RenderMeshInstanceShared {
RenderMeshInstanceShared {
mesh_asset_id: mesh.id(),
flags: mesh_instance_flags,
material_bindings_index,
// This gets filled in later, during `RenderMeshGpuBuilder::update`.
material_bindings_index: default(),
}
}

Expand Down Expand Up @@ -887,13 +885,15 @@ impl RenderMeshInstanceGpuQueue {
impl RenderMeshInstanceGpuBuilder {
/// Flushes this mesh instance to the [`RenderMeshInstanceGpu`] and
/// [`MeshInputUniform`] tables, replacing the existing entry if applicable.
#[allow(clippy::too_many_arguments)]
fn update(
self,
mut self,
entity: MainEntity,
render_mesh_instances: &mut MainEntityHashMap<RenderMeshInstanceGpu>,
current_input_buffer: &mut InstanceInputUniformBuffer<MeshInputUniform>,
previous_input_buffer: &mut InstanceInputUniformBuffer<MeshInputUniform>,
mesh_allocator: &MeshAllocator,
mesh_material_ids: &RenderMeshMaterialIds,
skin_indices: &SkinIndices,
) -> u32 {
let first_vertex_index = match mesh_allocator.mesh_vertex_slice(&self.shared.mesh_asset_id)
Expand All @@ -911,6 +911,10 @@ impl RenderMeshInstanceGpuBuilder {
None => u32::MAX,
};

// Look up the material index.
let mesh_material_binding_id = mesh_material_ids.mesh_material_binding_id(entity);
self.shared.material_bindings_index = mesh_material_binding_id;

// Create the mesh input uniform.
let mut mesh_input_uniform = MeshInputUniform {
world_from_local: self.world_from_local.to_transpose(),
Expand Down Expand Up @@ -1046,7 +1050,6 @@ pub struct ExtractMeshesSet;
pub fn extract_meshes_for_cpu_building(
mut render_mesh_instances: ResMut<RenderMeshInstances>,
render_visibility_ranges: Res<RenderVisibilityRanges>,
mesh_material_ids: Res<RenderMeshMaterialIds>,
mut render_mesh_instance_queues: Local<Parallel<Vec<(Entity, RenderMeshInstanceCpu)>>>,
meshes_query: Extract<
Query<(
Expand Down Expand Up @@ -1084,9 +1087,6 @@ pub fn extract_meshes_for_cpu_building(
return;
}

let mesh_material_binding_id =
mesh_material_ids.mesh_material_binding_id(MainEntity::from(entity));

let mut lod_index = None;
if visibility_range {
lod_index = render_visibility_ranges.lod_index_for_entity(entity.into());
Expand All @@ -1103,7 +1103,6 @@ pub fn extract_meshes_for_cpu_building(
let shared = RenderMeshInstanceShared::from_components(
previous_transform,
mesh,
mesh_material_binding_id,
not_shadow_caster,
no_automatic_batching,
);
Expand Down Expand Up @@ -1155,7 +1154,6 @@ pub fn extract_meshes_for_cpu_building(
pub fn extract_meshes_for_gpu_building(
mut render_mesh_instances: ResMut<RenderMeshInstances>,
render_visibility_ranges: Res<RenderVisibilityRanges>,
mesh_material_ids: Res<RenderMeshMaterialIds>,
mut render_mesh_instance_queues: ResMut<RenderMeshInstanceGpuQueues>,
changed_meshes_query: Extract<
Query<
Expand Down Expand Up @@ -1235,9 +1233,6 @@ pub fn extract_meshes_for_gpu_building(
return;
}

let mesh_material_binding_id =
mesh_material_ids.mesh_material_binding_id(MainEntity::from(entity));

let mut lod_index = None;
if visibility_range {
lod_index = render_visibility_ranges.lod_index_for_entity(entity.into());
Expand All @@ -1254,7 +1249,6 @@ pub fn extract_meshes_for_gpu_building(
let shared = RenderMeshInstanceShared::from_components(
previous_transform,
mesh,
mesh_material_binding_id,
not_shadow_caster,
no_automatic_batching,
);
Expand Down Expand Up @@ -1337,6 +1331,7 @@ fn set_mesh_motion_vector_flags(

/// Creates the [`RenderMeshInstanceGpu`]s and [`MeshInputUniform`]s when GPU
/// mesh uniforms are built.
#[allow(clippy::too_many_arguments)]
pub fn collect_meshes_for_gpu_building(
render_mesh_instances: ResMut<RenderMeshInstances>,
batched_instance_buffers: ResMut<
Expand All @@ -1345,6 +1340,7 @@ pub fn collect_meshes_for_gpu_building(
mut mesh_culling_data_buffer: ResMut<MeshCullingDataBuffer>,
mut render_mesh_instance_queues: ResMut<RenderMeshInstanceGpuQueues>,
mesh_allocator: Res<MeshAllocator>,
mesh_material_ids: Res<RenderMeshMaterialIds>,
skin_indices: Res<SkinIndices>,
) {
let RenderMeshInstances::GpuBuilding(ref mut render_mesh_instances) =
Expand Down Expand Up @@ -1381,6 +1377,7 @@ pub fn collect_meshes_for_gpu_building(
current_input_buffer,
previous_input_buffer,
&mesh_allocator,
&mesh_material_ids,
&skin_indices,
);
}
Expand All @@ -1405,6 +1402,7 @@ pub fn collect_meshes_for_gpu_building(
current_input_buffer,
previous_input_buffer,
&mesh_allocator,
&mesh_material_ids,
&skin_indices,
);
mesh_culling_builder
Expand Down

0 comments on commit a572915

Please sign in to comment.