diff --git a/crates/bevy_app/src/sub_app.rs b/crates/bevy_app/src/sub_app.rs index 56d6b43d38..56a496f2b5 100644 --- a/crates/bevy_app/src/sub_app.rs +++ b/crates/bevy_app/src/sub_app.rs @@ -12,7 +12,7 @@ use core::fmt::Debug; #[cfg(feature = "trace")] use tracing::info_span; -type ExtractFn = Box; +type ExtractFn = Box; /// A secondary application with its own [`World`]. These can run independently of each other. /// @@ -160,7 +160,7 @@ impl SubApp { /// The first argument is the `World` to extract data from, the second argument is the app `World`. pub fn set_extract(&mut self, extract: F) -> &mut Self where - F: Fn(&mut World, &mut World) + Send + 'static, + F: FnMut(&mut World, &mut World) + Send + 'static, { self.extract = Some(Box::new(extract)); self @@ -177,13 +177,13 @@ impl SubApp { /// ``` /// # use bevy_app::SubApp; /// # let mut app = SubApp::new(); - /// let default_fn = app.take_extract(); + /// let mut default_fn = app.take_extract(); /// app.set_extract(move |main, render| { /// // Do pre-extract custom logic /// // [...] /// /// // Call Bevy's default, which executes the Extract phase - /// if let Some(f) = default_fn.as_ref() { + /// if let Some(f) = default_fn.as_mut() { /// f(main, render); /// } /// diff --git a/crates/bevy_pbr/src/meshlet/meshlet_mesh_material.wgsl b/crates/bevy_pbr/src/meshlet/meshlet_mesh_material.wgsl index e574b64c71..a10570cef4 100644 --- a/crates/bevy_pbr/src/meshlet/meshlet_mesh_material.wgsl +++ b/crates/bevy_pbr/src/meshlet/meshlet_mesh_material.wgsl @@ -15,7 +15,6 @@ fn vertex(@builtin(vertex_index) vertex_input: u32) -> @builtin(position) vec4) -> @location(0) vec4 { let vertex_output = resolve_vertex_output(frag_coord); @@ -23,7 +22,6 @@ fn fragment(@builtin(position) frag_coord: vec4) -> @location(0) vec4 let color = vec3(rand_f(&rng), rand_f(&rng), rand_f(&rng)); return vec4(color, 1.0); } -#endif #ifdef PREPASS_FRAGMENT @fragment diff --git a/crates/bevy_render/src/lib.rs b/crates/bevy_render/src/lib.rs index 471a672540..9b8ef6fb37 100644 --- a/crates/bevy_render/src/lib.rs +++ b/crates/bevy_render/src/lib.rs @@ -221,22 +221,6 @@ pub enum RenderSystems { PostCleanup, } -/// The schedule that contains the app logic that is evaluated each tick -/// -/// This is highly inspired by [`bevy_app::Main`] -#[derive(ScheduleLabel, Clone, Debug, PartialEq, Eq, Hash, Default)] -pub struct MainRender; -impl MainRender { - pub fn run(world: &mut World, mut run_at_least_once: Local) { - if !*run_at_least_once { - let _ = world.try_run_schedule(RenderStartup); - *run_at_least_once = true; - } - - let _ = world.try_run_schedule(Render); - } -} - /// Deprecated alias for [`RenderSystems`]. #[deprecated(since = "0.17.0", note = "Renamed to `RenderSystems`.")] pub type RenderSet = RenderSystems; @@ -561,7 +545,7 @@ unsafe fn initialize_render_app(app: &mut App) { app.init_resource::(); let mut render_app = SubApp::new(); - render_app.update_schedule = Some(MainRender.intern()); + render_app.update_schedule = Some(Render.intern()); let mut extract_schedule = Schedule::new(ExtractSchedule); // We skip applying any commands during the ExtractSchedule @@ -576,7 +560,6 @@ unsafe fn initialize_render_app(app: &mut App) { .add_schedule(extract_schedule) .add_schedule(Render::base_schedule()) .init_resource::() - .add_systems(MainRender, MainRender::run) .insert_resource(app.world().resource::().clone()) .add_systems(ExtractSchedule, PipelineCache::extract_shaders) .add_systems( @@ -592,7 +575,19 @@ unsafe fn initialize_render_app(app: &mut App) { ), ); - render_app.set_extract(|main_world, render_world| { + // We want the closure to have a flag to only run the RenderStartup schedule once, but the only + // way to have the closure store this flag is by capturing it. This variable is otherwise + // unused. + let mut should_run_startup = true; + render_app.set_extract(move |main_world, render_world| { + if should_run_startup { + // Run the `RenderStartup` if it hasn't run yet. This does mean `RenderStartup` blocks + // the rest of the app extraction, but this is necessary since extraction itself can + // depend on resources initialized in `RenderStartup`. + render_world.run_schedule(RenderStartup); + should_run_startup = false; + } + { #[cfg(feature = "trace")] let _stage_span = tracing::info_span!("entity_sync").entered(); diff --git a/crates/bevy_render/src/maths.wgsl b/crates/bevy_render/src/maths.wgsl index b492dd6bb2..d1e35523dc 100644 --- a/crates/bevy_render/src/maths.wgsl +++ b/crates/bevy_render/src/maths.wgsl @@ -104,17 +104,11 @@ fn project_onto(lhs: vec3, rhs: vec3) -> vec3 { // are likely most useful when raymarching, for example, where complete numeric // accuracy can be sacrificed for greater sample count. -fn fast_sqrt(x: f32) -> f32 { - let n = bitcast(0x1fbd1df5 + (bitcast(x) >> 1u)); - // One Newton's method iteration for better precision - return 0.5 * (n + x / n); -} - // Slightly less accurate than fast_acos_4, but much simpler. fn fast_acos(in_x: f32) -> f32 { let x = abs(in_x); var res = -0.156583 * x + HALF_PI; - res *= fast_sqrt(1.0 - x); + res *= sqrt(1.0 - x); return select(PI - res, res, in_x >= 0.0); } @@ -131,7 +125,7 @@ fn fast_acos_4(x: f32) -> f32 { s = -0.2121144 * x1 + 1.5707288; s = 0.0742610 * x2 + s; s = -0.0187293 * x3 + s; - s = fast_sqrt(1.0 - x1) * s; + s = sqrt(1.0 - x1) * s; // acos function mirroring return select(PI - s, s, x >= 0.0); diff --git a/crates/bevy_render/src/mesh/allocator.rs b/crates/bevy_render/src/mesh/allocator.rs index c171cf3957..bbdb543116 100644 --- a/crates/bevy_render/src/mesh/allocator.rs +++ b/crates/bevy_render/src/mesh/allocator.rs @@ -452,13 +452,17 @@ impl MeshAllocator { // Allocate. for (mesh_id, mesh) in &extracted_meshes.extracted { + let vertex_buffer_size = mesh.get_vertex_buffer_size() as u64; + if vertex_buffer_size == 0 { + continue; + } // Allocate vertex data. Note that we can only pack mesh vertex data // together if the platform supports it. let vertex_element_layout = ElementLayout::vertex(mesh_vertex_buffer_layouts, mesh); if self.general_vertex_slabs_supported { self.allocate( mesh_id, - mesh.get_vertex_buffer_size() as u64, + vertex_buffer_size, vertex_element_layout, &mut slabs_to_grow, mesh_allocator_settings, diff --git a/release-content/migration-guides/extract_fn_is_mut.md b/release-content/migration-guides/extract_fn_is_mut.md new file mode 100644 index 0000000000..a27db69fc0 --- /dev/null +++ b/release-content/migration-guides/extract_fn_is_mut.md @@ -0,0 +1,10 @@ +--- +title: `take_extract` now returns `dyn FnMut` instead of `dyn Fn`. +pull_requests: [19926] +--- + +Previously, `set_extract` accepted any `Fn`. Now we accept any `FnMut`. For callers of +`set_extract`, there is no difference since `Fn: FnMut`. + +However, callers of `take_extract` will now be returned +`Option>` instead.