1
1
#![ deny( clippy:: unimplemented, clippy:: unwrap_used, clippy:: ok_expect) ]
2
2
3
- use std:: { fmt, mem :: ManuallyDrop } ;
3
+ use std:: fmt;
4
4
5
- use log:: { debug, Level } ;
5
+ use log:: { debug, warn , Level } ;
6
6
7
7
use windows:: Win32 :: { Foundation :: E_OUTOFMEMORY , Graphics :: Direct3D12 :: * } ;
8
8
@@ -233,18 +233,6 @@ pub struct AllocatorCreateDesc {
233
233
pub debug_settings : AllocatorDebugSettings ,
234
234
}
235
235
236
- #[ derive( Debug ) ]
237
- pub struct Allocation {
238
- chunk_id : Option < std:: num:: NonZeroU64 > ,
239
- offset : u64 ,
240
- size : u64 ,
241
- memory_block_index : usize ,
242
- memory_type_index : usize ,
243
- heap : ID3D12Heap ,
244
-
245
- name : Option < Box < str > > ,
246
- }
247
-
248
236
pub enum ResourceType < ' a > {
249
237
/// Allocation equivalent to Dx12's CommittedResource.
250
238
Committed {
@@ -257,19 +245,46 @@ pub enum ResourceType<'a> {
257
245
258
246
#[ derive( Debug ) ]
259
247
pub struct Resource {
248
+ name : String ,
260
249
pub allocation : Option < Allocation > ,
261
- pub resource : ManuallyDrop < ID3D12Resource > ,
250
+ resource : Option < ID3D12Resource > ,
262
251
pub memory_location : MemoryLocation ,
263
252
memory_type_index : Option < usize > ,
264
253
pub size : u64 ,
265
254
}
266
255
256
+ impl Resource {
257
+ pub fn resource ( & self ) -> & ID3D12Resource {
258
+ self . resource . as_ref ( ) . expect ( "Resource was already freed." )
259
+ }
260
+ }
261
+
262
+ impl Drop for Resource {
263
+ fn drop ( & mut self ) {
264
+ if self . resource . is_some ( ) {
265
+ warn ! ( "Dropping resource `{}` that was not freed. Call `Allocator::free_resource(resource)` instead." , self . name) ;
266
+ }
267
+ }
268
+ }
269
+
267
270
#[ derive( Debug ) ]
268
271
pub struct CommittedAllocationStatistics {
269
272
pub num_allocations : usize ,
270
273
pub total_size : u64 ,
271
274
}
272
275
276
+ #[ derive( Debug ) ]
277
+ pub struct Allocation {
278
+ chunk_id : Option < std:: num:: NonZeroU64 > ,
279
+ offset : u64 ,
280
+ size : u64 ,
281
+ memory_block_index : usize ,
282
+ memory_type_index : usize ,
283
+ heap : ID3D12Heap ,
284
+
285
+ name : Option < Box < str > > ,
286
+ }
287
+
273
288
impl Allocation {
274
289
pub fn chunk_id ( & self ) -> Option < std:: num:: NonZeroU64 > {
275
290
self . chunk_id
@@ -813,8 +828,9 @@ impl Allocator {
813
828
memory_type. committed_allocations . total_size += allocation_info. SizeInBytes ;
814
829
815
830
Ok ( Resource {
831
+ name : desc. name . into ( ) ,
816
832
allocation : None ,
817
- resource : ManuallyDrop :: new ( resource) ,
833
+ resource : Some ( resource) ,
818
834
size : allocation_info. SizeInBytes ,
819
835
memory_location : desc. memory_location ,
820
836
memory_type_index : Some ( memory_type. memory_type_index ) ,
@@ -856,8 +872,9 @@ impl Allocator {
856
872
result. expect ( "Allocation succeeded but no resource was returned?" ) ;
857
873
let size = allocation. size ( ) ;
858
874
Ok ( Resource {
875
+ name : desc. name . into ( ) ,
859
876
allocation : Some ( allocation) ,
860
- resource : ManuallyDrop :: new ( resource) ,
877
+ resource : Some ( resource) ,
861
878
size,
862
879
memory_location : desc. memory_location ,
863
880
memory_type_index : None ,
@@ -868,13 +885,19 @@ impl Allocator {
868
885
}
869
886
870
887
/// Free a resource and its memory.
871
- pub fn free_resource ( & mut self , resource : Resource ) -> Result < ( ) > {
872
- let _ = ManuallyDrop :: into_inner ( resource. resource ) ;
873
- if let Some ( allocation) = resource. allocation {
888
+ pub fn free_resource ( & mut self , mut resource : Resource ) -> Result < ( ) > {
889
+ // Explicitly drop the resource (which is backed by a refcounted COM object)
890
+ // before freeing allocated memory. Windows-rs performs a Release() on drop().
891
+ let _ = resource
892
+ . resource
893
+ . take ( )
894
+ . expect ( "Resource was already freed." ) ;
895
+
896
+ if let Some ( allocation) = resource. allocation . take ( ) {
874
897
self . free ( allocation)
875
898
} else {
876
- // Committed resources are implicitly dropped when their refcount reaches 0 .
877
- // We only have to change the allocation and size tracking .
899
+ // Dx12 CommittedResources do not have an application managed allocation .
900
+ // We only have to update the tracked allocation count and memory usage .
878
901
if let Some ( memory_type_index) = resource. memory_type_index {
879
902
let memory_type = & mut self . memory_types [ memory_type_index] ;
880
903
0 commit comments