@@ -21,7 +21,7 @@ use crate::{
2121 ArcCommand , ArcPassTimestampWrites , BasePass , BindGroupStateChange , CommandEncoder ,
2222 CommandEncoderError , DebugGroupError , EncoderStateError , InnerCommandEncoder , MapPassErr ,
2323 PassErrorScope , PassStateError , PassTimestampWrites , QueryUseError , StateChange ,
24- TimestampWritesError ,
24+ TimestampWritesError , TransitionResourcesError ,
2525 } ,
2626 device:: { Device , DeviceError , MissingDownlevelFlags , MissingFeatures } ,
2727 global:: Global ,
@@ -30,9 +30,9 @@ use crate::{
3030 pipeline:: ComputePipeline ,
3131 resource:: {
3232 self , Buffer , DestroyedResourceError , InvalidResourceError , Labeled ,
33- MissingBufferUsageError , ParentDevice , RawResourceAccess , Trackable ,
33+ MissingBufferUsageError , ParentDevice , RawResourceAccess , TextureView , Trackable ,
3434 } ,
35- track:: { ResourceUsageCompatibilityError , Tracker } ,
35+ track:: { ResourceUsageCompatibilityError , TextureViewBindGroupState , Tracker } ,
3636 Label ,
3737} ;
3838
@@ -179,6 +179,8 @@ pub enum ComputePassErrorInner {
179179 #[ error( transparent) ]
180180 QueryUse ( #[ from] QueryUseError ) ,
181181 #[ error( transparent) ]
182+ TransitionResources ( #[ from] TransitionResourcesError ) ,
183+ #[ error( transparent) ]
182184 MissingFeatures ( #[ from] MissingFeatures ) ,
183185 #[ error( transparent) ]
184186 MissingDownlevelFlags ( #[ from] MissingDownlevelFlags ) ,
@@ -235,6 +237,7 @@ impl WebGpuError for ComputePassError {
235237 ComputePassErrorInner :: Bind ( e) => e. webgpu_error_type ( ) ,
236238 ComputePassErrorInner :: ImmediateData ( e) => e. webgpu_error_type ( ) ,
237239 ComputePassErrorInner :: QueryUse ( e) => e. webgpu_error_type ( ) ,
240+ ComputePassErrorInner :: TransitionResources ( e) => e. webgpu_error_type ( ) ,
238241 ComputePassErrorInner :: MissingFeatures ( e) => e. webgpu_error_type ( ) ,
239242 ComputePassErrorInner :: MissingDownlevelFlags ( e) => e. webgpu_error_type ( ) ,
240243 ComputePassErrorInner :: InvalidResource ( e) => e. webgpu_error_type ( ) ,
@@ -368,6 +371,70 @@ impl<'scope, 'snatch_guard, 'cmd_enc> State<'scope, 'snatch_guard, 'cmd_enc> {
368371 }
369372}
370373
374+ /// Compute pass version of [`command::transition_resources`](crate::command::transition_resources).
375+ /// See also `State::flush_bindings` for details on the implementation.
376+ fn transition_resources (
377+ state : & mut State ,
378+ buffer_transitions : Vec < wgt:: BufferTransition < Arc < Buffer > > > ,
379+ texture_transitions : Vec < wgt:: TextureTransition < Arc < TextureView > > > ,
380+ ) -> Result < ( ) , TransitionResourcesError > {
381+ let indices = & state. pass . base . device . tracker_indices ;
382+ state. pass . scope . buffers . set_size ( indices. buffers . size ( ) ) ;
383+ state. pass . scope . textures . set_size ( indices. textures . size ( ) ) ;
384+
385+ let mut buffer_ids = Vec :: with_capacity ( buffer_transitions. len ( ) ) ;
386+ let mut textures = TextureViewBindGroupState :: new ( ) ;
387+
388+ // Process buffer transitions
389+ for buffer_transition in buffer_transitions {
390+ buffer_transition
391+ . buffer
392+ . same_device ( state. pass . base . device ) ?;
393+
394+ state
395+ . pass
396+ . scope
397+ . buffers
398+ . merge_single ( & buffer_transition. buffer , buffer_transition. state ) ?;
399+ buffer_ids. push ( buffer_transition. buffer . tracker_index ( ) ) ;
400+ }
401+
402+ state
403+ . intermediate_trackers
404+ . buffers
405+ . set_and_remove_from_usage_scope_sparse ( & mut state. pass . scope . buffers , buffer_ids) ;
406+
407+ // Process texture transitions
408+ for texture_transition in texture_transitions {
409+ texture_transition
410+ . texture
411+ . same_device ( state. pass . base . device ) ?;
412+
413+ unsafe {
414+ state. pass . scope . textures . merge_single (
415+ & texture_transition. texture . parent ,
416+ texture_transition. selector ,
417+ texture_transition. state ,
418+ )
419+ } ?;
420+
421+ textures. insert_single ( texture_transition. texture , texture_transition. state ) ;
422+ }
423+
424+ state
425+ . intermediate_trackers
426+ . textures
427+ . set_and_remove_from_usage_scope_sparse ( & mut state. pass . scope . textures , & textures) ;
428+
429+ // Record any needed barriers based on tracker data
430+ CommandEncoder :: drain_barriers (
431+ state. pass . base . raw_encoder ,
432+ & mut state. intermediate_trackers ,
433+ state. pass . base . snatch_guard ,
434+ ) ;
435+ Ok ( ( ) )
436+ }
437+
371438// Running the compute pass.
372439
373440impl Global {
@@ -729,6 +796,14 @@ pub(super) fn encode_compute_pass(
729796 end_pipeline_statistics_query ( state. pass . base . raw_encoder , & mut state. active_query )
730797 . map_pass_err ( scope) ?;
731798 }
799+ ArcComputeCommand :: TransitionResources {
800+ buffer_transitions,
801+ texture_transitions,
802+ } => {
803+ let scope = PassErrorScope :: TransitionResources ;
804+ transition_resources ( & mut state, buffer_transitions, texture_transitions)
805+ . map_pass_err ( scope) ?;
806+ }
732807 }
733808 }
734809
@@ -1316,4 +1391,49 @@ impl Global {
13161391
13171392 Ok ( ( ) )
13181393 }
1394+
1395+ pub fn compute_pass_transition_resources (
1396+ & self ,
1397+ pass : & mut ComputePass ,
1398+ buffer_transitions : impl Iterator < Item = wgt:: BufferTransition < id:: BufferId > > ,
1399+ texture_transitions : impl Iterator < Item = wgt:: TextureTransition < id:: TextureViewId > > ,
1400+ ) -> Result < ( ) , PassStateError > {
1401+ let scope = PassErrorScope :: TransitionResources ;
1402+ let base = pass_base ! ( pass, scope) ;
1403+
1404+ let hub = & self . hub ;
1405+ let buffer_transitions = pass_try ! (
1406+ base,
1407+ scope,
1408+ buffer_transitions
1409+ . map( |buffer_transition| -> Result <_, InvalidResourceError > {
1410+ Ok ( wgt:: BufferTransition {
1411+ buffer: hub. buffers. get( buffer_transition. buffer) . get( ) ?,
1412+ state: buffer_transition. state,
1413+ } )
1414+ } )
1415+ . collect:: <Result <Vec <_>, _>>( )
1416+ ) ;
1417+
1418+ let texture_transitions = pass_try ! (
1419+ base,
1420+ scope,
1421+ texture_transitions
1422+ . map( |texture_transition| -> Result <_, InvalidResourceError > {
1423+ Ok ( wgt:: TextureTransition {
1424+ texture: hub. texture_views. get( texture_transition. texture) . get( ) ?,
1425+ selector: texture_transition. selector,
1426+ state: texture_transition. state,
1427+ } )
1428+ } )
1429+ . collect:: <Result <Vec <_>, _>>( )
1430+ ) ;
1431+
1432+ base. commands . push ( ArcComputeCommand :: TransitionResources {
1433+ buffer_transitions,
1434+ texture_transitions,
1435+ } ) ;
1436+
1437+ Ok ( ( ) )
1438+ }
13191439}
0 commit comments