Skip to content

Commit 2e7c3b3

Browse files
committed
rt(d3d12): use gpu_allocator instead of CreateCommittedResource
1 parent e90c27e commit 2e7c3b3

File tree

9 files changed

+265
-148
lines changed

9 files changed

+265
-148
lines changed

Cargo.lock

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

librashader-runtime-d3d12/Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ array-concat = "0.5.2"
2929
mach-siegbert-vogt-dxcsa = "0.1.3"
3030

3131
rayon = "1.6.1"
32+
gpu-allocator = { version = "0.27.0", features = ["d3d12"], default-features = false}
33+
parking_lot = "0.12.3"
3234

3335
[target.'cfg(windows)'.dependencies.windows]
3436
workspace = true

librashader-runtime-d3d12/src/buffer.rs

+60-49
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,25 @@
11
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;
38
use std::ffi::c_void;
49
use std::mem::ManuallyDrop;
510
use std::ops::{Deref, DerefMut, Range};
611
use std::ptr::NonNull;
12+
use std::sync::Arc;
713
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,
1217
};
1318
use windows::Win32::Graphics::Dxgi::Common::DXGI_SAMPLE_DESC;
1419

1520
pub struct D3D12Buffer {
16-
handle: ID3D12Resource,
21+
resource: ManuallyDrop<Resource>,
22+
allocator: Arc<Mutex<Allocator>>,
1723
size: usize,
1824
}
1925

@@ -28,51 +34,51 @@ impl<'a> Drop for D3D12BufferMapHandle<'a> {
2834
}
2935
}
3036

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+
3146
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,
5562
},
63+
..Default::default()
64+
},
65+
castable_formats: &[],
66+
clear_value: None,
67+
initial_state_or_layout: ResourceStateOrBarrierLayout::ResourceState(
5668
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+
})
6878
}
6979

7080
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() }
7682
}
7783

7884
pub fn map(&mut self, range: Option<Range<usize>>) -> error::Result<D3D12BufferMapHandle> {
@@ -88,10 +94,12 @@ impl D3D12Buffer {
8894

8995
unsafe {
9096
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))?;
92100
let slice = std::slice::from_raw_parts_mut(ptr.cast(), size);
93101
Ok(D3D12BufferMapHandle {
94-
handle: &self.handle,
102+
handle: &self.resource.resource(),
95103
slice,
96104
})
97105
}
@@ -115,7 +123,10 @@ impl RawD3D12Buffer {
115123
let range = D3D12_RANGE { Begin: 0, End: 0 };
116124
let mut ptr = std::ptr::null_mut();
117125
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))?;
119130
}
120131

121132
// panic-safety: If Map returns Ok then ptr is not null
@@ -134,7 +145,7 @@ impl RawD3D12Buffer {
134145
impl Drop for RawD3D12Buffer {
135146
fn drop(&mut self) {
136147
unsafe {
137-
self.buffer.handle.Unmap(0, None);
148+
self.buffer.resource.resource().Unmap(0, None);
138149
ManuallyDrop::drop(&mut self.buffer);
139150
}
140151
}

librashader-runtime-d3d12/src/draw_quad.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@ use crate::buffer::D3D12Buffer;
22
use crate::error;
33
use array_concat::concat_arrays;
44
use bytemuck::offset_of;
5+
use gpu_allocator::d3d12::Allocator;
56
use librashader_runtime::quad::{QuadType, VertexInput};
7+
use parking_lot::Mutex;
8+
use std::sync::Arc;
69
use windows::core::PCSTR;
710
use windows::Win32::Graphics::Direct3D::D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
811
use windows::Win32::Graphics::Direct3D12::{
9-
ID3D12Device, ID3D12GraphicsCommandList, ID3D12GraphicsCommandList4, ID3D12Resource,
12+
ID3D12GraphicsCommandList, ID3D12GraphicsCommandList4,
1013
D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, D3D12_INPUT_ELEMENT_DESC, D3D12_VERTEX_BUFFER_VIEW,
1114
};
1215
use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT_R32G32_FLOAT;
@@ -52,15 +55,15 @@ const FINAL_VBO_DATA: [VertexInput; 4] = [
5255
static VBO_DATA: &[VertexInput; 8] = &concat_arrays!(OFFSCREEN_VBO_DATA, FINAL_VBO_DATA);
5356

5457
pub(crate) struct DrawQuad {
55-
_buffer: ID3D12Resource,
58+
_buffer: D3D12Buffer,
5659
view: D3D12_VERTEX_BUFFER_VIEW,
5760
}
5861

5962
impl DrawQuad {
60-
pub fn new(device: &ID3D12Device) -> error::Result<DrawQuad> {
63+
pub fn new(allocator: &Arc<Mutex<Allocator>>) -> error::Result<DrawQuad> {
6164
let stride = std::mem::size_of::<VertexInput>() as u32;
6265
let size = 2 * std::mem::size_of::<[VertexInput; 4]>() as u32;
63-
let mut buffer = D3D12Buffer::new(device, size as usize)?;
66+
let mut buffer = D3D12Buffer::new(allocator, size as usize)?;
6467
buffer
6568
.map(None)?
6669
.slice
@@ -72,7 +75,6 @@ impl DrawQuad {
7275
StrideInBytes: stride,
7376
};
7477

75-
let buffer = buffer.into_raw();
7678
Ok(DrawQuad {
7779
_buffer: buffer,
7880
view,

librashader-runtime-d3d12/src/error.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use thiserror::Error;
55
/// Cumulative error type for Direct3D12 filter chains.
66
#[derive(Error, Debug)]
77
pub enum FilterChainError {
8-
#[error("invariant assumption about d3d11 did not hold. report this as an issue.")]
8+
#[error("invariant assumption about d3d12 did not hold. report this as an issue.")]
99
Direct3DOperationError(&'static str),
1010
#[error("direct3d driver error")]
1111
Direct3DError(#[from] windows::core::Error),
@@ -21,6 +21,8 @@ pub enum FilterChainError {
2121
LutLoadError(#[from] ImageError),
2222
#[error("heap overflow")]
2323
DescriptorHeapOverflow(usize),
24+
#[error("allocation error")]
25+
AllocationError(#[from] gpu_allocator::AllocationError),
2426
}
2527

2628
/// Result type for Direct3D 12 filter chains.

0 commit comments

Comments
 (0)