Skip to content

Commit ad98e09

Browse files
committed
Fixes #115.
1 parent 13e7e0f commit ad98e09

1 file changed

Lines changed: 25 additions & 5 deletions

File tree

crates/processing_render/src/graphics.rs

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -224,9 +224,9 @@ pub fn create(
224224
Camera {
225225
// always load the previous frame (provides sketch like behavior)
226226
clear_color: ClearColorConfig::None,
227-
// TODO: toggle this conditionally based on whether we need to write back MSAA
228-
// when doing manual pixel updates
229-
msaa_writeback: MsaaWriteback::Off,
227+
// force MSAA writeback every frame so manual writes to `main_texture` (e.g. via
228+
// `graphics_update_region`) survive the next resolve
229+
msaa_writeback: MsaaWriteback::Always,
230230
..default()
231231
},
232232
target,
@@ -581,6 +581,7 @@ pub fn update_region_write(
581581
)>,
582582
graphics_query: Query<&Graphics>,
583583
graphics_targets: Res<GraphicsTargets>,
584+
render_device: Res<RenderDevice>,
584585
render_queue: Res<RenderQueue>,
585586
) -> Result<()> {
586587
let graphics = graphics_query
@@ -599,12 +600,12 @@ pub fn update_region_write(
599600
.get(&entity)
600601
.ok_or(ProcessingError::GraphicsNotFound)?;
601602

602-
let texture = view_target.main_texture();
603+
let main = view_target.main_texture();
603604
let bytes_per_row = width * px_size;
604605

605606
render_queue.write_texture(
606607
TexelCopyTextureInfo {
607-
texture,
608+
texture: main,
608609
mip_level: 0,
609610
origin: Origin3d { x, y, z: 0 },
610611
aspect: Default::default(),
@@ -622,6 +623,25 @@ pub fn update_region_write(
622623
},
623624
);
624625

626+
// when MSAA is enabled, the main pass renders into a sampled texture and resolves into one of
627+
// the two ping-pong main textures. bevy's main_texture atomic is reset to 0 at the start of
628+
// every frame, so next frame's MSAA writeback sources from whichever side the atomic points
629+
// at after reset, not necessarily the side we just wrote to. copy the current main (including
630+
// our pixel write, since queued writes are applied before this submit) into the other side so
631+
// the writeback propagates the updated content regardless of which direction the ping-pong
632+
// lands in.
633+
//
634+
// TODO: in theory bevy could just re-use the atomic to track which side is the latest main
635+
// texture and avoid this copy, unclear if that would cause other problems, but should be
636+
// considered for upstream if this ever matters for performance
637+
if view_target.sampled_main_texture().is_some() {
638+
let other = view_target.main_texture_other();
639+
let mut encoder =
640+
render_device.create_command_encoder(&CommandEncoderDescriptor::default());
641+
encoder.copy_texture_to_texture(main.as_image_copy(), other.as_image_copy(), graphics.size);
642+
render_queue.submit(std::iter::once(encoder.finish()));
643+
}
644+
625645
Ok(())
626646
}
627647

0 commit comments

Comments
 (0)