@@ -24,7 +24,7 @@ use crate::{
2424 } ,
2525 GpuResourceAppExt , Render , RenderApp , RenderSystems ,
2626} ;
27- use alloc:: sync:: Arc ;
27+ use alloc:: sync:: { Arc , Weak } ;
2828use bevy_app:: { App , Plugin } ;
2929use bevy_color:: { LinearRgba , Oklaba } ;
3030use bevy_derive:: { Deref , DerefMut } ;
@@ -1127,6 +1127,13 @@ pub fn cleanup_view_targets_for_resize(
11271127 }
11281128}
11291129
1130+ type MainTextureKey = (
1131+ Option < NormalizedRenderTarget > ,
1132+ TextureUsages ,
1133+ TextureFormat ,
1134+ Msaa ,
1135+ ) ;
1136+
11301137pub fn prepare_view_targets (
11311138 mut commands : Commands ,
11321139 clear_color_global : Res < ClearColor > ,
@@ -1140,7 +1147,10 @@ pub fn prepare_view_targets(
11401147 & Msaa ,
11411148 ) > ,
11421149 view_target_attachments : Res < ViewTargetAttachments > ,
1150+ mut main_texture_atomics : Local < HashMap < MainTextureKey , Weak < AtomicUsize > > > ,
11431151) {
1152+ main_texture_atomics. retain ( |_, weak| weak. strong_count ( ) > 0 ) ;
1153+
11441154 let mut textures = <HashMap < _ , _ > >:: default ( ) ;
11451155 for ( entity, camera, view, texture_usage, msaa) in cameras. iter ( ) {
11461156 let ( Some ( target_size) , Some ( out_attachment) ) = (
@@ -1181,63 +1191,74 @@ pub fn prepare_view_targets(
11811191 }
11821192 } ) ;
11831193
1184- let ( a, b, sampled, main_texture) = textures
1185- . entry ( (
1186- camera. target . clone ( ) ,
1187- texture_usage. 0 ,
1188- main_texture_format,
1189- msaa,
1190- ) )
1191- . or_insert_with ( || {
1192- let descriptor = TextureDescriptor {
1193- label : None ,
1194- size : target_size. to_extents ( ) ,
1195- mip_level_count : 1 ,
1196- sample_count : 1 ,
1197- dimension : TextureDimension :: D2 ,
1198- format : main_texture_format,
1199- usage : texture_usage. 0 ,
1200- view_formats : match main_texture_format {
1201- TextureFormat :: Bgra8Unorm => & [ TextureFormat :: Bgra8UnormSrgb ] ,
1202- TextureFormat :: Rgba8Unorm => & [ TextureFormat :: Rgba8UnormSrgb ] ,
1203- _ => & [ ] ,
1204- } ,
1205- } ;
1206- let a = texture_cache. get (
1207- & render_device,
1208- TextureDescriptor {
1209- label : Some ( "main_texture_a" ) ,
1210- ..descriptor
1211- } ,
1212- ) ;
1213- let b = texture_cache. get (
1194+ let key: MainTextureKey = (
1195+ camera. target . clone ( ) ,
1196+ texture_usage. 0 ,
1197+ main_texture_format,
1198+ * msaa,
1199+ ) ;
1200+ let ( a, b, sampled, main_texture) = textures. entry ( key. clone ( ) ) . or_insert_with ( || {
1201+ let descriptor = TextureDescriptor {
1202+ label : None ,
1203+ size : target_size. to_extents ( ) ,
1204+ mip_level_count : 1 ,
1205+ sample_count : 1 ,
1206+ dimension : TextureDimension :: D2 ,
1207+ format : main_texture_format,
1208+ usage : texture_usage. 0 ,
1209+ view_formats : match main_texture_format {
1210+ TextureFormat :: Bgra8Unorm => & [ TextureFormat :: Bgra8UnormSrgb ] ,
1211+ TextureFormat :: Rgba8Unorm => & [ TextureFormat :: Rgba8UnormSrgb ] ,
1212+ _ => & [ ] ,
1213+ } ,
1214+ } ;
1215+ let a = texture_cache. get (
1216+ & render_device,
1217+ TextureDescriptor {
1218+ label : Some ( "main_texture_a" ) ,
1219+ ..descriptor
1220+ } ,
1221+ ) ;
1222+ let b = texture_cache. get (
1223+ & render_device,
1224+ TextureDescriptor {
1225+ label : Some ( "main_texture_b" ) ,
1226+ ..descriptor
1227+ } ,
1228+ ) ;
1229+ let sampled = if msaa. samples ( ) > 1 {
1230+ let sampled = texture_cache. get (
12141231 & render_device,
12151232 TextureDescriptor {
1216- label : Some ( "main_texture_b" ) ,
1217- ..descriptor
1233+ label : Some ( "main_texture_sampled" ) ,
1234+ size : target_size. to_extents ( ) ,
1235+ mip_level_count : 1 ,
1236+ sample_count : msaa. samples ( ) ,
1237+ dimension : TextureDimension :: D2 ,
1238+ format : main_texture_format,
1239+ usage : TextureUsages :: RENDER_ATTACHMENT ,
1240+ view_formats : descriptor. view_formats ,
12181241 } ,
12191242 ) ;
1220- let sampled = if msaa. samples ( ) > 1 {
1221- let sampled = texture_cache. get (
1222- & render_device,
1223- TextureDescriptor {
1224- label : Some ( "main_texture_sampled" ) ,
1225- size : target_size. to_extents ( ) ,
1226- mip_level_count : 1 ,
1227- sample_count : msaa. samples ( ) ,
1228- dimension : TextureDimension :: D2 ,
1229- format : main_texture_format,
1230- usage : TextureUsages :: RENDER_ATTACHMENT ,
1231- view_formats : descriptor. view_formats ,
1232- } ,
1233- ) ;
1234- Some ( sampled)
1235- } else {
1236- None
1237- } ;
1238- let main_texture = Arc :: new ( AtomicUsize :: new ( 0 ) ) ;
1239- ( a, b, sampled, main_texture)
1240- } ) ;
1243+ Some ( sampled)
1244+ } else {
1245+ None
1246+ } ;
1247+ // re-use the same atomics frame to frame for views with the same main texture
1248+ // to ensure post process writes persist through msaa writeback
1249+ let main_texture = match main_texture_atomics. entry ( key) {
1250+ Entry :: Occupied ( e) => e
1251+ . get ( )
1252+ . upgrade ( )
1253+ . expect ( "dead weaks were pruned at top of system" ) ,
1254+ Entry :: Vacant ( e) => {
1255+ let arc = Arc :: new ( AtomicUsize :: new ( 0 ) ) ;
1256+ e. insert ( Arc :: downgrade ( & arc) ) ;
1257+ arc
1258+ }
1259+ } ;
1260+ ( a, b, sampled, main_texture)
1261+ } ) ;
12411262
12421263 let main_textures = MainTargetTextures {
12431264 a : ColorAttachment :: new ( a. clone ( ) , sampled. clone ( ) , None , converted_clear_color) ,
0 commit comments