@@ -15,7 +15,8 @@ use bevy::{
1515 render:: {
1616 RenderApp ,
1717 render_resource:: {
18- CommandEncoderDescriptor , Extent3d , MapMode , Origin3d , PollType , TexelCopyBufferInfo ,
18+ CommandEncoderDescriptor , Extent3d , LoadOp , MapMode , Operations , Origin3d , PollType ,
19+ RenderPassColorAttachment , RenderPassDescriptor , StoreOp , TexelCopyBufferInfo ,
1920 TexelCopyBufferLayout , TexelCopyTextureInfo , Texture , TextureFormat , TextureUsages ,
2021 } ,
2122 renderer:: { RenderDevice , RenderQueue } ,
@@ -36,6 +37,8 @@ use crate::{
3637} ;
3738use processing_core:: error:: { ProcessingError , Result } ;
3839
40+ pub const DEFAULT_CLEAR_COLOR : Color = Color :: srgba_u8 ( 208 , 208 , 208 , 255 ) ;
41+
3942pub struct GraphicsPlugin ;
4043
4144impl Plugin for GraphicsPlugin {
@@ -483,6 +486,61 @@ pub fn end_draw(app: &mut App, entity: Entity) -> Result<()> {
483486 present ( app, entity)
484487}
485488
489+
490+ /// Do some work on the GPU to ensure that the render target texture is initialized and can be read
491+ /// from/written to.
492+ ///
493+ /// This is necessary on some platforms (notably macOS) to avoid issues with the first few frames of
494+ /// rendering being corrupted or not appearing at all.
495+ ///
496+ // TODO: why is metal particularly affected by this? can we remove this?
497+ pub fn warmup ( app : & mut App , entity : Entity ) -> Result < ( ) > {
498+ let main_texture = {
499+ let render_world = app. sub_app_mut ( RenderApp ) . world_mut ( ) ;
500+ let mut query = render_world. query :: < ( & MainEntity , & ViewTarget ) > ( ) ;
501+ let mut found = None ;
502+ for ( main_entity, vt) in query. iter ( render_world) {
503+ if * * main_entity == entity {
504+ found = Some ( vt. main_texture ( ) . clone ( ) ) ;
505+ break ;
506+ }
507+ }
508+ found. ok_or ( ProcessingError :: GraphicsNotFound ) ?
509+ } ;
510+
511+ let render_app = app. sub_app ( RenderApp ) ;
512+ let render_device = render_app. world ( ) . resource :: < RenderDevice > ( ) ;
513+ let render_queue = render_app. world ( ) . resource :: < RenderQueue > ( ) ;
514+
515+ let view = main_texture. create_view ( & bevy:: render:: render_resource:: TextureViewDescriptor {
516+ label : Some ( "processing_warmup_view" ) ,
517+ ..Default :: default ( )
518+ } ) ;
519+ let mut encoder = render_device. create_command_encoder ( & CommandEncoderDescriptor {
520+ label : Some ( "processing_warmup_encoder" ) ,
521+ } ) ;
522+ {
523+ let _pass = encoder. begin_render_pass ( & RenderPassDescriptor {
524+ label : Some ( "processing_warmup_clear" ) ,
525+ color_attachments : & [ Some ( RenderPassColorAttachment {
526+ view : & view,
527+ depth_slice : None ,
528+ resolve_target : None ,
529+ ops : Operations {
530+ load : LoadOp :: Clear ( wgpu:: Color :: TRANSPARENT ) ,
531+ store : StoreOp :: Store ,
532+ } ,
533+ } ) ] ,
534+ depth_stencil_attachment : None ,
535+ timestamp_writes : None ,
536+ occlusion_query_set : None ,
537+ multiview_mask : None ,
538+ } ) ;
539+ }
540+ render_queue. submit ( [ encoder. finish ( ) ] ) ;
541+ Ok ( ( ) )
542+ }
543+
486544pub fn record_command (
487545 In ( ( graphics_entity, cmd) ) : In < ( Entity , DrawCommand ) > ,
488546 mut graphics_query : Query < & mut CommandBuffer > ,
0 commit comments