librashader/librashader-runtime-d3d12/src/buffer.rs

117 lines
3.6 KiB
Rust
Raw Normal View History

2023-01-31 15:30:11 +11:00
use crate::error;
use crate::error::assume_d3d12_init;
2023-02-06 08:17:23 +11:00
use std::ops::Range;
use windows::Win32::Graphics::Direct3D12::{
ID3D12Device, ID3D12Resource, D3D12_CONSTANT_BUFFER_VIEW_DESC, D3D12_CPU_PAGE_PROPERTY_UNKNOWN,
D3D12_HEAP_FLAG_NONE, D3D12_HEAP_PROPERTIES, D3D12_HEAP_TYPE_UPLOAD, D3D12_MEMORY_POOL_UNKNOWN,
D3D12_RANGE, D3D12_RESOURCE_DESC, D3D12_RESOURCE_DIMENSION_BUFFER,
D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_TEXTURE_LAYOUT_ROW_MAJOR,
};
use windows::Win32::Graphics::Dxgi::Common::DXGI_SAMPLE_DESC;
2023-01-31 15:30:11 +11:00
pub struct D3D12ConstantBuffer {
2023-02-01 16:16:06 +11:00
pub buffer: D3D12Buffer,
pub desc: D3D12_CONSTANT_BUFFER_VIEW_DESC,
2023-01-31 15:30:11 +11:00
}
pub struct D3D12Buffer {
handle: ID3D12Resource,
2023-02-06 08:17:23 +11:00
size: usize,
2023-01-31 15:30:11 +11:00
}
pub struct D3D12BufferMapHandle<'a> {
pub slice: &'a mut [u8],
pub handle: &'a ID3D12Resource,
}
impl<'a> Drop for D3D12BufferMapHandle<'a> {
fn drop(&mut self) {
2023-02-06 08:17:23 +11:00
unsafe { self.handle.Unmap(0, None) }
2023-01-31 15:30:11 +11:00
}
}
impl D3D12Buffer {
pub fn new(device: &ID3D12Device, size: usize) -> error::Result<D3D12Buffer> {
unsafe {
let mut buffer: Option<ID3D12Resource> = None;
device.CreateCommittedResource(
&D3D12_HEAP_PROPERTIES {
Type: D3D12_HEAP_TYPE_UPLOAD,
CPUPageProperty: D3D12_CPU_PAGE_PROPERTY_UNKNOWN,
MemoryPoolPreference: D3D12_MEMORY_POOL_UNKNOWN,
..Default::default()
},
D3D12_HEAP_FLAG_NONE,
&D3D12_RESOURCE_DESC {
Dimension: D3D12_RESOURCE_DIMENSION_BUFFER,
Width: size as u64,
Height: 1,
DepthOrArraySize: 1,
MipLevels: 1,
Layout: D3D12_TEXTURE_LAYOUT_ROW_MAJOR,
SampleDesc: DXGI_SAMPLE_DESC {
Count: 1,
2023-02-06 08:17:23 +11:00
Quality: 0,
2023-01-31 15:30:11 +11:00
},
..Default::default()
},
D3D12_RESOURCE_STATE_GENERIC_READ,
None,
2023-02-06 08:17:23 +11:00
&mut buffer,
2023-01-31 15:30:11 +11:00
)?;
assume_d3d12_init!(buffer, "CreateCommittedResource");
Ok(D3D12Buffer {
handle: buffer,
2023-02-06 08:17:23 +11:00
size,
2023-01-31 15:30:11 +11:00
})
}
}
pub fn gpu_address(&self) -> u64 {
2023-02-06 08:17:23 +11:00
unsafe { self.handle.GetGPUVirtualAddress() }
2023-01-31 15:30:11 +11:00
}
pub fn into_raw(self) -> ID3D12Resource {
self.handle
}
pub fn map(&mut self, range: Option<Range<usize>>) -> error::Result<D3D12BufferMapHandle> {
2023-02-06 08:17:23 +11:00
let (range, size) = range
.map(|range| {
(
D3D12_RANGE {
Begin: range.start,
End: range.end,
},
range.end - range.start,
)
})
.unwrap_or((D3D12_RANGE { Begin: 0, End: 0 }, self.size));
2023-01-31 15:30:11 +11:00
unsafe {
let mut ptr = std::ptr::null_mut();
self.handle.Map(0, Some(&range), Some(&mut ptr))?;
let slice = std::slice::from_raw_parts_mut(ptr.cast(), size);
Ok(D3D12BufferMapHandle {
handle: &self.handle,
slice,
})
}
}
}
impl D3D12ConstantBuffer {
pub fn new(buffer: D3D12Buffer) -> D3D12ConstantBuffer {
unsafe {
let desc = D3D12_CONSTANT_BUFFER_VIEW_DESC {
BufferLocation: buffer.handle.GetGPUVirtualAddress(),
SizeInBytes: buffer.size as u32,
};
2023-02-06 08:17:23 +11:00
D3D12ConstantBuffer { buffer, desc }
2023-01-31 15:30:11 +11:00
}
}
2023-02-06 08:17:23 +11:00
}