d3d12: allocate framebuffers
This commit is contained in:
parent
c28e5195c2
commit
624a749098
|
@ -1,4 +1,4 @@
|
||||||
|
use std::collections::VecDeque;
|
||||||
use crate::{error};
|
use crate::{error};
|
||||||
use crate::heap::{D3D12DescriptorHeap, CpuStagingHeap, ResourceWorkHeap};
|
use crate::heap::{D3D12DescriptorHeap, CpuStagingHeap, ResourceWorkHeap};
|
||||||
use crate::samplers::SamplerSet;
|
use crate::samplers::SamplerSet;
|
||||||
|
@ -21,16 +21,18 @@ use windows::Win32::Graphics::Direct3D12::{
|
||||||
};
|
};
|
||||||
use windows::Win32::System::Threading::{CreateEventA, ResetEvent, WaitForSingleObject};
|
use windows::Win32::System::Threading::{CreateEventA, ResetEvent, WaitForSingleObject};
|
||||||
use windows::Win32::System::WindowsProgramming::INFINITE;
|
use windows::Win32::System::WindowsProgramming::INFINITE;
|
||||||
use librashader_common::ImageFormat;
|
use librashader_common::{ImageFormat, Size};
|
||||||
use librashader_reflect::back::{CompileReflectShader, CompileShader};
|
use librashader_reflect::back::{CompileReflectShader, CompileShader};
|
||||||
use librashader_reflect::reflect::ReflectShader;
|
use librashader_reflect::reflect::ReflectShader;
|
||||||
use librashader_reflect::reflect::semantics::{MAX_BINDINGS_COUNT, ShaderSemantics, UniformBinding};
|
use librashader_reflect::reflect::semantics::{MAX_BINDINGS_COUNT, ShaderSemantics, TextureSemantics, UniformBinding};
|
||||||
use librashader_runtime::uniforms::UniformStorage;
|
use librashader_runtime::uniforms::UniformStorage;
|
||||||
use crate::buffer::{D3D12Buffer, D3D12ConstantBuffer};
|
use crate::buffer::{D3D12Buffer, D3D12ConstantBuffer};
|
||||||
use crate::filter_pass::FilterPass;
|
use crate::filter_pass::FilterPass;
|
||||||
|
use crate::framebuffer::OwnedImage;
|
||||||
use crate::graphics_pipeline::{D3D12GraphicsPipeline, D3D12RootSignature};
|
use crate::graphics_pipeline::{D3D12GraphicsPipeline, D3D12RootSignature};
|
||||||
use crate::mipmap::D3D12MipmapGen;
|
use crate::mipmap::D3D12MipmapGen;
|
||||||
use crate::quad_render::DrawQuad;
|
use crate::quad_render::DrawQuad;
|
||||||
|
use crate::texture::InputTexture;
|
||||||
|
|
||||||
type ShaderPassMeta = ShaderPassArtifact<impl CompileReflectShader<HLSL, GlslangCompilation>>;
|
type ShaderPassMeta = ShaderPassArtifact<impl CompileReflectShader<HLSL, GlslangCompilation>>;
|
||||||
|
|
||||||
|
@ -41,23 +43,21 @@ pub struct FilterMutable {
|
||||||
|
|
||||||
pub struct FilterChainD3D12 {
|
pub struct FilterChainD3D12 {
|
||||||
pub(crate) common: FilterCommon,
|
pub(crate) common: FilterCommon,
|
||||||
// pub(crate) passes: Vec<FilterPass>,
|
|
||||||
// pub(crate) output_framebuffers: Box<[OwnedFramebuffer]>,
|
|
||||||
// pub(crate) feedback_framebuffers: Box<[OwnedFramebuffer]>,
|
|
||||||
// pub(crate) history_framebuffers: VecDeque<OwnedFramebuffer>,
|
|
||||||
// pub(crate) draw_quad: DrawQuad,
|
|
||||||
pub(crate) passes: Vec<FilterPass>,
|
pub(crate) passes: Vec<FilterPass>,
|
||||||
|
pub(crate) output_framebuffers: Box<[OwnedImage]>,
|
||||||
|
pub(crate) feedback_framebuffers: Box<[OwnedImage]>,
|
||||||
|
pub(crate) history_framebuffers: VecDeque<OwnedImage>,
|
||||||
|
staging_heap: D3D12DescriptorHeap<CpuStagingHeap>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct FilterCommon {
|
pub(crate) struct FilterCommon {
|
||||||
pub(crate) d3d12: ID3D12Device,
|
pub(crate) d3d12: ID3D12Device,
|
||||||
pub samplers: SamplerSet,
|
pub samplers: SamplerSet,
|
||||||
// pub output_textures: Box<[Option<InputTexture>]>,
|
pub output_textures: Box<[Option<InputTexture>]>,
|
||||||
// pub feedback_textures: Box<[Option<InputTexture>]>,
|
pub feedback_textures: Box<[Option<InputTexture>]>,
|
||||||
// pub history_textures: Box<[Option<InputTexture>]>,
|
pub history_textures: Box<[Option<InputTexture>]>,
|
||||||
pub config: FilterMutable,
|
pub config: FilterMutable,
|
||||||
// pub disable_mipmaps: bool,
|
// pub disable_mipmaps: bool,
|
||||||
lut_heap: D3D12DescriptorHeap<CpuStagingHeap>,
|
|
||||||
pub luts: FxHashMap<usize, LutTexture>,
|
pub luts: FxHashMap<usize, LutTexture>,
|
||||||
pub mipmap_gen: D3D12MipmapGen,
|
pub mipmap_gen: D3D12MipmapGen,
|
||||||
pub root_signature: D3D12RootSignature,
|
pub root_signature: D3D12RootSignature,
|
||||||
|
@ -92,21 +92,70 @@ impl FilterChainD3D12 {
|
||||||
let mipmap_gen = D3D12MipmapGen::new(device).unwrap();
|
let mipmap_gen = D3D12MipmapGen::new(device).unwrap();
|
||||||
|
|
||||||
let draw_quad = DrawQuad::new(device)?;
|
let draw_quad = DrawQuad::new(device)?;
|
||||||
let mut lut_heap = D3D12DescriptorHeap::new(device, preset.textures.len())?;
|
let mut staging_heap =
|
||||||
let luts = FilterChainD3D12::load_luts(device, &mut lut_heap, &preset.textures, &mipmap_gen).unwrap();
|
D3D12DescriptorHeap::new(device,
|
||||||
|
(MAX_BINDINGS_COUNT as usize) * 64 + 2048 + preset.textures.len())?;
|
||||||
|
|
||||||
|
|
||||||
|
let luts = FilterChainD3D12::load_luts(device, &mut staging_heap, &preset.textures, &mipmap_gen).unwrap();
|
||||||
|
|
||||||
let root_signature = D3D12RootSignature::new(device)?;
|
let root_signature = D3D12RootSignature::new(device)?;
|
||||||
|
|
||||||
let filters = FilterChainD3D12::init_passes(device, &root_signature, passes, &semantics)?;
|
let filters = FilterChainD3D12::init_passes(device, &root_signature, passes, &semantics)?;
|
||||||
|
|
||||||
|
|
||||||
let work_heap =
|
let work_heap =
|
||||||
D3D12DescriptorHeap::<ResourceWorkHeap>::new(device, (MAX_BINDINGS_COUNT as usize) * 64 + 2048)?;
|
D3D12DescriptorHeap::<ResourceWorkHeap>::new(device, (MAX_BINDINGS_COUNT as usize) * 64 + 2048)?;
|
||||||
|
|
||||||
|
|
||||||
|
// initialize output framebuffers
|
||||||
|
let mut output_framebuffers = Vec::new();
|
||||||
|
output_framebuffers.resize_with(filters.len(), || {
|
||||||
|
OwnedImage::new(
|
||||||
|
device,
|
||||||
|
Size::new(1, 1),
|
||||||
|
ImageFormat::R8G8B8A8Unorm,
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
|
// resolve all results
|
||||||
|
let output_framebuffers = output_framebuffers
|
||||||
|
.into_iter()
|
||||||
|
.collect::<error::Result<Vec<OwnedImage>>>()?;
|
||||||
|
let mut output_textures = Vec::new();
|
||||||
|
output_textures.resize_with(filters.len(), || None);
|
||||||
|
|
||||||
|
// let mut output_textures = Vec::new();
|
||||||
|
// output_textures.resize_with(filters.len(), || None);
|
||||||
|
//
|
||||||
|
// // initialize feedback framebuffers
|
||||||
|
let mut feedback_framebuffers = Vec::new();
|
||||||
|
feedback_framebuffers.resize_with(filters.len(), || {
|
||||||
|
OwnedImage::new(
|
||||||
|
device,
|
||||||
|
Size::new(1, 1),
|
||||||
|
ImageFormat::R8G8B8A8Unorm,
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
|
// resolve all results
|
||||||
|
let feedback_framebuffers = feedback_framebuffers
|
||||||
|
.into_iter()
|
||||||
|
.collect::<error::Result<Vec<OwnedImage>>>()?;
|
||||||
|
let mut feedback_textures = Vec::new();
|
||||||
|
feedback_textures.resize_with(filters.len(), || None);
|
||||||
|
|
||||||
|
let (history_framebuffers, history_textures) =
|
||||||
|
FilterChainD3D12::init_history(device, &filters)?;
|
||||||
|
|
||||||
Ok(FilterChainD3D12 {
|
Ok(FilterChainD3D12 {
|
||||||
common: FilterCommon {
|
common: FilterCommon {
|
||||||
d3d12: device.clone(),
|
d3d12: device.clone(),
|
||||||
samplers,
|
samplers,
|
||||||
lut_heap,
|
output_textures: output_textures.into_boxed_slice(),
|
||||||
|
feedback_textures: feedback_textures.into_boxed_slice(),
|
||||||
luts,
|
luts,
|
||||||
mipmap_gen,
|
mipmap_gen,
|
||||||
root_signature,
|
root_signature,
|
||||||
|
@ -120,11 +169,73 @@ impl FilterChainD3D12 {
|
||||||
.map(|param| (param.name, param.value))
|
.map(|param| (param.name, param.value))
|
||||||
.collect(),
|
.collect(),
|
||||||
},
|
},
|
||||||
|
history_textures,
|
||||||
},
|
},
|
||||||
passes: filters
|
staging_heap,
|
||||||
|
passes: filters,
|
||||||
|
output_framebuffers: output_framebuffers.into_boxed_slice(),
|
||||||
|
feedback_framebuffers: feedback_framebuffers.into_boxed_slice(),
|
||||||
|
history_framebuffers,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn init_history(
|
||||||
|
device: &ID3D12Device,
|
||||||
|
filters: &Vec<FilterPass>,
|
||||||
|
) -> error::Result<(VecDeque<OwnedImage>, Box<[Option<InputTexture>]>)> {
|
||||||
|
let mut required_images = 0;
|
||||||
|
|
||||||
|
for pass in filters {
|
||||||
|
// If a shader uses history size, but not history, we still need to keep the texture.
|
||||||
|
let texture_count = pass
|
||||||
|
.reflection
|
||||||
|
.meta
|
||||||
|
.texture_meta
|
||||||
|
.iter()
|
||||||
|
.filter(|(semantics, _)| semantics.semantics == TextureSemantics::OriginalHistory)
|
||||||
|
.count();
|
||||||
|
let texture_size_count = pass
|
||||||
|
.reflection
|
||||||
|
.meta
|
||||||
|
.texture_size_meta
|
||||||
|
.iter()
|
||||||
|
.filter(|(semantics, _)| semantics.semantics == TextureSemantics::OriginalHistory)
|
||||||
|
.count();
|
||||||
|
|
||||||
|
required_images = std::cmp::max(required_images, texture_count);
|
||||||
|
required_images = std::cmp::max(required_images, texture_size_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
// not using frame history;
|
||||||
|
if required_images <= 1 {
|
||||||
|
// println!("[history] not using frame history");
|
||||||
|
return Ok((VecDeque::new(), Box::new([])));
|
||||||
|
}
|
||||||
|
|
||||||
|
// history0 is aliased with the original
|
||||||
|
|
||||||
|
// eprintln!("[history] using frame history with {required_images} images");
|
||||||
|
let mut framebuffers = VecDeque::with_capacity(required_images);
|
||||||
|
framebuffers.resize_with(required_images, || {
|
||||||
|
OwnedImage::new(
|
||||||
|
device,
|
||||||
|
Size::new(1, 1),
|
||||||
|
ImageFormat::R8G8B8A8Unorm,
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
|
let framebuffers = framebuffers
|
||||||
|
.into_iter()
|
||||||
|
.collect::<error::Result<VecDeque<OwnedImage>>>()?;
|
||||||
|
|
||||||
|
let mut history_textures = Vec::new();
|
||||||
|
history_textures.resize_with(required_images, || None);
|
||||||
|
|
||||||
|
Ok((framebuffers, history_textures.into_boxed_slice()))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
fn load_luts(
|
fn load_luts(
|
||||||
device: &ID3D12Device,
|
device: &ID3D12Device,
|
||||||
heap: &mut D3D12DescriptorHeap<CpuStagingHeap>,
|
heap: &mut D3D12DescriptorHeap<CpuStagingHeap>,
|
||||||
|
|
Loading…
Reference in a new issue