Skip to content

Commit

Permalink
Use render_init callbacks to init RenderApp state
Browse files Browse the repository at this point in the history
This wraps all plugin initialization that depends on the RenderApp
sub app into a render_init callback so that render state initialization
can be deferred by the runner.

For now the winit runner immediately calls app.render_init() so it's
not yet significantly deferred, but plugin building and render state
initialization now happen in two separate passes.

Note: This patch intentionally avoids making functional change to the
code that's moved into render_init functions to help keep this easy
to review. In the case of bevy_render/src/lib.rs any change in
indentation was also avoided to help reduce churn.
  • Loading branch information
rib committed Jun 3, 2022
1 parent a9f920f commit 1020901
Show file tree
Hide file tree
Showing 21 changed files with 390 additions and 338 deletions.
58 changes: 30 additions & 28 deletions crates/bevy_core_pipeline/src/core_2d/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,35 +37,37 @@ impl Plugin for Core2dPlugin {
app.register_type::<Camera2d>()
.add_plugin(ExtractComponentPlugin::<Camera2d>::default());

let render_app = match app.get_sub_app_mut(RenderApp) {
Ok(render_app) => render_app,
Err(_) => return,
};

render_app
.init_resource::<DrawFunctions<Transparent2d>>()
.add_system_to_stage(RenderStage::Extract, extract_core_2d_camera_phases)
.add_system_to_stage(RenderStage::PhaseSort, sort_phase_system::<Transparent2d>)
.add_system_to_stage(RenderStage::PhaseSort, batch_phase_system::<Transparent2d>);

let pass_node_2d = MainPass2dNode::new(&mut render_app.world);
let mut graph = render_app.world.resource_mut::<RenderGraph>();

let mut draw_2d_graph = RenderGraph::default();
draw_2d_graph.add_node(graph::node::MAIN_PASS, pass_node_2d);
let input_node_id = draw_2d_graph.set_input(vec![SlotInfo::new(
graph::input::VIEW_ENTITY,
SlotType::Entity,
)]);
draw_2d_graph
.add_slot_edge(
input_node_id,
app.add_render_init(move |app| {
let render_app = match app.get_sub_app_mut(RenderApp) {
Ok(render_app) => render_app,
Err(_) => return,
};

render_app
.init_resource::<DrawFunctions<Transparent2d>>()
.add_system_to_stage(RenderStage::Extract, extract_core_2d_camera_phases)
.add_system_to_stage(RenderStage::PhaseSort, sort_phase_system::<Transparent2d>)
.add_system_to_stage(RenderStage::PhaseSort, batch_phase_system::<Transparent2d>);

let pass_node_2d = MainPass2dNode::new(&mut render_app.world);
let mut graph = render_app.world.resource_mut::<RenderGraph>();

let mut draw_2d_graph = RenderGraph::default();
draw_2d_graph.add_node(graph::node::MAIN_PASS, pass_node_2d);
let input_node_id = draw_2d_graph.set_input(vec![SlotInfo::new(
graph::input::VIEW_ENTITY,
graph::node::MAIN_PASS,
MainPass2dNode::IN_VIEW,
)
.unwrap();
graph.add_sub_graph(graph::NAME, draw_2d_graph);
SlotType::Entity,
)]);
draw_2d_graph
.add_slot_edge(
input_node_id,
graph::input::VIEW_ENTITY,
graph::node::MAIN_PASS,
MainPass2dNode::IN_VIEW,
)
.unwrap();
graph.add_sub_graph(graph::NAME, draw_2d_graph);
});
}
}

Expand Down
66 changes: 34 additions & 32 deletions crates/bevy_core_pipeline/src/core_3d/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,39 +43,41 @@ impl Plugin for Core3dPlugin {
app.register_type::<Camera3d>()
.add_plugin(ExtractComponentPlugin::<Camera3d>::default());

let render_app = match app.get_sub_app_mut(RenderApp) {
Ok(render_app) => render_app,
Err(_) => return,
};

render_app
.init_resource::<DrawFunctions<Opaque3d>>()
.init_resource::<DrawFunctions<AlphaMask3d>>()
.init_resource::<DrawFunctions<Transparent3d>>()
.add_system_to_stage(RenderStage::Extract, extract_core_3d_camera_phases)
.add_system_to_stage(RenderStage::Prepare, prepare_core_3d_views_system)
.add_system_to_stage(RenderStage::PhaseSort, sort_phase_system::<Opaque3d>)
.add_system_to_stage(RenderStage::PhaseSort, sort_phase_system::<AlphaMask3d>)
.add_system_to_stage(RenderStage::PhaseSort, sort_phase_system::<Transparent3d>);

let pass_node_3d = MainPass3dNode::new(&mut render_app.world);
let mut graph = render_app.world.resource_mut::<RenderGraph>();

let mut draw_3d_graph = RenderGraph::default();
draw_3d_graph.add_node(graph::node::MAIN_PASS, pass_node_3d);
let input_node_id = draw_3d_graph.set_input(vec![SlotInfo::new(
graph::input::VIEW_ENTITY,
SlotType::Entity,
)]);
draw_3d_graph
.add_slot_edge(
input_node_id,
app.add_render_init(move |app| {
let render_app = match app.get_sub_app_mut(RenderApp) {
Ok(render_app) => render_app,
Err(_) => return,
};

render_app
.init_resource::<DrawFunctions<Opaque3d>>()
.init_resource::<DrawFunctions<AlphaMask3d>>()
.init_resource::<DrawFunctions<Transparent3d>>()
.add_system_to_stage(RenderStage::Extract, extract_core_3d_camera_phases)
.add_system_to_stage(RenderStage::Prepare, prepare_core_3d_views_system)
.add_system_to_stage(RenderStage::PhaseSort, sort_phase_system::<Opaque3d>)
.add_system_to_stage(RenderStage::PhaseSort, sort_phase_system::<AlphaMask3d>)
.add_system_to_stage(RenderStage::PhaseSort, sort_phase_system::<Transparent3d>);

let pass_node_3d = MainPass3dNode::new(&mut render_app.world);
let mut graph = render_app.world.resource_mut::<RenderGraph>();

let mut draw_3d_graph = RenderGraph::default();
draw_3d_graph.add_node(graph::node::MAIN_PASS, pass_node_3d);
let input_node_id = draw_3d_graph.set_input(vec![SlotInfo::new(
graph::input::VIEW_ENTITY,
graph::node::MAIN_PASS,
MainPass3dNode::IN_VIEW,
)
.unwrap();
graph.add_sub_graph(graph::NAME, draw_3d_graph);
SlotType::Entity,
)]);
draw_3d_graph
.add_slot_edge(
input_node_id,
graph::input::VIEW_ENTITY,
graph::node::MAIN_PASS,
MainPass3dNode::IN_VIEW,
)
.unwrap();
graph.add_sub_graph(graph::NAME, draw_3d_graph);
});
}
}

Expand Down
122 changes: 62 additions & 60 deletions crates/bevy_pbr/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,67 +149,69 @@ impl Plugin for PbrPlugin {
},
);

let render_app = match app.get_sub_app_mut(RenderApp) {
Ok(render_app) => render_app,
Err(_) => return,
};
app.add_render_init(move |app| {
let render_app = match app.get_sub_app_mut(RenderApp) {
Ok(render_app) => render_app,
Err(_) => return,
};

render_app
.add_system_to_stage(
RenderStage::Extract,
render::extract_clusters.label(RenderLightSystems::ExtractClusters),
)
.add_system_to_stage(
RenderStage::Extract,
render::extract_lights.label(RenderLightSystems::ExtractLights),
)
.add_system_to_stage(
RenderStage::Prepare,
// this is added as an exclusive system because it contributes new views. it must run (and have Commands applied)
// _before_ the `prepare_views()` system is run. ideally this becomes a normal system when "stageless" features come out
render::prepare_lights
.exclusive_system()
.label(RenderLightSystems::PrepareLights),
)
.add_system_to_stage(
RenderStage::Prepare,
// NOTE: This needs to run after prepare_lights. As prepare_lights is an exclusive system,
// just adding it to the non-exclusive systems in the Prepare stage means it runs after
// prepare_lights.
render::prepare_clusters.label(RenderLightSystems::PrepareClusters),
)
.add_system_to_stage(
RenderStage::Queue,
render::queue_shadows.label(RenderLightSystems::QueueShadows),
)
.add_system_to_stage(RenderStage::Queue, render::queue_shadow_view_bind_group)
.add_system_to_stage(RenderStage::PhaseSort, sort_phase_system::<Shadow>)
.init_resource::<ShadowPipeline>()
.init_resource::<DrawFunctions<Shadow>>()
.init_resource::<LightMeta>()
.init_resource::<GlobalLightMeta>()
.init_resource::<SpecializedMeshPipelines<ShadowPipeline>>();
render_app
.add_system_to_stage(
RenderStage::Extract,
render::extract_clusters.label(RenderLightSystems::ExtractClusters),
)
.add_system_to_stage(
RenderStage::Extract,
render::extract_lights.label(RenderLightSystems::ExtractLights),
)
.add_system_to_stage(
RenderStage::Prepare,
// this is added as an exclusive system because it contributes new views. it must run (and have Commands applied)
// _before_ the `prepare_views()` system is run. ideally this becomes a normal system when "stageless" features come out
render::prepare_lights
.exclusive_system()
.label(RenderLightSystems::PrepareLights),
)
.add_system_to_stage(
RenderStage::Prepare,
// NOTE: This needs to run after prepare_lights. As prepare_lights is an exclusive system,
// just adding it to the non-exclusive systems in the Prepare stage means it runs after
// prepare_lights.
render::prepare_clusters.label(RenderLightSystems::PrepareClusters),
)
.add_system_to_stage(
RenderStage::Queue,
render::queue_shadows.label(RenderLightSystems::QueueShadows),
)
.add_system_to_stage(RenderStage::Queue, render::queue_shadow_view_bind_group)
.add_system_to_stage(RenderStage::PhaseSort, sort_phase_system::<Shadow>)
.init_resource::<ShadowPipeline>()
.init_resource::<DrawFunctions<Shadow>>()
.init_resource::<LightMeta>()
.init_resource::<GlobalLightMeta>()
.init_resource::<SpecializedMeshPipelines<ShadowPipeline>>();

let shadow_pass_node = ShadowPassNode::new(&mut render_app.world);
render_app.add_render_command::<Shadow, DrawShadowMesh>();
let mut graph = render_app.world.resource_mut::<RenderGraph>();
let draw_3d_graph = graph
.get_sub_graph_mut(bevy_core_pipeline::core_3d::graph::NAME)
.unwrap();
draw_3d_graph.add_node(draw_3d_graph::node::SHADOW_PASS, shadow_pass_node);
draw_3d_graph
.add_node_edge(
draw_3d_graph::node::SHADOW_PASS,
bevy_core_pipeline::core_3d::graph::node::MAIN_PASS,
)
.unwrap();
draw_3d_graph
.add_slot_edge(
draw_3d_graph.input_node().unwrap().id,
bevy_core_pipeline::core_3d::graph::input::VIEW_ENTITY,
draw_3d_graph::node::SHADOW_PASS,
ShadowPassNode::IN_VIEW,
)
.unwrap();
let shadow_pass_node = ShadowPassNode::new(&mut render_app.world);
render_app.add_render_command::<Shadow, DrawShadowMesh>();
let mut graph = render_app.world.resource_mut::<RenderGraph>();
let draw_3d_graph = graph
.get_sub_graph_mut(bevy_core_pipeline::core_3d::graph::NAME)
.unwrap();
draw_3d_graph.add_node(draw_3d_graph::node::SHADOW_PASS, shadow_pass_node);
draw_3d_graph
.add_node_edge(
draw_3d_graph::node::SHADOW_PASS,
bevy_core_pipeline::core_3d::graph::node::MAIN_PASS,
)
.unwrap();
draw_3d_graph
.add_slot_edge(
draw_3d_graph.input_node().unwrap().id,
bevy_core_pipeline::core_3d::graph::input::VIEW_ENTITY,
draw_3d_graph::node::SHADOW_PASS,
ShadowPassNode::IN_VIEW,
)
.unwrap();
});
}
}
21 changes: 12 additions & 9 deletions crates/bevy_pbr/src/material.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,15 +226,18 @@ impl<M: SpecializedMaterial> Plugin for MaterialPlugin<M> {
app.add_asset::<M>()
.add_plugin(ExtractComponentPlugin::<Handle<M>>::extract_visible())
.add_plugin(RenderAssetPlugin::<M>::default());
if let Ok(render_app) = app.get_sub_app_mut(RenderApp) {
render_app
.add_render_command::<Transparent3d, DrawMaterial<M>>()
.add_render_command::<Opaque3d, DrawMaterial<M>>()
.add_render_command::<AlphaMask3d, DrawMaterial<M>>()
.init_resource::<MaterialPipeline<M>>()
.init_resource::<SpecializedMeshPipelines<MaterialPipeline<M>>>()
.add_system_to_stage(RenderStage::Queue, queue_material_meshes::<M>);
}

app.add_render_init(move |app| {
if let Ok(render_app) = app.get_sub_app_mut(RenderApp) {
render_app
.add_render_command::<Transparent3d, DrawMaterial<M>>()
.add_render_command::<Opaque3d, DrawMaterial<M>>()
.add_render_command::<AlphaMask3d, DrawMaterial<M>>()
.init_resource::<MaterialPipeline<M>>()
.init_resource::<SpecializedMeshPipelines<MaterialPipeline<M>>>()
.add_system_to_stage(RenderStage::Queue, queue_material_meshes::<M>);
}
});
}
}

Expand Down
22 changes: 12 additions & 10 deletions crates/bevy_pbr/src/render/mesh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,16 +74,18 @@ impl Plugin for MeshRenderPlugin {

app.add_plugin(UniformComponentPlugin::<MeshUniform>::default());

if let Ok(render_app) = app.get_sub_app_mut(RenderApp) {
render_app
.init_resource::<MeshPipeline>()
.init_resource::<SkinnedMeshUniform>()
.add_system_to_stage(RenderStage::Extract, extract_meshes)
.add_system_to_stage(RenderStage::Extract, extract_skinned_meshes)
.add_system_to_stage(RenderStage::Prepare, prepare_skinned_meshes)
.add_system_to_stage(RenderStage::Queue, queue_mesh_bind_group)
.add_system_to_stage(RenderStage::Queue, queue_mesh_view_bind_groups);
}
app.add_render_init(move |app| {
if let Ok(render_app) = app.get_sub_app_mut(RenderApp) {
render_app
.init_resource::<MeshPipeline>()
.init_resource::<SkinnedMeshUniform>()
.add_system_to_stage(RenderStage::Extract, extract_meshes)
.add_system_to_stage(RenderStage::Extract, extract_skinned_meshes)
.add_system_to_stage(RenderStage::Prepare, prepare_skinned_meshes)
.add_system_to_stage(RenderStage::Queue, queue_mesh_bind_group)
.add_system_to_stage(RenderStage::Queue, queue_mesh_view_bind_groups);
}
});
}
}

Expand Down
18 changes: 10 additions & 8 deletions crates/bevy_pbr/src/wireframe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,16 @@ impl Plugin for WireframePlugin {
app.init_resource::<WireframeConfig>()
.add_plugin(ExtractResourcePlugin::<WireframeConfig>::default());

if let Ok(render_app) = app.get_sub_app_mut(RenderApp) {
render_app
.add_render_command::<Opaque3d, DrawWireframes>()
.init_resource::<WireframePipeline>()
.init_resource::<SpecializedMeshPipelines<WireframePipeline>>()
.add_system_to_stage(RenderStage::Extract, extract_wireframes)
.add_system_to_stage(RenderStage::Queue, queue_wireframes);
}
app.add_render_init(move |app| {
if let Ok(render_app) = app.get_sub_app_mut(RenderApp) {
render_app
.add_render_command::<Opaque3d, DrawWireframes>()
.init_resource::<WireframePipeline>()
.init_resource::<SpecializedMeshPipelines<WireframePipeline>>()
.add_system_to_stage(RenderStage::Extract, extract_wireframes)
.add_system_to_stage(RenderStage::Queue, queue_wireframes);
}
});
}
}

Expand Down
14 changes: 8 additions & 6 deletions crates/bevy_render/src/camera/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,14 @@ impl Plugin for CameraPlugin {
.add_plugin(CameraProjectionPlugin::<OrthographicProjection>::default())
.add_plugin(CameraProjectionPlugin::<PerspectiveProjection>::default());

if let Ok(render_app) = app.get_sub_app_mut(RenderApp) {
render_app.add_system_to_stage(RenderStage::Extract, extract_cameras);
app.add_render_init(move |app| {
if let Ok(render_app) = app.get_sub_app_mut(RenderApp) {
render_app.add_system_to_stage(RenderStage::Extract, extract_cameras);

let camera_driver_node = CameraDriverNode::new(&mut render_app.world);
let mut render_graph = render_app.world.resource_mut::<RenderGraph>();
render_graph.add_node(crate::main_graph::node::CAMERA_DRIVER, camera_driver_node);
}
let camera_driver_node = CameraDriverNode::new(&mut render_app.world);
let mut render_graph = render_app.world.resource_mut::<RenderGraph>();
render_graph.add_node(crate::main_graph::node::CAMERA_DRIVER, camera_driver_node);
}
});
}
}
Loading

0 comments on commit 1020901

Please sign in to comment.