11#![ deny( clippy:: unimplemented, clippy:: unwrap_used, clippy:: ok_expect) ]
22
3- use std:: { fmt, mem :: ManuallyDrop } ;
3+ use std:: fmt;
44
5- use log:: { debug, Level } ;
5+ use log:: { debug, warn , Level } ;
66
77use windows:: Win32 :: { Foundation :: E_OUTOFMEMORY , Graphics :: Direct3D12 :: * } ;
88
@@ -233,18 +233,6 @@ pub struct AllocatorCreateDesc {
233233 pub debug_settings : AllocatorDebugSettings ,
234234}
235235
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-
248236pub enum ResourceType < ' a > {
249237 /// Allocation equivalent to Dx12's CommittedResource.
250238 Committed {
@@ -257,19 +245,46 @@ pub enum ResourceType<'a> {
257245
258246#[ derive( Debug ) ]
259247pub struct Resource {
248+ name : String ,
260249 pub allocation : Option < Allocation > ,
261- pub resource : ManuallyDrop < ID3D12Resource > ,
250+ resource : Option < ID3D12Resource > ,
262251 pub memory_location : MemoryLocation ,
263252 memory_type_index : Option < usize > ,
264253 pub size : u64 ,
265254}
266255
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+
267270#[ derive( Debug ) ]
268271pub struct CommittedAllocationStatistics {
269272 pub num_allocations : usize ,
270273 pub total_size : u64 ,
271274}
272275
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+
273288impl Allocation {
274289 pub fn chunk_id ( & self ) -> Option < std:: num:: NonZeroU64 > {
275290 self . chunk_id
@@ -813,8 +828,9 @@ impl Allocator {
813828 memory_type. committed_allocations . total_size += allocation_info. SizeInBytes ;
814829
815830 Ok ( Resource {
831+ name : desc. name . into ( ) ,
816832 allocation : None ,
817- resource : ManuallyDrop :: new ( resource) ,
833+ resource : Some ( resource) ,
818834 size : allocation_info. SizeInBytes ,
819835 memory_location : desc. memory_location ,
820836 memory_type_index : Some ( memory_type. memory_type_index ) ,
@@ -856,8 +872,9 @@ impl Allocator {
856872 result. expect ( "Allocation succeeded but no resource was returned?" ) ;
857873 let size = allocation. size ( ) ;
858874 Ok ( Resource {
875+ name : desc. name . into ( ) ,
859876 allocation : Some ( allocation) ,
860- resource : ManuallyDrop :: new ( resource) ,
877+ resource : Some ( resource) ,
861878 size,
862879 memory_location : desc. memory_location ,
863880 memory_type_index : None ,
@@ -868,13 +885,19 @@ impl Allocator {
868885 }
869886
870887 /// 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 ( ) {
874897 self . free ( allocation)
875898 } 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 .
878901 if let Some ( memory_type_index) = resource. memory_type_index {
879902 let memory_type = & mut self . memory_types [ memory_type_index] ;
880903
0 commit comments