1
1
use crate :: error;
2
- use crate :: error:: assume_d3d12_init;
2
+ use gpu_allocator:: d3d12:: {
3
+ Allocator , Resource , ResourceCategory , ResourceCreateDesc , ResourceStateOrBarrierLayout ,
4
+ ResourceType ,
5
+ } ;
6
+ use gpu_allocator:: MemoryLocation ;
7
+ use parking_lot:: Mutex ;
3
8
use std:: ffi:: c_void;
4
9
use std:: mem:: ManuallyDrop ;
5
10
use std:: ops:: { Deref , DerefMut , Range } ;
6
11
use std:: ptr:: NonNull ;
12
+ use std:: sync:: Arc ;
7
13
use windows:: Win32 :: Graphics :: Direct3D12 :: {
8
- ID3D12Device , ID3D12GraphicsCommandList , ID3D12Resource , D3D12_CPU_PAGE_PROPERTY_UNKNOWN ,
9
- D3D12_HEAP_FLAG_NONE , D3D12_HEAP_PROPERTIES , D3D12_HEAP_TYPE_UPLOAD , D3D12_MEMORY_POOL_UNKNOWN ,
10
- D3D12_RANGE , D3D12_RESOURCE_DESC , D3D12_RESOURCE_DIMENSION_BUFFER ,
11
- D3D12_RESOURCE_STATE_GENERIC_READ , D3D12_TEXTURE_LAYOUT_ROW_MAJOR ,
14
+ ID3D12GraphicsCommandList , ID3D12Resource , D3D12_RANGE , D3D12_RESOURCE_DESC ,
15
+ D3D12_RESOURCE_DIMENSION_BUFFER , D3D12_RESOURCE_STATE_GENERIC_READ ,
16
+ D3D12_TEXTURE_LAYOUT_ROW_MAJOR ,
12
17
} ;
13
18
use windows:: Win32 :: Graphics :: Dxgi :: Common :: DXGI_SAMPLE_DESC ;
14
19
15
20
pub struct D3D12Buffer {
16
- handle : ID3D12Resource ,
21
+ resource : ManuallyDrop < Resource > ,
22
+ allocator : Arc < Mutex < Allocator > > ,
17
23
size : usize ,
18
24
}
19
25
@@ -28,51 +34,51 @@ impl<'a> Drop for D3D12BufferMapHandle<'a> {
28
34
}
29
35
}
30
36
37
+ impl Drop for D3D12Buffer {
38
+ fn drop ( & mut self ) {
39
+ let resource = unsafe { ManuallyDrop :: take ( & mut self . resource ) } ;
40
+ if let Err ( e) = self . allocator . lock ( ) . free_resource ( resource) {
41
+ println ! ( "librashader-runtime-d3d12: [warn] failed to deallocate buffer memory {e}" )
42
+ }
43
+ }
44
+ }
45
+
31
46
impl D3D12Buffer {
32
- pub fn new ( device : & ID3D12Device , size : usize ) -> error:: Result < D3D12Buffer > {
33
- unsafe {
34
- let mut buffer: Option < ID3D12Resource > = None ;
35
- device. CreateCommittedResource (
36
- & D3D12_HEAP_PROPERTIES {
37
- Type : D3D12_HEAP_TYPE_UPLOAD ,
38
- CPUPageProperty : D3D12_CPU_PAGE_PROPERTY_UNKNOWN ,
39
- MemoryPoolPreference : D3D12_MEMORY_POOL_UNKNOWN ,
40
- ..Default :: default ( )
41
- } ,
42
- D3D12_HEAP_FLAG_NONE ,
43
- & D3D12_RESOURCE_DESC {
44
- Dimension : D3D12_RESOURCE_DIMENSION_BUFFER ,
45
- Width : size as u64 ,
46
- Height : 1 ,
47
- DepthOrArraySize : 1 ,
48
- MipLevels : 1 ,
49
- Layout : D3D12_TEXTURE_LAYOUT_ROW_MAJOR ,
50
- SampleDesc : DXGI_SAMPLE_DESC {
51
- Count : 1 ,
52
- Quality : 0 ,
53
- } ,
54
- ..Default :: default ( )
47
+ pub fn new ( allocator : & Arc < Mutex < Allocator > > , size : usize ) -> error:: Result < D3D12Buffer > {
48
+ let resource = allocator. lock ( ) . create_resource ( & ResourceCreateDesc {
49
+ name : "d3d12buffer" ,
50
+ memory_location : MemoryLocation :: CpuToGpu ,
51
+ resource_category : ResourceCategory :: Buffer ,
52
+ resource_desc : & D3D12_RESOURCE_DESC {
53
+ Dimension : D3D12_RESOURCE_DIMENSION_BUFFER ,
54
+ Width : size as u64 ,
55
+ Height : 1 ,
56
+ DepthOrArraySize : 1 ,
57
+ MipLevels : 1 ,
58
+ Layout : D3D12_TEXTURE_LAYOUT_ROW_MAJOR ,
59
+ SampleDesc : DXGI_SAMPLE_DESC {
60
+ Count : 1 ,
61
+ Quality : 0 ,
55
62
} ,
63
+ ..Default :: default ( )
64
+ } ,
65
+ castable_formats : & [ ] ,
66
+ clear_value : None ,
67
+ initial_state_or_layout : ResourceStateOrBarrierLayout :: ResourceState (
56
68
D3D12_RESOURCE_STATE_GENERIC_READ ,
57
- None ,
58
- & mut buffer,
59
- ) ?;
60
-
61
- assume_d3d12_init ! ( buffer, "CreateCommittedResource" ) ;
62
-
63
- Ok ( D3D12Buffer {
64
- handle : buffer,
65
- size,
66
- } )
67
- }
69
+ ) ,
70
+ resource_type : & ResourceType :: Placed ,
71
+ } ) ?;
72
+
73
+ Ok ( Self {
74
+ resource : ManuallyDrop :: new ( resource) ,
75
+ size,
76
+ allocator : Arc :: clone ( & allocator) ,
77
+ } )
68
78
}
69
79
70
80
pub fn gpu_address ( & self ) -> u64 {
71
- unsafe { self . handle . GetGPUVirtualAddress ( ) }
72
- }
73
-
74
- pub fn into_raw ( self ) -> ID3D12Resource {
75
- self . handle
81
+ unsafe { self . resource . resource ( ) . GetGPUVirtualAddress ( ) }
76
82
}
77
83
78
84
pub fn map ( & mut self , range : Option < Range < usize > > ) -> error:: Result < D3D12BufferMapHandle > {
@@ -88,10 +94,12 @@ impl D3D12Buffer {
88
94
89
95
unsafe {
90
96
let mut ptr = std:: ptr:: null_mut ( ) ;
91
- self . handle . Map ( 0 , Some ( & range) , Some ( & mut ptr) ) ?;
97
+ self . resource
98
+ . resource ( )
99
+ . Map ( 0 , Some ( & range) , Some ( & mut ptr) ) ?;
92
100
let slice = std:: slice:: from_raw_parts_mut ( ptr. cast ( ) , size) ;
93
101
Ok ( D3D12BufferMapHandle {
94
- handle : & self . handle ,
102
+ handle : & self . resource . resource ( ) ,
95
103
slice,
96
104
} )
97
105
}
@@ -115,7 +123,10 @@ impl RawD3D12Buffer {
115
123
let range = D3D12_RANGE { Begin : 0 , End : 0 } ;
116
124
let mut ptr = std:: ptr:: null_mut ( ) ;
117
125
unsafe {
118
- buffer. handle . Map ( 0 , Some ( & range) , Some ( & mut ptr) ) ?;
126
+ buffer
127
+ . resource
128
+ . resource ( )
129
+ . Map ( 0 , Some ( & range) , Some ( & mut ptr) ) ?;
119
130
}
120
131
121
132
// panic-safety: If Map returns Ok then ptr is not null
@@ -134,7 +145,7 @@ impl RawD3D12Buffer {
134
145
impl Drop for RawD3D12Buffer {
135
146
fn drop ( & mut self ) {
136
147
unsafe {
137
- self . buffer . handle . Unmap ( 0 , None ) ;
148
+ self . buffer . resource . resource ( ) . Unmap ( 0 , None ) ;
138
149
ManuallyDrop :: drop ( & mut self . buffer ) ;
139
150
}
140
151
}
0 commit comments