@@ -2432,9 +2432,23 @@ fn buffer_write_range(
24322432 data. len( )
24332433 ) ) ) ;
24342434 }
2435- ensure_buffer_synced ( app, entity) ?;
2435+ let write = ( handle, offset, data) ;
2436+ let on_gpu = app
2437+ . sub_app_mut ( bevy:: render:: RenderApp )
2438+ . world_mut ( )
2439+ . run_system_cached_with ( compute:: write_buffer_gpu, & write)
2440+ . unwrap ( ) ;
2441+ let synced = app
2442+ . world ( )
2443+ . get :: < compute:: Buffer > ( entity)
2444+ . ok_or ( error:: ProcessingError :: BufferNotFound ) ?
2445+ . synced ;
2446+ // next read will refresh
2447+ if on_gpu && !synced {
2448+ return Ok ( ( ) ) ;
2449+ }
24362450 app. world_mut ( )
2437- . run_system_cached_with ( compute:: write_buffer_cpu , ( handle , offset , data ) )
2451+ . run_system_cached_with ( compute:: write_buffer_asset , ( write , !on_gpu ) )
24382452 . unwrap ( )
24392453 } )
24402454}
@@ -2527,30 +2541,54 @@ pub fn compute_set(
25272541pub fn compute_dispatch ( entity : Entity , x : u32 , y : u32 , z : u32 ) -> error:: Result < ( ) > {
25282542 app_mut ( |app| {
25292543 app. update ( ) ;
2544+ dispatch_inner ( app, entity, x, y, z)
2545+ } )
2546+ }
25302547
2531- let args = {
2532- let world = app. world ( ) ;
2533- let c = world
2534- . get :: < compute:: Compute > ( entity)
2535- . ok_or ( error:: ProcessingError :: ComputeNotFound ) ?;
2536- let mesh_bindings = compute:: resolve_mesh_bindings ( world, c) ?;
2537- (
2538- c. pipeline_id ,
2539- c. bind_group_layout_descriptors . clone ( ) ,
2540- c. shader . clone ( ) ,
2541- mesh_bindings,
2542- x,
2543- y,
2544- z,
2545- )
2546- } ;
2547- app. sub_app_mut ( bevy:: render:: RenderApp )
2548- . world_mut ( )
2549- . run_system_cached_with ( compute:: dispatch, args)
2550- . unwrap ( )
2548+ /// Dispatch without an `app.update()` first; only updates if the pipeline isn't compiled yet.
2549+ pub ( crate ) fn compute_dispatch_no_update (
2550+ entity : Entity ,
2551+ x : u32 ,
2552+ y : u32 ,
2553+ z : u32 ,
2554+ ) -> error:: Result < ( ) > {
2555+ app_mut ( |app| match dispatch_inner ( app, entity, x, y, z) {
2556+ Err ( error:: ProcessingError :: PipelineNotReady ( _) ) => {
2557+ app. update ( ) ;
2558+ dispatch_inner ( app, entity, x, y, z)
2559+ }
2560+ r => r,
25512561 } )
25522562}
25532563
2564+ fn dispatch_inner ( app : & mut App , entity : Entity , x : u32 , y : u32 , z : u32 ) -> error:: Result < ( ) > {
2565+ let args = {
2566+ let world = app. world ( ) ;
2567+ let c = world
2568+ . get :: < compute:: Compute > ( entity)
2569+ . ok_or ( error:: ProcessingError :: ComputeNotFound ) ?;
2570+ let mesh_bindings = compute:: resolve_mesh_bindings ( world, c) ?;
2571+ (
2572+ c. pipeline_id ,
2573+ c. bind_group_layout_descriptors . clone ( ) ,
2574+ c. shader . clone ( ) ,
2575+ mesh_bindings,
2576+ x,
2577+ y,
2578+ z,
2579+ )
2580+ } ;
2581+ app. sub_app_mut ( bevy:: render:: RenderApp )
2582+ . world_mut ( )
2583+ . run_system_cached_with ( compute:: dispatch, args)
2584+ . unwrap ( ) ?;
2585+ // The kernel may have written its read-write buffers, so their assets are no longer synced.
2586+ app. world_mut ( )
2587+ . run_system_cached ( compute:: invalidate_rw_buffers)
2588+ . unwrap ( ) ;
2589+ Ok ( ( ) )
2590+ }
2591+
25542592pub fn compute_destroy ( entity : Entity ) -> error:: Result < ( ) > {
25552593 app_mut ( |app| {
25562594 app. world_mut ( )
0 commit comments