Merge branch 'main' into ad/bit-op-shaders
This commit is contained in:
commit
72c9a370b0
@ -12,7 +12,7 @@ use core::fmt::Debug;
|
||||
#[cfg(feature = "trace")]
|
||||
use tracing::info_span;
|
||||
|
||||
type ExtractFn = Box<dyn Fn(&mut World, &mut World) + Send>;
|
||||
type ExtractFn = Box<dyn FnMut(&mut World, &mut World) + Send>;
|
||||
|
||||
/// 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<F>(&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);
|
||||
/// }
|
||||
///
|
||||
|
@ -15,7 +15,6 @@ fn vertex(@builtin(vertex_index) vertex_input: u32) -> @builtin(position) vec4<f
|
||||
return vec4(uv_to_ndc(uv), material_depth, 1.0);
|
||||
}
|
||||
|
||||
#ifdef PREPASS_FRAGMENT
|
||||
@fragment
|
||||
fn fragment(@builtin(position) frag_coord: vec4<f32>) -> @location(0) vec4<f32> {
|
||||
let vertex_output = resolve_vertex_output(frag_coord);
|
||||
@ -23,7 +22,6 @@ fn fragment(@builtin(position) frag_coord: vec4<f32>) -> @location(0) vec4<f32>
|
||||
let color = vec3(rand_f(&rng), rand_f(&rng), rand_f(&rng));
|
||||
return vec4(color, 1.0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PREPASS_FRAGMENT
|
||||
@fragment
|
||||
|
@ -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<bool>) {
|
||||
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::<ScratchMainWorld>();
|
||||
|
||||
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::<render_graph::RenderGraph>()
|
||||
.add_systems(MainRender, MainRender::run)
|
||||
.insert_resource(app.world().resource::<AssetServer>().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();
|
||||
|
@ -104,17 +104,11 @@ fn project_onto(lhs: vec3<f32>, rhs: vec3<f32>) -> vec3<f32> {
|
||||
// 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<f32>(0x1fbd1df5 + (bitcast<i32>(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);
|
||||
|
@ -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,
|
||||
|
10
release-content/migration-guides/extract_fn_is_mut.md
Normal file
10
release-content/migration-guides/extract_fn_is_mut.md
Normal file
@ -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<Box<dyn FnMut(&mut World, &mut World) + Send>>` instead.
|
Loading…
Reference in New Issue
Block a user