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,14 @@ impl crate::CommandEncoder for super::CommandEncoder {
455
460
dst : & super :: AccelerationStructure ,
456
461
copy : wgt:: AccelerationStructureCopy ,
457
462
) {
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
+ }
458
471
let command_encoder = self . enter_acceleration_structure_builder ( ) ;
459
472
match copy {
460
473
wgt:: AccelerationStructureCopy :: Clone => {
@@ -1479,6 +1492,31 @@ impl crate::CommandEncoder for super::CommandEncoder {
1479
1492
for descriptor in descriptors {
1480
1493
let acceleration_structure_descriptor =
1481
1494
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
+ }
1482
1520
match descriptor. mode {
1483
1521
crate :: AccelerationStructureBuildMode :: Build => {
1484
1522
command_encoder
0 commit comments