Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow extract_meshes_for_gpu_building and extract_mesh_materials to run in parallel. #16799

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading