1+ use hashbrown:: HashSet ;
12use objc2:: {
23 rc:: { autoreleasepool, Retained } ,
34 runtime:: ProtocolObject ,
@@ -7,8 +8,8 @@ use objc2_metal::{
78 MTLAccelerationStructureCommandEncoder , MTLBlitCommandEncoder , MTLBlitPassDescriptor ,
89 MTLCommandBuffer , MTLCommandEncoder , MTLCommandQueue , MTLComputeCommandEncoder ,
910 MTLComputePassDescriptor , MTLCounterDontSample , MTLLoadAction , MTLPrimitiveType ,
10- MTLRenderCommandEncoder , MTLRenderPassDescriptor , MTLScissorRect , MTLSize , MTLStoreAction ,
11- MTLTexture , MTLViewport , MTLVisibilityResultMode ,
11+ MTLRenderCommandEncoder , MTLRenderPassDescriptor , MTLResidencySet , MTLScissorRect , MTLSize ,
12+ MTLStoreAction , MTLTexture , MTLViewport , MTLVisibilityResultMode ,
1213} ;
1314
1415use super :: { conv, TimestampQuerySupport } ;
@@ -37,6 +38,7 @@ impl Default for super::CommandState {
3738 height : 0 ,
3839 } ,
3940 stage_infos : Default :: default ( ) ,
41+ residency_sets : Default :: default ( ) ,
4042 storage_buffer_length_map : Default :: default ( ) ,
4143 vertex_buffer_size_map : Default :: default ( ) ,
4244 work_group_memory_sizes : Vec :: new ( ) ,
@@ -284,8 +286,11 @@ impl crate::CommandEncoder for super::CommandEncoder {
284286 debug_assert ! ( self . state. compute. is_none( ) ) ;
285287 debug_assert ! ( self . state. pending_timer_queries. is_empty( ) ) ;
286288
289+ let mut residency_sets = HashSet :: new ( ) ;
290+ core:: mem:: swap ( & mut residency_sets, & mut self . state . residency_sets ) ;
287291 Ok ( super :: CommandBuffer {
288292 raw : self . raw_cmd_buf . take ( ) . unwrap ( ) ,
293+ residency_sets,
289294 } )
290295 }
291296
@@ -455,6 +460,14 @@ impl crate::CommandEncoder for super::CommandEncoder {
455460 dst : & super :: AccelerationStructure ,
456461 copy : wgt:: AccelerationStructureCopy ,
457462 ) {
463+ self . state . residency_sets . insert ( dst. residency_set . clone ( ) ) ;
464+ dst. residency_set . requestResidency ( ) ;
465+ dst. residency_set . removeAllAllocations ( ) ;
466+ let allocations = src. residency_set . allAllocations ( ) ;
467+ for index in 0 ..allocations. count ( ) {
468+ dst. residency_set
469+ . addAllocation ( & allocations. objectAtIndex ( index) ) ;
470+ }
458471 let command_encoder = self . enter_acceleration_structure_builder ( ) ;
459472 match copy {
460473 wgt:: AccelerationStructureCopy :: Clone => {
@@ -1479,6 +1492,31 @@ impl crate::CommandEncoder for super::CommandEncoder {
14791492 for descriptor in descriptors {
14801493 let acceleration_structure_descriptor =
14811494 conv:: map_acceleration_structure_descriptor ( descriptor. entries , descriptor. flags ) ;
1495+ if matches ! (
1496+ descriptor. entries,
1497+ crate :: AccelerationStructureEntries :: Instances ( _)
1498+ ) {
1499+ self . state . residency_sets . insert (
1500+ descriptor
1501+ . destination_acceleration_structure
1502+ . residency_set
1503+ . clone ( ) ,
1504+ ) ;
1505+ descriptor
1506+ . destination_acceleration_structure
1507+ . residency_set
1508+ . requestResidency ( ) ;
1509+ descriptor
1510+ . destination_acceleration_structure
1511+ . residency_set
1512+ . removeAllAllocations ( ) ;
1513+ for dependency in descriptor. dependencies . iter ( ) {
1514+ descriptor
1515+ . destination_acceleration_structure
1516+ . residency_set
1517+ . addAllocation ( dependency. raw . as_ref ( ) ) ;
1518+ }
1519+ }
14821520 match descriptor. mode {
14831521 crate :: AccelerationStructureBuildMode :: Build => {
14841522 command_encoder
0 commit comments