Skip to content

Commit 6bb9b27

Browse files
committed
Migrate core gpu-allocator crate and basic examples to windows-rs
As has long been planned and discussed we'd like to get rid of the ancient and barely maintained `winapi` crate, in favour of something more modern: `windows-rs` is actively developed and maintained by Microsoft themselves, and generated out of header metadata rather than written by hand. Besides, it provides a more sophisticated and safer API for dealing with objects (abstracting away return types behind `Result`, hiding COM lifetime management, etc). The choice for the "heavier" `windows` crate over `windows-sys` is fairly obvious: DirectX APIs are built on the COM object model which is completely unsupported in `windows-sys` making us unable to perform any method calls. Besides, the `windows-sys` crate does very little to make the API more convenient nor safer to use, effectively taking us a step back from `winapi` instead of a step forward.
1 parent 7b29c82 commit 6bb9b27

12 files changed

Lines changed: 318 additions & 285 deletions

File tree

Cargo.toml

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,21 @@ ash = { version = "0.36", optional = true, default-features = false, features =
2828
imgui = { version = "0.8", optional = true }
2929

3030
[target.'cfg(windows)'.dependencies]
31-
# Only needed for d3d12.
31+
# Only needed for public-winapi interop helpers
3232
winapi = { version = "0.3.9", features = ["d3d12", "winerror", "impl-default", "impl-debug"], optional = true }
3333

34+
[target.'cfg(windows)'.dependencies.windows]
35+
version = "0.34"
36+
features = [
37+
"Win32_Foundation",
38+
"Win32_Graphics",
39+
"Win32_Graphics_Direct3D",
40+
"Win32_Graphics_Direct3D12",
41+
"Win32_Graphics_Dxgi",
42+
"Win32_Graphics_Dxgi_Common",
43+
]
44+
optional = true
45+
3446
[dev-dependencies]
3547
# Enable the "loaded" feature to be able to access the Vulkan entrypoint.
3648
ash = { version = "0.36", default-features = false, features = ["debug", "loaded"] }
@@ -77,7 +89,8 @@ required-features = ["d3d12", "public-winapi", "visualizer"]
7789
[features]
7890
visualizer = ["imgui"]
7991
vulkan = ["ash"]
80-
d3d12 = ["winapi"]
92+
d3d12 = ["windows"]
93+
# Expose helper functionality for winapi types to interface with gpu-allocator, which is primarily windows-rs driven
8194
public-winapi = ["winapi"]
8295

83-
default = ["d3d12", "vulkan", "public-winapi"]
96+
default = ["d3d12", "vulkan"]

README.md

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,19 @@ gpu-allocator = "0.17.0"
1717

1818
This crate provides a fully written in Rust memory allocator for Vulkan and DirectX 12.
1919

20+
### [Windows-rs] and [winapi]
21+
22+
`gpu-allocator` recently migrated from [winapi] to [windows-rs] but still provides convenient helpers to convert to and from [winapi] types, enabled when compiling with the `public-winapi` crate feature.
23+
24+
[Windows-rs]: https://github.com/microsoft/windows-rs
25+
[winapi]: https://github.com/retep998/winapi-rs
26+
2027
### Setting up the Vulkan memory allocator
2128

2229
```rust
2330
use gpu_allocator::vulkan::*;
2431

25-
let mut allocator = Allocator::new(&AllocatorCreateDesc {
32+
let mut allocator = Allocator::new(AllocatorCreateDesc {
2633
instance,
2734
device,
2835
physical_device,
@@ -67,7 +74,7 @@ unsafe { device.destroy_buffer(buffer, None) };
6774
```rust
6875
use gpu_allocator::d3d12::*;
6976

70-
let mut allocator = Allocator::new(&AllocatorCreateDesc {
77+
let mut allocator = Allocator::new(AllocatorCreateDesc {
7178
device,
7279
debug_settings: Default::default(),
7380
});
@@ -80,20 +87,20 @@ use gpu_allocator::d3d12::*;
8087
use gpu_allocator::MemoryLocation;
8188

8289

83-
let buffer_desc = d3d12::D3D12_RESOURCE_DESC {
84-
Dimension: d3d12::D3D12_RESOURCE_DIMENSION_BUFFER,
90+
let buffer_desc = Direct3D12::D3D12_RESOURCE_DESC {
91+
Dimension: Direct3D12::D3D12_RESOURCE_DIMENSION_BUFFER,
8592
Alignment: 0,
8693
Width: 512,
8794
Height: 1,
8895
DepthOrArraySize: 1,
8996
MipLevels: 1,
90-
Format: dxgiformat::DXGI_FORMAT_UNKNOWN,
91-
SampleDesc: dxgitype::DXGI_SAMPLE_DESC {
97+
Format: Dxgi::Common::DXGI_FORMAT_UNKNOWN,
98+
SampleDesc: Dxgi::Common::DXGI_SAMPLE_DESC {
9299
Count: 1,
93100
Quality: 0,
94101
},
95-
Layout: d3d12::D3D12_TEXTURE_LAYOUT_ROW_MAJOR,
96-
Flags: d3d12::D3D12_RESOURCE_FLAG_NONE,
102+
Layout: Direct3D12::D3D12_TEXTURE_LAYOUT_ROW_MAJOR,
103+
Flags: Direct3D12::D3D12_RESOURCE_FLAG_NONE,
97104
};
98105
let allocation_desc = AllocationCreateDesc::from_d3d12_resource_desc(
99106
allocator.device(),
@@ -102,24 +109,20 @@ let allocation_desc = AllocationCreateDesc::from_d3d12_resource_desc(
102109
MemoryLocation::GpuOnly,
103110
);
104111
let allocation = allocator.allocate(&allocation_desc).unwrap();
105-
let mut resource: *mut d3d12::ID3D12Resource = std::ptr::null_mut();
112+
let mut resource: Option<Direct3D12::ID3D12Resource> = None;
106113
let hr = unsafe {
107-
device.as_ref().unwrap().CreatePlacedResource(
108-
allocation.heap().as_winapi_mut(),
114+
device.CreatePlacedResource(
115+
allocation.heap(),
109116
allocation.offset(),
110117
&buffer_desc,
111-
d3d12::D3D12_RESOURCE_STATE_COMMON,
118+
Direct3D12::D3D12_RESOURCE_STATE_COMMON,
112119
std::ptr::null(),
113-
&d3d12::IID_ID3D12Resource,
114-
&mut resource as *mut _ as *mut _,
120+
&mut resource,
115121
)
116-
};
117-
if hr != winerror::S_OK {
118-
panic!("Failed to create placed resource.");
119-
}
122+
}?;
120123

121124
// Cleanup
122-
unsafe { resource.as_ref().unwrap().Release() };
125+
drop(resource);
123126
allocator.free(allocation).unwrap();
124127
```
125128

examples/d3d12-buffer-winrs.rs

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1+
//! Example showcasing [`gpu-allocator`] with types and functions from the [`windows`] crate.
12
use gpu_allocator::d3d12::{
2-
AllocationCreateDesc, Allocator, AllocatorCreateDesc, Dx12DevicePtr, ResourceCategory,
3+
AllocationCreateDesc, Allocator, AllocatorCreateDesc, ResourceCategory,
34
};
45
use gpu_allocator::MemoryLocation;
56
use log::error;
@@ -9,7 +10,7 @@ use windows::Win32::{
910
Graphics::{
1011
Direct3D::{D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_12_0},
1112
Direct3D12::{
12-
D3D12CreateDevice, ID3D12Device, ID3D12Heap, ID3D12Resource,
13+
D3D12CreateDevice, ID3D12Device, ID3D12Resource,
1314
D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT, D3D12_RESOURCE_DESC,
1415
D3D12_RESOURCE_DIMENSION_BUFFER, D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COMMON,
1516
D3D12_TEXTURE_LAYOUT_ROW_MAJOR,
@@ -82,11 +83,9 @@ fn main() -> Result<()> {
8283

8384
let device = create_d3d12_device(&dxgi_factory).expect("Failed to create D3D12 device.");
8485

85-
let device_ptr: Dx12DevicePtr = unsafe { std::mem::transmute_copy(&device) };
86-
8786
// Setting up the allocator
88-
let mut allocator = Allocator::new(&AllocatorCreateDesc {
89-
device: device_ptr,
87+
let mut allocator = Allocator::new(AllocatorCreateDesc {
88+
device: device.clone(),
9089
debug_settings: Default::default(),
9190
})
9291
.unwrap();
@@ -111,18 +110,16 @@ fn main() -> Result<()> {
111110

112111
let allocation_desc = AllocationCreateDesc::from_d3d12_resource_desc(
113112
allocator.device(),
114-
// Raw structs are binary-compatible
115-
unsafe { std::mem::transmute(&test_buffer_desc) },
113+
&test_buffer_desc,
116114
"Test allocation (Gpu only)",
117115
MemoryLocation::GpuOnly,
118116
);
119117
let allocation = allocator.allocate(&allocation_desc).unwrap();
120118

121119
let mut resource: Option<ID3D12Resource> = None;
122-
let heap: &ID3D12Heap = unsafe { std::mem::transmute(&allocation.heap()) };
123120
unsafe {
124121
device.CreatePlacedResource(
125-
heap,
122+
allocation.heap(),
126123
allocation.offset(),
127124
&test_buffer_desc,
128125
D3D12_RESOURCE_STATE_COMMON,
@@ -168,10 +165,9 @@ fn main() -> Result<()> {
168165
.unwrap();
169166

170167
let mut resource: Option<ID3D12Resource> = None;
171-
let heap: &ID3D12Heap = unsafe { std::mem::transmute(&allocation.heap()) };
172168
unsafe {
173169
device.CreatePlacedResource(
174-
heap,
170+
allocation.heap(),
175171
allocation.offset(),
176172
&test_buffer_desc,
177173
D3D12_RESOURCE_STATE_COMMON,
@@ -217,10 +213,9 @@ fn main() -> Result<()> {
217213
.unwrap();
218214

219215
let mut resource: Option<ID3D12Resource> = None;
220-
let heap: &ID3D12Heap = unsafe { std::mem::transmute(&allocation.heap()) };
221216
unsafe {
222217
device.CreatePlacedResource(
223-
heap,
218+
allocation.heap(),
224219
allocation.offset(),
225220
&test_buffer_desc,
226221
D3D12_RESOURCE_STATE_COMMON,
@@ -235,7 +230,5 @@ fn main() -> Result<()> {
235230
println!("Allocation and deallocation of CpuToGpu memory was successful.");
236231
}
237232

238-
drop(allocator); // Explicitly drop before destruction of device.
239-
240233
Ok(())
241234
}

examples/d3d12-buffer.rs

Lines changed: 21 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
//! Example showcasing [`winapi`] interop with [`gpu-allocator`] which is driven by the [`windows`] crate.
12
use winapi::shared::{dxgiformat, winerror};
23
use winapi::um::{d3d12, d3dcommon};
34
use winapi::Interface;
@@ -9,8 +10,7 @@ mod all_dxgi {
910
use log::*;
1011

1112
use gpu_allocator::d3d12::{
12-
AbstractWinapiPtr, AllocationCreateDesc, Allocator, AllocatorCreateDesc, Dx12DevicePtr,
13-
ResourceCategory,
13+
AllocationCreateDesc, Allocator, AllocatorCreateDesc, ResourceCategory, ToWinapi, ToWindows,
1414
};
1515
use gpu_allocator::MemoryLocation;
1616

@@ -68,7 +68,7 @@ fn create_d3d12_device(
6868
};
6969
match hr {
7070
winapi::shared::winerror::S_OK => {
71-
info!("Using D3D12 feature level: {}.", feature_level_name);
71+
println!("Using D3D12 feature level: {}.", feature_level_name);
7272
Some(device)
7373
}
7474
winapi::shared::winerror::E_NOINTERFACE => {
@@ -114,12 +114,14 @@ fn main() {
114114
let device = create_d3d12_device(dxgi_factory).expect("Failed to create D3D12 device.");
115115

116116
// Setting up the allocator
117-
let mut allocator = Allocator::new(&AllocatorCreateDesc {
118-
device: Dx12DevicePtr(device.cast()),
117+
let mut allocator = Allocator::new(AllocatorCreateDesc {
118+
device: device.as_windows().clone(),
119119
debug_settings: Default::default(),
120120
})
121121
.unwrap();
122122

123+
let device = unsafe { device.as_ref() }.unwrap();
124+
123125
// Test allocating Gpu Only memory
124126
{
125127
let test_buffer_desc = d3d12::D3D12_RESOURCE_DESC {
@@ -138,8 +140,8 @@ fn main() {
138140
Flags: d3d12::D3D12_RESOURCE_FLAG_NONE,
139141
};
140142

141-
let allocation_desc = AllocationCreateDesc::from_d3d12_resource_desc(
142-
allocator.device(),
143+
let allocation_desc = AllocationCreateDesc::from_winapi_d3d12_resource_desc(
144+
device,
143145
&test_buffer_desc,
144146
"Test allocation (Gpu Only)",
145147
MemoryLocation::GpuOnly,
@@ -148,8 +150,8 @@ fn main() {
148150

149151
let mut resource: *mut d3d12::ID3D12Resource = std::ptr::null_mut();
150152
let hr = unsafe {
151-
device.as_ref().unwrap().CreatePlacedResource(
152-
allocation.heap().as_winapi_mut(),
153+
device.CreatePlacedResource(
154+
allocation.heap().as_winapi() as *mut _,
153155
allocation.offset(),
154156
&test_buffer_desc,
155157
d3d12::D3D12_RESOURCE_STATE_COMMON,
@@ -165,7 +167,7 @@ fn main() {
165167
unsafe { resource.as_ref().unwrap().Release() };
166168

167169
allocator.free(allocation).unwrap();
168-
info!("Allocation and deallocation of GpuOnly memory was successful.");
170+
println!("Allocation and deallocation of GpuOnly memory was successful.");
169171
}
170172

171173
// Test allocating Cpu to Gpu memory
@@ -186,12 +188,7 @@ fn main() {
186188
Flags: d3d12::D3D12_RESOURCE_FLAG_NONE,
187189
};
188190

189-
let alloc_info = unsafe {
190-
device
191-
.as_ref()
192-
.unwrap()
193-
.GetResourceAllocationInfo(0, 1, &test_buffer_desc)
194-
};
191+
let alloc_info = unsafe { device.GetResourceAllocationInfo(0, 1, &test_buffer_desc) };
195192

196193
let allocation = allocator
197194
.allocate(&AllocationCreateDesc {
@@ -205,8 +202,8 @@ fn main() {
205202

206203
let mut resource: *mut d3d12::ID3D12Resource = std::ptr::null_mut();
207204
let hr = unsafe {
208-
device.as_ref().unwrap().CreatePlacedResource(
209-
allocation.heap().as_winapi_mut(),
205+
device.CreatePlacedResource(
206+
allocation.heap().as_winapi() as *mut _,
210207
allocation.offset(),
211208
&test_buffer_desc,
212209
d3d12::D3D12_RESOURCE_STATE_COMMON,
@@ -222,7 +219,7 @@ fn main() {
222219
unsafe { resource.as_ref().unwrap().Release() };
223220

224221
allocator.free(allocation).unwrap();
225-
info!("Allocation and deallocation of CpuToGpu memory was successful.");
222+
println!("Allocation and deallocation of CpuToGpu memory was successful.");
226223
}
227224

228225
// Test allocating Gpu to Cpu memory
@@ -243,12 +240,7 @@ fn main() {
243240
Flags: d3d12::D3D12_RESOURCE_FLAG_NONE,
244241
};
245242

246-
let alloc_info = unsafe {
247-
device
248-
.as_ref()
249-
.unwrap()
250-
.GetResourceAllocationInfo(0, 1, &test_buffer_desc)
251-
};
243+
let alloc_info = unsafe { device.GetResourceAllocationInfo(0, 1, &test_buffer_desc) };
252244

253245
let allocation = allocator
254246
.allocate(&AllocationCreateDesc {
@@ -262,8 +254,8 @@ fn main() {
262254

263255
let mut resource: *mut d3d12::ID3D12Resource = std::ptr::null_mut();
264256
let hr = unsafe {
265-
device.as_ref().unwrap().CreatePlacedResource(
266-
allocation.heap().as_winapi_mut(),
257+
device.CreatePlacedResource(
258+
allocation.heap().as_winapi() as *mut _,
267259
allocation.offset(),
268260
&test_buffer_desc,
269261
d3d12::D3D12_RESOURCE_STATE_COMMON,
@@ -279,10 +271,10 @@ fn main() {
279271
unsafe { resource.as_ref().unwrap().Release() };
280272

281273
allocator.free(allocation).unwrap();
282-
info!("Allocation and deallocation of CpuToGpu memory was successful.");
274+
println!("Allocation and deallocation of CpuToGpu memory was successful.");
283275
}
284276

285277
drop(allocator); // Explicitly drop before destruction of device.
286-
unsafe { device.as_ref().unwrap().Release() };
278+
unsafe { device.Release() };
287279
unsafe { dxgi_factory.as_ref().unwrap().Release() };
288280
}

0 commit comments

Comments
 (0)