diff --git a/librashader-runtime-d3d11/src/lib.rs b/librashader-runtime-d3d11/src/lib.rs index e6076b5..8f17147 100644 --- a/librashader-runtime-d3d11/src/lib.rs +++ b/librashader-runtime-d3d11/src/lib.rs @@ -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, diff --git a/librashader-runtime-d3d12/src/descriptor_heap.rs b/librashader-runtime-d3d12/src/descriptor_heap.rs index ef8c955..f9169af 100644 --- a/librashader-runtime-d3d12/src/descriptor_heap.rs +++ b/librashader-runtime-d3d12/src/descriptor_heap.rs @@ -337,7 +337,9 @@ impl D3D12DescriptorHeap { } } - Err(FilterChainError::DescriptorHeapOverflow) + Err(FilterChainError::DescriptorHeapOverflow( + inner.num_descriptors, + )) } pub fn alloc_range( diff --git a/librashader-runtime-d3d12/src/error.rs b/librashader-runtime-d3d12/src/error.rs index 6020244..09d2ad3 100644 --- a/librashader-runtime-d3d12/src/error.rs +++ b/librashader-runtime-d3d12/src/error.rs @@ -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. diff --git a/librashader-runtime-d3d12/src/filter_chain.rs b/librashader-runtime-d3d12/src/filter_chain.rs index 8744701..6041c92 100644 --- a/librashader-runtime-d3d12/src/filter_chain.rs +++ b/librashader-runtime-d3d12/src/filter_chain.rs @@ -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, + residuals: FrameResiduals, mipmap_heap: D3D12DescriptorHeap, disable_mipmaps: bool, @@ -94,6 +95,42 @@ pub(crate) struct FilterCommon { pub draw_quad: DrawQuad, } +pub(crate) struct FrameResiduals { + outputs: Vec, + mipmaps: Vec>, +} + +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>, + ) { + 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() } diff --git a/librashader-runtime-d3d12/src/framebuffer.rs b/librashader-runtime-d3d12/src/framebuffer.rs index 251ea27..19496f2 100644 --- a/librashader-runtime-d3d12/src/framebuffer.rs +++ b/librashader-runtime-d3d12/src/framebuffer.rs @@ -31,8 +31,8 @@ pub(crate) struct OwnedImage { pub(crate) handle: ID3D12Resource, pub(crate) size: Size, 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]; diff --git a/librashader-runtime-d3d12/src/lib.rs b/librashader-runtime-d3d12/src/lib.rs index b629607..d57b434 100644 --- a/librashader-runtime-d3d12/src/lib.rs +++ b/librashader-runtime-d3d12/src/lib.rs @@ -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", diff --git a/librashader-runtime-d3d12/src/mipmap.rs b/librashader-runtime-d3d12/src/mipmap.rs index 11a22a6..a8c0e3c 100644 --- a/librashader-runtime-d3d12/src/mipmap.rs +++ b/librashader-runtime-d3d12/src/mipmap.rs @@ -200,7 +200,6 @@ impl D3D12MipmapGen { &self, cmd: &ID3D12GraphicsCommandList, resource: &ID3D12Resource, - miplevels: u16, size: Size, 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, ); diff --git a/test/basic.slangp b/test/basic.slangp index 6e3cb6c..8edd75d 100644 --- a/test/basic.slangp +++ b/test/basic.slangp @@ -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"