1
+ use hashbrown:: HashSet ;
1
2
use objc2:: {
2
3
rc:: { autoreleasepool, Retained } ,
3
4
runtime:: ProtocolObject ,
@@ -7,8 +8,8 @@ use objc2_metal::{
7
8
MTLAccelerationStructureCommandEncoder , MTLBlitCommandEncoder , MTLBlitPassDescriptor ,
8
9
MTLCommandBuffer , MTLCommandEncoder , MTLCommandQueue , MTLComputeCommandEncoder ,
9
10
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 ,
12
13
} ;
13
14
14
15
use super :: { conv, TimestampQuerySupport } ;
@@ -37,6 +38,7 @@ impl Default for super::CommandState {
37
38
height : 0 ,
38
39
} ,
39
40
stage_infos : Default :: default ( ) ,
41
+ residency_sets : Default :: default ( ) ,
40
42
storage_buffer_length_map : Default :: default ( ) ,
41
43
vertex_buffer_size_map : Default :: default ( ) ,
42
44
work_group_memory_sizes : Vec :: new ( ) ,
@@ -284,8 +286,11 @@ impl crate::CommandEncoder for super::CommandEncoder {
284
286
debug_assert ! ( self . state. compute. is_none( ) ) ;
285
287
debug_assert ! ( self . state. pending_timer_queries. is_empty( ) ) ;
286
288
289
+ let mut residency_sets = HashSet :: new ( ) ;
290
+ core:: mem:: swap ( & mut residency_sets, & mut self . state . residency_sets ) ;
287
291
Ok ( super :: CommandBuffer {
288
292
raw : self . raw_cmd_buf . take ( ) . unwrap ( ) ,
293
+ residency_sets,
289
294
} )
290
295
}
291
296
@@ -455,6 +460,16 @@ impl crate::CommandEncoder for super::CommandEncoder {
455
460
dst : & super :: AccelerationStructure ,
456
461
copy : wgt:: AccelerationStructureCopy ,
457
462
) {
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
+ }
458
473
let command_encoder = self . enter_acceleration_structure_builder ( ) ;
459
474
match copy {
460
475
wgt:: AccelerationStructureCopy :: Clone => {
@@ -773,11 +788,12 @@ impl crate::CommandEncoder for super::CommandEncoder {
773
788
changes_sizes_buffer = true ;
774
789
}
775
790
}
776
- super :: BufferLikeResource :: AccelerationStructure ( ptr) => {
791
+ super :: BufferLikeResource :: AccelerationStructure ( ptr, residency_set ) => {
777
792
encoder. setVertexAccelerationStructure_atBufferIndex (
778
793
Some ( ptr. as_ref ( ) ) ,
779
794
( bg_info. base_resource_indices . vs . buffers + index) as usize ,
780
795
) ;
796
+ residency_set. as_ref ( ) . requestResidency ( ) ;
781
797
}
782
798
}
783
799
}
@@ -822,11 +838,12 @@ impl crate::CommandEncoder for super::CommandEncoder {
822
838
changes_sizes_buffer = true ;
823
839
}
824
840
}
825
- super :: BufferLikeResource :: AccelerationStructure ( ptr) => {
841
+ super :: BufferLikeResource :: AccelerationStructure ( ptr, residency_set ) => {
826
842
encoder. setFragmentAccelerationStructure_atBufferIndex (
827
843
Some ( ptr. as_ref ( ) ) ,
828
844
( bg_info. base_resource_indices . fs . buffers + index) as usize ,
829
845
) ;
846
+ residency_set. as_ref ( ) . requestResidency ( ) ;
830
847
}
831
848
}
832
849
}
@@ -914,11 +931,12 @@ impl crate::CommandEncoder for super::CommandEncoder {
914
931
changes_sizes_buffer = true ;
915
932
}
916
933
}
917
- super :: BufferLikeResource :: AccelerationStructure ( ptr) => {
934
+ super :: BufferLikeResource :: AccelerationStructure ( ptr, residency_set ) => {
918
935
encoder. setAccelerationStructure_atBufferIndex (
919
936
Some ( ptr. as_ref ( ) ) ,
920
937
( bg_info. base_resource_indices . cs . buffers + index) as usize ,
921
938
) ;
939
+ residency_set. as_ref ( ) . requestResidency ( ) ;
922
940
}
923
941
}
924
942
}
@@ -1479,6 +1497,25 @@ impl crate::CommandEncoder for super::CommandEncoder {
1479
1497
for descriptor in descriptors {
1480
1498
let acceleration_structure_descriptor =
1481
1499
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
+ }
1482
1519
match descriptor. mode {
1483
1520
crate :: AccelerationStructureBuildMode :: Build => {
1484
1521
command_encoder
0 commit comments