Skip to content

Commit 5888b26

Browse files
committed
Use render_init callbacks to init RenderApp state
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.
1 parent 00c50e9 commit 5888b26

File tree

21 files changed

+390
-338
lines changed

21 files changed

+390
-338
lines changed

crates/bevy_core_pipeline/src/core_2d/mod.rs

Lines changed: 30 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -37,35 +37,37 @@ impl Plugin for Core2dPlugin {
3737
app.register_type::<Camera2d>()
3838
.add_plugin(ExtractComponentPlugin::<Camera2d>::default());
3939

40-
let render_app = match app.get_sub_app_mut(RenderApp) {
41-
Ok(render_app) => render_app,
42-
Err(_) => return,
43-
};
44-
45-
render_app
46-
.init_resource::<DrawFunctions<Transparent2d>>()
47-
.add_system_to_stage(RenderStage::Extract, extract_core_2d_camera_phases)
48-
.add_system_to_stage(RenderStage::PhaseSort, sort_phase_system::<Transparent2d>)
49-
.add_system_to_stage(RenderStage::PhaseSort, batch_phase_system::<Transparent2d>);
50-
51-
let pass_node_2d = MainPass2dNode::new(&mut render_app.world);
52-
let mut graph = render_app.world.resource_mut::<RenderGraph>();
53-
54-
let mut draw_2d_graph = RenderGraph::default();
55-
draw_2d_graph.add_node(graph::node::MAIN_PASS, pass_node_2d);
56-
let input_node_id = draw_2d_graph.set_input(vec![SlotInfo::new(
57-
graph::input::VIEW_ENTITY,
58-
SlotType::Entity,
59-
)]);
60-
draw_2d_graph
61-
.add_slot_edge(
62-
input_node_id,
40+
app.add_render_init(move |app| {
41+
let render_app = match app.get_sub_app_mut(RenderApp) {
42+
Ok(render_app) => render_app,
43+
Err(_) => return,
44+
};
45+
46+
render_app
47+
.init_resource::<DrawFunctions<Transparent2d>>()
48+
.add_system_to_stage(RenderStage::Extract, extract_core_2d_camera_phases)
49+
.add_system_to_stage(RenderStage::PhaseSort, sort_phase_system::<Transparent2d>)
50+
.add_system_to_stage(RenderStage::PhaseSort, batch_phase_system::<Transparent2d>);
51+
52+
let pass_node_2d = MainPass2dNode::new(&mut render_app.world);
53+
let mut graph = render_app.world.resource_mut::<RenderGraph>();
54+
55+
let mut draw_2d_graph = RenderGraph::default();
56+
draw_2d_graph.add_node(graph::node::MAIN_PASS, pass_node_2d);
57+
let input_node_id = draw_2d_graph.set_input(vec![SlotInfo::new(
6358
graph::input::VIEW_ENTITY,
64-
graph::node::MAIN_PASS,
65-
MainPass2dNode::IN_VIEW,
66-
)
67-
.unwrap();
68-
graph.add_sub_graph(graph::NAME, draw_2d_graph);
59+
SlotType::Entity,
60+
)]);
61+
draw_2d_graph
62+
.add_slot_edge(
63+
input_node_id,
64+
graph::input::VIEW_ENTITY,
65+
graph::node::MAIN_PASS,
66+
MainPass2dNode::IN_VIEW,
67+
)
68+
.unwrap();
69+
graph.add_sub_graph(graph::NAME, draw_2d_graph);
70+
});
6971
}
7072
}
7173

crates/bevy_core_pipeline/src/core_3d/mod.rs

Lines changed: 34 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -43,39 +43,41 @@ impl Plugin for Core3dPlugin {
4343
app.register_type::<Camera3d>()
4444
.add_plugin(ExtractComponentPlugin::<Camera3d>::default());
4545

46-
let render_app = match app.get_sub_app_mut(RenderApp) {
47-
Ok(render_app) => render_app,
48-
Err(_) => return,
49-
};
50-
51-
render_app
52-
.init_resource::<DrawFunctions<Opaque3d>>()
53-
.init_resource::<DrawFunctions<AlphaMask3d>>()
54-
.init_resource::<DrawFunctions<Transparent3d>>()
55-
.add_system_to_stage(RenderStage::Extract, extract_core_3d_camera_phases)
56-
.add_system_to_stage(RenderStage::Prepare, prepare_core_3d_views_system)
57-
.add_system_to_stage(RenderStage::PhaseSort, sort_phase_system::<Opaque3d>)
58-
.add_system_to_stage(RenderStage::PhaseSort, sort_phase_system::<AlphaMask3d>)
59-
.add_system_to_stage(RenderStage::PhaseSort, sort_phase_system::<Transparent3d>);
60-
61-
let pass_node_3d = MainPass3dNode::new(&mut render_app.world);
62-
let mut graph = render_app.world.resource_mut::<RenderGraph>();
63-
64-
let mut draw_3d_graph = RenderGraph::default();
65-
draw_3d_graph.add_node(graph::node::MAIN_PASS, pass_node_3d);
66-
let input_node_id = draw_3d_graph.set_input(vec![SlotInfo::new(
67-
graph::input::VIEW_ENTITY,
68-
SlotType::Entity,
69-
)]);
70-
draw_3d_graph
71-
.add_slot_edge(
72-
input_node_id,
46+
app.add_render_init(move |app| {
47+
let render_app = match app.get_sub_app_mut(RenderApp) {
48+
Ok(render_app) => render_app,
49+
Err(_) => return,
50+
};
51+
52+
render_app
53+
.init_resource::<DrawFunctions<Opaque3d>>()
54+
.init_resource::<DrawFunctions<AlphaMask3d>>()
55+
.init_resource::<DrawFunctions<Transparent3d>>()
56+
.add_system_to_stage(RenderStage::Extract, extract_core_3d_camera_phases)
57+
.add_system_to_stage(RenderStage::Prepare, prepare_core_3d_views_system)
58+
.add_system_to_stage(RenderStage::PhaseSort, sort_phase_system::<Opaque3d>)
59+
.add_system_to_stage(RenderStage::PhaseSort, sort_phase_system::<AlphaMask3d>)
60+
.add_system_to_stage(RenderStage::PhaseSort, sort_phase_system::<Transparent3d>);
61+
62+
let pass_node_3d = MainPass3dNode::new(&mut render_app.world);
63+
let mut graph = render_app.world.resource_mut::<RenderGraph>();
64+
65+
let mut draw_3d_graph = RenderGraph::default();
66+
draw_3d_graph.add_node(graph::node::MAIN_PASS, pass_node_3d);
67+
let input_node_id = draw_3d_graph.set_input(vec![SlotInfo::new(
7368
graph::input::VIEW_ENTITY,
74-
graph::node::MAIN_PASS,
75-
MainPass3dNode::IN_VIEW,
76-
)
77-
.unwrap();
78-
graph.add_sub_graph(graph::NAME, draw_3d_graph);
69+
SlotType::Entity,
70+
)]);
71+
draw_3d_graph
72+
.add_slot_edge(
73+
input_node_id,
74+
graph::input::VIEW_ENTITY,
75+
graph::node::MAIN_PASS,
76+
MainPass3dNode::IN_VIEW,
77+
)
78+
.unwrap();
79+
graph.add_sub_graph(graph::NAME, draw_3d_graph);
80+
});
7981
}
8082
}
8183

crates/bevy_pbr/src/lib.rs

Lines changed: 62 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -149,67 +149,69 @@ impl Plugin for PbrPlugin {
149149
},
150150
);
151151

152-
let render_app = match app.get_sub_app_mut(RenderApp) {
153-
Ok(render_app) => render_app,
154-
Err(_) => return,
155-
};
152+
app.add_render_init(move |app| {
153+
let render_app = match app.get_sub_app_mut(RenderApp) {
154+
Ok(render_app) => render_app,
155+
Err(_) => return,
156+
};
156157

157-
render_app
158-
.add_system_to_stage(
159-
RenderStage::Extract,
160-
render::extract_clusters.label(RenderLightSystems::ExtractClusters),
161-
)
162-
.add_system_to_stage(
163-
RenderStage::Extract,
164-
render::extract_lights.label(RenderLightSystems::ExtractLights),
165-
)
166-
.add_system_to_stage(
167-
RenderStage::Prepare,
168-
// this is added as an exclusive system because it contributes new views. it must run (and have Commands applied)
169-
// _before_ the `prepare_views()` system is run. ideally this becomes a normal system when "stageless" features come out
170-
render::prepare_lights
171-
.exclusive_system()
172-
.label(RenderLightSystems::PrepareLights),
173-
)
174-
.add_system_to_stage(
175-
RenderStage::Prepare,
176-
// NOTE: This needs to run after prepare_lights. As prepare_lights is an exclusive system,
177-
// just adding it to the non-exclusive systems in the Prepare stage means it runs after
178-
// prepare_lights.
179-
render::prepare_clusters.label(RenderLightSystems::PrepareClusters),
180-
)
181-
.add_system_to_stage(
182-
RenderStage::Queue,
183-
render::queue_shadows.label(RenderLightSystems::QueueShadows),
184-
)
185-
.add_system_to_stage(RenderStage::Queue, render::queue_shadow_view_bind_group)
186-
.add_system_to_stage(RenderStage::PhaseSort, sort_phase_system::<Shadow>)
187-
.init_resource::<ShadowPipeline>()
188-
.init_resource::<DrawFunctions<Shadow>>()
189-
.init_resource::<LightMeta>()
190-
.init_resource::<GlobalLightMeta>()
191-
.init_resource::<SpecializedMeshPipelines<ShadowPipeline>>();
158+
render_app
159+
.add_system_to_stage(
160+
RenderStage::Extract,
161+
render::extract_clusters.label(RenderLightSystems::ExtractClusters),
162+
)
163+
.add_system_to_stage(
164+
RenderStage::Extract,
165+
render::extract_lights.label(RenderLightSystems::ExtractLights),
166+
)
167+
.add_system_to_stage(
168+
RenderStage::Prepare,
169+
// this is added as an exclusive system because it contributes new views. it must run (and have Commands applied)
170+
// _before_ the `prepare_views()` system is run. ideally this becomes a normal system when "stageless" features come out
171+
render::prepare_lights
172+
.exclusive_system()
173+
.label(RenderLightSystems::PrepareLights),
174+
)
175+
.add_system_to_stage(
176+
RenderStage::Prepare,
177+
// NOTE: This needs to run after prepare_lights. As prepare_lights is an exclusive system,
178+
// just adding it to the non-exclusive systems in the Prepare stage means it runs after
179+
// prepare_lights.
180+
render::prepare_clusters.label(RenderLightSystems::PrepareClusters),
181+
)
182+
.add_system_to_stage(
183+
RenderStage::Queue,
184+
render::queue_shadows.label(RenderLightSystems::QueueShadows),
185+
)
186+
.add_system_to_stage(RenderStage::Queue, render::queue_shadow_view_bind_group)
187+
.add_system_to_stage(RenderStage::PhaseSort, sort_phase_system::<Shadow>)
188+
.init_resource::<ShadowPipeline>()
189+
.init_resource::<DrawFunctions<Shadow>>()
190+
.init_resource::<LightMeta>()
191+
.init_resource::<GlobalLightMeta>()
192+
.init_resource::<SpecializedMeshPipelines<ShadowPipeline>>();
192193

193-
let shadow_pass_node = ShadowPassNode::new(&mut render_app.world);
194-
render_app.add_render_command::<Shadow, DrawShadowMesh>();
195-
let mut graph = render_app.world.resource_mut::<RenderGraph>();
196-
let draw_3d_graph = graph
197-
.get_sub_graph_mut(bevy_core_pipeline::core_3d::graph::NAME)
198-
.unwrap();
199-
draw_3d_graph.add_node(draw_3d_graph::node::SHADOW_PASS, shadow_pass_node);
200-
draw_3d_graph
201-
.add_node_edge(
202-
draw_3d_graph::node::SHADOW_PASS,
203-
bevy_core_pipeline::core_3d::graph::node::MAIN_PASS,
204-
)
205-
.unwrap();
206-
draw_3d_graph
207-
.add_slot_edge(
208-
draw_3d_graph.input_node().unwrap().id,
209-
bevy_core_pipeline::core_3d::graph::input::VIEW_ENTITY,
210-
draw_3d_graph::node::SHADOW_PASS,
211-
ShadowPassNode::IN_VIEW,
212-
)
213-
.unwrap();
194+
let shadow_pass_node = ShadowPassNode::new(&mut render_app.world);
195+
render_app.add_render_command::<Shadow, DrawShadowMesh>();
196+
let mut graph = render_app.world.resource_mut::<RenderGraph>();
197+
let draw_3d_graph = graph
198+
.get_sub_graph_mut(bevy_core_pipeline::core_3d::graph::NAME)
199+
.unwrap();
200+
draw_3d_graph.add_node(draw_3d_graph::node::SHADOW_PASS, shadow_pass_node);
201+
draw_3d_graph
202+
.add_node_edge(
203+
draw_3d_graph::node::SHADOW_PASS,
204+
bevy_core_pipeline::core_3d::graph::node::MAIN_PASS,
205+
)
206+
.unwrap();
207+
draw_3d_graph
208+
.add_slot_edge(
209+
draw_3d_graph.input_node().unwrap().id,
210+
bevy_core_pipeline::core_3d::graph::input::VIEW_ENTITY,
211+
draw_3d_graph::node::SHADOW_PASS,
212+
ShadowPassNode::IN_VIEW,
213+
)
214+
.unwrap();
215+
});
214216
}
215217
}

crates/bevy_pbr/src/material.rs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -226,15 +226,18 @@ impl<M: SpecializedMaterial> Plugin for MaterialPlugin<M> {
226226
app.add_asset::<M>()
227227
.add_plugin(ExtractComponentPlugin::<Handle<M>>::extract_visible())
228228
.add_plugin(RenderAssetPlugin::<M>::default());
229-
if let Ok(render_app) = app.get_sub_app_mut(RenderApp) {
230-
render_app
231-
.add_render_command::<Transparent3d, DrawMaterial<M>>()
232-
.add_render_command::<Opaque3d, DrawMaterial<M>>()
233-
.add_render_command::<AlphaMask3d, DrawMaterial<M>>()
234-
.init_resource::<MaterialPipeline<M>>()
235-
.init_resource::<SpecializedMeshPipelines<MaterialPipeline<M>>>()
236-
.add_system_to_stage(RenderStage::Queue, queue_material_meshes::<M>);
237-
}
229+
230+
app.add_render_init(move |app| {
231+
if let Ok(render_app) = app.get_sub_app_mut(RenderApp) {
232+
render_app
233+
.add_render_command::<Transparent3d, DrawMaterial<M>>()
234+
.add_render_command::<Opaque3d, DrawMaterial<M>>()
235+
.add_render_command::<AlphaMask3d, DrawMaterial<M>>()
236+
.init_resource::<MaterialPipeline<M>>()
237+
.init_resource::<SpecializedMeshPipelines<MaterialPipeline<M>>>()
238+
.add_system_to_stage(RenderStage::Queue, queue_material_meshes::<M>);
239+
}
240+
});
238241
}
239242
}
240243

crates/bevy_pbr/src/render/mesh.rs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -74,16 +74,18 @@ impl Plugin for MeshRenderPlugin {
7474

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

77-
if let Ok(render_app) = app.get_sub_app_mut(RenderApp) {
78-
render_app
79-
.init_resource::<MeshPipeline>()
80-
.init_resource::<SkinnedMeshUniform>()
81-
.add_system_to_stage(RenderStage::Extract, extract_meshes)
82-
.add_system_to_stage(RenderStage::Extract, extract_skinned_meshes)
83-
.add_system_to_stage(RenderStage::Prepare, prepare_skinned_meshes)
84-
.add_system_to_stage(RenderStage::Queue, queue_mesh_bind_group)
85-
.add_system_to_stage(RenderStage::Queue, queue_mesh_view_bind_groups);
86-
}
77+
app.add_render_init(move |app| {
78+
if let Ok(render_app) = app.get_sub_app_mut(RenderApp) {
79+
render_app
80+
.init_resource::<MeshPipeline>()
81+
.init_resource::<SkinnedMeshUniform>()
82+
.add_system_to_stage(RenderStage::Extract, extract_meshes)
83+
.add_system_to_stage(RenderStage::Extract, extract_skinned_meshes)
84+
.add_system_to_stage(RenderStage::Prepare, prepare_skinned_meshes)
85+
.add_system_to_stage(RenderStage::Queue, queue_mesh_bind_group)
86+
.add_system_to_stage(RenderStage::Queue, queue_mesh_view_bind_groups);
87+
}
88+
});
8789
}
8890
}
8991

crates/bevy_pbr/src/wireframe.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,16 @@ impl Plugin for WireframePlugin {
3838
app.init_resource::<WireframeConfig>()
3939
.add_plugin(ExtractResourcePlugin::<WireframeConfig>::default());
4040

41-
if let Ok(render_app) = app.get_sub_app_mut(RenderApp) {
42-
render_app
43-
.add_render_command::<Opaque3d, DrawWireframes>()
44-
.init_resource::<WireframePipeline>()
45-
.init_resource::<SpecializedMeshPipelines<WireframePipeline>>()
46-
.add_system_to_stage(RenderStage::Extract, extract_wireframes)
47-
.add_system_to_stage(RenderStage::Queue, queue_wireframes);
48-
}
41+
app.add_render_init(move |app| {
42+
if let Ok(render_app) = app.get_sub_app_mut(RenderApp) {
43+
render_app
44+
.add_render_command::<Opaque3d, DrawWireframes>()
45+
.init_resource::<WireframePipeline>()
46+
.init_resource::<SpecializedMeshPipelines<WireframePipeline>>()
47+
.add_system_to_stage(RenderStage::Extract, extract_wireframes)
48+
.add_system_to_stage(RenderStage::Queue, queue_wireframes);
49+
}
50+
});
4951
}
5052
}
5153

crates/bevy_render/src/camera/mod.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,14 @@ impl Plugin for CameraPlugin {
3333
.add_plugin(CameraProjectionPlugin::<OrthographicProjection>::default())
3434
.add_plugin(CameraProjectionPlugin::<PerspectiveProjection>::default());
3535

36-
if let Ok(render_app) = app.get_sub_app_mut(RenderApp) {
37-
render_app.add_system_to_stage(RenderStage::Extract, extract_cameras);
36+
app.add_render_init(move |app| {
37+
if let Ok(render_app) = app.get_sub_app_mut(RenderApp) {
38+
render_app.add_system_to_stage(RenderStage::Extract, extract_cameras);
3839

39-
let camera_driver_node = CameraDriverNode::new(&mut render_app.world);
40-
let mut render_graph = render_app.world.resource_mut::<RenderGraph>();
41-
render_graph.add_node(crate::main_graph::node::CAMERA_DRIVER, camera_driver_node);
42-
}
40+
let camera_driver_node = CameraDriverNode::new(&mut render_app.world);
41+
let mut render_graph = render_app.world.resource_mut::<RenderGraph>();
42+
render_graph.add_node(crate::main_graph::node::CAMERA_DRIVER, camera_driver_node);
43+
}
44+
});
4345
}
4446
}

0 commit comments

Comments
 (0)