rt(d3d12): use gpu_allocator instead of CreateCommittedResource
This commit is contained in:
parent
e90c27ebbd
commit
2e7c3b3273
3
Cargo.lock
generated
3
Cargo.lock
generated
|
@ -1265,6 +1265,7 @@ dependencies = [
|
|||
"log",
|
||||
"presser",
|
||||
"thiserror",
|
||||
"windows 0.58.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1774,6 +1775,7 @@ dependencies = [
|
|||
"bitvec",
|
||||
"bytemuck",
|
||||
"gfx-maths",
|
||||
"gpu-allocator 0.27.0",
|
||||
"librashader-cache",
|
||||
"librashader-common",
|
||||
"librashader-preprocess",
|
||||
|
@ -1781,6 +1783,7 @@ dependencies = [
|
|||
"librashader-reflect",
|
||||
"librashader-runtime",
|
||||
"mach-siegbert-vogt-dxcsa",
|
||||
"parking_lot",
|
||||
"rayon",
|
||||
"thiserror",
|
||||
"widestring",
|
||||
|
|
|
@ -29,6 +29,8 @@ array-concat = "0.5.2"
|
|||
mach-siegbert-vogt-dxcsa = "0.1.3"
|
||||
|
||||
rayon = "1.6.1"
|
||||
gpu-allocator = { version = "0.27.0", features = ["d3d12"], default-features = false}
|
||||
parking_lot = "0.12.3"
|
||||
|
||||
[target.'cfg(windows)'.dependencies.windows]
|
||||
workspace = true
|
||||
|
|
|
@ -1,19 +1,25 @@
|
|||
use crate::error;
|
||||
use crate::error::assume_d3d12_init;
|
||||
use gpu_allocator::d3d12::{
|
||||
Allocator, Resource, ResourceCategory, ResourceCreateDesc, ResourceStateOrBarrierLayout,
|
||||
ResourceType,
|
||||
};
|
||||
use gpu_allocator::MemoryLocation;
|
||||
use parking_lot::Mutex;
|
||||
use std::ffi::c_void;
|
||||
use std::mem::ManuallyDrop;
|
||||
use std::ops::{Deref, DerefMut, Range};
|
||||
use std::ptr::NonNull;
|
||||
use std::sync::Arc;
|
||||
use windows::Win32::Graphics::Direct3D12::{
|
||||
ID3D12Device, ID3D12GraphicsCommandList, ID3D12Resource, 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,
|
||||
ID3D12GraphicsCommandList, ID3D12Resource, 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;
|
||||
|
||||
pub struct D3D12Buffer {
|
||||
handle: ID3D12Resource,
|
||||
resource: ManuallyDrop<Resource>,
|
||||
allocator: Arc<Mutex<Allocator>>,
|
||||
size: usize,
|
||||
}
|
||||
|
||||
|
@ -28,19 +34,22 @@ impl<'a> Drop for D3D12BufferMapHandle<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl Drop for D3D12Buffer {
|
||||
fn drop(&mut self) {
|
||||
let resource = unsafe { ManuallyDrop::take(&mut self.resource) };
|
||||
if let Err(e) = self.allocator.lock().free_resource(resource) {
|
||||
println!("librashader-runtime-d3d12: [warn] failed to deallocate buffer memory {e}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
pub fn new(allocator: &Arc<Mutex<Allocator>>, size: usize) -> error::Result<D3D12Buffer> {
|
||||
let resource = allocator.lock().create_resource(&ResourceCreateDesc {
|
||||
name: "d3d12buffer",
|
||||
memory_location: MemoryLocation::CpuToGpu,
|
||||
resource_category: ResourceCategory::Buffer,
|
||||
resource_desc: &D3D12_RESOURCE_DESC {
|
||||
Dimension: D3D12_RESOURCE_DIMENSION_BUFFER,
|
||||
Width: size as u64,
|
||||
Height: 1,
|
||||
|
@ -53,26 +62,23 @@ impl D3D12Buffer {
|
|||
},
|
||||
..Default::default()
|
||||
},
|
||||
castable_formats: &[],
|
||||
clear_value: None,
|
||||
initial_state_or_layout: ResourceStateOrBarrierLayout::ResourceState(
|
||||
D3D12_RESOURCE_STATE_GENERIC_READ,
|
||||
None,
|
||||
&mut buffer,
|
||||
)?;
|
||||
),
|
||||
resource_type: &ResourceType::Placed,
|
||||
})?;
|
||||
|
||||
assume_d3d12_init!(buffer, "CreateCommittedResource");
|
||||
|
||||
Ok(D3D12Buffer {
|
||||
handle: buffer,
|
||||
Ok(Self {
|
||||
resource: ManuallyDrop::new(resource),
|
||||
size,
|
||||
allocator: Arc::clone(&allocator),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn gpu_address(&self) -> u64 {
|
||||
unsafe { self.handle.GetGPUVirtualAddress() }
|
||||
}
|
||||
|
||||
pub fn into_raw(self) -> ID3D12Resource {
|
||||
self.handle
|
||||
unsafe { self.resource.resource().GetGPUVirtualAddress() }
|
||||
}
|
||||
|
||||
pub fn map(&mut self, range: Option<Range<usize>>) -> error::Result<D3D12BufferMapHandle> {
|
||||
|
@ -88,10 +94,12 @@ impl D3D12Buffer {
|
|||
|
||||
unsafe {
|
||||
let mut ptr = std::ptr::null_mut();
|
||||
self.handle.Map(0, Some(&range), Some(&mut ptr))?;
|
||||
self.resource
|
||||
.resource()
|
||||
.Map(0, Some(&range), Some(&mut ptr))?;
|
||||
let slice = std::slice::from_raw_parts_mut(ptr.cast(), size);
|
||||
Ok(D3D12BufferMapHandle {
|
||||
handle: &self.handle,
|
||||
handle: &self.resource.resource(),
|
||||
slice,
|
||||
})
|
||||
}
|
||||
|
@ -115,7 +123,10 @@ impl RawD3D12Buffer {
|
|||
let range = D3D12_RANGE { Begin: 0, End: 0 };
|
||||
let mut ptr = std::ptr::null_mut();
|
||||
unsafe {
|
||||
buffer.handle.Map(0, Some(&range), Some(&mut ptr))?;
|
||||
buffer
|
||||
.resource
|
||||
.resource()
|
||||
.Map(0, Some(&range), Some(&mut ptr))?;
|
||||
}
|
||||
|
||||
// panic-safety: If Map returns Ok then ptr is not null
|
||||
|
@ -134,7 +145,7 @@ impl RawD3D12Buffer {
|
|||
impl Drop for RawD3D12Buffer {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
self.buffer.handle.Unmap(0, None);
|
||||
self.buffer.resource.resource().Unmap(0, None);
|
||||
ManuallyDrop::drop(&mut self.buffer);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,11 +2,14 @@ use crate::buffer::D3D12Buffer;
|
|||
use crate::error;
|
||||
use array_concat::concat_arrays;
|
||||
use bytemuck::offset_of;
|
||||
use gpu_allocator::d3d12::Allocator;
|
||||
use librashader_runtime::quad::{QuadType, VertexInput};
|
||||
use parking_lot::Mutex;
|
||||
use std::sync::Arc;
|
||||
use windows::core::PCSTR;
|
||||
use windows::Win32::Graphics::Direct3D::D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
|
||||
use windows::Win32::Graphics::Direct3D12::{
|
||||
ID3D12Device, ID3D12GraphicsCommandList, ID3D12GraphicsCommandList4, ID3D12Resource,
|
||||
ID3D12GraphicsCommandList, ID3D12GraphicsCommandList4,
|
||||
D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, D3D12_INPUT_ELEMENT_DESC, D3D12_VERTEX_BUFFER_VIEW,
|
||||
};
|
||||
use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT_R32G32_FLOAT;
|
||||
|
@ -52,15 +55,15 @@ const FINAL_VBO_DATA: [VertexInput; 4] = [
|
|||
static VBO_DATA: &[VertexInput; 8] = &concat_arrays!(OFFSCREEN_VBO_DATA, FINAL_VBO_DATA);
|
||||
|
||||
pub(crate) struct DrawQuad {
|
||||
_buffer: ID3D12Resource,
|
||||
_buffer: D3D12Buffer,
|
||||
view: D3D12_VERTEX_BUFFER_VIEW,
|
||||
}
|
||||
|
||||
impl DrawQuad {
|
||||
pub fn new(device: &ID3D12Device) -> error::Result<DrawQuad> {
|
||||
pub fn new(allocator: &Arc<Mutex<Allocator>>) -> error::Result<DrawQuad> {
|
||||
let stride = std::mem::size_of::<VertexInput>() as u32;
|
||||
let size = 2 * std::mem::size_of::<[VertexInput; 4]>() as u32;
|
||||
let mut buffer = D3D12Buffer::new(device, size as usize)?;
|
||||
let mut buffer = D3D12Buffer::new(allocator, size as usize)?;
|
||||
buffer
|
||||
.map(None)?
|
||||
.slice
|
||||
|
@ -72,7 +75,6 @@ impl DrawQuad {
|
|||
StrideInBytes: stride,
|
||||
};
|
||||
|
||||
let buffer = buffer.into_raw();
|
||||
Ok(DrawQuad {
|
||||
_buffer: buffer,
|
||||
view,
|
||||
|
|
|
@ -5,7 +5,7 @@ use thiserror::Error;
|
|||
/// Cumulative error type for Direct3D12 filter chains.
|
||||
#[derive(Error, Debug)]
|
||||
pub enum FilterChainError {
|
||||
#[error("invariant assumption about d3d11 did not hold. report this as an issue.")]
|
||||
#[error("invariant assumption about d3d12 did not hold. report this as an issue.")]
|
||||
Direct3DOperationError(&'static str),
|
||||
#[error("direct3d driver error")]
|
||||
Direct3DError(#[from] windows::core::Error),
|
||||
|
@ -21,6 +21,8 @@ pub enum FilterChainError {
|
|||
LutLoadError(#[from] ImageError),
|
||||
#[error("heap overflow")]
|
||||
DescriptorHeapOverflow(usize),
|
||||
#[error("allocation error")]
|
||||
AllocationError(#[from] gpu_allocator::AllocationError),
|
||||
}
|
||||
|
||||
/// Result type for Direct3D 12 filter chains.
|
||||
|
|
|
@ -14,6 +14,7 @@ use crate::options::{FilterChainOptionsD3D12, FrameOptionsD3D12};
|
|||
use crate::samplers::SamplerSet;
|
||||
use crate::texture::{D3D12InputImage, D3D12OutputView, InputTexture, OutputDescriptor};
|
||||
use crate::{error, util};
|
||||
use gpu_allocator::d3d12::{Allocator, AllocatorCreateDesc, ID3D12DeviceVersion};
|
||||
use librashader_common::map::FastHashMap;
|
||||
use librashader_common::{ImageFormat, Size, Viewport};
|
||||
use librashader_presets::{ShaderPassConfig, ShaderPreset, TextureConfig};
|
||||
|
@ -27,9 +28,11 @@ use librashader_runtime::binding::{BindingUtil, TextureInput};
|
|||
use librashader_runtime::image::{Image, ImageError, UVDirection};
|
||||
use librashader_runtime::quad::QuadType;
|
||||
use librashader_runtime::uniforms::UniformStorage;
|
||||
use parking_lot::Mutex;
|
||||
use std::collections::VecDeque;
|
||||
use std::mem::ManuallyDrop;
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
use windows::core::Interface;
|
||||
use windows::Win32::Foundation::CloseHandle;
|
||||
use windows::Win32::Graphics::Direct3D::Dxc::{
|
||||
|
@ -93,6 +96,7 @@ pub(crate) struct FilterCommon {
|
|||
pub mipmap_gen: D3D12MipmapGen,
|
||||
pub root_signature: D3D12RootSignature,
|
||||
pub draw_quad: DrawQuad,
|
||||
allocator: Arc<Mutex<Allocator>>,
|
||||
}
|
||||
|
||||
pub(crate) struct FrameResiduals {
|
||||
|
@ -275,7 +279,13 @@ impl FilterChainD3D12 {
|
|||
let samplers = SamplerSet::new(device)?;
|
||||
let mipmap_gen = D3D12MipmapGen::new(device, false)?;
|
||||
|
||||
let draw_quad = DrawQuad::new(device)?;
|
||||
let allocator = Arc::new(Mutex::new(Allocator::new(&AllocatorCreateDesc {
|
||||
device: ID3D12DeviceVersion::Device(device.clone()),
|
||||
debug_settings: Default::default(),
|
||||
allocation_sizes: Default::default(),
|
||||
})?));
|
||||
|
||||
let draw_quad = DrawQuad::new(&allocator)?;
|
||||
let mut staging_heap = D3D12DescriptorHeap::new(
|
||||
device,
|
||||
(MAX_BINDINGS_COUNT as usize) * shader_count
|
||||
|
@ -294,6 +304,7 @@ impl FilterChainD3D12 {
|
|||
let (texture_heap, sampler_heap, filters, mut mipmap_heap) = FilterChainD3D12::init_passes(
|
||||
device,
|
||||
&root_signature,
|
||||
&allocator,
|
||||
passes,
|
||||
hlsl_passes,
|
||||
&semantics,
|
||||
|
@ -306,6 +317,7 @@ impl FilterChainD3D12 {
|
|||
let luts = FilterChainD3D12::load_luts(
|
||||
device,
|
||||
cmd,
|
||||
&allocator,
|
||||
&mut staging_heap,
|
||||
&mut mipmap_heap,
|
||||
&mut residuals,
|
||||
|
@ -315,6 +327,7 @@ impl FilterChainD3D12 {
|
|||
let framebuffer_gen = || {
|
||||
OwnedImage::new(
|
||||
device,
|
||||
&allocator,
|
||||
Size::new(1, 1),
|
||||
ImageFormat::R8G8B8A8Unorm.into(),
|
||||
false,
|
||||
|
@ -341,6 +354,7 @@ impl FilterChainD3D12 {
|
|||
common: FilterCommon {
|
||||
d3d12: device.clone(),
|
||||
samplers,
|
||||
allocator: allocator,
|
||||
output_textures,
|
||||
feedback_textures,
|
||||
luts,
|
||||
|
@ -375,6 +389,7 @@ impl FilterChainD3D12 {
|
|||
fn load_luts(
|
||||
device: &ID3D12Device,
|
||||
cmd: &ID3D12GraphicsCommandList,
|
||||
allocator: &Arc<Mutex<Allocator>>,
|
||||
staging_heap: &mut D3D12DescriptorHeap<CpuStagingHeap>,
|
||||
mipmap_heap: &mut D3D12DescriptorHeap<ResourceWorkHeap>,
|
||||
gc: &mut FrameResiduals,
|
||||
|
@ -392,6 +407,7 @@ impl FilterChainD3D12 {
|
|||
for (index, (texture, image)) in textures.iter().zip(images).enumerate() {
|
||||
let texture = LutTexture::new(
|
||||
device,
|
||||
allocator,
|
||||
staging_heap,
|
||||
cmd,
|
||||
&image,
|
||||
|
@ -425,6 +441,7 @@ impl FilterChainD3D12 {
|
|||
fn init_passes(
|
||||
device: &ID3D12Device,
|
||||
root_signature: &D3D12RootSignature,
|
||||
allocator: &Arc<Mutex<Allocator>>,
|
||||
passes: Vec<DxilShaderPassMeta>,
|
||||
hlsl_passes: Vec<HlslShaderPassMeta>,
|
||||
semantics: &ShaderSemantics,
|
||||
|
@ -535,8 +552,8 @@ impl FilterChainD3D12 {
|
|||
.map_or(1, |push| push.size as usize);
|
||||
|
||||
let uniform_storage = UniformStorage::new_with_storage(
|
||||
RawD3D12Buffer::new(D3D12Buffer::new(device, ubo_size)?)?,
|
||||
RawD3D12Buffer::new(D3D12Buffer::new(device, push_size)?)?,
|
||||
RawD3D12Buffer::new(D3D12Buffer::new(allocator, ubo_size)?)?,
|
||||
RawD3D12Buffer::new(D3D12Buffer::new(allocator, push_size)?)?,
|
||||
);
|
||||
|
||||
let uniform_bindings =
|
||||
|
@ -584,7 +601,13 @@ impl FilterChainD3D12 {
|
|||
// old back will get dropped.. do we need to defer?
|
||||
let _old_back = std::mem::replace(
|
||||
&mut back,
|
||||
OwnedImage::new(&self.common.d3d12, input.size, input.format, false)?,
|
||||
OwnedImage::new(
|
||||
&self.common.d3d12,
|
||||
&self.common.allocator,
|
||||
input.size,
|
||||
input.format,
|
||||
false,
|
||||
)?,
|
||||
);
|
||||
}
|
||||
unsafe {
|
||||
|
@ -731,7 +754,7 @@ impl FilterChainD3D12 {
|
|||
|
||||
util::d3d12_resource_transition(
|
||||
cmd,
|
||||
&target.handle,
|
||||
&target.handle.resource(),
|
||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
|
||||
D3D12_RESOURCE_STATE_RENDER_TARGET,
|
||||
);
|
||||
|
@ -754,7 +777,7 @@ impl FilterChainD3D12 {
|
|||
|
||||
util::d3d12_resource_transition(
|
||||
cmd,
|
||||
&target.handle,
|
||||
&target.handle.resource(),
|
||||
D3D12_RESOURCE_STATE_RENDER_TARGET,
|
||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
|
||||
);
|
||||
|
@ -765,7 +788,7 @@ impl FilterChainD3D12 {
|
|||
&mut self.mipmap_heap,
|
||||
|ctx| {
|
||||
ctx.generate_mipmaps(
|
||||
&target.handle,
|
||||
&target.handle.resource(),
|
||||
target.max_mipmap,
|
||||
target.size,
|
||||
target.format.into(),
|
||||
|
|
|
@ -1,22 +1,27 @@
|
|||
use crate::descriptor_heap::{CpuStagingHeap, D3D12DescriptorHeap, RenderTargetHeap};
|
||||
use crate::error::{assume_d3d12_init, FilterChainError};
|
||||
use crate::error::FilterChainError;
|
||||
use crate::filter_chain::FrameResiduals;
|
||||
use crate::texture::{D3D12OutputView, InputTexture};
|
||||
use crate::util::d3d12_get_closest_format;
|
||||
use crate::{error, util};
|
||||
use gpu_allocator::d3d12::{
|
||||
Allocator, Resource, ResourceCategory, ResourceCreateDesc, ResourceStateOrBarrierLayout,
|
||||
ResourceType,
|
||||
};
|
||||
use gpu_allocator::MemoryLocation;
|
||||
use librashader_common::{FilterMode, ImageFormat, Size, WrapMode};
|
||||
use librashader_presets::Scale2D;
|
||||
use librashader_runtime::scaling::{MipmapSize, ScaleFramebuffer, ViewportSize};
|
||||
use parking_lot::Mutex;
|
||||
use std::mem::ManuallyDrop;
|
||||
use std::ops::Deref;
|
||||
use std::sync::Arc;
|
||||
use windows::Win32::Graphics::Direct3D12::{
|
||||
ID3D12Device, ID3D12GraphicsCommandList, ID3D12Resource, D3D12_BOX,
|
||||
D3D12_CPU_PAGE_PROPERTY_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING,
|
||||
ID3D12Device, ID3D12GraphicsCommandList, D3D12_BOX, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING,
|
||||
D3D12_FEATURE_DATA_FORMAT_SUPPORT, D3D12_FORMAT_SUPPORT1_MIP,
|
||||
D3D12_FORMAT_SUPPORT1_RENDER_TARGET, D3D12_FORMAT_SUPPORT1_SHADER_SAMPLE,
|
||||
D3D12_FORMAT_SUPPORT1_TEXTURE2D, D3D12_FORMAT_SUPPORT2_UAV_TYPED_LOAD,
|
||||
D3D12_FORMAT_SUPPORT2_UAV_TYPED_STORE, D3D12_HEAP_FLAG_NONE, D3D12_HEAP_PROPERTIES,
|
||||
D3D12_HEAP_TYPE_DEFAULT, D3D12_MEMORY_POOL_UNKNOWN, D3D12_RENDER_TARGET_VIEW_DESC,
|
||||
D3D12_FORMAT_SUPPORT2_UAV_TYPED_STORE, D3D12_RENDER_TARGET_VIEW_DESC,
|
||||
D3D12_RENDER_TARGET_VIEW_DESC_0, D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES, D3D12_RESOURCE_DESC,
|
||||
D3D12_RESOURCE_DIMENSION_TEXTURE2D, D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET,
|
||||
D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_DEST,
|
||||
|
@ -28,13 +33,14 @@ use windows::Win32::Graphics::Direct3D12::{
|
|||
};
|
||||
use windows::Win32::Graphics::Dxgi::Common::{DXGI_FORMAT, DXGI_SAMPLE_DESC};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct OwnedImage {
|
||||
pub(crate) handle: ID3D12Resource,
|
||||
pub(crate) handle: ManuallyDrop<Resource>,
|
||||
pub(crate) size: Size<u32>,
|
||||
pub(crate) format: DXGI_FORMAT,
|
||||
pub(crate) max_mipmap: u16,
|
||||
device: ID3D12Device,
|
||||
allocator: Arc<Mutex<Allocator>>,
|
||||
}
|
||||
|
||||
static CLEAR: &[f32; 4] = &[0.0, 0.0, 0.0, 0.0];
|
||||
|
@ -64,6 +70,7 @@ impl OwnedImage {
|
|||
|
||||
pub fn new(
|
||||
device: &ID3D12Device,
|
||||
allocator: &Arc<Mutex<Allocator>>,
|
||||
size: Size<u32>,
|
||||
format: DXGI_FORMAT,
|
||||
mipmap: bool,
|
||||
|
@ -105,31 +112,46 @@ impl OwnedImage {
|
|||
}
|
||||
|
||||
desc.Format = d3d12_get_closest_format(device, format_support);
|
||||
let mut resource: Option<ID3D12Resource> = None;
|
||||
unsafe {
|
||||
device.CreateCommittedResource(
|
||||
&D3D12_HEAP_PROPERTIES {
|
||||
Type: D3D12_HEAP_TYPE_DEFAULT,
|
||||
CPUPageProperty: D3D12_CPU_PAGE_PROPERTY_UNKNOWN,
|
||||
MemoryPoolPreference: D3D12_MEMORY_POOL_UNKNOWN,
|
||||
CreationNodeMask: 1,
|
||||
VisibleNodeMask: 1,
|
||||
},
|
||||
D3D12_HEAP_FLAG_NONE,
|
||||
&desc,
|
||||
|
||||
let resource = allocator.lock().create_resource(&ResourceCreateDesc {
|
||||
name: "ownedimage",
|
||||
memory_location: MemoryLocation::GpuOnly,
|
||||
resource_category: ResourceCategory::RtvDsvTexture,
|
||||
resource_desc: &desc,
|
||||
castable_formats: &[],
|
||||
clear_value: None,
|
||||
initial_state_or_layout: ResourceStateOrBarrierLayout::ResourceState(
|
||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
|
||||
None,
|
||||
&mut resource,
|
||||
)?;
|
||||
}
|
||||
assume_d3d12_init!(resource, "CreateCommittedResource");
|
||||
),
|
||||
resource_type: &ResourceType::Placed,
|
||||
})?;
|
||||
|
||||
// let mut resource: Option<ID3D12Resource> = None;
|
||||
// unsafe {
|
||||
// device.CreateCommittedResource(
|
||||
// &D3D12_HEAP_PROPERTIES {
|
||||
// Type: D3D12_HEAP_TYPE_DEFAULT,
|
||||
// CPUPageProperty: D3D12_CPU_PAGE_PROPERTY_UNKNOWN,
|
||||
// MemoryPoolPreference: D3D12_MEMORY_POOL_UNKNOWN,
|
||||
// CreationNodeMask: 1,
|
||||
// VisibleNodeMask: 1,
|
||||
// },
|
||||
// D3D12_HEAP_FLAG_NONE,
|
||||
// &desc,
|
||||
// D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
|
||||
// None,
|
||||
// &mut resource,
|
||||
// )?;
|
||||
// }
|
||||
// assume_d3d12_init!(resource, "CreateCommittedResource");
|
||||
|
||||
Ok(OwnedImage {
|
||||
handle: resource,
|
||||
handle: ManuallyDrop::new(resource),
|
||||
size,
|
||||
format: desc.Format,
|
||||
device: device.clone(),
|
||||
max_mipmap: miplevels as u16,
|
||||
allocator: Arc::clone(&allocator),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -149,7 +171,7 @@ impl OwnedImage {
|
|||
D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES,
|
||||
),
|
||||
util::d3d12_get_resource_transition_subresource(
|
||||
&self.handle,
|
||||
&self.handle.resource(),
|
||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
|
||||
D3D12_RESOURCE_STATE_COPY_DEST,
|
||||
D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES,
|
||||
|
@ -160,7 +182,7 @@ impl OwnedImage {
|
|||
cmd.ResourceBarrier(&barriers);
|
||||
|
||||
let dst = D3D12_TEXTURE_COPY_LOCATION {
|
||||
pResource: ManuallyDrop::new(Some(self.handle.clone())),
|
||||
pResource: ManuallyDrop::new(Some(self.handle.resource().clone())),
|
||||
Type: D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
|
||||
Anonymous: D3D12_TEXTURE_COPY_LOCATION_0 {
|
||||
SubresourceIndex: 0,
|
||||
|
@ -203,7 +225,7 @@ impl OwnedImage {
|
|||
D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES,
|
||||
),
|
||||
util::d3d12_get_resource_transition_subresource(
|
||||
&self.handle,
|
||||
&self.handle.resource(),
|
||||
D3D12_RESOURCE_STATE_COPY_DEST,
|
||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
|
||||
D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES,
|
||||
|
@ -224,7 +246,7 @@ impl OwnedImage {
|
|||
) -> error::Result<()> {
|
||||
util::d3d12_resource_transition(
|
||||
cmd,
|
||||
&self.handle,
|
||||
&self.handle.resource(),
|
||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
|
||||
D3D12_RESOURCE_STATE_RENDER_TARGET,
|
||||
);
|
||||
|
@ -235,7 +257,7 @@ impl OwnedImage {
|
|||
|
||||
util::d3d12_resource_transition(
|
||||
cmd,
|
||||
&self.handle,
|
||||
&self.handle.resource(),
|
||||
D3D12_RESOURCE_STATE_RENDER_TARGET,
|
||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
|
||||
);
|
||||
|
@ -265,14 +287,14 @@ impl OwnedImage {
|
|||
};
|
||||
|
||||
self.device.CreateShaderResourceView(
|
||||
&self.handle,
|
||||
self.handle.resource(),
|
||||
Some(&srv_desc),
|
||||
*descriptor.deref().as_ref(),
|
||||
);
|
||||
}
|
||||
|
||||
Ok(InputTexture::new(
|
||||
self.handle.clone(),
|
||||
self.handle.resource().clone(),
|
||||
descriptor,
|
||||
self.size,
|
||||
self.format,
|
||||
|
@ -300,7 +322,7 @@ impl OwnedImage {
|
|||
};
|
||||
|
||||
self.device.CreateRenderTargetView(
|
||||
&self.handle,
|
||||
self.handle.resource(),
|
||||
Some(&rtv_desc),
|
||||
*descriptor.deref().as_ref(),
|
||||
);
|
||||
|
@ -330,7 +352,7 @@ impl OwnedImage {
|
|||
|| (!mipmap && self.max_mipmap != 1)
|
||||
|| format != self.format
|
||||
{
|
||||
let mut new = OwnedImage::new(&self.device, size, format, mipmap)?;
|
||||
let mut new = OwnedImage::new(&self.device, &self.allocator, size, format, mipmap)?;
|
||||
std::mem::swap(self, &mut new);
|
||||
}
|
||||
Ok(size)
|
||||
|
@ -361,3 +383,12 @@ impl ScaleFramebuffer for OwnedImage {
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for OwnedImage {
|
||||
fn drop(&mut self) {
|
||||
let resource = unsafe { ManuallyDrop::take(&mut self.handle) };
|
||||
if let Err(e) = self.allocator.lock().free_resource(resource) {
|
||||
println!("librashader-runtime-d3d12: [warn] failed to deallocate owned image buffer memory {e}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,20 +1,25 @@
|
|||
use crate::descriptor_heap::{CpuStagingHeap, D3D12DescriptorHeap};
|
||||
use crate::error;
|
||||
use crate::error::assume_d3d12_init;
|
||||
use crate::filter_chain::FrameResiduals;
|
||||
use crate::mipmap::MipmapGenContext;
|
||||
use crate::texture::InputTexture;
|
||||
use crate::util::{d3d12_get_closest_format, d3d12_resource_transition, d3d12_update_subresources};
|
||||
use gpu_allocator::d3d12::{
|
||||
Allocator, Resource, ResourceCategory, ResourceCreateDesc, ResourceStateOrBarrierLayout,
|
||||
ResourceType,
|
||||
};
|
||||
use gpu_allocator::MemoryLocation;
|
||||
use librashader_common::{FilterMode, ImageFormat, WrapMode};
|
||||
use librashader_runtime::image::Image;
|
||||
use librashader_runtime::scaling::MipmapSize;
|
||||
use parking_lot::Mutex;
|
||||
use std::mem::ManuallyDrop;
|
||||
use std::ops::Deref;
|
||||
use std::sync::Arc;
|
||||
use windows::Win32::Graphics::Direct3D12::{
|
||||
ID3D12Device, ID3D12GraphicsCommandList, ID3D12Resource, D3D12_CPU_PAGE_PROPERTY_UNKNOWN,
|
||||
D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING, D3D12_FEATURE_DATA_FORMAT_SUPPORT,
|
||||
D3D12_FORMAT_SUPPORT1_MIP, D3D12_FORMAT_SUPPORT1_SHADER_SAMPLE,
|
||||
D3D12_FORMAT_SUPPORT1_TEXTURE2D, D3D12_HEAP_FLAG_NONE, D3D12_HEAP_PROPERTIES,
|
||||
D3D12_HEAP_TYPE_DEFAULT, D3D12_HEAP_TYPE_UPLOAD, D3D12_MEMORY_POOL_UNKNOWN,
|
||||
ID3D12Device, ID3D12GraphicsCommandList, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING,
|
||||
D3D12_FEATURE_DATA_FORMAT_SUPPORT, D3D12_FORMAT_SUPPORT1_MIP,
|
||||
D3D12_FORMAT_SUPPORT1_SHADER_SAMPLE, D3D12_FORMAT_SUPPORT1_TEXTURE2D,
|
||||
D3D12_PLACED_SUBRESOURCE_FOOTPRINT, D3D12_RESOURCE_DESC, D3D12_RESOURCE_DIMENSION_BUFFER,
|
||||
D3D12_RESOURCE_DIMENSION_TEXTURE2D, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS,
|
||||
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_GENERIC_READ,
|
||||
|
@ -25,15 +30,19 @@ use windows::Win32::Graphics::Direct3D12::{
|
|||
use windows::Win32::Graphics::Dxgi::Common::DXGI_SAMPLE_DESC;
|
||||
|
||||
pub struct LutTexture {
|
||||
resource: ID3D12Resource,
|
||||
resource: ManuallyDrop<Resource>,
|
||||
view: InputTexture,
|
||||
miplevels: Option<u16>,
|
||||
_staging: ID3D12Resource,
|
||||
// Staging heap needs to be kept alive until the command list is submitted, which is
|
||||
// really annoying. We could probably do better but it's safer to keep it around.
|
||||
staging: ManuallyDrop<Resource>,
|
||||
allocator: Arc<Mutex<Allocator>>,
|
||||
}
|
||||
|
||||
impl LutTexture {
|
||||
pub(crate) fn new(
|
||||
device: &ID3D12Device,
|
||||
allocator: &Arc<Mutex<Allocator>>,
|
||||
heap: &mut D3D12DescriptorHeap<CpuStagingHeap>,
|
||||
cmd: &ID3D12GraphicsCommandList,
|
||||
source: &Image,
|
||||
|
@ -74,24 +83,19 @@ impl LutTexture {
|
|||
let descriptor = heap.alloc_slot()?;
|
||||
|
||||
// create handles on GPU
|
||||
let mut resource: Option<ID3D12Resource> = None;
|
||||
unsafe {
|
||||
device.CreateCommittedResource(
|
||||
&D3D12_HEAP_PROPERTIES {
|
||||
Type: D3D12_HEAP_TYPE_DEFAULT,
|
||||
CPUPageProperty: D3D12_CPU_PAGE_PROPERTY_UNKNOWN,
|
||||
MemoryPoolPreference: D3D12_MEMORY_POOL_UNKNOWN,
|
||||
CreationNodeMask: 1,
|
||||
VisibleNodeMask: 1,
|
||||
},
|
||||
D3D12_HEAP_FLAG_NONE,
|
||||
&desc,
|
||||
let resource = allocator.lock().create_resource(&ResourceCreateDesc {
|
||||
name: "lut alloc",
|
||||
memory_location: MemoryLocation::GpuOnly,
|
||||
resource_category: ResourceCategory::OtherTexture,
|
||||
resource_desc: &desc,
|
||||
castable_formats: &[],
|
||||
clear_value: None,
|
||||
initial_state_or_layout: ResourceStateOrBarrierLayout::ResourceState(
|
||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
|
||||
None,
|
||||
&mut resource,
|
||||
)?;
|
||||
}
|
||||
assume_d3d12_init!(resource, "CreateCommittedResource");
|
||||
),
|
||||
resource_type: &ResourceType::Placed,
|
||||
})?;
|
||||
|
||||
unsafe {
|
||||
let srv_desc = D3D12_SHADER_RESOURCE_VIEW_DESC {
|
||||
Format: desc.Format,
|
||||
|
@ -106,7 +110,7 @@ impl LutTexture {
|
|||
};
|
||||
|
||||
device.CreateShaderResourceView(
|
||||
&resource,
|
||||
resource.resource(),
|
||||
Some(&srv_desc),
|
||||
*descriptor.deref().as_ref(),
|
||||
);
|
||||
|
@ -139,25 +143,40 @@ impl LutTexture {
|
|||
buffer_desc.SampleDesc.Count = 1;
|
||||
buffer_desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
|
||||
}
|
||||
let mut upload: Option<ID3D12Resource> = None;
|
||||
|
||||
unsafe {
|
||||
device.CreateCommittedResource(
|
||||
&D3D12_HEAP_PROPERTIES {
|
||||
Type: D3D12_HEAP_TYPE_UPLOAD,
|
||||
CPUPageProperty: D3D12_CPU_PAGE_PROPERTY_UNKNOWN,
|
||||
MemoryPoolPreference: D3D12_MEMORY_POOL_UNKNOWN,
|
||||
CreationNodeMask: 1,
|
||||
VisibleNodeMask: 1,
|
||||
},
|
||||
D3D12_HEAP_FLAG_NONE,
|
||||
&buffer_desc,
|
||||
let upload = allocator.lock().create_resource(&ResourceCreateDesc {
|
||||
name: "lut staging",
|
||||
memory_location: MemoryLocation::CpuToGpu,
|
||||
resource_category: ResourceCategory::Buffer,
|
||||
resource_desc: &buffer_desc,
|
||||
castable_formats: &[],
|
||||
clear_value: None,
|
||||
initial_state_or_layout: ResourceStateOrBarrierLayout::ResourceState(
|
||||
D3D12_RESOURCE_STATE_GENERIC_READ,
|
||||
None,
|
||||
&mut upload,
|
||||
)?;
|
||||
}
|
||||
assume_d3d12_init!(upload, "CreateCommittedResource");
|
||||
),
|
||||
resource_type: &ResourceType::Placed,
|
||||
})?;
|
||||
|
||||
//
|
||||
// let mut upload: Option<ID3D12Resource> = None;
|
||||
//
|
||||
// unsafe {
|
||||
// device.CreateCommittedResource(
|
||||
// &D3D12_HEAP_PROPERTIES {
|
||||
// Type: D3D12_HEAP_TYPE_UPLOAD,
|
||||
// CPUPageProperty: D3D12_CPU_PAGE_PROPERTY_UNKNOWN,
|
||||
// MemoryPoolPreference: D3D12_MEMORY_POOL_UNKNOWN,
|
||||
// CreationNodeMask: 1,
|
||||
// VisibleNodeMask: 1,
|
||||
// },
|
||||
// D3D12_HEAP_FLAG_NONE,
|
||||
// &buffer_desc,
|
||||
// D3D12_RESOURCE_STATE_GENERIC_READ,
|
||||
// None,
|
||||
// &mut upload,
|
||||
// )?;
|
||||
// }
|
||||
// assume_d3d12_init!(upload, "CreateCommittedResource");
|
||||
|
||||
let subresource = [D3D12_SUBRESOURCE_DATA {
|
||||
pData: source.bytes.as_ptr().cast(),
|
||||
|
@ -167,22 +186,31 @@ impl LutTexture {
|
|||
|
||||
d3d12_resource_transition(
|
||||
cmd,
|
||||
&resource,
|
||||
&resource.resource(),
|
||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
|
||||
D3D12_RESOURCE_STATE_COPY_DEST,
|
||||
);
|
||||
|
||||
d3d12_update_subresources(cmd, &resource, &upload, 0, 0, 1, &subresource, gc)?;
|
||||
d3d12_update_subresources(
|
||||
cmd,
|
||||
&resource.resource(),
|
||||
&upload.resource(),
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
&subresource,
|
||||
gc,
|
||||
)?;
|
||||
|
||||
d3d12_resource_transition(
|
||||
cmd,
|
||||
&resource,
|
||||
&resource.resource(),
|
||||
D3D12_RESOURCE_STATE_COPY_DEST,
|
||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
|
||||
);
|
||||
|
||||
let view = InputTexture::new(
|
||||
resource.clone(),
|
||||
resource.resource().clone(),
|
||||
descriptor,
|
||||
source.size,
|
||||
ImageFormat::R8G8B8A8Unorm.into(),
|
||||
|
@ -190,17 +218,18 @@ impl LutTexture {
|
|||
wrap_mode,
|
||||
);
|
||||
Ok(LutTexture {
|
||||
resource,
|
||||
_staging: upload,
|
||||
resource: ManuallyDrop::new(resource),
|
||||
staging: ManuallyDrop::new(upload),
|
||||
view,
|
||||
miplevels: if mipmap { Some(miplevels) } else { None },
|
||||
allocator: Arc::clone(&allocator),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn generate_mipmaps(&self, gen_mips: &mut MipmapGenContext) -> error::Result<()> {
|
||||
if let Some(miplevels) = self.miplevels {
|
||||
gen_mips.generate_mipmaps(
|
||||
&self.resource,
|
||||
&self.resource.resource(),
|
||||
miplevels,
|
||||
self.view.size,
|
||||
ImageFormat::R8G8B8A8Unorm.into(),
|
||||
|
@ -216,3 +245,17 @@ impl AsRef<InputTexture> for LutTexture {
|
|||
&self.view
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for LutTexture {
|
||||
fn drop(&mut self) {
|
||||
let resource = unsafe { ManuallyDrop::take(&mut self.resource) };
|
||||
if let Err(e) = self.allocator.lock().free_resource(resource) {
|
||||
println!("librashader-runtime-d3d12: [warn] failed to deallocate lut buffer memory {e}")
|
||||
}
|
||||
|
||||
let staging = unsafe { ManuallyDrop::take(&mut self.staging) };
|
||||
if let Err(e) = self.allocator.lock().free_resource(staging) {
|
||||
println!("librashader-runtime-d3d12: [warn] failed to deallocate lut staging buffer memory {e}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,11 +6,11 @@ use crate::hello_triangle::{DXSample, SampleCommandLine};
|
|||
fn triangle_d3d12() {
|
||||
let sample = hello_triangle::d3d12_hello_triangle::Sample::new(
|
||||
// "../test/shaders_slang/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp",
|
||||
"../test/shaders_slang/crt/crt-lottes.slangp",
|
||||
// "../test/shaders_slang/crt/crt-lottes.slangp",
|
||||
// "../test/basic.slangp",
|
||||
// "../test/shaders_slang/handheld/console-border/gbc-lcd-grid-v2.slangp",
|
||||
// "../test/Mega_Bezel_Packs/Duimon-Mega-Bezel/Presets/Advanced/Nintendo_GBA_SP/GBA_SP-[ADV]-[LCD-GRID]-[Night].slangp",
|
||||
// "../test/slang-shaders/test/feedback.slangp",
|
||||
"../test/shaders_slang/test/feedback.slangp",
|
||||
// "../test/shaders_slang/test/history.slangp",
|
||||
// "../test/shaders_slang/crt/crt-royale.slangp",
|
||||
// "../test/slang-shaders/vhs/VHSPro.slangp",
|
||||
|
|
Loading…
Reference in a new issue