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.
This commit is contained in:
parent
bb87bd4d02
commit
592822b702
@ -34,6 +34,7 @@ use bevy_platform_support::collections::{HashMap, HashSet};
|
||||
use bevy_platform_support::hash::FixedHasher;
|
||||
use bevy_reflect::std_traits::ReflectDefault;
|
||||
use bevy_reflect::Reflect;
|
||||
use bevy_render::camera::extract_cameras;
|
||||
use bevy_render::mesh::mark_3d_meshes_as_changed_if_their_assets_changed;
|
||||
use bevy_render::render_asset::prepare_assets;
|
||||
use bevy_render::renderer::RenderQueue;
|
||||
@ -315,7 +316,7 @@ where
|
||||
ExtractSchedule,
|
||||
(
|
||||
extract_mesh_materials::<M>.before(ExtractMeshesSet),
|
||||
extract_entities_needs_specialization::<M>,
|
||||
extract_entities_needs_specialization::<M>.after(extract_cameras),
|
||||
),
|
||||
)
|
||||
.add_systems(
|
||||
@ -707,6 +708,15 @@ fn extract_mesh_materials<M: Material>(
|
||||
pub fn extract_entities_needs_specialization<M>(
|
||||
entities_needing_specialization: Extract<Res<EntitiesNeedingSpecialization<M>>>,
|
||||
mut entity_specialization_ticks: ResMut<EntitySpecializationTicks<M>>,
|
||||
mut removed_mesh_material_components: Extract<RemovedComponents<MeshMaterial3d<M>>>,
|
||||
mut specialized_material_pipeline_cache: ResMut<SpecializedMaterialPipelineCache<M>>,
|
||||
mut specialized_prepass_material_pipeline_cache: Option<
|
||||
ResMut<SpecializedPrepassMaterialPipelineCache<M>>,
|
||||
>,
|
||||
mut specialized_shadow_material_pipeline_cache: Option<
|
||||
ResMut<SpecializedShadowMaterialPipelineCache<M>>,
|
||||
>,
|
||||
views: Query<&ExtractedView>,
|
||||
ticks: SystemChangeTick,
|
||||
) where
|
||||
M: Material,
|
||||
@ -715,6 +725,29 @@ pub fn extract_entities_needs_specialization<M>(
|
||||
// Update the entity's specialization tick with this run's tick
|
||||
entity_specialization_ticks.insert((*entity).into(), ticks.this_run());
|
||||
}
|
||||
// Clean up any despawned entities
|
||||
for entity in removed_mesh_material_components.read() {
|
||||
entity_specialization_ticks.remove(&MainEntity::from(entity));
|
||||
for view in views {
|
||||
if let Some(cache) =
|
||||
specialized_material_pipeline_cache.get_mut(&view.retained_view_entity)
|
||||
{
|
||||
cache.remove(&MainEntity::from(entity));
|
||||
}
|
||||
if let Some(cache) = specialized_prepass_material_pipeline_cache
|
||||
.as_mut()
|
||||
.and_then(|c| c.get_mut(&view.retained_view_entity))
|
||||
{
|
||||
cache.remove(&MainEntity::from(entity));
|
||||
}
|
||||
if let Some(cache) = specialized_shadow_material_pipeline_cache
|
||||
.as_mut()
|
||||
.and_then(|c| c.get_mut(&view.retained_view_entity))
|
||||
{
|
||||
cache.remove(&MainEntity::from(entity));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Resource, Deref, DerefMut, Clone, Debug)]
|
||||
@ -789,12 +822,15 @@ impl<M> Default for SpecializedMaterialViewPipelineCache<M> {
|
||||
pub fn check_entities_needing_specialization<M>(
|
||||
needs_specialization: Query<
|
||||
Entity,
|
||||
Or<(
|
||||
Changed<Mesh3d>,
|
||||
AssetChanged<Mesh3d>,
|
||||
Changed<MeshMaterial3d<M>>,
|
||||
AssetChanged<MeshMaterial3d<M>>,
|
||||
)>,
|
||||
(
|
||||
Or<(
|
||||
Changed<Mesh3d>,
|
||||
AssetChanged<Mesh3d>,
|
||||
Changed<MeshMaterial3d<M>>,
|
||||
AssetChanged<MeshMaterial3d<M>>,
|
||||
)>,
|
||||
With<MeshMaterial3d<M>>,
|
||||
),
|
||||
>,
|
||||
mut entities_needing_specialization: ResMut<EntitiesNeedingSpecialization<M>>,
|
||||
) where
|
||||
|
@ -21,6 +21,7 @@ use bevy_ecs::{
|
||||
use bevy_math::FloatOrd;
|
||||
use bevy_platform_support::collections::HashMap;
|
||||
use bevy_reflect::{prelude::ReflectDefault, Reflect};
|
||||
use bevy_render::camera::extract_cameras;
|
||||
use bevy_render::render_phase::{DrawFunctionId, InputUniformIndex};
|
||||
use bevy_render::render_resource::CachedRenderPipelineId;
|
||||
use bevy_render::view::RenderVisibleEntities;
|
||||
@ -286,7 +287,7 @@ where
|
||||
.add_systems(
|
||||
ExtractSchedule,
|
||||
(
|
||||
extract_entities_needs_specialization::<M>,
|
||||
extract_entities_needs_specialization::<M>.after(extract_cameras),
|
||||
extract_mesh_materials_2d::<M>,
|
||||
),
|
||||
)
|
||||
@ -555,6 +556,9 @@ pub const fn tonemapping_pipeline_key(tonemapping: Tonemapping) -> Mesh2dPipelin
|
||||
pub fn extract_entities_needs_specialization<M>(
|
||||
entities_needing_specialization: Extract<Res<EntitiesNeedingSpecialization<M>>>,
|
||||
mut entity_specialization_ticks: ResMut<EntitySpecializationTicks<M>>,
|
||||
mut removed_mesh_material_components: Extract<RemovedComponents<MeshMaterial2d<M>>>,
|
||||
mut specialized_material2d_pipeline_cache: ResMut<SpecializedMaterial2dPipelineCache<M>>,
|
||||
views: Query<&MainEntity, With<ExtractedView>>,
|
||||
ticks: SystemChangeTick,
|
||||
) where
|
||||
M: Material2d,
|
||||
@ -563,6 +567,15 @@ pub fn extract_entities_needs_specialization<M>(
|
||||
// Update the entity's specialization tick with this run's tick
|
||||
entity_specialization_ticks.insert((*entity).into(), ticks.this_run());
|
||||
}
|
||||
// Clean up any despawned entities
|
||||
for entity in removed_mesh_material_components.read() {
|
||||
entity_specialization_ticks.remove(&MainEntity::from(entity));
|
||||
for view in views {
|
||||
if let Some(cache) = specialized_material2d_pipeline_cache.get_mut(view) {
|
||||
cache.remove(&MainEntity::from(entity));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Resource, Deref, DerefMut, Debug)]
|
||||
@ -637,12 +650,15 @@ impl<M> Default for SpecializedMaterial2dViewPipelineCache<M> {
|
||||
pub fn check_entities_needing_specialization<M>(
|
||||
needs_specialization: Query<
|
||||
Entity,
|
||||
Or<(
|
||||
Changed<Mesh2d>,
|
||||
AssetChanged<Mesh2d>,
|
||||
Changed<MeshMaterial2d<M>>,
|
||||
AssetChanged<MeshMaterial2d<M>>,
|
||||
)>,
|
||||
(
|
||||
Or<(
|
||||
Changed<Mesh2d>,
|
||||
AssetChanged<Mesh2d>,
|
||||
Changed<MeshMaterial2d<M>>,
|
||||
AssetChanged<MeshMaterial2d<M>>,
|
||||
)>,
|
||||
With<MeshMaterial2d<M>>,
|
||||
),
|
||||
>,
|
||||
mut entities_needing_specialization: ResMut<EntitiesNeedingSpecialization<M>>,
|
||||
) where
|
||||
|
Loading…
Reference in New Issue
Block a user