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_platform_support::hash::FixedHasher;
|
||||||
use bevy_reflect::std_traits::ReflectDefault;
|
use bevy_reflect::std_traits::ReflectDefault;
|
||||||
use bevy_reflect::Reflect;
|
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::mesh::mark_3d_meshes_as_changed_if_their_assets_changed;
|
||||||
use bevy_render::render_asset::prepare_assets;
|
use bevy_render::render_asset::prepare_assets;
|
||||||
use bevy_render::renderer::RenderQueue;
|
use bevy_render::renderer::RenderQueue;
|
||||||
@ -315,7 +316,7 @@ where
|
|||||||
ExtractSchedule,
|
ExtractSchedule,
|
||||||
(
|
(
|
||||||
extract_mesh_materials::<M>.before(ExtractMeshesSet),
|
extract_mesh_materials::<M>.before(ExtractMeshesSet),
|
||||||
extract_entities_needs_specialization::<M>,
|
extract_entities_needs_specialization::<M>.after(extract_cameras),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.add_systems(
|
.add_systems(
|
||||||
@ -707,6 +708,15 @@ fn extract_mesh_materials<M: Material>(
|
|||||||
pub fn extract_entities_needs_specialization<M>(
|
pub fn extract_entities_needs_specialization<M>(
|
||||||
entities_needing_specialization: Extract<Res<EntitiesNeedingSpecialization<M>>>,
|
entities_needing_specialization: Extract<Res<EntitiesNeedingSpecialization<M>>>,
|
||||||
mut entity_specialization_ticks: ResMut<EntitySpecializationTicks<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,
|
ticks: SystemChangeTick,
|
||||||
) where
|
) where
|
||||||
M: Material,
|
M: Material,
|
||||||
@ -715,6 +725,29 @@ pub fn extract_entities_needs_specialization<M>(
|
|||||||
// Update the entity's specialization tick with this run's tick
|
// Update the entity's specialization tick with this run's tick
|
||||||
entity_specialization_ticks.insert((*entity).into(), ticks.this_run());
|
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)]
|
#[derive(Resource, Deref, DerefMut, Clone, Debug)]
|
||||||
@ -789,12 +822,15 @@ impl<M> Default for SpecializedMaterialViewPipelineCache<M> {
|
|||||||
pub fn check_entities_needing_specialization<M>(
|
pub fn check_entities_needing_specialization<M>(
|
||||||
needs_specialization: Query<
|
needs_specialization: Query<
|
||||||
Entity,
|
Entity,
|
||||||
Or<(
|
(
|
||||||
Changed<Mesh3d>,
|
Or<(
|
||||||
AssetChanged<Mesh3d>,
|
Changed<Mesh3d>,
|
||||||
Changed<MeshMaterial3d<M>>,
|
AssetChanged<Mesh3d>,
|
||||||
AssetChanged<MeshMaterial3d<M>>,
|
Changed<MeshMaterial3d<M>>,
|
||||||
)>,
|
AssetChanged<MeshMaterial3d<M>>,
|
||||||
|
)>,
|
||||||
|
With<MeshMaterial3d<M>>,
|
||||||
|
),
|
||||||
>,
|
>,
|
||||||
mut entities_needing_specialization: ResMut<EntitiesNeedingSpecialization<M>>,
|
mut entities_needing_specialization: ResMut<EntitiesNeedingSpecialization<M>>,
|
||||||
) where
|
) where
|
||||||
|
@ -21,6 +21,7 @@ use bevy_ecs::{
|
|||||||
use bevy_math::FloatOrd;
|
use bevy_math::FloatOrd;
|
||||||
use bevy_platform_support::collections::HashMap;
|
use bevy_platform_support::collections::HashMap;
|
||||||
use bevy_reflect::{prelude::ReflectDefault, Reflect};
|
use bevy_reflect::{prelude::ReflectDefault, Reflect};
|
||||||
|
use bevy_render::camera::extract_cameras;
|
||||||
use bevy_render::render_phase::{DrawFunctionId, InputUniformIndex};
|
use bevy_render::render_phase::{DrawFunctionId, InputUniformIndex};
|
||||||
use bevy_render::render_resource::CachedRenderPipelineId;
|
use bevy_render::render_resource::CachedRenderPipelineId;
|
||||||
use bevy_render::view::RenderVisibleEntities;
|
use bevy_render::view::RenderVisibleEntities;
|
||||||
@ -286,7 +287,7 @@ where
|
|||||||
.add_systems(
|
.add_systems(
|
||||||
ExtractSchedule,
|
ExtractSchedule,
|
||||||
(
|
(
|
||||||
extract_entities_needs_specialization::<M>,
|
extract_entities_needs_specialization::<M>.after(extract_cameras),
|
||||||
extract_mesh_materials_2d::<M>,
|
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>(
|
pub fn extract_entities_needs_specialization<M>(
|
||||||
entities_needing_specialization: Extract<Res<EntitiesNeedingSpecialization<M>>>,
|
entities_needing_specialization: Extract<Res<EntitiesNeedingSpecialization<M>>>,
|
||||||
mut entity_specialization_ticks: ResMut<EntitySpecializationTicks<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,
|
ticks: SystemChangeTick,
|
||||||
) where
|
) where
|
||||||
M: Material2d,
|
M: Material2d,
|
||||||
@ -563,6 +567,15 @@ pub fn extract_entities_needs_specialization<M>(
|
|||||||
// Update the entity's specialization tick with this run's tick
|
// Update the entity's specialization tick with this run's tick
|
||||||
entity_specialization_ticks.insert((*entity).into(), ticks.this_run());
|
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)]
|
#[derive(Clone, Resource, Deref, DerefMut, Debug)]
|
||||||
@ -637,12 +650,15 @@ impl<M> Default for SpecializedMaterial2dViewPipelineCache<M> {
|
|||||||
pub fn check_entities_needing_specialization<M>(
|
pub fn check_entities_needing_specialization<M>(
|
||||||
needs_specialization: Query<
|
needs_specialization: Query<
|
||||||
Entity,
|
Entity,
|
||||||
Or<(
|
(
|
||||||
Changed<Mesh2d>,
|
Or<(
|
||||||
AssetChanged<Mesh2d>,
|
Changed<Mesh2d>,
|
||||||
Changed<MeshMaterial2d<M>>,
|
AssetChanged<Mesh2d>,
|
||||||
AssetChanged<MeshMaterial2d<M>>,
|
Changed<MeshMaterial2d<M>>,
|
||||||
)>,
|
AssetChanged<MeshMaterial2d<M>>,
|
||||||
|
)>,
|
||||||
|
With<MeshMaterial2d<M>>,
|
||||||
|
),
|
||||||
>,
|
>,
|
||||||
mut entities_needing_specialization: ResMut<EntitiesNeedingSpecialization<M>>,
|
mut entities_needing_specialization: ResMut<EntitiesNeedingSpecialization<M>>,
|
||||||
) where
|
) where
|
||||||
|
Loading…
Reference in New Issue
Block a user