@@ -25,6 +25,14 @@ use crate::material::custom::{Shader, apply_reflect_field, shader_value_to_refle
2525use crate :: shader_value:: ShaderValue ;
2626use processing_core:: error:: { ProcessingError , Result } ;
2727
28+ pub struct ComputePlugin ;
29+
30+ impl Plugin for ComputePlugin {
31+ fn build ( & self , app : & mut App ) {
32+ app. add_systems ( Last , invalidate_rw_buffers) ;
33+ }
34+ }
35+
2836#[ derive( Component ) ]
2937pub struct Buffer {
3038 pub handle : Handle < ShaderBuffer > ,
@@ -34,6 +42,10 @@ pub struct Buffer {
3442 /// when a pipeline that may write to the buffer runs; the next read or
3543 /// write must readback first.
3644 pub synced : bool ,
45+ /// Set permanently once the buffer is bound to any pipeline as read_write
46+ /// storage. When true, any frame tick could have mutated GPU contents via
47+ /// a render pass, so `synced` must be cleared after each `app.update()`.
48+ pub bound_rw : bool ,
3749}
3850
3951fn readback_buffer ( device : & RenderDevice , size : u64 ) -> WgpuBuffer {
@@ -61,6 +73,7 @@ pub fn create_buffer(
6173 readback_buffer : readback_buffer ( & render_device, size) ,
6274 size,
6375 synced : true ,
76+ bound_rw : false ,
6477 } )
6578 . id ( )
6679}
@@ -79,6 +92,7 @@ pub fn create_buffer_with_data(
7992 readback_buffer : readback_buffer ( & render_device, size) ,
8093 size,
8194 synced : true ,
95+ bound_rw : false ,
8296 } )
8397 . id ( )
8498}
@@ -139,6 +153,14 @@ pub fn read_buffer_gpu(
139153 Ok ( bytes)
140154}
141155
156+ pub fn invalidate_rw_buffers ( mut buffers : Query < & mut Buffer > ) {
157+ for mut buf in & mut buffers {
158+ if buf. bound_rw {
159+ buf. synced = false ;
160+ }
161+ }
162+ }
163+
142164pub fn destroy_buffer ( In ( entity) : In < Entity > , mut commands : Commands ) -> Result < ( ) > {
143165 commands. entity ( entity) . despawn ( ) ;
144166 Ok ( ( ) )
@@ -267,7 +289,7 @@ pub fn create_compute(app: &mut App, shader_entity: Entity) -> Result<Entity> {
267289pub fn set_compute_property (
268290 In ( ( entity, name, value) ) : In < ( Entity , String , ShaderValue ) > ,
269291 mut computes : Query < & mut Compute > ,
270- p_buffers : Query < & Buffer > ,
292+ mut p_buffers : Query < & mut Buffer > ,
271293 p_images : Query < & PImage > ,
272294) -> Result < ( ) > {
273295 use bevy_naga_reflect:: reflect:: ParameterCategory ;
@@ -285,14 +307,15 @@ pub fn set_compute_property(
285307
286308 match ( & value, category) {
287309 ( ShaderValue :: Buffer ( buf_entity) , ParameterCategory :: Storage { read_only } ) => {
288- let buffer = p_buffers
289- . get ( * buf_entity)
310+ let mut buffer = p_buffers
311+ . get_mut ( * buf_entity)
290312 . map_err ( |_| ProcessingError :: BufferNotFound ) ?;
291313 compute. shader . insert ( & name, buffer. handle . clone ( ) ) ;
292314 if read_only {
293315 compute. rw_buffers . remove ( & name) ;
294316 } else {
295317 compute. rw_buffers . insert ( name. clone ( ) , * buf_entity) ;
318+ buffer. bound_rw = true ;
296319 }
297320 Ok ( ( ) )
298321 }
0 commit comments