d3d12: fix mipmaps again

This commit is contained in:
chyyran 2023-02-09 19:44:01 -05:00
parent 8cfe59c7aa
commit 55e800b67e
8 changed files with 86 additions and 35 deletions

View file

@ -35,10 +35,11 @@ mod tests {
// "../test/slang-shaders/scalefx/scalefx-9x.slangp",
// "../test/slang-shaders/bezel/koko-aio/monitor-bloom.slangp",
// "../test/slang-shaders/presets/crt-geom-ntsc-upscale-sharp.slangp",
const FILTER_PATH: &str =
"../test/slang-shaders/handheld/console-border/gbc-lcd-grid-v2.slangp";
// const FILTER_PATH: &str =
// "../test/slang-shaders/handheld/console-border/gbc-lcd-grid-v2.slangp";
// "../test/null.slangp",
// const FILTER_PATH: &str = "../test/slang-shaders/crt/crt-royale.slangp";
const FILTER_PATH: &str =
"../test/slang-shaders/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV-GLASS.slangp";
// const FILTER_PATH: &str = "../test/slang-shaders/crt/crt-royale.slangp";
const IMAGE_PATH: &str = "../triangle.png";
@ -83,7 +84,7 @@ mod tests {
FILTER_PATH,
Some(&FilterChainOptionsD3D11 {
use_deferred_context: false,
force_no_mipmaps: false,
force_no_mipmaps: true,
}),
// replace below with 'None' for the triangle
// None,

View file

@ -337,7 +337,9 @@ impl<T> D3D12DescriptorHeap<T> {
}
}
Err(FilterChainError::DescriptorHeapOverflow)
Err(FilterChainError::DescriptorHeapOverflow(
inner.num_descriptors,
))
}
pub fn alloc_range<const NUM_DESC: usize>(

View file

@ -22,7 +22,7 @@ pub enum FilterChainError {
#[error("lut loading error")]
LutLoadError(#[from] ImageError),
#[error("heap overflow")]
DescriptorHeapOverflow,
DescriptorHeapOverflow(usize),
}
/// Result type for Direct3D 12 filter chains.

View file

@ -1,6 +1,7 @@
use crate::buffer::{D3D12Buffer, RawD3D12Buffer};
use crate::descriptor_heap::{
CpuStagingHeap, D3D12DescriptorHeap, RenderTargetHeap, ResourceWorkHeap,
CpuStagingHeap, D3D12DescriptorHeap, D3D12DescriptorHeapSlot, RenderTargetHeap,
ResourceWorkHeap,
};
use crate::error::FilterChainError;
use crate::filter_pass::FilterPass;
@ -74,7 +75,7 @@ pub struct FilterChainD3D12 {
work_heap: ID3D12DescriptorHeap,
sampler_heap: ID3D12DescriptorHeap,
residuals: Vec<OutputDescriptor>,
residuals: FrameResiduals,
mipmap_heap: D3D12DescriptorHeap<ResourceWorkHeap>,
disable_mipmaps: bool,
@ -94,6 +95,42 @@ pub(crate) struct FilterCommon {
pub draw_quad: DrawQuad,
}
pub(crate) struct FrameResiduals {
outputs: Vec<OutputDescriptor>,
mipmaps: Vec<D3D12DescriptorHeapSlot<ResourceWorkHeap>>,
}
impl FrameResiduals {
pub fn new() -> Self {
Self {
outputs: Vec::new(),
mipmaps: Vec::new(),
}
}
pub fn dispose_output(&mut self, descriptor: OutputDescriptor) {
self.outputs.push(descriptor)
}
pub fn dispose_mipmap_handles(
&mut self,
handles: Vec<D3D12DescriptorHeapSlot<ResourceWorkHeap>>,
) {
self.mipmaps.extend(handles)
}
pub fn dispose(&mut self) {
self.outputs.clear();
self.mipmaps.clear();
}
}
impl Drop for FrameResiduals {
fn drop(&mut self) {
self.dispose();
}
}
impl FilterChainD3D12 {
/// Load the shader preset at the given path into a filter chain.
pub fn load_from_path(
@ -215,7 +252,7 @@ impl FilterChainD3D12 {
sampler_heap,
mipmap_heap,
disable_mipmaps: options.map_or(false, |o| o.force_no_mipmaps),
residuals: Vec::new(),
residuals: FrameResiduals::new(),
})
}
@ -530,7 +567,7 @@ impl FilterChainD3D12 {
frame_count: usize,
options: Option<&FrameOptionsD3D12>,
) -> error::Result<()> {
self.residuals.clear();
self.residuals.dispose();
if let Some(options) = options {
if options.clear_history {
@ -632,24 +669,6 @@ impl FilterChainD3D12 {
source.filter = pass.config.filter;
source.wrap_mode = pass.config.wrap_mode;
if pass.config.mipmap_input && !self.disable_mipmaps {
unsafe {
self.common.mipmap_gen.mipmapping_context(
cmd,
&mut self.mipmap_heap,
|ctx| {
ctx.generate_mipmaps(
&source.resource,
source.size().calculate_miplevels() as u16,
source.size,
source.format,
)?;
Ok::<(), FilterChainError>(())
},
)?;
}
}
let target = &self.output_framebuffers[index];
util::d3d12_resource_transition(
cmd,
@ -681,7 +700,27 @@ impl FilterChainD3D12 {
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
);
self.residuals.push(view.descriptor);
if target.max_mipmap > 1 && !self.disable_mipmaps {
let residuals = unsafe {
self.common.mipmap_gen.mipmapping_context(
cmd,
&mut self.mipmap_heap,
|ctx| {
ctx.generate_mipmaps(
&target.handle,
target.max_mipmap,
target.size,
target.format.into(),
)?;
Ok::<(), FilterChainError>(())
},
)?
};
self.residuals.dispose_mipmap_handles(residuals);
}
self.residuals.dispose_output(view.descriptor);
source = self.common.output_textures[index].as_ref().unwrap().clone()
}

View file

@ -31,8 +31,8 @@ pub(crate) struct OwnedImage {
pub(crate) handle: ID3D12Resource,
pub(crate) size: Size<u32>,
pub(crate) format: ImageFormat,
pub(crate) max_mipmap: u16,
device: ID3D12Device,
max_mipmap: u16,
}
static CLEAR: &[f32; 4] = &[0.0, 0.0, 0.0, 0.0];

View file

@ -2,6 +2,7 @@
#![feature(const_trait_impl)]
#![feature(let_chains)]
#![feature(type_alias_impl_trait)]
#![feature(int_roundings)]
mod buffer;
mod descriptor_heap;
@ -33,6 +34,7 @@ mod tests {
fn triangle_d3d12() {
let sample = hello_triangle::d3d12_hello_triangle::Sample::new(
// "../test/slang-shaders/crt/crt-lottes.slangp",
// "../test/basic.slangp",
"../test/slang-shaders/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV-GLASS.slangp",
// "../test/slang-shaders/crt/crt-royale.slangp",
// "../test/slang-shaders/vhs/VHSPro.slangp",

View file

@ -200,7 +200,6 @@ impl D3D12MipmapGen {
&self,
cmd: &ID3D12GraphicsCommandList,
resource: &ID3D12Resource,
miplevels: u16,
size: Size<u32>,
format: DXGI_FORMAT,
@ -287,8 +286,8 @@ impl D3D12MipmapGen {
);
cmd.Dispatch(
std::cmp::max(scaled.width / 8, 1),
std::cmp::max(scaled.height / 8, 1),
std::cmp::max(scaled.width.div_ceil(8), 1),
std::cmp::max(scaled.height.div_ceil(8), 1),
1,
);

View file

@ -1,8 +1,16 @@
shaders = "1"
shaders = "2"
shader0 = "basic.slang"
wrap_mode0 = "clamp_to_border"
mipmap_input0 = "false"
mipmap_input0 = "true"
alias0 = ""
float_framebuffer0 = "false"
srgb_framebuffer0 = "false"
ColorMod = "1.700000"
shader1 = "basic.slang"
wrap_mode1 = "clamp_to_border"
mipmap_input1 = "true"
alias1 = ""
float_framebuffer0 = "false"
srgb_framebuffer0 = "false"
ColorMod = "1.700000"