Skip to content

Commit 592822b

Browse files
authored
Remove entities from specialization caches when despawned. (#18627)
# Objective Fixes #17872 ## Solution This should have basically no impact on static scenes. We can optimize more later if anything comes up. Needing to iterate the two level bin is a bit unfortunate but shouldn't matter for apps that use a single camera.
1 parent bb87bd4 commit 592822b

File tree

2 files changed

+66
-14
lines changed

2 files changed

+66
-14
lines changed

crates/bevy_pbr/src/material.rs

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ use bevy_platform_support::collections::{HashMap, HashSet};
3434
use bevy_platform_support::hash::FixedHasher;
3535
use bevy_reflect::std_traits::ReflectDefault;
3636
use bevy_reflect::Reflect;
37+
use bevy_render::camera::extract_cameras;
3738
use bevy_render::mesh::mark_3d_meshes_as_changed_if_their_assets_changed;
3839
use bevy_render::render_asset::prepare_assets;
3940
use bevy_render::renderer::RenderQueue;
@@ -315,7 +316,7 @@ where
315316
ExtractSchedule,
316317
(
317318
extract_mesh_materials::<M>.before(ExtractMeshesSet),
318-
extract_entities_needs_specialization::<M>,
319+
extract_entities_needs_specialization::<M>.after(extract_cameras),
319320
),
320321
)
321322
.add_systems(
@@ -707,6 +708,15 @@ fn extract_mesh_materials<M: Material>(
707708
pub fn extract_entities_needs_specialization<M>(
708709
entities_needing_specialization: Extract<Res<EntitiesNeedingSpecialization<M>>>,
709710
mut entity_specialization_ticks: ResMut<EntitySpecializationTicks<M>>,
711+
mut removed_mesh_material_components: Extract<RemovedComponents<MeshMaterial3d<M>>>,
712+
mut specialized_material_pipeline_cache: ResMut<SpecializedMaterialPipelineCache<M>>,
713+
mut specialized_prepass_material_pipeline_cache: Option<
714+
ResMut<SpecializedPrepassMaterialPipelineCache<M>>,
715+
>,
716+
mut specialized_shadow_material_pipeline_cache: Option<
717+
ResMut<SpecializedShadowMaterialPipelineCache<M>>,
718+
>,
719+
views: Query<&ExtractedView>,
710720
ticks: SystemChangeTick,
711721
) where
712722
M: Material,
@@ -715,6 +725,29 @@ pub fn extract_entities_needs_specialization<M>(
715725
// Update the entity's specialization tick with this run's tick
716726
entity_specialization_ticks.insert((*entity).into(), ticks.this_run());
717727
}
728+
// Clean up any despawned entities
729+
for entity in removed_mesh_material_components.read() {
730+
entity_specialization_ticks.remove(&MainEntity::from(entity));
731+
for view in views {
732+
if let Some(cache) =
733+
specialized_material_pipeline_cache.get_mut(&view.retained_view_entity)
734+
{
735+
cache.remove(&MainEntity::from(entity));
736+
}
737+
if let Some(cache) = specialized_prepass_material_pipeline_cache
738+
.as_mut()
739+
.and_then(|c| c.get_mut(&view.retained_view_entity))
740+
{
741+
cache.remove(&MainEntity::from(entity));
742+
}
743+
if let Some(cache) = specialized_shadow_material_pipeline_cache
744+
.as_mut()
745+
.and_then(|c| c.get_mut(&view.retained_view_entity))
746+
{
747+
cache.remove(&MainEntity::from(entity));
748+
}
749+
}
750+
}
718751
}
719752

720753
#[derive(Resource, Deref, DerefMut, Clone, Debug)]
@@ -789,12 +822,15 @@ impl<M> Default for SpecializedMaterialViewPipelineCache<M> {
789822
pub fn check_entities_needing_specialization<M>(
790823
needs_specialization: Query<
791824
Entity,
792-
Or<(
793-
Changed<Mesh3d>,
794-
AssetChanged<Mesh3d>,
795-
Changed<MeshMaterial3d<M>>,
796-
AssetChanged<MeshMaterial3d<M>>,
797-
)>,
825+
(
826+
Or<(
827+
Changed<Mesh3d>,
828+
AssetChanged<Mesh3d>,
829+
Changed<MeshMaterial3d<M>>,
830+
AssetChanged<MeshMaterial3d<M>>,
831+
)>,
832+
With<MeshMaterial3d<M>>,
833+
),
798834
>,
799835
mut entities_needing_specialization: ResMut<EntitiesNeedingSpecialization<M>>,
800836
) where

crates/bevy_sprite/src/mesh2d/material.rs

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use bevy_ecs::{
2121
use bevy_math::FloatOrd;
2222
use bevy_platform_support::collections::HashMap;
2323
use bevy_reflect::{prelude::ReflectDefault, Reflect};
24+
use bevy_render::camera::extract_cameras;
2425
use bevy_render::render_phase::{DrawFunctionId, InputUniformIndex};
2526
use bevy_render::render_resource::CachedRenderPipelineId;
2627
use bevy_render::view::RenderVisibleEntities;
@@ -286,7 +287,7 @@ where
286287
.add_systems(
287288
ExtractSchedule,
288289
(
289-
extract_entities_needs_specialization::<M>,
290+
extract_entities_needs_specialization::<M>.after(extract_cameras),
290291
extract_mesh_materials_2d::<M>,
291292
),
292293
)
@@ -555,6 +556,9 @@ pub const fn tonemapping_pipeline_key(tonemapping: Tonemapping) -> Mesh2dPipelin
555556
pub fn extract_entities_needs_specialization<M>(
556557
entities_needing_specialization: Extract<Res<EntitiesNeedingSpecialization<M>>>,
557558
mut entity_specialization_ticks: ResMut<EntitySpecializationTicks<M>>,
559+
mut removed_mesh_material_components: Extract<RemovedComponents<MeshMaterial2d<M>>>,
560+
mut specialized_material2d_pipeline_cache: ResMut<SpecializedMaterial2dPipelineCache<M>>,
561+
views: Query<&MainEntity, With<ExtractedView>>,
558562
ticks: SystemChangeTick,
559563
) where
560564
M: Material2d,
@@ -563,6 +567,15 @@ pub fn extract_entities_needs_specialization<M>(
563567
// Update the entity's specialization tick with this run's tick
564568
entity_specialization_ticks.insert((*entity).into(), ticks.this_run());
565569
}
570+
// Clean up any despawned entities
571+
for entity in removed_mesh_material_components.read() {
572+
entity_specialization_ticks.remove(&MainEntity::from(entity));
573+
for view in views {
574+
if let Some(cache) = specialized_material2d_pipeline_cache.get_mut(view) {
575+
cache.remove(&MainEntity::from(entity));
576+
}
577+
}
578+
}
566579
}
567580

568581
#[derive(Clone, Resource, Deref, DerefMut, Debug)]
@@ -637,12 +650,15 @@ impl<M> Default for SpecializedMaterial2dViewPipelineCache<M> {
637650
pub fn check_entities_needing_specialization<M>(
638651
needs_specialization: Query<
639652
Entity,
640-
Or<(
641-
Changed<Mesh2d>,
642-
AssetChanged<Mesh2d>,
643-
Changed<MeshMaterial2d<M>>,
644-
AssetChanged<MeshMaterial2d<M>>,
645-
)>,
653+
(
654+
Or<(
655+
Changed<Mesh2d>,
656+
AssetChanged<Mesh2d>,
657+
Changed<MeshMaterial2d<M>>,
658+
AssetChanged<MeshMaterial2d<M>>,
659+
)>,
660+
With<MeshMaterial2d<M>>,
661+
),
646662
>,
647663
mut entities_needing_specialization: ResMut<EntitiesNeedingSpecialization<M>>,
648664
) where

0 commit comments

Comments
 (0)