From b2c1414551029cd41dd825d8ef1197b808e6eeee Mon Sep 17 00:00:00 2001 From: Trashtalk Date: Mon, 8 Jul 2024 22:30:18 +0200 Subject: [PATCH 1/6] Only extract added entities, stop nuking render world --- crates/bevy_pbr/src/render/light.rs | 10 ++++----- crates/bevy_render/src/camera/camera.rs | 3 ++- crates/bevy_render/src/extract_component.rs | 15 +++++++------ crates/bevy_render/src/lib.rs | 21 ++++++++++++++----- .../bevy_render/src/view/visibility/range.rs | 3 ++- crates/bevy_render/src/view/window/mod.rs | 2 +- crates/bevy_ui/src/render/mod.rs | 2 +- 7 files changed, 36 insertions(+), 20 deletions(-) diff --git a/crates/bevy_pbr/src/render/light.rs b/crates/bevy_pbr/src/render/light.rs index 1356e94825ccc..2bab20c4061c8 100644 --- a/crates/bevy_pbr/src/render/light.rs +++ b/crates/bevy_pbr/src/render/light.rs @@ -181,7 +181,7 @@ pub fn extract_lights( &GlobalTransform, &ViewVisibility, &CubemapFrusta, - )>, + ), Added>, >, spot_lights: Extract< Query<( @@ -190,7 +190,7 @@ pub fn extract_lights( &GlobalTransform, &ViewVisibility, &Frustum, - )>, + ), Added>, >, directional_lights: Extract< Query< @@ -206,7 +206,7 @@ pub fn extract_lights( Option<&RenderLayers>, Option<&VolumetricLight>, ), - Without, + (Without, Added), >, >, mut previous_point_lights_len: Local, @@ -531,8 +531,8 @@ pub fn prepare_lights( Entity, &ExtractedPointLight, AnyOf<(&CubemapFrusta, &Frustum)>, - )>, - directional_lights: Query<(Entity, &ExtractedDirectionalLight)>, + ), Added>, + directional_lights: Query<(Entity, &ExtractedDirectionalLight), Added>, mut live_shadow_mapping_lights: Local, ) { let views_iter = views.iter(); diff --git a/crates/bevy_render/src/camera/camera.rs b/crates/bevy_render/src/camera/camera.rs index b950b2a6b9382..5b40767637bcd 100644 --- a/crates/bevy_render/src/camera/camera.rs +++ b/crates/bevy_render/src/camera/camera.rs @@ -15,6 +15,7 @@ use crate::{ use bevy_asset::{AssetEvent, AssetId, Assets, Handle}; use bevy_derive::{Deref, DerefMut}; use bevy_ecs::{ + prelude::*, change_detection::DetectChanges, component::Component, entity::Entity, @@ -842,7 +843,7 @@ pub fn extract_cameras( Option<&RenderLayers>, Option<&Projection>, Has, - )>, + ), Added>, >, primary_window: Extract>>, gpu_preprocessing_support: Res, diff --git a/crates/bevy_render/src/extract_component.rs b/crates/bevy_render/src/extract_component.rs index 4b327cf6af3e8..f29036a545b03 100644 --- a/crates/bevy_render/src/extract_component.rs +++ b/crates/bevy_render/src/extract_component.rs @@ -16,6 +16,9 @@ use std::{marker::PhantomData, ops::Deref}; pub use bevy_render_macros::ExtractComponent; +#[derive(Component)] +pub struct MainWorldEntity(Entity); + /// Stores the index of a uniform inside of [`ComponentUniforms`]. #[derive(Component)] pub struct DynamicUniformIndex { @@ -209,32 +212,32 @@ impl ExtractComponent for Handle { fn extract_components( mut commands: Commands, mut previous_len: Local, - query: Extract>, + query: Extract)>>, ) { let mut values = Vec::with_capacity(*previous_len); for (entity, query_item) in &query { if let Some(component) = C::extract_component(query_item) { - values.push((entity, component)); + values.push((component, MainWorldEntity(entity))); } } *previous_len = values.len(); - commands.insert_or_spawn_batch(values); + commands.spawn_batch(values); } /// This system extracts all visible components of the corresponding [`ExtractComponent`] type. fn extract_visible_components( mut commands: Commands, mut previous_len: Local, - query: Extract>, + query: Extract)>>, ) { let mut values = Vec::with_capacity(*previous_len); for (entity, view_visibility, query_item) in &query { if view_visibility.get() { if let Some(component) = C::extract_component(query_item) { - values.push((entity, component)); + values.push((component, MainWorldEntity(entity))); } } } *previous_len = values.len(); - commands.insert_or_spawn_batch(values); + commands.spawn_batch(values); } diff --git a/crates/bevy_render/src/lib.rs b/crates/bevy_render/src/lib.rs index 49f25530b1323..67d0e1e51f79b 100644 --- a/crates/bevy_render/src/lib.rs +++ b/crates/bevy_render/src/lib.rs @@ -463,9 +463,7 @@ unsafe fn initialize_render_app(app: &mut App) { render_system, ) .in_set(RenderSet::Render), - World::clear_entities.in_set(RenderSet::Cleanup), - ), - ); + )); render_app.set_extract(|main_world, render_world| { #[cfg(feature = "trace")] @@ -479,7 +477,7 @@ unsafe fn initialize_render_app(app: &mut App) { // reserve all existing main world entities for use in render_app // they can only be spawned using `get_or_spawn()` let total_count = main_world.entities().total_count(); - + /* assert_eq!( render_world.entities().len(), 0, @@ -492,8 +490,21 @@ unsafe fn initialize_render_app(app: &mut App) { .entities_mut() .flush_and_reserve_invalid_assuming_no_entities(total_count); } + */ } - + println!("{}", render_world.entities().len()); + /* + if (render_world.entities().len() < 50) { + println!("Entities:"); + for entity in render_world.iter_entities() { + print!("["); + for component_info in render_world.inspect_entity(entity.id()).take(5) { + print!("{:?}, ", component_info.name()); + } + print!("] "); + } + } + */ // run extract schedule extract(main_world, render_world); }); diff --git a/crates/bevy_render/src/view/visibility/range.rs b/crates/bevy_render/src/view/visibility/range.rs index d1e1d6546fa14..fbdbb960b140b 100644 --- a/crates/bevy_render/src/view/visibility/range.rs +++ b/crates/bevy_render/src/view/visibility/range.rs @@ -8,6 +8,7 @@ use std::{ use bevy_app::{App, Plugin, PostUpdate}; use bevy_ecs::{ + prelude::*, component::Component, entity::Entity, query::{Changed, With}, @@ -405,7 +406,7 @@ pub fn check_visibility_ranges( /// render world and inserts them into [`RenderVisibilityRanges`]. pub fn extract_visibility_ranges( mut render_visibility_ranges: ResMut, - visibility_ranges_query: Extract>, + visibility_ranges_query: Extract>>, changed_ranges_query: Extract>>, ) { if changed_ranges_query.is_empty() { diff --git a/crates/bevy_render/src/view/window/mod.rs b/crates/bevy_render/src/view/window/mod.rs index cf347586e6429..8bf92defcd74b 100644 --- a/crates/bevy_render/src/view/window/mod.rs +++ b/crates/bevy_render/src/view/window/mod.rs @@ -118,7 +118,7 @@ fn extract_windows( mut extracted_windows: ResMut, screenshot_manager: Extract>, mut closing: Extract>, - windows: Extract)>>, + windows: Extract), Added>>, mut removed: Extract>, mut window_surfaces: ResMut, ) { diff --git a/crates/bevy_ui/src/render/mod.rs b/crates/bevy_ui/src/render/mod.rs index c4cafa593ab1f..402fcca277731 100644 --- a/crates/bevy_ui/src/render/mod.rs +++ b/crates/bevy_ui/src/render/mod.rs @@ -725,7 +725,7 @@ pub fn extract_default_ui_camera_view( mut commands: Commands, mut transparent_render_phases: ResMut>, ui_scale: Extract>, - query: Extract, With)>>>, + query: Extract, With)>, Added)>>, mut live_entities: Local, ) { live_entities.clear(); From 4a17b03d2f85d14445a78a44caea6b89b72b4cf5 Mon Sep 17 00:00:00 2001 From: Trashtalk Date: Wed, 10 Jul 2024 22:51:52 +0200 Subject: [PATCH 2/6] Revert "Only extract added entities, stop nuking render world" This reverts commit b2c1414551029cd41dd825d8ef1197b808e6eeee. --- crates/bevy_pbr/src/render/light.rs | 10 ++++----- crates/bevy_render/src/camera/camera.rs | 3 +-- crates/bevy_render/src/extract_component.rs | 15 ++++++------- crates/bevy_render/src/lib.rs | 21 +++++-------------- .../bevy_render/src/view/visibility/range.rs | 3 +-- crates/bevy_render/src/view/window/mod.rs | 2 +- crates/bevy_ui/src/render/mod.rs | 2 +- 7 files changed, 20 insertions(+), 36 deletions(-) diff --git a/crates/bevy_pbr/src/render/light.rs b/crates/bevy_pbr/src/render/light.rs index 2bab20c4061c8..1356e94825ccc 100644 --- a/crates/bevy_pbr/src/render/light.rs +++ b/crates/bevy_pbr/src/render/light.rs @@ -181,7 +181,7 @@ pub fn extract_lights( &GlobalTransform, &ViewVisibility, &CubemapFrusta, - ), Added>, + )>, >, spot_lights: Extract< Query<( @@ -190,7 +190,7 @@ pub fn extract_lights( &GlobalTransform, &ViewVisibility, &Frustum, - ), Added>, + )>, >, directional_lights: Extract< Query< @@ -206,7 +206,7 @@ pub fn extract_lights( Option<&RenderLayers>, Option<&VolumetricLight>, ), - (Without, Added), + Without, >, >, mut previous_point_lights_len: Local, @@ -531,8 +531,8 @@ pub fn prepare_lights( Entity, &ExtractedPointLight, AnyOf<(&CubemapFrusta, &Frustum)>, - ), Added>, - directional_lights: Query<(Entity, &ExtractedDirectionalLight), Added>, + )>, + directional_lights: Query<(Entity, &ExtractedDirectionalLight)>, mut live_shadow_mapping_lights: Local, ) { let views_iter = views.iter(); diff --git a/crates/bevy_render/src/camera/camera.rs b/crates/bevy_render/src/camera/camera.rs index 5b40767637bcd..b950b2a6b9382 100644 --- a/crates/bevy_render/src/camera/camera.rs +++ b/crates/bevy_render/src/camera/camera.rs @@ -15,7 +15,6 @@ use crate::{ use bevy_asset::{AssetEvent, AssetId, Assets, Handle}; use bevy_derive::{Deref, DerefMut}; use bevy_ecs::{ - prelude::*, change_detection::DetectChanges, component::Component, entity::Entity, @@ -843,7 +842,7 @@ pub fn extract_cameras( Option<&RenderLayers>, Option<&Projection>, Has, - ), Added>, + )>, >, primary_window: Extract>>, gpu_preprocessing_support: Res, diff --git a/crates/bevy_render/src/extract_component.rs b/crates/bevy_render/src/extract_component.rs index f29036a545b03..4b327cf6af3e8 100644 --- a/crates/bevy_render/src/extract_component.rs +++ b/crates/bevy_render/src/extract_component.rs @@ -16,9 +16,6 @@ use std::{marker::PhantomData, ops::Deref}; pub use bevy_render_macros::ExtractComponent; -#[derive(Component)] -pub struct MainWorldEntity(Entity); - /// Stores the index of a uniform inside of [`ComponentUniforms`]. #[derive(Component)] pub struct DynamicUniformIndex { @@ -212,32 +209,32 @@ impl ExtractComponent for Handle { fn extract_components( mut commands: Commands, mut previous_len: Local, - query: Extract)>>, + query: Extract>, ) { let mut values = Vec::with_capacity(*previous_len); for (entity, query_item) in &query { if let Some(component) = C::extract_component(query_item) { - values.push((component, MainWorldEntity(entity))); + values.push((entity, component)); } } *previous_len = values.len(); - commands.spawn_batch(values); + commands.insert_or_spawn_batch(values); } /// This system extracts all visible components of the corresponding [`ExtractComponent`] type. fn extract_visible_components( mut commands: Commands, mut previous_len: Local, - query: Extract)>>, + query: Extract>, ) { let mut values = Vec::with_capacity(*previous_len); for (entity, view_visibility, query_item) in &query { if view_visibility.get() { if let Some(component) = C::extract_component(query_item) { - values.push((component, MainWorldEntity(entity))); + values.push((entity, component)); } } } *previous_len = values.len(); - commands.spawn_batch(values); + commands.insert_or_spawn_batch(values); } diff --git a/crates/bevy_render/src/lib.rs b/crates/bevy_render/src/lib.rs index 67d0e1e51f79b..49f25530b1323 100644 --- a/crates/bevy_render/src/lib.rs +++ b/crates/bevy_render/src/lib.rs @@ -463,7 +463,9 @@ unsafe fn initialize_render_app(app: &mut App) { render_system, ) .in_set(RenderSet::Render), - )); + World::clear_entities.in_set(RenderSet::Cleanup), + ), + ); render_app.set_extract(|main_world, render_world| { #[cfg(feature = "trace")] @@ -477,7 +479,7 @@ unsafe fn initialize_render_app(app: &mut App) { // reserve all existing main world entities for use in render_app // they can only be spawned using `get_or_spawn()` let total_count = main_world.entities().total_count(); - /* + assert_eq!( render_world.entities().len(), 0, @@ -490,21 +492,8 @@ unsafe fn initialize_render_app(app: &mut App) { .entities_mut() .flush_and_reserve_invalid_assuming_no_entities(total_count); } - */ } - println!("{}", render_world.entities().len()); - /* - if (render_world.entities().len() < 50) { - println!("Entities:"); - for entity in render_world.iter_entities() { - print!("["); - for component_info in render_world.inspect_entity(entity.id()).take(5) { - print!("{:?}, ", component_info.name()); - } - print!("] "); - } - } - */ + // run extract schedule extract(main_world, render_world); }); diff --git a/crates/bevy_render/src/view/visibility/range.rs b/crates/bevy_render/src/view/visibility/range.rs index fbdbb960b140b..d1e1d6546fa14 100644 --- a/crates/bevy_render/src/view/visibility/range.rs +++ b/crates/bevy_render/src/view/visibility/range.rs @@ -8,7 +8,6 @@ use std::{ use bevy_app::{App, Plugin, PostUpdate}; use bevy_ecs::{ - prelude::*, component::Component, entity::Entity, query::{Changed, With}, @@ -406,7 +405,7 @@ pub fn check_visibility_ranges( /// render world and inserts them into [`RenderVisibilityRanges`]. pub fn extract_visibility_ranges( mut render_visibility_ranges: ResMut, - visibility_ranges_query: Extract>>, + visibility_ranges_query: Extract>, changed_ranges_query: Extract>>, ) { if changed_ranges_query.is_empty() { diff --git a/crates/bevy_render/src/view/window/mod.rs b/crates/bevy_render/src/view/window/mod.rs index 8bf92defcd74b..cf347586e6429 100644 --- a/crates/bevy_render/src/view/window/mod.rs +++ b/crates/bevy_render/src/view/window/mod.rs @@ -118,7 +118,7 @@ fn extract_windows( mut extracted_windows: ResMut, screenshot_manager: Extract>, mut closing: Extract>, - windows: Extract), Added>>, + windows: Extract)>>, mut removed: Extract>, mut window_surfaces: ResMut, ) { diff --git a/crates/bevy_ui/src/render/mod.rs b/crates/bevy_ui/src/render/mod.rs index 402fcca277731..c4cafa593ab1f 100644 --- a/crates/bevy_ui/src/render/mod.rs +++ b/crates/bevy_ui/src/render/mod.rs @@ -725,7 +725,7 @@ pub fn extract_default_ui_camera_view( mut commands: Commands, mut transparent_render_phases: ResMut>, ui_scale: Extract>, - query: Extract, With)>, Added)>>, + query: Extract, With)>>>, mut live_entities: Local, ) { live_entities.clear(); From 03c849a03680c04afc4522aa21e715df6adb588d Mon Sep 17 00:00:00 2001 From: Trashtalk Date: Sat, 20 Jul 2024 22:14:44 +0200 Subject: [PATCH 3/6] attempt at decoupling main/render ids via a map --- crates/bevy_render/src/extract_component.rs | 40 ++++++++++++++------- crates/bevy_render/src/lib.rs | 23 +++++++++++- 2 files changed, 50 insertions(+), 13 deletions(-) diff --git a/crates/bevy_render/src/extract_component.rs b/crates/bevy_render/src/extract_component.rs index 4b327cf6af3e8..eaea2336cb710 100644 --- a/crates/bevy_render/src/extract_component.rs +++ b/crates/bevy_render/src/extract_component.rs @@ -15,6 +15,7 @@ use bevy_ecs::{ use std::{marker::PhantomData, ops::Deref}; pub use bevy_render_macros::ExtractComponent; +pub use bevy_utils::EntityHashMap; /// Stores the index of a uniform inside of [`ComponentUniforms`]. #[derive(Component)] @@ -155,6 +156,9 @@ fn prepare_uniform_components( commands.insert_or_spawn_batch(entities); } +#[derive(Resource)] +pub struct MainToRenderEntityMap(pub EntityHashMap); + /// This plugin extracts the components into the "render world". /// /// Therefore it sets up the [`ExtractSchedule`] step @@ -185,6 +189,7 @@ impl ExtractComponentPlugin { impl Plugin for ExtractComponentPlugin { fn build(&self, app: &mut App) { if let Some(render_app) = app.get_sub_app_mut(RenderApp) { + render_app.insert_resource(MainToRenderEntityMap(EntityHashMap::default())); if self.only_extract_visible { render_app.add_systems(ExtractSchedule, extract_visible_components::); } else { @@ -205,36 +210,47 @@ impl ExtractComponent for Handle { } } +#[derive(Component)] +struct Mayfly; + /// This system extracts all components of the corresponding [`ExtractComponent`] type. fn extract_components( mut commands: Commands, - mut previous_len: Local, + mut map: ResMut, query: Extract>, ) { - let mut values = Vec::with_capacity(*previous_len); for (entity, query_item) in &query { if let Some(component) = C::extract_component(query_item) { - values.push((entity, component)); + if map.0.contains_key(&entity) { + println!("Hey, we've seen this one before!"); + let render_entity = map.0.get(&entity).unwrap(); + commands.insert_or_spawn_batch([(*render_entity, component)]); + } else { + println!("This is new!"); + let id = commands.spawn((component, Mayfly{})).id(); + map.0.insert(entity, id); + } } } - *previous_len = values.len(); - commands.insert_or_spawn_batch(values); } /// This system extracts all visible components of the corresponding [`ExtractComponent`] type. fn extract_visible_components( mut commands: Commands, - mut previous_len: Local, + mut map: ResMut, query: Extract>, ) { - let mut values = Vec::with_capacity(*previous_len); for (entity, view_visibility, query_item) in &query { - if view_visibility.get() { - if let Some(component) = C::extract_component(query_item) { - values.push((entity, component)); + if let Some(component) = C::extract_component(query_item) { + if view_visibility.get() { + if map.0.contains_key(&entity) { + let render_entity = map.0.get(&entity).unwrap(); + commands.insert_or_spawn_batch([(*render_entity, component)]); + } else { + let id = commands.spawn(component).id(); + map.0.insert(entity, id); + } } } } - *previous_len = values.len(); - commands.insert_or_spawn_batch(values); } diff --git a/crates/bevy_render/src/lib.rs b/crates/bevy_render/src/lib.rs index 49f25530b1323..c24eb5466e06a 100644 --- a/crates/bevy_render/src/lib.rs +++ b/crates/bevy_render/src/lib.rs @@ -55,6 +55,7 @@ pub mod prelude { use batching::gpu_preprocessing::BatchingPlugin; use bevy_ecs::schedule::ScheduleBuildSettings; use bevy_utils::prelude::default; +use extract_component::MainToRenderEntityMap; pub use extract_param::Extract; use bevy_hierarchy::ValidParentCheckPlugin; @@ -430,6 +431,21 @@ fn extract(main_world: &mut World, render_world: &mut World) { main_world.insert_resource(ScratchMainWorld(scratch_world)); } +fn print_entities(render_world: &World) { + println!("Entities:"); + for entity in render_world.iter_entities() { + print!("["); + for component_info in render_world.inspect_entity(entity.id()) { + print!("{:?}, ", component_info.name()); + } + print!("] \n"); + } +} + +fn clear_map(mut map: ResMut) { + map.0.clear(); +} + /// SAFETY: this function must be called from the main thread. unsafe fn initialize_render_app(app: &mut App) { app.init_resource::(); @@ -461,9 +477,14 @@ unsafe fn initialize_render_app(app: &mut App) { ( PipelineCache::process_pipeline_queue_system.before(render_system), render_system, + print_entities.after(render_system), ) .in_set(RenderSet::Render), - World::clear_entities.in_set(RenderSet::Cleanup), + ( + World::clear_entities, + clear_map, + ) + .in_set(RenderSet::Cleanup), ), ); From 943dcaa8c9f5a3dea8faaeff1564644055c7c545 Mon Sep 17 00:00:00 2001 From: Trashtalk Date: Sun, 21 Jul 2024 00:59:40 +0200 Subject: [PATCH 4/6] fix extracted cameras --- crates/bevy_render/src/camera/camera.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/crates/bevy_render/src/camera/camera.rs b/crates/bevy_render/src/camera/camera.rs index b950b2a6b9382..6239a8e21f1b6 100644 --- a/crates/bevy_render/src/camera/camera.rs +++ b/crates/bevy_render/src/camera/camera.rs @@ -11,6 +11,7 @@ use crate::{ ColorGrading, ExtractedView, ExtractedWindows, GpuCulling, RenderLayers, VisibleEntities, }, Extract, + extract_component::MainToRenderEntityMap, }; use bevy_asset::{AssetEvent, AssetId, Assets, Handle}; use bevy_derive::{Deref, DerefMut}; @@ -22,7 +23,7 @@ use bevy_ecs::{ prelude::With, query::Has, reflect::ReflectComponent, - system::{Commands, Query, Res, ResMut, Resource}, + system::{EntityCommands, Commands, Query, Res, ResMut, Resource}, }; use bevy_math::{vec2, Dir3, Mat4, Ray3d, Rect, URect, UVec2, UVec4, Vec2, Vec3}; use bevy_reflect::prelude::*; @@ -844,6 +845,7 @@ pub fn extract_cameras( Has, )>, >, + map: Res, primary_window: Extract>>, gpu_preprocessing_support: Res, ) { @@ -885,7 +887,13 @@ pub fn extract_cameras( continue; } - let mut commands = commands.get_or_spawn(entity); + let entity_commands: EntityCommands; + if map.0.contains_key(&entity) { + entity_commands = commands.entity(*map.0.get(&entity).unwrap()); + } else { + entity_commands = commands.spawn_empty(); + } + let mut commands = entity_commands; commands.insert(( ExtractedCamera { From 59b0af1402985b0fe58952f6dfd9ae01d8e15b0e Mon Sep 17 00:00:00 2001 From: Trashtalk Date: Sun, 21 Jul 2024 21:12:37 +0200 Subject: [PATCH 5/6] More decoupling entities (3d_scene works now) --- crates/bevy_core_pipeline/src/core_3d/mod.rs | 12 +++++++++++- crates/bevy_pbr/src/cluster/mod.rs | 19 +++++++++++++------ 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/crates/bevy_core_pipeline/src/core_3d/mod.rs b/crates/bevy_core_pipeline/src/core_3d/mod.rs index d2ddc76982668..744bb234636ee 100644 --- a/crates/bevy_core_pipeline/src/core_3d/mod.rs +++ b/crates/bevy_core_pipeline/src/core_3d/mod.rs @@ -75,7 +75,7 @@ use bevy_ecs::{entity::EntityHashSet, prelude::*}; use bevy_math::FloatOrd; use bevy_render::{ camera::{Camera, ExtractedCamera}, - extract_component::ExtractComponentPlugin, + extract_component::{ExtractComponentPlugin, MainToRenderEntityMap}, prelude::Msaa, render_graph::{EmptyNode, RenderGraphApp, ViewNodeRunner}, render_phase::{ @@ -504,6 +504,7 @@ impl CachedRenderPipelinePhaseItem for Transparent3d { pub fn extract_core_3d_camera_phases( mut commands: Commands, + mut map: ResMut, mut opaque_3d_phases: ResMut>, mut alpha_mask_3d_phases: ResMut>, mut transmissive_3d_phases: ResMut>, @@ -518,6 +519,15 @@ pub fn extract_core_3d_camera_phases( continue; } + let render_entity: Entity; + if map.0.contains_key(&entity) { + render_entity = *map.0.get(&entity).unwrap(); + } else { + render_entity = commands.spawn_empty().id(); + map.0.insert(entity, render_entity); + } + let entity = render_entity; + commands.get_or_spawn(entity); opaque_3d_phases.insert_or_clear(entity); diff --git a/crates/bevy_pbr/src/cluster/mod.rs b/crates/bevy_pbr/src/cluster/mod.rs index a0d628474db8e..d5deebe9c2fc9 100644 --- a/crates/bevy_pbr/src/cluster/mod.rs +++ b/crates/bevy_pbr/src/cluster/mod.rs @@ -9,17 +9,15 @@ use bevy_ecs::{ reflect::ReflectComponent, system::{Commands, Query, Res, Resource}, world::{FromWorld, World}, + prelude::ResMut, }; use bevy_math::{AspectRatio, UVec2, UVec3, UVec4, Vec3Swizzles as _, Vec4}; use bevy_reflect::{std_traits::ReflectDefault, Reflect}; use bevy_render::{ - camera::Camera, - render_resource::{ + camera::Camera, extract_component::MainToRenderEntityMap, render_resource::{ BindingResource, BufferBindingType, ShaderSize as _, ShaderType, StorageBuffer, UniformBuffer, - }, - renderer::{RenderDevice, RenderQueue}, - Extract, + }, renderer::{RenderDevice, RenderQueue}, Extract }; use bevy_utils::{hashbrown::HashSet, tracing::warn}; @@ -511,6 +509,7 @@ pub(crate) fn clusterable_object_order( /// Extracts clusters from the main world from the render world. pub fn extract_clusters( mut commands: Commands, + mut map: ResMut, views: Extract>, ) { for (entity, clusters, camera) in &views { @@ -536,7 +535,15 @@ pub fn extract_clusters( } } - commands.get_or_spawn(entity).insert(( + let render_entity: Entity; + if map.0.contains_key(&entity) { + render_entity = *map.0.get(&entity).unwrap(); + } else { + render_entity = commands.spawn_empty().id(); + map.0.insert(entity, render_entity); + } + + commands.entity(render_entity).insert(( ExtractedClusterableObjects { data }, ExtractedClusterConfig { near: clusters.near, From df580b26754f1ef60f42c2404adbf3961cfd753e Mon Sep 17 00:00:00 2001 From: Trashtalk Date: Sun, 21 Jul 2024 23:22:54 +0200 Subject: [PATCH 6/6] Added mayflies that are removed every frame, stop nuking the world --- crates/bevy_pbr/src/render/light.rs | 4 +++ crates/bevy_render/src/camera/camera.rs | 3 +- crates/bevy_render/src/extract_component.rs | 6 ++-- crates/bevy_render/src/lib.rs | 32 +++++++++++++++------ crates/bevy_ui/src/render/mod.rs | 5 ++-- 5 files changed, 35 insertions(+), 15 deletions(-) diff --git a/crates/bevy_pbr/src/render/light.rs b/crates/bevy_pbr/src/render/light.rs index 1356e94825ccc..209a039f63a9f 100644 --- a/crates/bevy_pbr/src/render/light.rs +++ b/crates/bevy_pbr/src/render/light.rs @@ -17,6 +17,7 @@ use bevy_render::{ texture::*, view::{ExtractedView, RenderLayers, ViewVisibility, VisibleEntities, WithMesh}, Extract, + extract_component::Mayfly, }; use bevy_transform::{components::GlobalTransform, prelude::Transform}; #[cfg(feature = "trace")] @@ -922,6 +923,7 @@ pub fn prepare_lights( light_entity, face_index, }, + Mayfly {}, )) .id(); view_lights.push(view_light_entity); @@ -980,6 +982,7 @@ pub fn prepare_lights( }, *spot_light_frustum.unwrap(), LightEntity::Spot { light_entity }, + Mayfly {}, )) .id(); @@ -1079,6 +1082,7 @@ pub fn prepare_lights( light_entity, cascade_index, }, + Mayfly {}, )) .id(); view_lights.push(view_light_entity); diff --git a/crates/bevy_render/src/camera/camera.rs b/crates/bevy_render/src/camera/camera.rs index 6239a8e21f1b6..2a51f12c86bf8 100644 --- a/crates/bevy_render/src/camera/camera.rs +++ b/crates/bevy_render/src/camera/camera.rs @@ -11,7 +11,7 @@ use crate::{ ColorGrading, ExtractedView, ExtractedWindows, GpuCulling, RenderLayers, VisibleEntities, }, Extract, - extract_component::MainToRenderEntityMap, + extract_component::{MainToRenderEntityMap, Mayfly}, }; use bevy_asset::{AssetEvent, AssetId, Assets, Handle}; use bevy_derive::{Deref, DerefMut}; @@ -928,6 +928,7 @@ pub fn extract_cameras( }, visible_entities.clone(), *frustum, + Mayfly{}, )); if let Some(temporal_jitter) = temporal_jitter { diff --git a/crates/bevy_render/src/extract_component.rs b/crates/bevy_render/src/extract_component.rs index eaea2336cb710..218277d2247be 100644 --- a/crates/bevy_render/src/extract_component.rs +++ b/crates/bevy_render/src/extract_component.rs @@ -211,7 +211,7 @@ impl ExtractComponent for Handle { } #[derive(Component)] -struct Mayfly; +pub struct Mayfly; /// This system extracts all components of the corresponding [`ExtractComponent`] type. fn extract_components( @@ -222,11 +222,9 @@ fn extract_components( for (entity, query_item) in &query { if let Some(component) = C::extract_component(query_item) { if map.0.contains_key(&entity) { - println!("Hey, we've seen this one before!"); let render_entity = map.0.get(&entity).unwrap(); commands.insert_or_spawn_batch([(*render_entity, component)]); } else { - println!("This is new!"); let id = commands.spawn((component, Mayfly{})).id(); map.0.insert(entity, id); } @@ -247,7 +245,7 @@ fn extract_visible_components( let render_entity = map.0.get(&entity).unwrap(); commands.insert_or_spawn_batch([(*render_entity, component)]); } else { - let id = commands.spawn(component).id(); + let id = commands.spawn((component, Mayfly)).id(); map.0.insert(entity, id); } } diff --git a/crates/bevy_render/src/lib.rs b/crates/bevy_render/src/lib.rs index c24eb5466e06a..9dd4c96d08422 100644 --- a/crates/bevy_render/src/lib.rs +++ b/crates/bevy_render/src/lib.rs @@ -74,6 +74,7 @@ use crate::{ render_resource::{PipelineCache, Shader, ShaderLoader}, renderer::{render_system, RenderInstance}, settings::RenderCreation, + extract_component::Mayfly, view::{ViewPlugin, WindowRenderPlugin}, }; use bevy_app::{App, AppLabel, Plugin, SubApp}; @@ -432,13 +433,17 @@ fn extract(main_world: &mut World, render_world: &mut World) { } fn print_entities(render_world: &World) { - println!("Entities:"); - for entity in render_world.iter_entities() { - print!("["); - for component_info in render_world.inspect_entity(entity.id()) { - print!("{:?}, ", component_info.name()); + let entity_count = render_world.entities().total_count(); + println!("Entities: {:?}", entity_count); + + if entity_count < 20 { + for entity in render_world.iter_entities() { + print!("["); + for component_info in render_world.inspect_entity(entity.id()) { + print!("{:?}, ", component_info.name()); + } + print!("] \n"); } - print!("] \n"); } } @@ -446,6 +451,15 @@ fn clear_map(mut map: ResMut) { map.0.clear(); } +fn despawn_mayflies( + mut commands: Commands, + query: Query>, +) { + for entity in query.iter() { + commands.entity(entity).despawn(); + } +} + /// SAFETY: this function must be called from the main thread. unsafe fn initialize_render_app(app: &mut App) { app.init_resource::(); @@ -481,8 +495,9 @@ unsafe fn initialize_render_app(app: &mut App) { ) .in_set(RenderSet::Render), ( - World::clear_entities, + //World::clear_entities, clear_map, + despawn_mayflies ) .in_set(RenderSet::Cleanup), ), @@ -500,7 +515,7 @@ unsafe fn initialize_render_app(app: &mut App) { // reserve all existing main world entities for use in render_app // they can only be spawned using `get_or_spawn()` let total_count = main_world.entities().total_count(); - + /* assert_eq!( render_world.entities().len(), 0, @@ -513,6 +528,7 @@ unsafe fn initialize_render_app(app: &mut App) { .entities_mut() .flush_and_reserve_invalid_assuming_no_entities(total_count); } + */ } // run extract schedule diff --git a/crates/bevy_ui/src/render/mod.rs b/crates/bevy_ui/src/render/mod.rs index c4cafa593ab1f..814dfcf5c986b 100644 --- a/crates/bevy_ui/src/render/mod.rs +++ b/crates/bevy_ui/src/render/mod.rs @@ -42,6 +42,7 @@ use bevy_render::{ texture::Image, view::{ExtractedView, ViewUniforms}, Extract, RenderApp, RenderSet, + extract_component::Mayfly, }; use bevy_sprite::TextureAtlasLayout; #[cfg(feature = "bevy_text")] @@ -759,7 +760,7 @@ pub fn extract_default_ui_camera_view( UI_CAMERA_FAR, ); let default_camera_view = commands - .spawn(ExtractedView { + .spawn((ExtractedView { clip_from_view: projection_matrix, world_from_view: GlobalTransform::from_xyz( 0.0, @@ -775,7 +776,7 @@ pub fn extract_default_ui_camera_view( physical_size.y, ), color_grading: Default::default(), - }) + }, Mayfly{})) .id(); commands .get_or_spawn(entity)