@@ -78,6 +78,12 @@ pub enum RenderStage {
78
78
79
79
/// Cleanup render resources here.
80
80
Cleanup ,
81
+
82
+ /// Extract data from the "render world" and insert it into the "app world".
83
+ /// This should be used very sparingly and will be combined with the Extract stage
84
+ /// when pipelined rendering is implemented. You will only be able to access resources here
85
+ /// entities are cleared in the cleanup stage that runs before this.
86
+ ExtractToApp ,
81
87
}
82
88
83
89
/// The Render App World. This is only available as a resource during the Extract step.
@@ -170,6 +176,7 @@ impl Plugin for RenderPlugin {
170
176
. with_system ( render_system. exclusive_system ( ) . at_end ( ) ) ,
171
177
)
172
178
. add_stage ( RenderStage :: Cleanup , SystemStage :: parallel ( ) )
179
+ . add_stage ( RenderStage :: ExtractToApp , SystemStage :: parallel ( ) )
173
180
. insert_resource ( instance)
174
181
. insert_resource ( device)
175
182
. insert_resource ( queue)
@@ -276,6 +283,15 @@ impl Plugin for RenderPlugin {
276
283
277
284
render_app. world . clear_entities ( ) ;
278
285
}
286
+
287
+ {
288
+ #[ cfg( feature = "trace" ) ]
289
+ let _stage_span =
290
+ bevy_utils:: tracing:: info_span!( "stage" , name = "extract to app" ) . entered ( ) ;
291
+
292
+ // extract to app
293
+ extract_to_app ( app_world, render_app) ;
294
+ }
279
295
} ) ;
280
296
}
281
297
@@ -311,3 +327,26 @@ fn extract(app_world: &mut World, render_app: &mut App) {
311
327
312
328
extract. apply_buffers ( & mut render_app. world ) ;
313
329
}
330
+
331
+ /// Executes the [`ExtractToApp`](RenderStage::Extract) stage of the renderer.
332
+ /// This updates the render world with the extracted ECS data of the current frame.
333
+ fn extract_to_app ( app_world : & mut World , render_app : & mut App ) {
334
+ let extract_to_app = render_app
335
+ . schedule
336
+ . get_stage_mut :: < SystemStage > ( & RenderStage :: ExtractToApp )
337
+ . unwrap ( ) ;
338
+
339
+ // temporarily add the render world to the app world as a resource
340
+ let scratch_world = app_world. remove_resource :: < ScratchRenderWorld > ( ) . unwrap ( ) ;
341
+ let render_world = std:: mem:: replace ( & mut render_app. world , scratch_world. 0 ) ;
342
+ app_world. insert_resource ( RenderWorld ( render_world) ) ;
343
+
344
+ extract_to_app. run ( app_world) ;
345
+
346
+ // add the render world back to the render app
347
+ let render_world = app_world. remove_resource :: < RenderWorld > ( ) . unwrap ( ) ;
348
+ let scratch_world = std:: mem:: replace ( & mut render_app. world , render_world. 0 ) ;
349
+ app_world. insert_resource ( ScratchRenderWorld ( scratch_world) ) ;
350
+
351
+ extract_to_app. apply_buffers ( & mut render_app. world ) ;
352
+ }
0 commit comments