@@ -73,12 +73,14 @@ pub const DEPTH_TEXTURE_SAMPLING_SUPPORTED: bool = true;
7373use core:: ops:: Range ;
7474
7575use bevy_camera:: { Camera , Camera3d , Camera3dDepthLoadOp } ;
76+ use bevy_diagnostic:: FrameCount ;
7677use bevy_render:: {
7778 batching:: gpu_preprocessing:: { GpuPreprocessingMode , GpuPreprocessingSupport } ,
7879 camera:: CameraRenderGraph ,
7980 experimental:: occlusion_culling:: OcclusionCulling ,
8081 mesh:: allocator:: SlabId ,
8182 render_phase:: PhaseItemBatchSetKey ,
83+ texture:: CachedTexture ,
8284 view:: { prepare_view_targets, NoIndirectDrawing , RetainedViewEntity } ,
8385} ;
8486pub use main_opaque_pass_3d_node:: * ;
@@ -124,9 +126,10 @@ use crate::{
124126 } ,
125127 prepass:: {
126128 node:: { EarlyPrepassNode , LatePrepassNode } ,
127- AlphaMask3dPrepass , DeferredPrepass , DepthPrepass , MotionVectorPrepass , NormalPrepass ,
128- Opaque3dPrepass , OpaqueNoLightmap3dBatchSetKey , OpaqueNoLightmap3dBinKey ,
129- ViewPrepassTextures , MOTION_VECTOR_PREPASS_FORMAT , NORMAL_PREPASS_FORMAT ,
129+ AlphaMask3dPrepass , DeferredPrepass , DeferredPrepassDoubleBuffer , DepthPrepass ,
130+ DepthPrepassDoubleBuffer , MotionVectorPrepass , NormalPrepass , Opaque3dPrepass ,
131+ OpaqueNoLightmap3dBatchSetKey , OpaqueNoLightmap3dBinKey , ViewPrepassTextures ,
132+ MOTION_VECTOR_PREPASS_FORMAT , NORMAL_PREPASS_FORMAT ,
130133 } ,
131134 skybox:: SkyboxPlugin ,
132135 tonemapping:: { DebandDither , Tonemapping , TonemappingNode } ,
@@ -676,6 +679,8 @@ pub fn extract_camera_prepass_phase(
676679 Has < NormalPrepass > ,
677680 Has < MotionVectorPrepass > ,
678681 Has < DeferredPrepass > ,
682+ Has < DepthPrepassDoubleBuffer > ,
683+ Has < DeferredPrepassDoubleBuffer > ,
679684 ) ,
680685 With < Camera3d > ,
681686 > ,
@@ -694,6 +699,8 @@ pub fn extract_camera_prepass_phase(
694699 normal_prepass,
695700 motion_vector_prepass,
696701 deferred_prepass,
702+ depth_prepass_double_buffer,
703+ deferred_prepass_double_buffer,
697704 ) in cameras_3d. iter ( )
698705 {
699706 if !camera. is_active {
@@ -761,6 +768,18 @@ pub fn extract_camera_prepass_phase(
761768 } else {
762769 camera_commands. remove :: < DeferredPrepass > ( ) ;
763770 }
771+
772+ if depth_prepass_double_buffer {
773+ camera_commands. insert ( DepthPrepassDoubleBuffer ) ;
774+ } else {
775+ camera_commands. remove :: < DepthPrepassDoubleBuffer > ( ) ;
776+ }
777+
778+ if deferred_prepass_double_buffer {
779+ camera_commands. insert ( DeferredPrepassDoubleBuffer ) ;
780+ } else {
781+ camera_commands. remove :: < DeferredPrepassDoubleBuffer > ( ) ;
782+ }
764783 }
765784
766785 opaque_3d_prepass_phases. retain ( |view_entity, _| live_entities. contains ( view_entity) ) ;
@@ -973,6 +992,7 @@ pub fn prepare_prepass_textures(
973992 mut commands : Commands ,
974993 mut texture_cache : ResMut < TextureCache > ,
975994 render_device : Res < RenderDevice > ,
995+ frame_count : Res < FrameCount > ,
976996 opaque_3d_prepass_phases : Res < ViewBinnedRenderPhases < Opaque3dPrepass > > ,
977997 alpha_mask_3d_prepass_phases : Res < ViewBinnedRenderPhases < AlphaMask3dPrepass > > ,
978998 opaque_3d_deferred_phases : Res < ViewBinnedRenderPhases < Opaque3dDeferred > > ,
@@ -986,11 +1006,15 @@ pub fn prepare_prepass_textures(
9861006 Has < NormalPrepass > ,
9871007 Has < MotionVectorPrepass > ,
9881008 Has < DeferredPrepass > ,
1009+ Has < DepthPrepassDoubleBuffer > ,
1010+ Has < DeferredPrepassDoubleBuffer > ,
9891011 ) > ,
9901012) {
991- let mut depth_textures = <HashMap < _ , _ > >:: default ( ) ;
1013+ let mut depth_textures1 = <HashMap < _ , _ > >:: default ( ) ;
1014+ let mut depth_textures2 = <HashMap < _ , _ > >:: default ( ) ;
9921015 let mut normal_textures = <HashMap < _ , _ > >:: default ( ) ;
993- let mut deferred_textures = <HashMap < _ , _ > >:: default ( ) ;
1016+ let mut deferred_textures1: HashMap < _ , _ > = <HashMap < _ , _ > >:: default ( ) ;
1017+ let mut deferred_textures2: HashMap < _ , _ > = <HashMap < _ , _ > >:: default ( ) ;
9941018 let mut deferred_lighting_id_textures = <HashMap < _ , _ > >:: default ( ) ;
9951019 let mut motion_vectors_textures = <HashMap < _ , _ > >:: default ( ) ;
9961020 for (
@@ -1002,6 +1026,8 @@ pub fn prepare_prepass_textures(
10021026 normal_prepass,
10031027 motion_vector_prepass,
10041028 deferred_prepass,
1029+ depth_prepass_double_buffer,
1030+ deferred_prepass_double_buffer,
10051031 ) in & views_3d
10061032 {
10071033 if !opaque_3d_prepass_phases. contains_key ( & view. retained_view_entity )
@@ -1019,21 +1045,41 @@ pub fn prepare_prepass_textures(
10191045
10201046 let size = physical_target_size. to_extents ( ) ;
10211047
1022- let cached_depth_texture = depth_prepass. then ( || {
1023- depth_textures
1048+ let cached_depth_texture1 = depth_prepass. then ( || {
1049+ depth_textures1
1050+ . entry ( camera. target . clone ( ) )
1051+ . or_insert_with ( || {
1052+ let descriptor = TextureDescriptor {
1053+ label : Some ( "prepass_depth_texture_1" ) ,
1054+ size,
1055+ mip_level_count : 1 ,
1056+ sample_count : msaa. samples ( ) ,
1057+ dimension : TextureDimension :: D2 ,
1058+ format : CORE_3D_DEPTH_FORMAT ,
1059+ usage : TextureUsages :: COPY_DST
1060+ | TextureUsages :: RENDER_ATTACHMENT
1061+ | TextureUsages :: TEXTURE_BINDING ,
1062+ view_formats : & [ ] ,
1063+ } ;
1064+ texture_cache. get ( & render_device, descriptor)
1065+ } )
1066+ . clone ( )
1067+ } ) ;
1068+
1069+ let cached_depth_texture2 = depth_prepass_double_buffer. then ( || {
1070+ depth_textures2
10241071 . entry ( camera. target . clone ( ) )
10251072 . or_insert_with ( || {
10261073 let descriptor = TextureDescriptor {
1027- label : Some ( "prepass_depth_texture " ) ,
1074+ label : Some ( "prepass_depth_texture_2 " ) ,
10281075 size,
10291076 mip_level_count : 1 ,
10301077 sample_count : msaa. samples ( ) ,
10311078 dimension : TextureDimension :: D2 ,
10321079 format : CORE_3D_DEPTH_FORMAT ,
10331080 usage : TextureUsages :: COPY_DST
10341081 | TextureUsages :: RENDER_ATTACHMENT
1035- | TextureUsages :: TEXTURE_BINDING
1036- | TextureUsages :: COPY_SRC , // TODO: Remove COPY_SRC, double buffer instead (for bevy_solari)
1082+ | TextureUsages :: TEXTURE_BINDING ,
10371083 view_formats : & [ ] ,
10381084 } ;
10391085 texture_cache. get ( & render_device, descriptor)
@@ -1085,22 +1131,43 @@ pub fn prepare_prepass_textures(
10851131 . clone ( )
10861132 } ) ;
10871133
1088- let cached_deferred_texture = deferred_prepass. then ( || {
1089- deferred_textures
1134+ let cached_deferred_texture1 = deferred_prepass. then ( || {
1135+ deferred_textures1
1136+ . entry ( camera. target . clone ( ) )
1137+ . or_insert_with ( || {
1138+ texture_cache. get (
1139+ & render_device,
1140+ TextureDescriptor {
1141+ label : Some ( "prepass_deferred_texture_1" ) ,
1142+ size,
1143+ mip_level_count : 1 ,
1144+ sample_count : 1 ,
1145+ dimension : TextureDimension :: D2 ,
1146+ format : DEFERRED_PREPASS_FORMAT ,
1147+ usage : TextureUsages :: RENDER_ATTACHMENT
1148+ | TextureUsages :: TEXTURE_BINDING ,
1149+ view_formats : & [ ] ,
1150+ } ,
1151+ )
1152+ } )
1153+ . clone ( )
1154+ } ) ;
1155+
1156+ let cached_deferred_texture2 = deferred_prepass_double_buffer. then ( || {
1157+ deferred_textures2
10901158 . entry ( camera. target . clone ( ) )
10911159 . or_insert_with ( || {
10921160 texture_cache. get (
10931161 & render_device,
10941162 TextureDescriptor {
1095- label : Some ( "prepass_deferred_texture " ) ,
1163+ label : Some ( "prepass_deferred_texture_2 " ) ,
10961164 size,
10971165 mip_level_count : 1 ,
10981166 sample_count : 1 ,
10991167 dimension : TextureDimension :: D2 ,
11001168 format : DEFERRED_PREPASS_FORMAT ,
11011169 usage : TextureUsages :: RENDER_ATTACHMENT
1102- | TextureUsages :: TEXTURE_BINDING
1103- | TextureUsages :: COPY_SRC , // TODO: Remove COPY_SRC, double buffer instead (for bevy_solari)
1170+ | TextureUsages :: TEXTURE_BINDING ,
11041171 view_formats : & [ ] ,
11051172 } ,
11061173 )
@@ -1131,20 +1198,54 @@ pub fn prepare_prepass_textures(
11311198 } ) ;
11321199
11331200 commands. entity ( entity) . insert ( ViewPrepassTextures {
1134- depth : cached_depth_texture
1135- . map ( |t| ColorAttachment :: new ( t, None , Some ( LinearRgba :: BLACK ) ) ) ,
1201+ depth : package_double_buffered_texture (
1202+ cached_depth_texture1,
1203+ cached_depth_texture2,
1204+ frame_count. 0 ,
1205+ ) ,
11361206 normal : cached_normals_texture
1137- . map ( |t| ColorAttachment :: new ( t, None , Some ( LinearRgba :: BLACK ) ) ) ,
1207+ . map ( |t| ColorAttachment :: new ( t, None , None , Some ( LinearRgba :: BLACK ) ) ) ,
11381208 // Red and Green channels are X and Y components of the motion vectors
11391209 // Blue channel doesn't matter, but set to 0.0 for possible faster clear
11401210 // https://gpuopen.com/performance/#clears
11411211 motion_vectors : cached_motion_vectors_texture
1142- . map ( |t| ColorAttachment :: new ( t, None , Some ( LinearRgba :: BLACK ) ) ) ,
1143- deferred : cached_deferred_texture
1144- . map ( |t| ColorAttachment :: new ( t, None , Some ( LinearRgba :: BLACK ) ) ) ,
1212+ . map ( |t| ColorAttachment :: new ( t, None , None , Some ( LinearRgba :: BLACK ) ) ) ,
1213+ deferred : package_double_buffered_texture (
1214+ cached_deferred_texture1,
1215+ cached_deferred_texture2,
1216+ frame_count. 0 ,
1217+ ) ,
11451218 deferred_lighting_pass_id : cached_deferred_lighting_pass_id_texture
1146- . map ( |t| ColorAttachment :: new ( t, None , Some ( LinearRgba :: BLACK ) ) ) ,
1219+ . map ( |t| ColorAttachment :: new ( t, None , None , Some ( LinearRgba :: BLACK ) ) ) ,
11471220 size,
11481221 } ) ;
11491222 }
11501223}
1224+
1225+ fn package_double_buffered_texture (
1226+ texture1 : Option < CachedTexture > ,
1227+ texture2 : Option < CachedTexture > ,
1228+ frame_count : u32 ,
1229+ ) -> Option < ColorAttachment > {
1230+ match ( texture1, texture2) {
1231+ ( Some ( t1) , None ) => Some ( ColorAttachment :: new (
1232+ t1,
1233+ None ,
1234+ None ,
1235+ Some ( LinearRgba :: BLACK ) ,
1236+ ) ) ,
1237+ ( Some ( t1) , Some ( t2) ) if frame_count. is_multiple_of ( 2 ) => Some ( ColorAttachment :: new (
1238+ t1,
1239+ None ,
1240+ Some ( t2) ,
1241+ Some ( LinearRgba :: BLACK ) ,
1242+ ) ) ,
1243+ ( Some ( t1) , Some ( t2) ) => Some ( ColorAttachment :: new (
1244+ t2,
1245+ None ,
1246+ Some ( t1) ,
1247+ Some ( LinearRgba :: BLACK ) ,
1248+ ) ) ,
1249+ _ => None ,
1250+ }
1251+ }
0 commit comments