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