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,16 @@ impl crate::CommandEncoder for super::CommandEncoder {
455460 dst : & super :: AccelerationStructure ,
456461 copy : wgt:: AccelerationStructureCopy ,
457462 ) {
463+ // Store a reference of the residency_set in the encoder state to be committed later
464+ self . state
465+ . residency_sets
466+ . insert ( Retained :: clone ( & dst. residency_set ) ) ;
467+ dst. residency_set . removeAllAllocations ( ) ;
468+ let allocations = src. residency_set . allAllocations ( ) ;
469+ for index in 0 ..allocations. count ( ) {
470+ dst. residency_set
471+ . addAllocation ( & allocations. objectAtIndex ( index) ) ;
472+ }
458473 let command_encoder = self . enter_acceleration_structure_builder ( ) ;
459474 match copy {
460475 wgt:: AccelerationStructureCopy :: Clone => {
@@ -773,11 +788,12 @@ impl crate::CommandEncoder for super::CommandEncoder {
773788 changes_sizes_buffer = true ;
774789 }
775790 }
776- super :: BufferLikeResource :: AccelerationStructure ( ptr) => {
791+ super :: BufferLikeResource :: AccelerationStructure ( ptr, residency_set ) => {
777792 encoder. setVertexAccelerationStructure_atBufferIndex (
778793 Some ( ptr. as_ref ( ) ) ,
779794 ( bg_info. base_resource_indices . vs . buffers + index) as usize ,
780795 ) ;
796+ residency_set. as_ref ( ) . requestResidency ( ) ;
781797 }
782798 }
783799 }
@@ -822,11 +838,12 @@ impl crate::CommandEncoder for super::CommandEncoder {
822838 changes_sizes_buffer = true ;
823839 }
824840 }
825- super :: BufferLikeResource :: AccelerationStructure ( ptr) => {
841+ super :: BufferLikeResource :: AccelerationStructure ( ptr, residency_set ) => {
826842 encoder. setFragmentAccelerationStructure_atBufferIndex (
827843 Some ( ptr. as_ref ( ) ) ,
828844 ( bg_info. base_resource_indices . fs . buffers + index) as usize ,
829845 ) ;
846+ residency_set. as_ref ( ) . requestResidency ( ) ;
830847 }
831848 }
832849 }
@@ -914,11 +931,12 @@ impl crate::CommandEncoder for super::CommandEncoder {
914931 changes_sizes_buffer = true ;
915932 }
916933 }
917- super :: BufferLikeResource :: AccelerationStructure ( ptr) => {
934+ super :: BufferLikeResource :: AccelerationStructure ( ptr, residency_set ) => {
918935 encoder. setAccelerationStructure_atBufferIndex (
919936 Some ( ptr. as_ref ( ) ) ,
920937 ( bg_info. base_resource_indices . cs . buffers + index) as usize ,
921938 ) ;
939+ residency_set. as_ref ( ) . requestResidency ( ) ;
922940 }
923941 }
924942 }
@@ -1479,6 +1497,25 @@ impl crate::CommandEncoder for super::CommandEncoder {
14791497 for descriptor in descriptors {
14801498 let acceleration_structure_descriptor =
14811499 conv:: map_acceleration_structure_descriptor ( descriptor. entries , descriptor. flags ) ;
1500+ if matches ! (
1501+ descriptor. entries,
1502+ crate :: AccelerationStructureEntries :: Instances ( _)
1503+ ) {
1504+ // Store a reference of the residency_set in the encoder state to be committed later
1505+ self . state . residency_sets . insert ( Retained :: clone (
1506+ & descriptor. destination_acceleration_structure . residency_set ,
1507+ ) ) ;
1508+ descriptor
1509+ . destination_acceleration_structure
1510+ . residency_set
1511+ . removeAllAllocations ( ) ;
1512+ for dependency in descriptor. dependencies . iter ( ) {
1513+ descriptor
1514+ . destination_acceleration_structure
1515+ . residency_set
1516+ . addAllocation ( dependency. raw . as_ref ( ) ) ;
1517+ }
1518+ }
14821519 match descriptor. mode {
14831520 crate :: AccelerationStructureBuildMode :: Build => {
14841521 command_encoder
0 commit comments