diff --git a/crates/bevy_pbr/src/material.rs b/crates/bevy_pbr/src/material.rs index 1979e995e6..7465260a63 100644 --- a/crates/bevy_pbr/src/material.rs +++ b/crates/bevy_pbr/src/material.rs @@ -52,6 +52,7 @@ use bevy_render::{ }; use bevy_render::{mesh::allocator::MeshAllocator, sync_world::MainEntityHashMap}; use bevy_render::{texture::FallbackImage, view::RenderVisibleEntities}; +use bevy_utils::Parallel; use core::{hash::Hash, marker::PhantomData}; use tracing::error; @@ -832,14 +833,18 @@ pub fn check_entities_needing_specialization( With>, ), >, + mut par_local: Local>>, mut entities_needing_specialization: ResMut>, ) where M: Material, { entities_needing_specialization.clear(); - for entity in &needs_specialization { - entities_needing_specialization.push(entity); - } + + needs_specialization + .par_iter() + .for_each(|entity| par_local.borrow_local_mut().push(entity)); + + par_local.drain_into(&mut entities_needing_specialization); } pub fn specialize_material_meshes( diff --git a/crates/bevy_pbr/src/prepass/mod.rs b/crates/bevy_pbr/src/prepass/mod.rs index 7b70df38aa..a13a5487da 100644 --- a/crates/bevy_pbr/src/prepass/mod.rs +++ b/crates/bevy_pbr/src/prepass/mod.rs @@ -268,20 +268,22 @@ type PreviousMeshFilter = Or<(With, With)>; pub fn update_mesh_previous_global_transforms( mut commands: Commands, views: Query<&Camera, Or<(With, With)>>, - meshes: Query<(Entity, &GlobalTransform, Option<&PreviousGlobalTransform>), PreviousMeshFilter>, + new_meshes: Query< + (Entity, &GlobalTransform), + (PreviousMeshFilter, Without), + >, + mut meshes: Query<(&GlobalTransform, &mut PreviousGlobalTransform), PreviousMeshFilter>, ) { let should_run = views.iter().any(|camera| camera.is_active); if should_run { - for (entity, transform, old_previous_transform) in &meshes { + for (entity, transform) in &new_meshes { let new_previous_transform = PreviousGlobalTransform(transform.affine()); - // Make sure not to trigger change detection on - // `PreviousGlobalTransform` if the previous transform hasn't - // changed. - if old_previous_transform != Some(&new_previous_transform) { - commands.entity(entity).try_insert(new_previous_transform); - } + commands.entity(entity).try_insert(new_previous_transform); } + meshes.par_iter_mut().for_each(|(transform, mut previous)| { + previous.set_if_neq(PreviousGlobalTransform(transform.affine())); + }); } } diff --git a/crates/bevy_render/src/view/visibility/range.rs b/crates/bevy_render/src/view/visibility/range.rs index 86e75733c5..74ac212bf3 100644 --- a/crates/bevy_render/src/view/visibility/range.rs +++ b/crates/bevy_render/src/view/visibility/range.rs @@ -15,13 +15,13 @@ use bevy_ecs::{ removal_detection::RemovedComponents, resource::Resource, schedule::IntoScheduleConfigs as _, - system::{Query, Res, ResMut}, + system::{Local, Query, Res, ResMut}, }; use bevy_math::{vec4, FloatOrd, Vec4}; use bevy_platform_support::collections::HashMap; use bevy_reflect::Reflect; use bevy_transform::components::GlobalTransform; -use bevy_utils::prelude::default; +use bevy_utils::{prelude::default, Parallel}; use nonmax::NonMaxU16; use wgpu::{BufferBindingType, BufferUsages}; @@ -385,7 +385,8 @@ impl VisibleEntityRanges { pub fn check_visibility_ranges( mut visible_entity_ranges: ResMut, view_query: Query<(Entity, &GlobalTransform), With>, - mut entity_query: Query<(Entity, &GlobalTransform, Option<&Aabb>, &VisibilityRange)>, + mut par_local: Local>>, + entity_query: Query<(Entity, &GlobalTransform, Option<&Aabb>, &VisibilityRange)>, ) { visible_entity_ranges.clear(); @@ -404,30 +405,34 @@ pub fn check_visibility_ranges( // Check each entity/view pair. Only consider entities with // [`VisibilityRange`] components. - for (entity, entity_transform, maybe_model_aabb, visibility_range) in entity_query.iter_mut() { - let mut visibility = 0; - for (view_index, &(_, view_position)) in views.iter().enumerate() { - // If instructed to use the AABB and the model has one, use its - // center as the model position. Otherwise, use the model's - // translation. - let model_position = match (visibility_range.use_aabb, maybe_model_aabb) { - (true, Some(model_aabb)) => entity_transform - .affine() - .transform_point3a(model_aabb.center), - _ => entity_transform.translation_vec3a(), - }; + entity_query.par_iter().for_each( + |(entity, entity_transform, maybe_model_aabb, visibility_range)| { + let mut visibility = 0; + for (view_index, &(_, view_position)) in views.iter().enumerate() { + // If instructed to use the AABB and the model has one, use its + // center as the model position. Otherwise, use the model's + // translation. + let model_position = match (visibility_range.use_aabb, maybe_model_aabb) { + (true, Some(model_aabb)) => entity_transform + .affine() + .transform_point3a(model_aabb.center), + _ => entity_transform.translation_vec3a(), + }; - if visibility_range.is_visible_at_all((view_position - model_position).length()) { - visibility |= 1 << view_index; + if visibility_range.is_visible_at_all((view_position - model_position).length()) { + visibility |= 1 << view_index; + } } - } - // Invisible entities have no entry at all in the hash map. This speeds - // up checks slightly in this common case. - if visibility != 0 { - visible_entity_ranges.entities.insert(entity, visibility); - } - } + // Invisible entities have no entry at all in the hash map. This speeds + // up checks slightly in this common case. + if visibility != 0 { + par_local.borrow_local_mut().push((entity, visibility)); + } + }, + ); + + visible_entity_ranges.entities.extend(par_local.drain()); } /// Extracts all [`VisibilityRange`] components from the main world to the diff --git a/crates/bevy_sprite/src/mesh2d/material.rs b/crates/bevy_sprite/src/mesh2d/material.rs index a9401a8144..5df02cfc7b 100644 --- a/crates/bevy_sprite/src/mesh2d/material.rs +++ b/crates/bevy_sprite/src/mesh2d/material.rs @@ -45,6 +45,7 @@ use bevy_render::{ view::{ExtractedView, ViewVisibility}, Extract, ExtractSchedule, Render, RenderApp, RenderSet, }; +use bevy_utils::Parallel; use core::{hash::Hash, marker::PhantomData}; use derive_more::derive::From; use tracing::error; @@ -660,14 +661,18 @@ pub fn check_entities_needing_specialization( With>, ), >, + mut par_local: Local>>, mut entities_needing_specialization: ResMut>, ) where M: Material2d, { entities_needing_specialization.clear(); - for entity in &needs_specialization { - entities_needing_specialization.push(entity); - } + + needs_specialization + .par_iter() + .for_each(|entity| par_local.borrow_local_mut().push(entity)); + + par_local.drain_into(&mut entities_needing_specialization); } pub fn specialize_material2d_meshes(